@snow-labs/brutal-ui 0.3.2 → 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.
@@ -0,0 +1,17 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface MarqueeProps {
4
+ children: React.ReactNode;
5
+ speed?: "slow" | "normal" | "fast";
6
+ direction?: "left" | "right";
7
+ pauseOnHover?: boolean;
8
+ className?: string;
9
+ }
10
+ declare function Marquee({ children, speed, direction, pauseOnHover, className, }: MarqueeProps): react_jsx_runtime.JSX.Element;
11
+ interface MarqueeItemProps {
12
+ children: React.ReactNode;
13
+ className?: string;
14
+ }
15
+ declare function MarqueeItem({ children, className }: MarqueeItemProps): react_jsx_runtime.JSX.Element;
16
+
17
+ export { Marquee, MarqueeItem };
@@ -0,0 +1,66 @@
1
+ "use client";
2
+ import { clsx } from 'clsx';
3
+ import { twMerge } from 'tailwind-merge';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ // src/lib/utils.ts
7
+ function cn(...inputs) {
8
+ return twMerge(clsx(inputs));
9
+ }
10
+ var speedMap = {
11
+ slow: "60s",
12
+ normal: "30s",
13
+ fast: "15s"
14
+ };
15
+ function Marquee({
16
+ children,
17
+ speed = "normal",
18
+ direction = "left",
19
+ pauseOnHover = true,
20
+ className
21
+ }) {
22
+ return /* @__PURE__ */ jsx(
23
+ "div",
24
+ {
25
+ className: cn(
26
+ "group flex overflow-hidden border-y-brutal border-foreground bg-foreground py-3",
27
+ className
28
+ ),
29
+ children: [0, 1].map((copy) => /* @__PURE__ */ jsxs(
30
+ "div",
31
+ {
32
+ "aria-hidden": copy === 1,
33
+ className: cn(
34
+ "flex shrink-0 items-center gap-8",
35
+ pauseOnHover && "group-hover:[animation-play-state:paused]"
36
+ ),
37
+ style: {
38
+ animation: `marquee ${speedMap[speed]} linear infinite`,
39
+ animationDirection: direction === "right" ? "reverse" : "normal"
40
+ },
41
+ children: [
42
+ children,
43
+ /* @__PURE__ */ jsx("span", { className: "mx-4 text-background/30 select-none", children: "\u2022" })
44
+ ]
45
+ },
46
+ copy
47
+ ))
48
+ }
49
+ );
50
+ }
51
+ function MarqueeItem({ children, className }) {
52
+ return /* @__PURE__ */ jsx(
53
+ "span",
54
+ {
55
+ className: cn(
56
+ "inline-flex shrink-0 items-center gap-2 whitespace-nowrap font-bold text-background",
57
+ className
58
+ ),
59
+ children
60
+ }
61
+ );
62
+ }
63
+
64
+ export { Marquee, MarqueeItem };
65
+ //# sourceMappingURL=marquee.js.map
66
+ //# sourceMappingURL=marquee.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/brutal/marquee.tsx"],"names":[],"mappings":";;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACKA,IAAM,QAAA,GAAW;AAAA,EACf,IAAA,EAAM,KAAA;AAAA,EACN,MAAA,EAAQ,KAAA;AAAA,EACR,IAAA,EAAM;AACR,CAAA;AAEO,SAAS,OAAA,CAAQ;AAAA,EACtB,QAAA;AAAA,EACA,KAAA,GAAQ,QAAA;AAAA,EACR,SAAA,GAAY,MAAA;AAAA,EACZ,YAAA,GAAe,IAAA;AAAA,EACf;AACF,CAAA,EAAiB;AACf,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,iFAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEC,WAAC,CAAA,EAAG,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,qBACX,IAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAEC,eAAa,IAAA,KAAS,CAAA;AAAA,UACtB,SAAA,EAAW,EAAA;AAAA,YACT,kCAAA;AAAA,YACA,YAAA,IAAgB;AAAA,WAClB;AAAA,UACA,KAAA,EAAO;AAAA,YACL,SAAA,EAAW,CAAA,QAAA,EAAW,QAAA,CAAS,KAAK,CAAC,CAAA,gBAAA,CAAA;AAAA,YACrC,kBAAA,EAAoB,SAAA,KAAc,OAAA,GAAU,SAAA,GAAY;AAAA,WAC1D;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,QAAA;AAAA,4BAED,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAA,EAAsC,QAAA,EAAA,QAAA,EAAC;AAAA;AAAA,SAAA;AAAA,QAblD;AAAA,OAeR;AAAA;AAAA,GACH;AAEJ;AAOO,SAAS,WAAA,CAAY,EAAE,QAAA,EAAU,SAAA,EAAU,EAAqB;AACrE,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,qFAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ","file":"marquee.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\ninterface MarqueeProps {\n children: React.ReactNode;\n speed?: \"slow\" | \"normal\" | \"fast\";\n direction?: \"left\" | \"right\";\n pauseOnHover?: boolean;\n className?: string;\n}\n\nconst speedMap = {\n slow: \"60s\",\n normal: \"30s\",\n fast: \"15s\",\n};\n\nexport function Marquee({\n children,\n speed = \"normal\",\n direction = \"left\",\n pauseOnHover = true,\n className,\n}: MarqueeProps) {\n return (\n <div\n className={cn(\n \"group flex overflow-hidden border-y-brutal border-foreground bg-foreground py-3\",\n className\n )}\n >\n {[0, 1].map((copy) => (\n <div\n key={copy}\n aria-hidden={copy === 1}\n className={cn(\n \"flex shrink-0 items-center gap-8\",\n pauseOnHover && \"group-hover:[animation-play-state:paused]\"\n )}\n style={{\n animation: `marquee ${speedMap[speed]} linear infinite`,\n animationDirection: direction === \"right\" ? \"reverse\" : \"normal\",\n }}\n >\n {children}\n {/* Separator */}\n <span className=\"mx-4 text-background/30 select-none\">•</span>\n </div>\n ))}\n </div>\n );\n}\n\ninterface MarqueeItemProps {\n children: React.ReactNode;\n className?: string;\n}\n\nexport function MarqueeItem({ children, className }: MarqueeItemProps) {\n return (\n <span\n className={cn(\n \"inline-flex shrink-0 items-center gap-2 whitespace-nowrap font-bold text-background\",\n className\n )}\n >\n {children}\n </span>\n );\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface MockupWindowProps {
4
+ children: React.ReactNode;
5
+ title?: string;
6
+ variant?: "browser" | "terminal" | "phone";
7
+ className?: string;
8
+ }
9
+ declare function MockupWindow({ children, title, variant, className, }: MockupWindowProps): react_jsx_runtime.JSX.Element;
10
+
11
+ export { MockupWindow };
@@ -0,0 +1,80 @@
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 MockupWindow({
11
+ children,
12
+ title = "app.example.com",
13
+ variant = "browser",
14
+ className
15
+ }) {
16
+ if (variant === "phone") {
17
+ return /* @__PURE__ */ jsxs(
18
+ "div",
19
+ {
20
+ className: cn(
21
+ "mx-auto w-[280px] overflow-hidden rounded-[2rem] border-brutal border-foreground bg-background shadow-brutal-lg",
22
+ className
23
+ ),
24
+ children: [
25
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center bg-foreground py-2", children: /* @__PURE__ */ jsx("div", { className: "h-5 w-28 rounded-full bg-background/20" }) }),
26
+ /* @__PURE__ */ jsx("div", { className: "overflow-hidden", children }),
27
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center bg-foreground py-3", children: /* @__PURE__ */ jsx("div", { className: "h-1 w-24 rounded-full bg-background/30" }) })
28
+ ]
29
+ }
30
+ );
31
+ }
32
+ if (variant === "terminal") {
33
+ return /* @__PURE__ */ jsxs(
34
+ "div",
35
+ {
36
+ className: cn(
37
+ "overflow-hidden rounded-lg border-brutal border-foreground shadow-brutal-lg",
38
+ className
39
+ ),
40
+ children: [
41
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b-brutal border-foreground bg-foreground px-4 py-2.5", children: [
42
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
43
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full bg-red-500" }),
44
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full bg-yellow-500" }),
45
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full bg-green-500" })
46
+ ] }),
47
+ /* @__PURE__ */ jsx("span", { className: "ml-2 font-mono text-xs text-background/60", children: title })
48
+ ] }),
49
+ /* @__PURE__ */ jsx("div", { className: "bg-foreground text-background", children })
50
+ ]
51
+ }
52
+ );
53
+ }
54
+ return /* @__PURE__ */ jsxs(
55
+ "div",
56
+ {
57
+ className: cn(
58
+ "overflow-hidden rounded-lg border-brutal border-foreground shadow-brutal-lg",
59
+ className
60
+ ),
61
+ children: [
62
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 border-b-brutal border-foreground bg-muted px-4 py-2.5", children: [
63
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
64
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full border border-foreground/20 bg-red-400" }),
65
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full border border-foreground/20 bg-yellow-400" }),
66
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full border border-foreground/20 bg-green-400" })
67
+ ] }),
68
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx("div", { className: "mx-auto max-w-sm rounded-md border border-foreground/10 bg-background px-3 py-1 text-center font-mono text-xs text-muted-foreground", children: title }) }),
69
+ /* @__PURE__ */ jsx("div", { className: "w-[54px]" }),
70
+ " "
71
+ ] }),
72
+ /* @__PURE__ */ jsx("div", { className: "bg-background", children })
73
+ ]
74
+ }
75
+ );
76
+ }
77
+
78
+ export { MockupWindow };
79
+ //# sourceMappingURL=mockup-window.js.map
80
+ //# sourceMappingURL=mockup-window.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/brutal/mockup-window.tsx"],"names":[],"mappings":"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","file":"mockup-window.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\ninterface MockupWindowProps {\n children: React.ReactNode;\n title?: string;\n variant?: \"browser\" | \"terminal\" | \"phone\";\n className?: string;\n}\n\nexport function MockupWindow({\n children,\n title = \"app.example.com\",\n variant = \"browser\",\n className,\n}: MockupWindowProps) {\n if (variant === \"phone\") {\n return (\n <div\n className={cn(\n \"mx-auto w-[280px] overflow-hidden rounded-[2rem] border-brutal border-foreground bg-background shadow-brutal-lg\",\n className\n )}\n >\n {/* Notch */}\n <div className=\"flex justify-center bg-foreground py-2\">\n <div className=\"h-5 w-28 rounded-full bg-background/20\" />\n </div>\n {/* Screen */}\n <div className=\"overflow-hidden\">{children}</div>\n {/* Home indicator */}\n <div className=\"flex justify-center bg-foreground py-3\">\n <div className=\"h-1 w-24 rounded-full bg-background/30\" />\n </div>\n </div>\n );\n }\n\n if (variant === \"terminal\") {\n return (\n <div\n className={cn(\n \"overflow-hidden rounded-lg border-brutal border-foreground shadow-brutal-lg\",\n className\n )}\n >\n {/* Title bar */}\n <div className=\"flex items-center gap-2 border-b-brutal border-foreground bg-foreground px-4 py-2.5\">\n <div className=\"flex gap-1.5\">\n <div className=\"size-3 rounded-full bg-red-500\" />\n <div className=\"size-3 rounded-full bg-yellow-500\" />\n <div className=\"size-3 rounded-full bg-green-500\" />\n </div>\n <span className=\"ml-2 font-mono text-xs text-background/60\">\n {title}\n </span>\n </div>\n {/* Content */}\n <div className=\"bg-foreground text-background\">{children}</div>\n </div>\n );\n }\n\n // Browser variant (default)\n return (\n <div\n className={cn(\n \"overflow-hidden rounded-lg border-brutal border-foreground shadow-brutal-lg\",\n className\n )}\n >\n {/* Title bar */}\n <div className=\"flex items-center gap-3 border-b-brutal border-foreground bg-muted px-4 py-2.5\">\n <div className=\"flex gap-1.5\">\n <div className=\"size-3 rounded-full border border-foreground/20 bg-red-400\" />\n <div className=\"size-3 rounded-full border border-foreground/20 bg-yellow-400\" />\n <div className=\"size-3 rounded-full border border-foreground/20 bg-green-400\" />\n </div>\n {/* URL bar */}\n <div className=\"flex-1\">\n <div className=\"mx-auto max-w-sm rounded-md border border-foreground/10 bg-background px-3 py-1 text-center font-mono text-xs text-muted-foreground\">\n {title}\n </div>\n </div>\n <div className=\"w-[54px]\" /> {/* Spacer for centering */}\n </div>\n {/* Content */}\n <div className=\"bg-background\">{children}</div>\n </div>\n );\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -40,9 +40,11 @@ export { BrutalSection, SectionColor, SectionPattern } from './components/brutal
40
40
  export { SectionDivider, SectionDivider as WaveDivider } from './components/brutal/section-divider.js';
41
41
  export { BrutalHero } from './components/brutal/hero.js';
42
42
  export { BrutalFeatureGrid } from './components/brutal/feature-grid.js';
43
+ export { BrutalFeatureShowcase } from './components/brutal/feature-showcase.js';
43
44
  export { BrutalTestimonials, Testimonial } from './components/brutal/testimonials.js';
44
45
  export { BrutalIntegrationGrid } from './components/brutal/integration-grid.js';
45
46
  export { BrutalCTA } from './components/brutal/cta-section.js';
47
+ export { BrutalComparisonTable } from './components/brutal/comparison-table.js';
46
48
  export { BrutalNav } from './components/brutal/nav.js';
47
49
  export { BrutalFooter } from './components/brutal/footer.js';
48
50
  export { PricingTable } from './components/brutal/pricing-table.js';
@@ -50,6 +52,8 @@ export { LogoCloud } from './components/brutal/logo-cloud.js';
50
52
  export { StatsBar } from './components/brutal/stats-bar.js';
51
53
  export { FAQ } from './components/brutal/faq.js';
52
54
  export { Newsletter } from './components/brutal/newsletter.js';
55
+ export { MockupWindow } from './components/brutal/mockup-window.js';
56
+ export { Marquee, MarqueeItem } from './components/brutal/marquee.js';
53
57
  export { AppShell, useAppShell } from './components/dashboard/app-shell.js';
54
58
  export { Sidebar } from './components/dashboard/sidebar.js';
55
59
  export { StatCard } from './components/dashboard/stat-card.js';
package/dist/index.js CHANGED
@@ -3128,6 +3128,14 @@ function FeatureCard({
3128
3128
  index
3129
3129
  }) {
3130
3130
  const isBentoFeatured = variant === "bento" && feature.featured;
3131
+ if (variant === "minimal") {
3132
+ return /* @__PURE__ */ jsxs("div", { className: "group flex flex-col gap-3 border-l-4 border-l-brand py-1 pl-5", children: [
3133
+ feature.icon && /* @__PURE__ */ jsx("div", { className: "text-2xl", children: feature.icon }),
3134
+ feature.stat && /* @__PURE__ */ jsx("p", { className: "brutal-label text-brand", children: feature.stat }),
3135
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-bold", children: feature.title }),
3136
+ /* @__PURE__ */ jsx("p", { className: "text-sm leading-relaxed text-muted-foreground", children: feature.description })
3137
+ ] });
3138
+ }
3131
3139
  if (variant === "icon-left") {
3132
3140
  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: [
3133
3141
  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 }),
@@ -3165,6 +3173,52 @@ function FeatureCard({
3165
3173
  }
3166
3174
  );
3167
3175
  }
3176
+ function BrutalFeatureShowcase({
3177
+ badge,
3178
+ headline,
3179
+ description,
3180
+ visual,
3181
+ features,
3182
+ reversed = false,
3183
+ color = "white",
3184
+ pattern,
3185
+ className
3186
+ }) {
3187
+ return /* @__PURE__ */ jsx(BrutalSection, { color, pattern, className, children: /* @__PURE__ */ jsxs(
3188
+ "div",
3189
+ {
3190
+ className: cn(
3191
+ "grid items-center gap-12 lg:grid-cols-2 lg:gap-20",
3192
+ reversed && "lg:[&>*:first-child]:order-2"
3193
+ ),
3194
+ children: [
3195
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
3196
+ badge && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "w-fit font-mono text-xs uppercase tracking-widest", children: badge }),
3197
+ /* @__PURE__ */ jsx("h2", { className: "brutal-h2", children: headline }),
3198
+ /* @__PURE__ */ jsx("p", { className: "brutal-body text-muted-foreground", children: description }),
3199
+ 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: [
3200
+ 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" }),
3201
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: f.text })
3202
+ ] }, i)) })
3203
+ ] }),
3204
+ /* @__PURE__ */ jsxs(
3205
+ "div",
3206
+ {
3207
+ className: cn(
3208
+ "relative",
3209
+ reversed ? "-rotate-1" : "rotate-1",
3210
+ "transform transition-transform duration-300 hover:rotate-0"
3211
+ ),
3212
+ children: [
3213
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 translate-x-3 translate-y-3 border-brutal border-foreground bg-brand opacity-20" }),
3214
+ /* @__PURE__ */ jsx("div", { className: "relative border-brutal border-foreground bg-background shadow-brutal-lg", children: visual })
3215
+ ]
3216
+ }
3217
+ )
3218
+ ]
3219
+ }
3220
+ ) });
3221
+ }
3168
3222
  function StarRating({ rating }) {
3169
3223
  return /* @__PURE__ */ jsx("div", { className: "flex gap-0.5", children: Array.from({ length: 5 }, (_, i) => /* @__PURE__ */ jsx(
3170
3224
  "span",
@@ -3460,6 +3514,54 @@ function BrutalCTA({
3460
3514
  variant === "with-visual" && /* @__PURE__ */ jsx(WithVisualCTA, { ...props, variant, color })
3461
3515
  ] });
3462
3516
  }
3517
+ function CellValue({ value }) {
3518
+ if (typeof value === "boolean") {
3519
+ 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" });
3520
+ }
3521
+ return /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: value });
3522
+ }
3523
+ function BrutalComparisonTable({
3524
+ badge,
3525
+ headline,
3526
+ description,
3527
+ usName,
3528
+ themName,
3529
+ features,
3530
+ color = "white",
3531
+ pattern,
3532
+ className
3533
+ }) {
3534
+ return /* @__PURE__ */ jsxs(BrutalSection, { color, pattern, className, children: [
3535
+ /* @__PURE__ */ jsxs("div", { className: "mb-12 max-w-2xl", children: [
3536
+ badge && /* @__PURE__ */ jsx("p", { className: "brutal-label mb-4 text-brand", children: badge }),
3537
+ /* @__PURE__ */ jsx("h2", { className: "brutal-h2 mb-4", children: headline }),
3538
+ description && /* @__PURE__ */ jsx("p", { className: "brutal-body text-muted-foreground", children: description })
3539
+ ] }),
3540
+ /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse", children: [
3541
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
3542
+ /* @__PURE__ */ jsx("th", { className: "border-b-brutal border-foreground px-4 py-3 text-left text-sm font-medium text-muted-foreground", children: "Feature" }),
3543
+ /* @__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 }) }),
3544
+ /* @__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 }) })
3545
+ ] }) }),
3546
+ /* @__PURE__ */ jsx("tbody", { children: features.map((f, i) => /* @__PURE__ */ jsxs(
3547
+ "tr",
3548
+ {
3549
+ className: cn(
3550
+ "transition-colors",
3551
+ f.highlight && "bg-brand-muted/50",
3552
+ i % 2 === 0 && !f.highlight && "bg-muted/30"
3553
+ ),
3554
+ children: [
3555
+ /* @__PURE__ */ jsx("td", { className: "border-b border-foreground/10 px-4 py-3 text-sm font-medium", children: f.name }),
3556
+ /* @__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 }) }),
3557
+ /* @__PURE__ */ jsx("td", { className: "border-b border-foreground/10 px-4 py-3 text-center", children: /* @__PURE__ */ jsx(CellValue, { value: f.them }) })
3558
+ ]
3559
+ },
3560
+ i
3561
+ )) })
3562
+ ] }) })
3563
+ ] });
3564
+ }
3463
3565
  function BrutalNav({
3464
3566
  logo,
3465
3567
  links,
@@ -3931,6 +4033,126 @@ function Newsletter({
3931
4033
  )
3932
4034
  ] }) });
3933
4035
  }
4036
+ function MockupWindow({
4037
+ children,
4038
+ title = "app.example.com",
4039
+ variant = "browser",
4040
+ className
4041
+ }) {
4042
+ if (variant === "phone") {
4043
+ return /* @__PURE__ */ jsxs(
4044
+ "div",
4045
+ {
4046
+ className: cn(
4047
+ "mx-auto w-[280px] overflow-hidden rounded-[2rem] border-brutal border-foreground bg-background shadow-brutal-lg",
4048
+ className
4049
+ ),
4050
+ children: [
4051
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center bg-foreground py-2", children: /* @__PURE__ */ jsx("div", { className: "h-5 w-28 rounded-full bg-background/20" }) }),
4052
+ /* @__PURE__ */ jsx("div", { className: "overflow-hidden", children }),
4053
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center bg-foreground py-3", children: /* @__PURE__ */ jsx("div", { className: "h-1 w-24 rounded-full bg-background/30" }) })
4054
+ ]
4055
+ }
4056
+ );
4057
+ }
4058
+ if (variant === "terminal") {
4059
+ return /* @__PURE__ */ jsxs(
4060
+ "div",
4061
+ {
4062
+ className: cn(
4063
+ "overflow-hidden rounded-lg border-brutal border-foreground shadow-brutal-lg",
4064
+ className
4065
+ ),
4066
+ children: [
4067
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b-brutal border-foreground bg-foreground px-4 py-2.5", children: [
4068
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
4069
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full bg-red-500" }),
4070
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full bg-yellow-500" }),
4071
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full bg-green-500" })
4072
+ ] }),
4073
+ /* @__PURE__ */ jsx("span", { className: "ml-2 font-mono text-xs text-background/60", children: title })
4074
+ ] }),
4075
+ /* @__PURE__ */ jsx("div", { className: "bg-foreground text-background", children })
4076
+ ]
4077
+ }
4078
+ );
4079
+ }
4080
+ return /* @__PURE__ */ jsxs(
4081
+ "div",
4082
+ {
4083
+ className: cn(
4084
+ "overflow-hidden rounded-lg border-brutal border-foreground shadow-brutal-lg",
4085
+ className
4086
+ ),
4087
+ children: [
4088
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 border-b-brutal border-foreground bg-muted px-4 py-2.5", children: [
4089
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
4090
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full border border-foreground/20 bg-red-400" }),
4091
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full border border-foreground/20 bg-yellow-400" }),
4092
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full border border-foreground/20 bg-green-400" })
4093
+ ] }),
4094
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx("div", { className: "mx-auto max-w-sm rounded-md border border-foreground/10 bg-background px-3 py-1 text-center font-mono text-xs text-muted-foreground", children: title }) }),
4095
+ /* @__PURE__ */ jsx("div", { className: "w-[54px]" }),
4096
+ " "
4097
+ ] }),
4098
+ /* @__PURE__ */ jsx("div", { className: "bg-background", children })
4099
+ ]
4100
+ }
4101
+ );
4102
+ }
4103
+ var speedMap = {
4104
+ slow: "60s",
4105
+ normal: "30s",
4106
+ fast: "15s"
4107
+ };
4108
+ function Marquee({
4109
+ children,
4110
+ speed = "normal",
4111
+ direction = "left",
4112
+ pauseOnHover = true,
4113
+ className
4114
+ }) {
4115
+ return /* @__PURE__ */ jsx(
4116
+ "div",
4117
+ {
4118
+ className: cn(
4119
+ "group flex overflow-hidden border-y-brutal border-foreground bg-foreground py-3",
4120
+ className
4121
+ ),
4122
+ children: [0, 1].map((copy) => /* @__PURE__ */ jsxs(
4123
+ "div",
4124
+ {
4125
+ "aria-hidden": copy === 1,
4126
+ className: cn(
4127
+ "flex shrink-0 items-center gap-8",
4128
+ pauseOnHover && "group-hover:[animation-play-state:paused]"
4129
+ ),
4130
+ style: {
4131
+ animation: `marquee ${speedMap[speed]} linear infinite`,
4132
+ animationDirection: direction === "right" ? "reverse" : "normal"
4133
+ },
4134
+ children: [
4135
+ children,
4136
+ /* @__PURE__ */ jsx("span", { className: "mx-4 text-background/30 select-none", children: "\u2022" })
4137
+ ]
4138
+ },
4139
+ copy
4140
+ ))
4141
+ }
4142
+ );
4143
+ }
4144
+ function MarqueeItem({ children, className }) {
4145
+ return /* @__PURE__ */ jsx(
4146
+ "span",
4147
+ {
4148
+ className: cn(
4149
+ "inline-flex shrink-0 items-center gap-2 whitespace-nowrap font-bold text-background",
4150
+ className
4151
+ ),
4152
+ children
4153
+ }
4154
+ );
4155
+ }
3934
4156
  var AppShellContext = createContext({
3935
4157
  collapsed: false,
3936
4158
  setCollapsed: () => {
@@ -4927,6 +5149,6 @@ function DashboardTemplate({
4927
5149
  );
4928
5150
  }
4929
5151
 
4930
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityFeed, Alert, AlertDescription, AlertTitle, AppShell, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BrutalCTA, BrutalFeatureGrid, BrutalFooter, BrutalHero, BrutalIntegrationGrid, BrutalNav, BrutalSection, BrutalTestimonials, Button, CalendarView, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DashboardTemplate, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, FAQ, FileUpload, GridView, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputGroup, InputGroupAddon, InputGroupInput, InputGroupTextarea, KanbanBoard, Label, ListView, LogoCloud, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuPositioner, NavigationMenuTrigger, Newsletter, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, PricingTable, Progress, RadioGroup, RadioGroupItem, SaaSLaunchTemplate, ScrollArea, ScrollBar, SearchBar, SectionDivider, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, Skeleton, Slider, StatCard, StatsBar, StudioTemplate, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserMenu, ViewSwitcher, SectionDivider as WaveDivider, badgeVariants, buttonVariants, cn, defaultTransition, fadeIn, fadeInUp, navigationMenuTriggerStyle, scaleIn, slideInLeft, slideInRight, springTransition, staggerContainer, tabsListVariants, toggleVariants, useAppShell };
5152
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityFeed, Alert, AlertDescription, AlertTitle, AppShell, Avatar, AvatarFallback, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BrutalCTA, BrutalComparisonTable, BrutalFeatureGrid, BrutalFeatureShowcase, BrutalFooter, BrutalHero, BrutalIntegrationGrid, BrutalNav, BrutalSection, BrutalTestimonials, Button, CalendarView, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DashboardTemplate, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, FAQ, FileUpload, GridView, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputGroup, InputGroupAddon, InputGroupInput, InputGroupTextarea, KanbanBoard, Label, ListView, LogoCloud, Marquee, MarqueeItem, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MockupWindow, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuPositioner, NavigationMenuTrigger, Newsletter, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, PricingTable, Progress, RadioGroup, RadioGroupItem, SaaSLaunchTemplate, ScrollArea, ScrollBar, SearchBar, SectionDivider, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, Skeleton, Slider, StatCard, StatsBar, StudioTemplate, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserMenu, ViewSwitcher, SectionDivider as WaveDivider, badgeVariants, buttonVariants, cn, defaultTransition, fadeIn, fadeInUp, navigationMenuTriggerStyle, scaleIn, slideInLeft, slideInRight, springTransition, staggerContainer, tabsListVariants, toggleVariants, useAppShell };
4931
5153
  //# sourceMappingURL=index.js.map
4932
5154
  //# sourceMappingURL=index.js.map