@snow-labs/brutal-ui 0.3.1 → 0.4.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.
Files changed (32) hide show
  1. package/dist/components/brutal/comparison-table.d.ts +23 -0
  2. package/dist/components/brutal/comparison-table.js +117 -0
  3. package/dist/components/brutal/comparison-table.js.map +1 -0
  4. package/dist/components/brutal/cta-section.js +8 -4
  5. package/dist/components/brutal/cta-section.js.map +1 -1
  6. package/dist/components/brutal/feature-grid.d.ts +1 -1
  7. package/dist/components/brutal/feature-grid.js +8 -0
  8. package/dist/components/brutal/feature-grid.js.map +1 -1
  9. package/dist/components/brutal/feature-showcase.d.ts +20 -0
  10. package/dist/components/brutal/feature-showcase.js +158 -0
  11. package/dist/components/brutal/feature-showcase.js.map +1 -0
  12. package/dist/components/brutal/hero.js +4 -4
  13. package/dist/components/brutal/hero.js.map +1 -1
  14. package/dist/components/brutal/index.d.ts +4 -0
  15. package/dist/components/brutal/index.js +277 -51
  16. package/dist/components/brutal/index.js.map +1 -1
  17. package/dist/components/brutal/marquee.d.ts +17 -0
  18. package/dist/components/brutal/marquee.js +66 -0
  19. package/dist/components/brutal/marquee.js.map +1 -0
  20. package/dist/components/brutal/mockup-window.d.ts +11 -0
  21. package/dist/components/brutal/mockup-window.js +80 -0
  22. package/dist/components/brutal/mockup-window.js.map +1 -0
  23. package/dist/index.d.ts +4 -0
  24. package/dist/index.js +235 -9
  25. package/dist/index.js.map +1 -1
  26. package/dist/templates/index.js +20 -8
  27. package/dist/templates/index.js.map +1 -1
  28. package/dist/templates/saas-launch.js +20 -8
  29. package/dist/templates/saas-launch.js.map +1 -1
  30. package/dist/templates/studio.js +20 -8
  31. package/dist/templates/studio.js.map +1 -1
  32. package/package.json +1 -1
@@ -0,0 +1,23 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SectionColor, SectionPattern } from './section.js';
3
+
4
+ interface ComparisonFeature {
5
+ name: string;
6
+ us: string | boolean;
7
+ them: string | boolean;
8
+ highlight?: boolean;
9
+ }
10
+ interface BrutalComparisonTableProps {
11
+ badge?: string;
12
+ headline: string;
13
+ description?: string;
14
+ usName: string;
15
+ themName: string;
16
+ features: ComparisonFeature[];
17
+ color?: SectionColor;
18
+ pattern?: SectionPattern;
19
+ className?: string;
20
+ }
21
+ declare function BrutalComparisonTable({ badge, headline, description, usName, themName, features, color, pattern, className, }: BrutalComparisonTableProps): react_jsx_runtime.JSX.Element;
22
+
23
+ export { BrutalComparisonTable };
@@ -0,0 +1,117 @@
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
+ var colorMap = {
11
+ white: "bg-background text-foreground",
12
+ brand: "bg-brand",
13
+ "brand-muted": "bg-brand-muted text-foreground",
14
+ blue: "bg-section-blue",
15
+ gray: "bg-section-gray text-foreground",
16
+ cream: "bg-section-cream text-foreground",
17
+ black: "bg-foreground text-background",
18
+ cta: "bg-cta"
19
+ };
20
+ var containerMap = {
21
+ sm: "brutal-container-sm",
22
+ default: "brutal-container",
23
+ lg: "brutal-container-lg"
24
+ };
25
+ var paddingMap = {
26
+ sm: "brutal-section-sm",
27
+ default: "brutal-section",
28
+ lg: "brutal-section py-28 sm:py-36 md:py-44"
29
+ };
30
+ var patternMap = {
31
+ dots: "brutal-dots",
32
+ stripes: "brutal-stripes",
33
+ noise: "brutal-noise",
34
+ grain: "brutal-grain",
35
+ crosshatch: "brutal-crosshatch",
36
+ "grid-dots": "brutal-grid-dots",
37
+ "gradient-mesh": "brutal-gradient-mesh",
38
+ none: ""
39
+ };
40
+ function BrutalSection({
41
+ children,
42
+ color = "white",
43
+ className,
44
+ containerSize = "default",
45
+ padding = "default",
46
+ pattern,
47
+ dots = false,
48
+ stripes = false,
49
+ id
50
+ }) {
51
+ const resolvedPattern = pattern ?? (dots ? "dots" : void 0) ?? (stripes ? "stripes" : void 0) ?? "none";
52
+ return /* @__PURE__ */ jsx(
53
+ "section",
54
+ {
55
+ id,
56
+ className: cn(
57
+ paddingMap[padding],
58
+ colorMap[color],
59
+ patternMap[resolvedPattern],
60
+ className
61
+ ),
62
+ children: /* @__PURE__ */ jsx("div", { className: containerMap[containerSize], children })
63
+ }
64
+ );
65
+ }
66
+ function CellValue({ value }) {
67
+ if (typeof value === "boolean") {
68
+ return value ? /* @__PURE__ */ jsx("span", { className: "inline-flex size-7 items-center justify-center border-brutal border-foreground bg-brand font-bold text-brand-foreground text-sm", children: "\u2713" }) : /* @__PURE__ */ jsx("span", { className: "inline-flex size-7 items-center justify-center border-brutal border-foreground/20 text-sm text-muted-foreground", children: "\u2014" });
69
+ }
70
+ return /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: value });
71
+ }
72
+ function BrutalComparisonTable({
73
+ badge,
74
+ headline,
75
+ description,
76
+ usName,
77
+ themName,
78
+ features,
79
+ color = "white",
80
+ pattern,
81
+ className
82
+ }) {
83
+ return /* @__PURE__ */ jsxs(BrutalSection, { color, pattern, className, children: [
84
+ /* @__PURE__ */ jsxs("div", { className: "mb-12 max-w-2xl", children: [
85
+ badge && /* @__PURE__ */ jsx("p", { className: "brutal-label mb-4 text-brand", children: badge }),
86
+ /* @__PURE__ */ jsx("h2", { className: "brutal-h2 mb-4", children: headline }),
87
+ description && /* @__PURE__ */ jsx("p", { className: "brutal-body text-muted-foreground", children: description })
88
+ ] }),
89
+ /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse", children: [
90
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
91
+ /* @__PURE__ */ jsx("th", { className: "border-b-brutal border-foreground px-4 py-3 text-left text-sm font-medium text-muted-foreground", children: "Feature" }),
92
+ /* @__PURE__ */ jsx("th", { className: "border-b-brutal border-foreground bg-brand-muted px-4 py-3 text-center", children: /* @__PURE__ */ jsx("span", { className: "brutal-label text-brand", children: usName }) }),
93
+ /* @__PURE__ */ jsx("th", { className: "border-b-brutal border-foreground px-4 py-3 text-center", children: /* @__PURE__ */ jsx("span", { className: "brutal-label text-muted-foreground", children: themName }) })
94
+ ] }) }),
95
+ /* @__PURE__ */ jsx("tbody", { children: features.map((f, i) => /* @__PURE__ */ jsxs(
96
+ "tr",
97
+ {
98
+ className: cn(
99
+ "transition-colors",
100
+ f.highlight && "bg-brand-muted/50",
101
+ i % 2 === 0 && !f.highlight && "bg-muted/30"
102
+ ),
103
+ children: [
104
+ /* @__PURE__ */ jsx("td", { className: "border-b border-foreground/10 px-4 py-3 text-sm font-medium", children: f.name }),
105
+ /* @__PURE__ */ jsx("td", { className: "border-b border-foreground/10 bg-brand-muted/30 px-4 py-3 text-center", children: /* @__PURE__ */ jsx(CellValue, { value: f.us }) }),
106
+ /* @__PURE__ */ jsx("td", { className: "border-b border-foreground/10 px-4 py-3 text-center", children: /* @__PURE__ */ jsx(CellValue, { value: f.them }) })
107
+ ]
108
+ },
109
+ i
110
+ )) })
111
+ ] }) })
112
+ ] });
113
+ }
114
+
115
+ export { BrutalComparisonTable };
116
+ //# sourceMappingURL=comparison-table.js.map
117
+ //# sourceMappingURL=comparison-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/brutal/section.tsx","../../../src/components/brutal/comparison-table.tsx"],"names":["jsx"],"mappings":"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","file":"comparison-table.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 { 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 { BrutalSection } from \"./section\";\nimport type { SectionColor, SectionPattern } from \"./section\";\n\ninterface ComparisonFeature {\n name: string;\n us: string | boolean;\n them: string | boolean;\n highlight?: boolean;\n}\n\ninterface BrutalComparisonTableProps {\n badge?: string;\n headline: string;\n description?: string;\n usName: string;\n themName: string;\n features: ComparisonFeature[];\n color?: SectionColor;\n pattern?: SectionPattern;\n className?: string;\n}\n\nfunction CellValue({ value }: { value: string | boolean }) {\n if (typeof value === \"boolean\") {\n return value ? (\n <span className=\"inline-flex size-7 items-center justify-center border-brutal border-foreground bg-brand font-bold text-brand-foreground text-sm\">\n ✓\n </span>\n ) : (\n <span className=\"inline-flex size-7 items-center justify-center border-brutal border-foreground/20 text-sm text-muted-foreground\">\n —\n </span>\n );\n }\n return <span className=\"text-sm font-medium\">{value}</span>;\n}\n\nexport function BrutalComparisonTable({\n badge,\n headline,\n description,\n usName,\n themName,\n features,\n color = \"white\",\n pattern,\n className,\n}: BrutalComparisonTableProps) {\n return (\n <BrutalSection color={color} pattern={pattern} className={className}>\n <div className=\"mb-12 max-w-2xl\">\n {badge && <p className=\"brutal-label mb-4 text-brand\">{badge}</p>}\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 className=\"overflow-x-auto\">\n <table className=\"w-full border-collapse\">\n <thead>\n <tr>\n <th className=\"border-b-brutal border-foreground px-4 py-3 text-left text-sm font-medium text-muted-foreground\">\n Feature\n </th>\n <th className=\"border-b-brutal border-foreground bg-brand-muted px-4 py-3 text-center\">\n <span className=\"brutal-label text-brand\">{usName}</span>\n </th>\n <th className=\"border-b-brutal border-foreground px-4 py-3 text-center\">\n <span className=\"brutal-label text-muted-foreground\">\n {themName}\n </span>\n </th>\n </tr>\n </thead>\n <tbody>\n {features.map((f, i) => (\n <tr\n key={i}\n className={cn(\n \"transition-colors\",\n f.highlight && \"bg-brand-muted/50\",\n i % 2 === 0 && !f.highlight && \"bg-muted/30\"\n )}\n >\n <td className=\"border-b border-foreground/10 px-4 py-3 text-sm font-medium\">\n {f.name}\n </td>\n <td className=\"border-b border-foreground/10 bg-brand-muted/30 px-4 py-3 text-center\">\n <CellValue value={f.us} />\n </td>\n <td className=\"border-b border-foreground/10 px-4 py-3 text-center\">\n <CellValue value={f.them} />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </BrutalSection>\n );\n}\n"]}
@@ -128,12 +128,13 @@ function CTAButtons({
128
128
  secondaryText,
129
129
  secondaryHref
130
130
  }) {
131
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-center gap-4", children: [
131
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:justify-center sm:gap-4", children: [
132
132
  /* @__PURE__ */ jsx(
133
133
  Button,
134
134
  {
135
135
  variant: ctaVariant,
136
136
  size: "xl",
137
+ className: "w-full sm:w-auto",
137
138
  render: /* @__PURE__ */ jsx("a", { href: ctaHref }),
138
139
  children: ctaText
139
140
  }
@@ -142,7 +143,8 @@ function CTAButtons({
142
143
  Button,
143
144
  {
144
145
  variant: "outline",
145
- size: "lg",
146
+ size: "xl",
147
+ className: "w-full sm:w-auto",
146
148
  render: /* @__PURE__ */ jsx("a", { href: secondaryHref || "#" }),
147
149
  children: secondaryText
148
150
  }
@@ -172,12 +174,13 @@ function SplitCTA(props) {
172
174
  /* @__PURE__ */ jsx("h2", { className: "brutal-h1 mb-6", children: props.headline }),
173
175
  props.description && /* @__PURE__ */ jsx("p", { className: "brutal-body mb-4 opacity-80", children: props.description }),
174
176
  props.stats && /* @__PURE__ */ jsx("p", { className: "brutal-label mb-8 opacity-60", children: props.stats }),
175
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-4", children: [
177
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:gap-4", children: [
176
178
  /* @__PURE__ */ jsx(
177
179
  Button,
178
180
  {
179
181
  variant: props.ctaVariant || "cta",
180
182
  size: "xl",
183
+ className: "w-full sm:w-auto",
181
184
  render: /* @__PURE__ */ jsx("a", { href: props.ctaHref || "#" }),
182
185
  children: props.ctaText
183
186
  }
@@ -186,7 +189,8 @@ function SplitCTA(props) {
186
189
  Button,
187
190
  {
188
191
  variant: "outline",
189
- size: "lg",
192
+ size: "xl",
193
+ className: "w-full sm:w-auto",
190
194
  render: /* @__PURE__ */ jsx("a", { href: props.secondaryHref || "#" }),
191
195
  children: props.secondaryText
192
196
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/button.tsx","../../../src/components/brutal/section.tsx","../../../src/components/brutal/cta-section.tsx"],"names":["ButtonPrimitive","jsx"],"mappings":"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","file":"cta-section.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 { 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 { Button } from \"../ui/button\";\nimport { BrutalSection } from \"./section\";\nimport type { SectionColor, SectionPattern } from \"./section\";\n\ninterface BrutalCTAProps {\n headline: string;\n description?: string;\n ctaText: string;\n ctaHref?: string;\n ctaVariant?: \"cta\" | \"brand\" | \"default\" | \"outline\";\n secondaryText?: string;\n secondaryHref?: string;\n color?: SectionColor;\n pattern?: SectionPattern;\n className?: string;\n variant?: \"centered\" | \"split\" | \"with-visual\" | \"floating-card\";\n visual?: React.ReactNode;\n stats?: string;\n}\n\nfunction CTAButtons({\n ctaText,\n ctaHref = \"#\",\n ctaVariant = \"cta\",\n secondaryText,\n secondaryHref,\n}: Pick<\n BrutalCTAProps,\n \"ctaText\" | \"ctaHref\" | \"ctaVariant\" | \"secondaryText\" | \"secondaryHref\"\n>) {\n return (\n <div className=\"flex flex-wrap items-center justify-center gap-4\">\n <Button\n variant={ctaVariant}\n size=\"xl\"\n render={<a href={ctaHref} />}\n >\n {ctaText}\n </Button>\n {secondaryText && (\n <Button\n variant=\"outline\"\n size=\"lg\"\n render={<a href={secondaryHref || \"#\"} />}\n >\n {secondaryText}\n </Button>\n )}\n </div>\n );\n}\n\nfunction CenteredCTA(props: BrutalCTAProps) {\n return (\n <div className=\"mx-auto max-w-2xl text-center\">\n <h2 className=\"brutal-h1 mb-6\">{props.headline}</h2>\n {props.description && (\n <p className=\"brutal-body mb-4 opacity-80\">{props.description}</p>\n )}\n {props.stats && (\n <p className=\"brutal-label mb-8 opacity-60\">{props.stats}</p>\n )}\n <CTAButtons\n ctaText={props.ctaText}\n ctaHref={props.ctaHref}\n ctaVariant={props.ctaVariant}\n secondaryText={props.secondaryText}\n secondaryHref={props.secondaryHref}\n />\n </div>\n );\n}\n\nfunction SplitCTA(props: BrutalCTAProps) {\n return (\n <div className=\"grid items-center gap-12 lg:grid-cols-2\">\n <div>\n <h2 className=\"brutal-h1 mb-6\">{props.headline}</h2>\n {props.description && (\n <p className=\"brutal-body mb-4 opacity-80\">{props.description}</p>\n )}\n {props.stats && (\n <p className=\"brutal-label mb-8 opacity-60\">{props.stats}</p>\n )}\n <div className=\"flex flex-wrap gap-4\">\n <Button\n variant={props.ctaVariant || \"cta\"}\n size=\"xl\"\n render={<a href={props.ctaHref || \"#\"} />}\n >\n {props.ctaText}\n </Button>\n {props.secondaryText && (\n <Button\n variant=\"outline\"\n size=\"lg\"\n render={<a href={props.secondaryHref || \"#\"} />}\n >\n {props.secondaryText}\n </Button>\n )}\n </div>\n </div>\n {props.visual && <div>{props.visual}</div>}\n </div>\n );\n}\n\nfunction WithVisualCTA(props: BrutalCTAProps) {\n return (\n <div className=\"relative\">\n {props.visual && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center opacity-10\">\n {props.visual}\n </div>\n )}\n <div className=\"relative mx-auto max-w-2xl text-center\">\n <h2 className=\"brutal-h1 mb-6\">{props.headline}</h2>\n {props.description && (\n <p className=\"brutal-body mb-4 opacity-80\">{props.description}</p>\n )}\n {props.stats && (\n <p className=\"brutal-label mb-8 opacity-60\">{props.stats}</p>\n )}\n <CTAButtons\n ctaText={props.ctaText}\n ctaHref={props.ctaHref}\n ctaVariant={props.ctaVariant}\n secondaryText={props.secondaryText}\n secondaryHref={props.secondaryHref}\n />\n </div>\n </div>\n );\n}\n\nfunction FloatingCardCTA(props: BrutalCTAProps) {\n return (\n <div className=\"relative z-10 -mt-16\">\n <div className=\"mx-auto max-w-2xl border-brutal border-foreground bg-background p-8 text-center text-foreground shadow-brutal-lg\">\n <h2 className=\"brutal-h1 mb-6\">{props.headline}</h2>\n {props.description && (\n <p className=\"brutal-body mb-4 opacity-80\">{props.description}</p>\n )}\n {props.stats && (\n <p className=\"brutal-label mb-8 opacity-60\">{props.stats}</p>\n )}\n <CTAButtons\n ctaText={props.ctaText}\n ctaHref={props.ctaHref}\n ctaVariant={props.ctaVariant}\n secondaryText={props.secondaryText}\n secondaryHref={props.secondaryHref}\n />\n </div>\n </div>\n );\n}\n\nexport function BrutalCTA({\n variant = \"centered\",\n color = \"black\",\n className,\n pattern,\n ...props\n}: BrutalCTAProps) {\n // floating-card variant doesn't wrap in a section — it floats above the previous section\n if (variant === \"floating-card\") {\n return (\n <div className={cn(\"brutal-container px-6\", className)}>\n <FloatingCardCTA {...props} variant={variant} color={color} />\n </div>\n );\n }\n\n return (\n <BrutalSection color={color} pattern={pattern} className={className}>\n {variant === \"centered\" && <CenteredCTA {...props} variant={variant} color={color} />}\n {variant === \"split\" && <SplitCTA {...props} variant={variant} color={color} />}\n {variant === \"with-visual\" && <WithVisualCTA {...props} variant={variant} color={color} />}\n </BrutalSection>\n );\n}\n"]}
1
+ {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/button.tsx","../../../src/components/brutal/section.tsx","../../../src/components/brutal/cta-section.tsx"],"names":["ButtonPrimitive","jsx"],"mappings":"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","file":"cta-section.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 { 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 { Button } from \"../ui/button\";\nimport { BrutalSection } from \"./section\";\nimport type { SectionColor, SectionPattern } from \"./section\";\n\ninterface BrutalCTAProps {\n headline: string;\n description?: string;\n ctaText: string;\n ctaHref?: string;\n ctaVariant?: \"cta\" | \"brand\" | \"default\" | \"outline\";\n secondaryText?: string;\n secondaryHref?: string;\n color?: SectionColor;\n pattern?: SectionPattern;\n className?: string;\n variant?: \"centered\" | \"split\" | \"with-visual\" | \"floating-card\";\n visual?: React.ReactNode;\n stats?: string;\n}\n\nfunction CTAButtons({\n ctaText,\n ctaHref = \"#\",\n ctaVariant = \"cta\",\n secondaryText,\n secondaryHref,\n}: Pick<\n BrutalCTAProps,\n \"ctaText\" | \"ctaHref\" | \"ctaVariant\" | \"secondaryText\" | \"secondaryHref\"\n>) {\n return (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:justify-center sm:gap-4\">\n <Button\n variant={ctaVariant}\n size=\"xl\"\n className=\"w-full sm:w-auto\"\n render={<a href={ctaHref} />}\n >\n {ctaText}\n </Button>\n {secondaryText && (\n <Button\n variant=\"outline\"\n size=\"xl\"\n className=\"w-full sm:w-auto\"\n render={<a href={secondaryHref || \"#\"} />}\n >\n {secondaryText}\n </Button>\n )}\n </div>\n );\n}\n\nfunction CenteredCTA(props: BrutalCTAProps) {\n return (\n <div className=\"mx-auto max-w-2xl text-center\">\n <h2 className=\"brutal-h1 mb-6\">{props.headline}</h2>\n {props.description && (\n <p className=\"brutal-body mb-4 opacity-80\">{props.description}</p>\n )}\n {props.stats && (\n <p className=\"brutal-label mb-8 opacity-60\">{props.stats}</p>\n )}\n <CTAButtons\n ctaText={props.ctaText}\n ctaHref={props.ctaHref}\n ctaVariant={props.ctaVariant}\n secondaryText={props.secondaryText}\n secondaryHref={props.secondaryHref}\n />\n </div>\n );\n}\n\nfunction SplitCTA(props: BrutalCTAProps) {\n return (\n <div className=\"grid items-center gap-12 lg:grid-cols-2\">\n <div>\n <h2 className=\"brutal-h1 mb-6\">{props.headline}</h2>\n {props.description && (\n <p className=\"brutal-body mb-4 opacity-80\">{props.description}</p>\n )}\n {props.stats && (\n <p className=\"brutal-label mb-8 opacity-60\">{props.stats}</p>\n )}\n <div className=\"flex flex-col gap-3 sm:flex-row sm:gap-4\">\n <Button\n variant={props.ctaVariant || \"cta\"}\n size=\"xl\"\n className=\"w-full sm:w-auto\"\n render={<a href={props.ctaHref || \"#\"} />}\n >\n {props.ctaText}\n </Button>\n {props.secondaryText && (\n <Button\n variant=\"outline\"\n size=\"xl\"\n className=\"w-full sm:w-auto\"\n render={<a href={props.secondaryHref || \"#\"} />}\n >\n {props.secondaryText}\n </Button>\n )}\n </div>\n </div>\n {props.visual && <div>{props.visual}</div>}\n </div>\n );\n}\n\nfunction WithVisualCTA(props: BrutalCTAProps) {\n return (\n <div className=\"relative\">\n {props.visual && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center opacity-10\">\n {props.visual}\n </div>\n )}\n <div className=\"relative mx-auto max-w-2xl text-center\">\n <h2 className=\"brutal-h1 mb-6\">{props.headline}</h2>\n {props.description && (\n <p className=\"brutal-body mb-4 opacity-80\">{props.description}</p>\n )}\n {props.stats && (\n <p className=\"brutal-label mb-8 opacity-60\">{props.stats}</p>\n )}\n <CTAButtons\n ctaText={props.ctaText}\n ctaHref={props.ctaHref}\n ctaVariant={props.ctaVariant}\n secondaryText={props.secondaryText}\n secondaryHref={props.secondaryHref}\n />\n </div>\n </div>\n );\n}\n\nfunction FloatingCardCTA(props: BrutalCTAProps) {\n return (\n <div className=\"relative z-10 -mt-16\">\n <div className=\"mx-auto max-w-2xl border-brutal border-foreground bg-background p-8 text-center text-foreground shadow-brutal-lg\">\n <h2 className=\"brutal-h1 mb-6\">{props.headline}</h2>\n {props.description && (\n <p className=\"brutal-body mb-4 opacity-80\">{props.description}</p>\n )}\n {props.stats && (\n <p className=\"brutal-label mb-8 opacity-60\">{props.stats}</p>\n )}\n <CTAButtons\n ctaText={props.ctaText}\n ctaHref={props.ctaHref}\n ctaVariant={props.ctaVariant}\n secondaryText={props.secondaryText}\n secondaryHref={props.secondaryHref}\n />\n </div>\n </div>\n );\n}\n\nexport function BrutalCTA({\n variant = \"centered\",\n color = \"black\",\n className,\n pattern,\n ...props\n}: BrutalCTAProps) {\n // floating-card variant doesn't wrap in a section — it floats above the previous section\n if (variant === \"floating-card\") {\n return (\n <div className={cn(\"brutal-container px-6\", className)}>\n <FloatingCardCTA {...props} variant={variant} color={color} />\n </div>\n );\n }\n\n return (\n <BrutalSection color={color} pattern={pattern} className={className}>\n {variant === \"centered\" && <CenteredCTA {...props} variant={variant} color={color} />}\n {variant === \"split\" && <SplitCTA {...props} variant={variant} color={color} />}\n {variant === \"with-visual\" && <WithVisualCTA {...props} variant={variant} color={color} />}\n </BrutalSection>\n );\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
 
3
- type FeatureGridVariant = "icon-top" | "icon-left" | "numbered" | "bento";
3
+ type FeatureGridVariant = "icon-top" | "icon-left" | "numbered" | "bento" | "minimal";
4
4
  interface Feature {
5
5
  icon?: React.ReactNode;
6
6
  title: string;
@@ -166,6 +166,14 @@ function FeatureCard({
166
166
  index
167
167
  }) {
168
168
  const isBentoFeatured = variant === "bento" && feature.featured;
169
+ if (variant === "minimal") {
170
+ return /* @__PURE__ */ jsxs("div", { className: "group flex flex-col gap-3 border-l-4 border-l-brand py-1 pl-5", children: [
171
+ feature.icon && /* @__PURE__ */ jsx("div", { className: "text-2xl", children: feature.icon }),
172
+ feature.stat && /* @__PURE__ */ jsx("p", { className: "brutal-label text-brand", children: feature.stat }),
173
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-bold", children: feature.title }),
174
+ /* @__PURE__ */ jsx("p", { className: "text-sm leading-relaxed text-muted-foreground", children: feature.description })
175
+ ] });
176
+ }
169
177
  if (variant === "icon-left") {
170
178
  return /* @__PURE__ */ jsxs("div", { className: "flex gap-4 border-brutal border-foreground border-l-4 border-l-brand bg-background p-5 shadow-brutal transition-all duration-150 hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg", children: [
171
179
  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 }),
@@ -1 +1 @@
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 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-brand\">{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 />\n ))}\n </div>\n </BrutalSection>\n );\n}\n\nfunction FeatureCard({\n feature,\n variant,\n index,\n}: {\n feature: Feature;\n variant: FeatureGridVariant;\n index: number;\n}) {\n const isBentoFeatured = variant === \"bento\" && feature.featured;\n\n if (variant === \"icon-left\") {\n return (\n <div className=\"flex gap-4 border-brutal border-foreground border-l-4 border-l-brand 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 {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 className=\"brutal-display mb-2 block text-brand opacity-20\">\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 className=\"mb-2 inline-flex size-12 items-center justify-center border-brutal border-foreground border-b-brand bg-brand-muted text-2xl shadow-brutal-sm\">\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"]}
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\" | \"minimal\";\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 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-brand\">{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 />\n ))}\n </div>\n </BrutalSection>\n );\n}\n\nfunction FeatureCard({\n feature,\n variant,\n index,\n}: {\n feature: Feature;\n variant: FeatureGridVariant;\n index: number;\n}) {\n const isBentoFeatured = variant === \"bento\" && feature.featured;\n\n if (variant === \"minimal\") {\n return (\n <div className=\"group flex flex-col gap-3 border-l-4 border-l-brand py-1 pl-5\">\n {feature.icon && (\n <div className=\"text-2xl\">{feature.icon}</div>\n )}\n {feature.stat && (\n <p className=\"brutal-label text-brand\">{feature.stat}</p>\n )}\n <h3 className=\"text-lg font-bold\">{feature.title}</h3>\n <p className=\"text-sm leading-relaxed text-muted-foreground\">{feature.description}</p>\n </div>\n );\n }\n\n if (variant === \"icon-left\") {\n return (\n <div className=\"flex gap-4 border-brutal border-foreground border-l-4 border-l-brand 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 {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 className=\"brutal-display mb-2 block text-brand opacity-20\">\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 className=\"mb-2 inline-flex size-12 items-center justify-center border-brutal border-foreground border-b-brand bg-brand-muted text-2xl shadow-brutal-sm\">\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"]}
@@ -0,0 +1,20 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SectionColor, SectionPattern } from './section.js';
3
+
4
+ interface BrutalFeatureShowcaseProps {
5
+ badge?: string;
6
+ headline: string;
7
+ description: string;
8
+ visual: React.ReactNode;
9
+ features?: {
10
+ icon?: React.ReactNode;
11
+ text: string;
12
+ }[];
13
+ reversed?: boolean;
14
+ color?: SectionColor;
15
+ pattern?: SectionPattern;
16
+ className?: string;
17
+ }
18
+ declare function BrutalFeatureShowcase({ badge, headline, description, visual, features, reversed, color, pattern, className, }: BrutalFeatureShowcaseProps): react_jsx_runtime.JSX.Element;
19
+
20
+ export { BrutalFeatureShowcase };
@@ -0,0 +1,158 @@
1
+ "use client";
2
+ import { clsx } from 'clsx';
3
+ import { twMerge } from 'tailwind-merge';
4
+ import { mergeProps } from '@base-ui/react/merge-props';
5
+ import { useRender } from '@base-ui/react/use-render';
6
+ import { cva } from 'class-variance-authority';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
8
+
9
+ // src/lib/utils.ts
10
+ function cn(...inputs) {
11
+ return twMerge(clsx(inputs));
12
+ }
13
+ var badgeVariants = cva(
14
+ "group/badge inline-flex w-fit shrink-0 items-center justify-center gap-1 rounded-md whitespace-nowrap font-bold transition-all [&>svg]:pointer-events-none [&>svg]:size-3!",
15
+ {
16
+ variants: {
17
+ variant: {
18
+ default: "border-brutal border-foreground bg-primary px-3 py-1 text-xs text-primary-foreground shadow-brutal-sm",
19
+ secondary: "border-brutal border-foreground bg-secondary px-3 py-1 text-xs text-secondary-foreground shadow-brutal-sm",
20
+ brand: "border-brutal border-foreground bg-brand px-3 py-1 text-xs text-brand-foreground shadow-brutal-sm",
21
+ cta: "border-brutal border-foreground bg-cta px-3 py-1 text-xs text-cta-foreground shadow-brutal-sm",
22
+ outline: "border-brutal border-foreground bg-background px-3 py-1 text-xs text-foreground",
23
+ destructive: "border-brutal border-destructive bg-destructive/10 px-3 py-1 text-xs text-destructive",
24
+ ghost: "px-2 py-0.5 text-xs text-muted-foreground"
25
+ }
26
+ },
27
+ defaultVariants: {
28
+ variant: "default"
29
+ }
30
+ }
31
+ );
32
+ function Badge({
33
+ className,
34
+ variant = "default",
35
+ render,
36
+ ...props
37
+ }) {
38
+ return useRender({
39
+ defaultTagName: "span",
40
+ props: mergeProps(
41
+ {
42
+ className: cn(badgeVariants({ variant }), className)
43
+ },
44
+ props
45
+ ),
46
+ render,
47
+ state: {
48
+ slot: "badge",
49
+ variant
50
+ }
51
+ });
52
+ }
53
+ var colorMap = {
54
+ white: "bg-background text-foreground",
55
+ brand: "bg-brand",
56
+ "brand-muted": "bg-brand-muted text-foreground",
57
+ blue: "bg-section-blue",
58
+ gray: "bg-section-gray text-foreground",
59
+ cream: "bg-section-cream text-foreground",
60
+ black: "bg-foreground text-background",
61
+ cta: "bg-cta"
62
+ };
63
+ var containerMap = {
64
+ sm: "brutal-container-sm",
65
+ default: "brutal-container",
66
+ lg: "brutal-container-lg"
67
+ };
68
+ var paddingMap = {
69
+ sm: "brutal-section-sm",
70
+ default: "brutal-section",
71
+ lg: "brutal-section py-28 sm:py-36 md:py-44"
72
+ };
73
+ var patternMap = {
74
+ dots: "brutal-dots",
75
+ stripes: "brutal-stripes",
76
+ noise: "brutal-noise",
77
+ grain: "brutal-grain",
78
+ crosshatch: "brutal-crosshatch",
79
+ "grid-dots": "brutal-grid-dots",
80
+ "gradient-mesh": "brutal-gradient-mesh",
81
+ none: ""
82
+ };
83
+ function BrutalSection({
84
+ children,
85
+ color = "white",
86
+ className,
87
+ containerSize = "default",
88
+ padding = "default",
89
+ pattern,
90
+ dots = false,
91
+ stripes = false,
92
+ id
93
+ }) {
94
+ const resolvedPattern = pattern ?? (dots ? "dots" : void 0) ?? (stripes ? "stripes" : void 0) ?? "none";
95
+ return /* @__PURE__ */ jsx(
96
+ "section",
97
+ {
98
+ id,
99
+ className: cn(
100
+ paddingMap[padding],
101
+ colorMap[color],
102
+ patternMap[resolvedPattern],
103
+ className
104
+ ),
105
+ children: /* @__PURE__ */ jsx("div", { className: containerMap[containerSize], children })
106
+ }
107
+ );
108
+ }
109
+ function BrutalFeatureShowcase({
110
+ badge,
111
+ headline,
112
+ description,
113
+ visual,
114
+ features,
115
+ reversed = false,
116
+ color = "white",
117
+ pattern,
118
+ className
119
+ }) {
120
+ return /* @__PURE__ */ jsx(BrutalSection, { color, pattern, className, children: /* @__PURE__ */ jsxs(
121
+ "div",
122
+ {
123
+ className: cn(
124
+ "grid items-center gap-12 lg:grid-cols-2 lg:gap-20",
125
+ reversed && "lg:[&>*:first-child]:order-2"
126
+ ),
127
+ children: [
128
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
129
+ badge && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "w-fit font-mono text-xs uppercase tracking-widest", children: badge }),
130
+ /* @__PURE__ */ jsx("h2", { className: "brutal-h2", children: headline }),
131
+ /* @__PURE__ */ jsx("p", { className: "brutal-body text-muted-foreground", children: description }),
132
+ features && features.length > 0 && /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-3 pt-2", children: features.map((f, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-3", children: [
133
+ f.icon ? /* @__PURE__ */ jsx("span", { className: "mt-0.5 flex size-6 shrink-0 items-center justify-center border-brutal border-foreground bg-brand-muted text-sm", children: f.icon }) : /* @__PURE__ */ jsx("span", { className: "mt-0.5 flex size-6 shrink-0 items-center justify-center border-brutal border-foreground bg-brand text-sm text-brand-foreground font-bold", children: "\u2713" }),
134
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: f.text })
135
+ ] }, i)) })
136
+ ] }),
137
+ /* @__PURE__ */ jsxs(
138
+ "div",
139
+ {
140
+ className: cn(
141
+ "relative",
142
+ reversed ? "-rotate-1" : "rotate-1",
143
+ "transform transition-transform duration-300 hover:rotate-0"
144
+ ),
145
+ children: [
146
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 translate-x-3 translate-y-3 border-brutal border-foreground bg-brand opacity-20" }),
147
+ /* @__PURE__ */ jsx("div", { className: "relative border-brutal border-foreground bg-background shadow-brutal-lg", children: visual })
148
+ ]
149
+ }
150
+ )
151
+ ]
152
+ }
153
+ ) });
154
+ }
155
+
156
+ export { BrutalFeatureShowcase };
157
+ //# sourceMappingURL=feature-showcase.js.map
158
+ //# sourceMappingURL=feature-showcase.js.map