@snow-labs/brutal-ui 0.3.2 → 0.5.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 (53) 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 +2 -2
  5. package/dist/components/brutal/cta-section.js.map +1 -1
  6. package/dist/components/brutal/faq.js +2 -2
  7. package/dist/components/brutal/faq.js.map +1 -1
  8. package/dist/components/brutal/feature-grid.d.ts +1 -1
  9. package/dist/components/brutal/feature-grid.js +10 -2
  10. package/dist/components/brutal/feature-grid.js.map +1 -1
  11. package/dist/components/brutal/feature-showcase.d.ts +20 -0
  12. package/dist/components/brutal/feature-showcase.js +158 -0
  13. package/dist/components/brutal/feature-showcase.js.map +1 -0
  14. package/dist/components/brutal/footer.js +1 -2
  15. package/dist/components/brutal/footer.js.map +1 -1
  16. package/dist/components/brutal/hero.js +2 -2
  17. package/dist/components/brutal/hero.js.map +1 -1
  18. package/dist/components/brutal/index.d.ts +4 -0
  19. package/dist/components/brutal/index.js +275 -59
  20. package/dist/components/brutal/index.js.map +1 -1
  21. package/dist/components/brutal/integration-grid.js +3 -3
  22. package/dist/components/brutal/integration-grid.js.map +1 -1
  23. package/dist/components/brutal/logo-cloud.js +2 -2
  24. package/dist/components/brutal/logo-cloud.js.map +1 -1
  25. package/dist/components/brutal/marquee.d.ts +17 -0
  26. package/dist/components/brutal/marquee.js +66 -0
  27. package/dist/components/brutal/marquee.js.map +1 -0
  28. package/dist/components/brutal/mockup-window.d.ts +11 -0
  29. package/dist/components/brutal/mockup-window.js +80 -0
  30. package/dist/components/brutal/mockup-window.js.map +1 -0
  31. package/dist/components/brutal/nav.js +1 -1
  32. package/dist/components/brutal/nav.js.map +1 -1
  33. package/dist/components/brutal/newsletter.js +2 -2
  34. package/dist/components/brutal/newsletter.js.map +1 -1
  35. package/dist/components/brutal/pricing-table.js +2 -2
  36. package/dist/components/brutal/pricing-table.js.map +1 -1
  37. package/dist/components/brutal/section.js +2 -2
  38. package/dist/components/brutal/section.js.map +1 -1
  39. package/dist/components/brutal/stats-bar.js +3 -3
  40. package/dist/components/brutal/stats-bar.js.map +1 -1
  41. package/dist/components/brutal/testimonials.js +6 -11
  42. package/dist/components/brutal/testimonials.js.map +1 -1
  43. package/dist/index.d.ts +4 -0
  44. package/dist/index.js +233 -17
  45. package/dist/index.js.map +1 -1
  46. package/dist/templates/index.js +17 -15
  47. package/dist/templates/index.js.map +1 -1
  48. package/dist/templates/saas-launch.js +17 -15
  49. package/dist/templates/saas-launch.js.map +1 -1
  50. package/dist/templates/studio.js +16 -14
  51. package/dist/templates/studio.js.map +1 -1
  52. package/dist/theme.css +41 -4
  53. package/package.json +1 -1
@@ -4,12 +4,12 @@ import { twMerge } from 'tailwind-merge';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { Button as Button$1 } from '@base-ui/react/button';
6
6
  import { cva } from 'class-variance-authority';
7
+ import { mergeProps } from '@base-ui/react/merge-props';
8
+ import { useRender } from '@base-ui/react/use-render';
7
9
  import { useState, useEffect, useRef } from 'react';
8
10
  import { Dialog } from '@base-ui/react/dialog';
9
11
  import { Menu, XIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react';
10
12
  import { Input as Input$1 } from '@base-ui/react/input';
11
- import { mergeProps } from '@base-ui/react/merge-props';
12
- import { useRender } from '@base-ui/react/use-render';
13
13
  import { Accordion as Accordion$1 } from '@base-ui/react/accordion';
14
14
 
15
15
  // src/lib/utils.ts
@@ -21,8 +21,8 @@ var colorMap = {
21
21
  brand: "bg-brand",
22
22
  "brand-muted": "bg-brand-muted text-foreground",
23
23
  blue: "bg-section-blue",
24
- gray: "bg-section-gray text-foreground",
25
- cream: "bg-section-cream text-foreground",
24
+ gray: "bg-muted text-foreground",
25
+ cream: "bg-secondary text-foreground",
26
26
  black: "bg-foreground text-background",
27
27
  cta: "bg-cta"
28
28
  };
@@ -360,6 +360,14 @@ function FeatureCard({
360
360
  index
361
361
  }) {
362
362
  const isBentoFeatured = variant === "bento" && feature.featured;
363
+ if (variant === "minimal") {
364
+ return /* @__PURE__ */ jsxs("div", { className: "group flex flex-col gap-3 border-l-4 border-l-brand py-1 pl-5", children: [
365
+ feature.icon && /* @__PURE__ */ jsx("div", { className: "text-2xl", children: feature.icon }),
366
+ feature.stat && /* @__PURE__ */ jsx("p", { className: "brutal-label text-brand", children: feature.stat }),
367
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-bold", children: feature.title }),
368
+ /* @__PURE__ */ jsx("p", { className: "text-sm leading-relaxed text-muted-foreground", children: feature.description })
369
+ ] });
370
+ }
363
371
  if (variant === "icon-left") {
364
372
  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: [
365
373
  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 }),
@@ -397,13 +405,99 @@ function FeatureCard({
397
405
  }
398
406
  );
399
407
  }
408
+ var badgeVariants = cva(
409
+ "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!",
410
+ {
411
+ variants: {
412
+ variant: {
413
+ default: "border-brutal border-foreground bg-primary px-3 py-1 text-xs text-primary-foreground shadow-brutal-sm",
414
+ secondary: "border-brutal border-foreground bg-secondary px-3 py-1 text-xs text-secondary-foreground shadow-brutal-sm",
415
+ brand: "border-brutal border-foreground bg-brand px-3 py-1 text-xs text-brand-foreground shadow-brutal-sm",
416
+ cta: "border-brutal border-foreground bg-cta px-3 py-1 text-xs text-cta-foreground shadow-brutal-sm",
417
+ outline: "border-brutal border-foreground bg-background px-3 py-1 text-xs text-foreground",
418
+ destructive: "border-brutal border-destructive bg-destructive/10 px-3 py-1 text-xs text-destructive",
419
+ ghost: "px-2 py-0.5 text-xs text-muted-foreground"
420
+ }
421
+ },
422
+ defaultVariants: {
423
+ variant: "default"
424
+ }
425
+ }
426
+ );
427
+ function Badge({
428
+ className,
429
+ variant = "default",
430
+ render,
431
+ ...props
432
+ }) {
433
+ return useRender({
434
+ defaultTagName: "span",
435
+ props: mergeProps(
436
+ {
437
+ className: cn(badgeVariants({ variant }), className)
438
+ },
439
+ props
440
+ ),
441
+ render,
442
+ state: {
443
+ slot: "badge",
444
+ variant
445
+ }
446
+ });
447
+ }
448
+ function BrutalFeatureShowcase({
449
+ badge,
450
+ headline,
451
+ description,
452
+ visual,
453
+ features,
454
+ reversed = false,
455
+ color = "white",
456
+ pattern,
457
+ className
458
+ }) {
459
+ return /* @__PURE__ */ jsx(BrutalSection, { color, pattern, className, children: /* @__PURE__ */ jsxs(
460
+ "div",
461
+ {
462
+ className: cn(
463
+ "grid items-center gap-12 lg:grid-cols-2 lg:gap-20",
464
+ reversed && "lg:[&>*:first-child]:order-2"
465
+ ),
466
+ children: [
467
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
468
+ badge && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "w-fit font-mono text-xs uppercase tracking-widest", children: badge }),
469
+ /* @__PURE__ */ jsx("h2", { className: "brutal-h2", children: headline }),
470
+ /* @__PURE__ */ jsx("p", { className: "brutal-body text-muted-foreground", children: description }),
471
+ 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: [
472
+ 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" }),
473
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: f.text })
474
+ ] }, i)) })
475
+ ] }),
476
+ /* @__PURE__ */ jsxs(
477
+ "div",
478
+ {
479
+ className: cn(
480
+ "relative",
481
+ reversed ? "-rotate-1" : "rotate-1",
482
+ "transform transition-transform duration-300 hover:rotate-0"
483
+ ),
484
+ children: [
485
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 translate-x-3 translate-y-3 border-brutal border-foreground bg-brand opacity-20" }),
486
+ /* @__PURE__ */ jsx("div", { className: "relative border-brutal border-foreground bg-background shadow-brutal-lg", children: visual })
487
+ ]
488
+ }
489
+ )
490
+ ]
491
+ }
492
+ ) });
493
+ }
400
494
  function StarRating({ rating }) {
401
495
  return /* @__PURE__ */ jsx("div", { className: "flex gap-0.5", children: Array.from({ length: 5 }, (_, i) => /* @__PURE__ */ jsx(
402
496
  "span",
403
497
  {
404
498
  className: cn(
405
499
  "text-sm",
406
- i < rating ? "text-amber-500" : "text-foreground/20"
500
+ i < rating ? "text-brand" : "text-foreground/20"
407
501
  ),
408
502
  children: "\u2605"
409
503
  },
@@ -431,17 +525,12 @@ function TestimonialCard({
431
525
  {
432
526
  src: t.avatar,
433
527
  alt: t.name,
434
- className: "size-9 border-2 object-cover",
435
- style: { borderColor: "hsl(var(--brand))" }
528
+ className: "size-9 border-2 border-brand object-cover"
436
529
  }
437
530
  ) : /* @__PURE__ */ jsx(
438
531
  "div",
439
532
  {
440
- className: "flex size-9 items-center justify-center border-2 font-bold text-brand-foreground",
441
- style: {
442
- borderColor: "hsl(var(--brand))",
443
- backgroundColor: "hsl(var(--brand))"
444
- },
533
+ className: "flex size-9 items-center justify-center border-2 border-brand bg-brand font-bold text-brand-foreground",
445
534
  children: t.name[0]
446
535
  }
447
536
  ),
@@ -507,7 +596,7 @@ function BrutalTestimonials({
507
596
  headline,
508
597
  testimonials,
509
598
  variant = "masonry",
510
- color = "blue",
599
+ color = "white",
511
600
  pattern,
512
601
  className
513
602
  }) {
@@ -534,7 +623,7 @@ function BrutalIntegrationGrid({
534
623
  /* @__PURE__ */ jsxs("div", { className: "mb-12 text-center", children: [
535
624
  badge && /* @__PURE__ */ jsx("p", { className: "brutal-label mb-4 opacity-70", children: badge }),
536
625
  /* @__PURE__ */ jsx("h2", { className: "brutal-h2 mb-4", children: headline }),
537
- description && /* @__PURE__ */ jsx("p", { className: "brutal-body mx-auto max-w-lg text-muted-foreground", children: description })
626
+ description && /* @__PURE__ */ jsx("p", { className: "brutal-body mx-auto max-w-lg opacity-80", children: description })
538
627
  ] }),
539
628
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center justify-center gap-6", children: integrations.map((item) => {
540
629
  const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -692,6 +781,54 @@ function BrutalCTA({
692
781
  variant === "with-visual" && /* @__PURE__ */ jsx(WithVisualCTA, { ...props, variant, color })
693
782
  ] });
694
783
  }
784
+ function CellValue({ value }) {
785
+ if (typeof value === "boolean") {
786
+ 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" });
787
+ }
788
+ return /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: value });
789
+ }
790
+ function BrutalComparisonTable({
791
+ badge,
792
+ headline,
793
+ description,
794
+ usName,
795
+ themName,
796
+ features,
797
+ color = "white",
798
+ pattern,
799
+ className
800
+ }) {
801
+ return /* @__PURE__ */ jsxs(BrutalSection, { color, pattern, className, children: [
802
+ /* @__PURE__ */ jsxs("div", { className: "mb-12 max-w-2xl", children: [
803
+ badge && /* @__PURE__ */ jsx("p", { className: "brutal-label mb-4 text-brand", children: badge }),
804
+ /* @__PURE__ */ jsx("h2", { className: "brutal-h2 mb-4", children: headline }),
805
+ description && /* @__PURE__ */ jsx("p", { className: "brutal-body text-muted-foreground", children: description })
806
+ ] }),
807
+ /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse", children: [
808
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
809
+ /* @__PURE__ */ jsx("th", { className: "border-b-brutal border-foreground px-4 py-3 text-left text-sm font-medium text-muted-foreground", children: "Feature" }),
810
+ /* @__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 }) }),
811
+ /* @__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 }) })
812
+ ] }) }),
813
+ /* @__PURE__ */ jsx("tbody", { children: features.map((f, i) => /* @__PURE__ */ jsxs(
814
+ "tr",
815
+ {
816
+ className: cn(
817
+ "transition-colors",
818
+ f.highlight && "bg-brand-muted/50",
819
+ i % 2 === 0 && !f.highlight && "bg-muted/30"
820
+ ),
821
+ children: [
822
+ /* @__PURE__ */ jsx("td", { className: "border-b border-foreground/10 px-4 py-3 text-sm font-medium", children: f.name }),
823
+ /* @__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 }) }),
824
+ /* @__PURE__ */ jsx("td", { className: "border-b border-foreground/10 px-4 py-3 text-center", children: /* @__PURE__ */ jsx(CellValue, { value: f.them }) })
825
+ ]
826
+ },
827
+ i
828
+ )) })
829
+ ] }) })
830
+ ] });
831
+ }
695
832
  function Sheet({ ...props }) {
696
833
  return /* @__PURE__ */ jsx(Dialog.Root, { "data-slot": "sheet", ...props });
697
834
  }
@@ -792,7 +929,7 @@ function BrutalNav({
792
929
  solid: "sticky top-0 z-50 w-full border-b-brutal border-foreground bg-brand",
793
930
  transparent: cn(
794
931
  "fixed top-0 left-0 right-0 z-50 w-full transition-all duration-200",
795
- isScrolled ? "bg-background/80 text-foreground backdrop-blur-md border-b border-foreground/10" : "bg-transparent text-white"
932
+ isScrolled ? "bg-background/80 text-foreground backdrop-blur-md border-b border-border/30" : "bg-transparent text-foreground"
796
933
  ),
797
934
  "floating-pill": "fixed top-0 left-0 right-0 z-50 mx-4 mt-4 rounded-full border-brutal border-foreground bg-background shadow-brutal"
798
935
  };
@@ -1001,10 +1138,9 @@ function BrutalFooter({
1001
1138
  "footer",
1002
1139
  {
1003
1140
  className: cn(
1004
- "w-full border-t-4 bg-background px-6 py-12 text-foreground",
1141
+ "w-full border-t-4 border-t-brand bg-background px-6 py-12 text-foreground",
1005
1142
  className
1006
1143
  ),
1007
- style: { borderTopColor: "hsl(var(--brand))" },
1008
1144
  children: /* @__PURE__ */ jsxs("div", { className: "brutal-container", children: [
1009
1145
  variant === "newsletter" && newsletter && /* @__PURE__ */ jsx(NewsletterSection, { newsletter }),
1010
1146
  variant === "minimal" ? /* @__PURE__ */ jsx(MinimalContent, { logo, columns, socials }) : /* @__PURE__ */ jsx(
@@ -1024,46 +1160,6 @@ function BrutalFooter({
1024
1160
  }
1025
1161
  );
1026
1162
  }
1027
- var badgeVariants = cva(
1028
- "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!",
1029
- {
1030
- variants: {
1031
- variant: {
1032
- default: "border-brutal border-foreground bg-primary px-3 py-1 text-xs text-primary-foreground shadow-brutal-sm",
1033
- secondary: "border-brutal border-foreground bg-secondary px-3 py-1 text-xs text-secondary-foreground shadow-brutal-sm",
1034
- brand: "border-brutal border-foreground bg-brand px-3 py-1 text-xs text-brand-foreground shadow-brutal-sm",
1035
- cta: "border-brutal border-foreground bg-cta px-3 py-1 text-xs text-cta-foreground shadow-brutal-sm",
1036
- outline: "border-brutal border-foreground bg-background px-3 py-1 text-xs text-foreground",
1037
- destructive: "border-brutal border-destructive bg-destructive/10 px-3 py-1 text-xs text-destructive",
1038
- ghost: "px-2 py-0.5 text-xs text-muted-foreground"
1039
- }
1040
- },
1041
- defaultVariants: {
1042
- variant: "default"
1043
- }
1044
- }
1045
- );
1046
- function Badge({
1047
- className,
1048
- variant = "default",
1049
- render,
1050
- ...props
1051
- }) {
1052
- return useRender({
1053
- defaultTagName: "span",
1054
- props: mergeProps(
1055
- {
1056
- className: cn(badgeVariants({ variant }), className)
1057
- },
1058
- props
1059
- ),
1060
- render,
1061
- state: {
1062
- slot: "badge",
1063
- variant
1064
- }
1065
- });
1066
- }
1067
1163
  function PricingTable({
1068
1164
  badge,
1069
1165
  headline,
@@ -1203,7 +1299,7 @@ function StatItem({ stat, inView }) {
1203
1299
  count.toLocaleString(),
1204
1300
  stat.suffix
1205
1301
  ] }),
1206
- /* @__PURE__ */ jsx("p", { className: "brutal-label mt-2 text-muted-foreground", children: stat.label })
1302
+ /* @__PURE__ */ jsx("p", { className: "brutal-label mt-2 opacity-70", children: stat.label })
1207
1303
  ] });
1208
1304
  }
1209
1305
  function StatsBar({ stats, color = "white", className }) {
@@ -1362,7 +1458,127 @@ function Newsletter({
1362
1458
  )
1363
1459
  ] }) });
1364
1460
  }
1461
+ function MockupWindow({
1462
+ children,
1463
+ title = "app.example.com",
1464
+ variant = "browser",
1465
+ className
1466
+ }) {
1467
+ if (variant === "phone") {
1468
+ return /* @__PURE__ */ jsxs(
1469
+ "div",
1470
+ {
1471
+ className: cn(
1472
+ "mx-auto w-[280px] overflow-hidden rounded-[2rem] border-brutal border-foreground bg-background shadow-brutal-lg",
1473
+ className
1474
+ ),
1475
+ children: [
1476
+ /* @__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" }) }),
1477
+ /* @__PURE__ */ jsx("div", { className: "overflow-hidden", children }),
1478
+ /* @__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" }) })
1479
+ ]
1480
+ }
1481
+ );
1482
+ }
1483
+ if (variant === "terminal") {
1484
+ return /* @__PURE__ */ jsxs(
1485
+ "div",
1486
+ {
1487
+ className: cn(
1488
+ "overflow-hidden rounded-lg border-brutal border-foreground shadow-brutal-lg",
1489
+ className
1490
+ ),
1491
+ children: [
1492
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b-brutal border-foreground bg-foreground px-4 py-2.5", children: [
1493
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
1494
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full bg-red-500" }),
1495
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full bg-yellow-500" }),
1496
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full bg-green-500" })
1497
+ ] }),
1498
+ /* @__PURE__ */ jsx("span", { className: "ml-2 font-mono text-xs text-background/60", children: title })
1499
+ ] }),
1500
+ /* @__PURE__ */ jsx("div", { className: "bg-foreground text-background", children })
1501
+ ]
1502
+ }
1503
+ );
1504
+ }
1505
+ return /* @__PURE__ */ jsxs(
1506
+ "div",
1507
+ {
1508
+ className: cn(
1509
+ "overflow-hidden rounded-lg border-brutal border-foreground shadow-brutal-lg",
1510
+ className
1511
+ ),
1512
+ children: [
1513
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 border-b-brutal border-foreground bg-muted px-4 py-2.5", children: [
1514
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
1515
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full border border-foreground/20 bg-red-400" }),
1516
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full border border-foreground/20 bg-yellow-400" }),
1517
+ /* @__PURE__ */ jsx("div", { className: "size-3 rounded-full border border-foreground/20 bg-green-400" })
1518
+ ] }),
1519
+ /* @__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 }) }),
1520
+ /* @__PURE__ */ jsx("div", { className: "w-[54px]" }),
1521
+ " "
1522
+ ] }),
1523
+ /* @__PURE__ */ jsx("div", { className: "bg-background", children })
1524
+ ]
1525
+ }
1526
+ );
1527
+ }
1528
+ var speedMap = {
1529
+ slow: "60s",
1530
+ normal: "30s",
1531
+ fast: "15s"
1532
+ };
1533
+ function Marquee({
1534
+ children,
1535
+ speed = "normal",
1536
+ direction = "left",
1537
+ pauseOnHover = true,
1538
+ className
1539
+ }) {
1540
+ return /* @__PURE__ */ jsx(
1541
+ "div",
1542
+ {
1543
+ className: cn(
1544
+ "group flex overflow-hidden border-y-brutal border-foreground bg-foreground py-3",
1545
+ className
1546
+ ),
1547
+ children: [0, 1].map((copy) => /* @__PURE__ */ jsxs(
1548
+ "div",
1549
+ {
1550
+ "aria-hidden": copy === 1,
1551
+ className: cn(
1552
+ "flex shrink-0 items-center gap-8",
1553
+ pauseOnHover && "group-hover:[animation-play-state:paused]"
1554
+ ),
1555
+ style: {
1556
+ animation: `marquee ${speedMap[speed]} linear infinite`,
1557
+ animationDirection: direction === "right" ? "reverse" : "normal"
1558
+ },
1559
+ children: [
1560
+ children,
1561
+ /* @__PURE__ */ jsx("span", { className: "mx-4 text-background/30 select-none", children: "\u2022" })
1562
+ ]
1563
+ },
1564
+ copy
1565
+ ))
1566
+ }
1567
+ );
1568
+ }
1569
+ function MarqueeItem({ children, className }) {
1570
+ return /* @__PURE__ */ jsx(
1571
+ "span",
1572
+ {
1573
+ className: cn(
1574
+ "inline-flex shrink-0 items-center gap-2 whitespace-nowrap font-bold text-background",
1575
+ className
1576
+ ),
1577
+ children
1578
+ }
1579
+ );
1580
+ }
1365
1581
 
1366
- export { BrutalCTA, BrutalFeatureGrid, BrutalFooter, BrutalHero, BrutalIntegrationGrid, BrutalNav, BrutalSection, BrutalTestimonials, FAQ, LogoCloud, Newsletter, PricingTable, SectionDivider, StatsBar, SectionDivider as WaveDivider };
1582
+ export { BrutalCTA, BrutalComparisonTable, BrutalFeatureGrid, BrutalFeatureShowcase, BrutalFooter, BrutalHero, BrutalIntegrationGrid, BrutalNav, BrutalSection, BrutalTestimonials, FAQ, LogoCloud, Marquee, MarqueeItem, MockupWindow, Newsletter, PricingTable, SectionDivider, StatsBar, SectionDivider as WaveDivider };
1367
1583
  //# sourceMappingURL=index.js.map
1368
1584
  //# sourceMappingURL=index.js.map