@geomak/ui 6.31.0 → 6.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { createPortal } from 'react-dom';
6
6
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
7
7
  import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
8
8
  import * as Dialog from '@radix-ui/react-dialog';
9
- import { useReducedMotion, AnimatePresence, motion } from 'framer-motion';
9
+ import { useReducedMotion, AnimatePresence, motion, useScroll, useTransform } from 'framer-motion';
10
10
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
11
11
  import * as TabsPrimitive from '@radix-ui/react-tabs';
12
12
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
@@ -9437,7 +9437,398 @@ function Testimonials({ testimonials, eyebrow, title, description, columns = 3,
9437
9437
  ] }, tm.key ?? i)) })
9438
9438
  ] });
9439
9439
  }
9440
+ var Arrow4 = ({ dir }) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-5 w-5", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: dir === "left" ? "M15 18l-6-6 6-6" : "M9 18l6-6-6-6" }) });
9441
+ var SCRIM = "linear-gradient(to top, color-mix(in oklab, var(--color-foreground) 70%, transparent), color-mix(in oklab, var(--color-foreground) 25%, transparent))";
9442
+ function SlideShow({
9443
+ slides,
9444
+ autoPlay = true,
9445
+ interval = 6e3,
9446
+ showArrows = true,
9447
+ showDots = true,
9448
+ height = 460,
9449
+ "aria-label": ariaLabel = "Slideshow",
9450
+ className = "",
9451
+ style
9452
+ }) {
9453
+ const reduced = useReducedMotion();
9454
+ const [index, setIndex] = useState(0);
9455
+ const [paused, setPaused] = useState(false);
9456
+ const count = slides.length;
9457
+ const idx = count ? (index % count + count) % count : 0;
9458
+ const go = useCallback((d) => setIndex((i) => i + d), []);
9459
+ const timer = useRef(null);
9460
+ useEffect(() => {
9461
+ if (!autoPlay || paused || count <= 1) return;
9462
+ timer.current = setInterval(() => setIndex((i) => i + 1), interval);
9463
+ return () => {
9464
+ if (timer.current) clearInterval(timer.current);
9465
+ };
9466
+ }, [autoPlay, paused, interval, count]);
9467
+ if (count === 0) return null;
9468
+ const slide = slides[idx];
9469
+ const onImage = Boolean(slide.image);
9470
+ const align = slide.align ?? "center";
9471
+ return /* @__PURE__ */ jsxs(
9472
+ "section",
9473
+ {
9474
+ "aria-label": ariaLabel,
9475
+ "aria-roledescription": "carousel",
9476
+ className: ["relative overflow-hidden rounded-2xl", className].filter(Boolean).join(" "),
9477
+ style: { height, ...style },
9478
+ onMouseEnter: () => setPaused(true),
9479
+ onMouseLeave: () => setPaused(false),
9480
+ children: [
9481
+ /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: /* @__PURE__ */ jsxs(
9482
+ motion.div,
9483
+ {
9484
+ className: "absolute inset-0",
9485
+ initial: { opacity: 0 },
9486
+ animate: { opacity: 1 },
9487
+ exit: { opacity: 0 },
9488
+ transition: { duration: reduced ? 0 : 0.6, ease: "easeInOut" },
9489
+ style: onImage ? { backgroundImage: `url(${slide.image})`, backgroundSize: "cover", backgroundPosition: "center" } : void 0,
9490
+ children: [
9491
+ onImage && /* @__PURE__ */ jsx("div", { className: "absolute inset-0", style: { backgroundImage: SCRIM }, "aria-hidden": "true" }),
9492
+ /* @__PURE__ */ jsxs("div", { className: ["relative flex h-full flex-col justify-center gap-5 px-8 sm:px-14", align === "center" ? "items-center text-center" : "items-start text-left", onImage ? "text-white" : "bg-surface text-foreground"].join(" "), children: [
9493
+ slide.eyebrow != null && /* @__PURE__ */ jsx("div", { className: ["text-xs font-semibold uppercase tracking-wide", onImage ? "text-white/80" : "text-accent"].join(" "), children: slide.eyebrow }),
9494
+ /* @__PURE__ */ jsx("h2", { className: "max-w-3xl text-3xl font-bold leading-tight tracking-tight sm:text-5xl", children: slide.title }),
9495
+ slide.description != null && /* @__PURE__ */ jsx("p", { className: ["max-w-xl text-base leading-relaxed sm:text-lg", onImage ? "text-white/85" : "text-foreground-secondary"].join(" "), children: slide.description }),
9496
+ slide.actions != null && /* @__PURE__ */ jsx("div", { className: ["mt-2 flex flex-wrap gap-3", align === "center" ? "justify-center" : ""].join(" "), children: slide.actions })
9497
+ ] })
9498
+ ]
9499
+ },
9500
+ slide.key ?? idx
9501
+ ) }),
9502
+ showArrows && count > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
9503
+ /* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Previous slide", onClick: () => go(-1), className: "absolute left-3 top-1/2 z-10 flex h-9 w-9 -translate-y-1/2 items-center justify-center rounded-full border border-white/30 bg-white/15 text-white backdrop-blur transition-colors hover:bg-white/25 focus:outline-none focus-visible:ring-2 focus-visible:ring-white", children: /* @__PURE__ */ jsx(Arrow4, { dir: "left" }) }),
9504
+ /* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Next slide", onClick: () => go(1), className: "absolute right-3 top-1/2 z-10 flex h-9 w-9 -translate-y-1/2 items-center justify-center rounded-full border border-white/30 bg-white/15 text-white backdrop-blur transition-colors hover:bg-white/25 focus:outline-none focus-visible:ring-2 focus-visible:ring-white", children: /* @__PURE__ */ jsx(Arrow4, { dir: "right" }) })
9505
+ ] }),
9506
+ showDots && count > 1 && /* @__PURE__ */ jsx("div", { className: "absolute bottom-4 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1.5", children: slides.map((_, i) => /* @__PURE__ */ jsx(
9507
+ "button",
9508
+ {
9509
+ type: "button",
9510
+ "aria-label": `Go to slide ${i + 1}`,
9511
+ "aria-current": i === idx,
9512
+ onClick: () => setIndex(i),
9513
+ className: ["h-1.5 rounded-full transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-white", i === idx ? "w-6 bg-white" : "w-1.5 bg-white/50 hover:bg-white/80"].join(" ")
9514
+ },
9515
+ i
9516
+ )) })
9517
+ ]
9518
+ }
9519
+ );
9520
+ }
9521
+ var PlayGlyph = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", className: "h-7 w-7 translate-x-0.5", children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z" }) });
9522
+ function Video({
9523
+ src,
9524
+ embedUrl,
9525
+ poster,
9526
+ aspect = "16/9",
9527
+ title,
9528
+ controls = true,
9529
+ autoPlay = false,
9530
+ loop = false,
9531
+ muted = false,
9532
+ framed = true,
9533
+ className = "",
9534
+ style
9535
+ }) {
9536
+ const [playing, setPlaying] = useState(autoPlay);
9537
+ const frame = ["relative w-full overflow-hidden bg-backdrop", framed ? "rounded-2xl border border-border shadow-sm" : "", className].filter(Boolean).join(" ");
9538
+ const ratio = aspect.replace("/", " / ");
9539
+ return /* @__PURE__ */ jsx("div", { className: frame, style: { aspectRatio: ratio, ...style }, children: embedUrl ? /* @__PURE__ */ jsx(
9540
+ "iframe",
9541
+ {
9542
+ src: embedUrl,
9543
+ title: title ?? "Embedded video",
9544
+ className: "absolute inset-0 h-full w-full",
9545
+ frameBorder: 0,
9546
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
9547
+ allowFullScreen: true
9548
+ }
9549
+ ) : src ? /* @__PURE__ */ jsxs(Fragment, { children: [
9550
+ /* @__PURE__ */ jsx(
9551
+ "video",
9552
+ {
9553
+ src,
9554
+ poster,
9555
+ title,
9556
+ controls: controls && playing,
9557
+ autoPlay: playing,
9558
+ loop,
9559
+ muted: muted || autoPlay,
9560
+ playsInline: true,
9561
+ className: "absolute inset-0 h-full w-full object-cover"
9562
+ }
9563
+ ),
9564
+ !playing && /* @__PURE__ */ jsxs(
9565
+ "button",
9566
+ {
9567
+ type: "button",
9568
+ "aria-label": title ? `Play ${title}` : "Play video",
9569
+ onClick: () => setPlaying(true),
9570
+ className: "group absolute inset-0 flex items-center justify-center focus:outline-none",
9571
+ style: poster ? { backgroundImage: `url(${poster})`, backgroundSize: "cover", backgroundPosition: "center" } : void 0,
9572
+ children: [
9573
+ /* @__PURE__ */ jsx("span", { className: "absolute inset-0", style: { backgroundColor: "color-mix(in oklab, var(--color-foreground) 30%, transparent)" }, "aria-hidden": "true" }),
9574
+ /* @__PURE__ */ jsx("span", { className: "relative flex h-16 w-16 items-center justify-center rounded-full bg-white/90 text-accent shadow-lg transition-transform duration-200 ease-out group-hover:scale-105 group-focus-visible:ring-4 group-focus-visible:ring-white", children: /* @__PURE__ */ jsx(PlayGlyph, {}) })
9575
+ ]
9576
+ }
9577
+ )
9578
+ ] }) : /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center text-sm text-foreground-muted", children: "No video source" }) });
9579
+ }
9580
+ var isUrl = (v) => typeof v === "string";
9581
+ function Parallax({
9582
+ background,
9583
+ children,
9584
+ height = 440,
9585
+ speed = 0.3,
9586
+ overlay = true,
9587
+ className = "",
9588
+ style
9589
+ }) {
9590
+ const reduced = useReducedMotion();
9591
+ const ref = useRef(null);
9592
+ const { scrollYProgress } = useScroll({ target: ref, offset: ["start end", "end start"] });
9593
+ const shift = Math.max(0, Math.min(1, speed)) * 100;
9594
+ const y = useTransform(scrollYProgress, [0, 1], reduced ? ["0%", "0%"] : [`-${shift / 2}%`, `${shift / 2}%`]);
9595
+ return /* @__PURE__ */ jsxs(
9596
+ "div",
9597
+ {
9598
+ ref,
9599
+ className: ["relative overflow-hidden rounded-2xl", className].filter(Boolean).join(" "),
9600
+ style: { height, ...style },
9601
+ children: [
9602
+ /* @__PURE__ */ jsx(
9603
+ motion.div,
9604
+ {
9605
+ "aria-hidden": isUrl(background) ? true : void 0,
9606
+ className: "absolute inset-x-0 -top-[15%] -bottom-[15%] will-change-transform",
9607
+ style: {
9608
+ y,
9609
+ ...isUrl(background) ? { backgroundImage: `url(${background})`, backgroundSize: "cover", backgroundPosition: "center" } : {}
9610
+ },
9611
+ children: !isUrl(background) && background
9612
+ }
9613
+ ),
9614
+ overlay && /* @__PURE__ */ jsx(
9615
+ "div",
9616
+ {
9617
+ className: "absolute inset-0",
9618
+ style: { backgroundColor: "color-mix(in oklab, var(--color-foreground) 45%, transparent)" },
9619
+ "aria-hidden": "true"
9620
+ }
9621
+ ),
9622
+ /* @__PURE__ */ jsx("div", { className: "relative flex h-full flex-col items-center justify-center gap-4 px-6 text-center", children })
9623
+ ]
9624
+ }
9625
+ );
9626
+ }
9627
+ var COLS3 = {
9628
+ 2: "sm:grid-cols-2",
9629
+ 3: "sm:grid-cols-2 lg:grid-cols-3"
9630
+ };
9631
+ function Blog({
9632
+ posts,
9633
+ eyebrow,
9634
+ title,
9635
+ description,
9636
+ columns = 3,
9637
+ centeredHeader = true,
9638
+ className = "",
9639
+ style
9640
+ }) {
9641
+ const hasHeader = eyebrow != null || title != null || description != null;
9642
+ return /* @__PURE__ */ jsxs("section", { className: ["w-full", className].filter(Boolean).join(" "), style, children: [
9643
+ hasHeader && /* @__PURE__ */ jsxs("header", { className: ["mb-10 flex flex-col gap-3", centeredHeader ? "items-center text-center" : "items-start text-left"].join(" "), children: [
9644
+ eyebrow != null && /* @__PURE__ */ jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-accent", children: eyebrow }),
9645
+ title != null && /* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold tracking-tight text-foreground sm:text-3xl", children: title }),
9646
+ description != null && /* @__PURE__ */ jsx("p", { className: "max-w-2xl text-base leading-relaxed text-foreground-secondary", children: description })
9647
+ ] }),
9648
+ /* @__PURE__ */ jsx("div", { className: ["grid grid-cols-1 gap-6", COLS3[columns]].join(" "), children: posts.map((post, i) => {
9649
+ const meta = [post.author, post.date, post.readTime].filter((m) => m != null);
9650
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
9651
+ post.image && /* @__PURE__ */ jsxs("div", { className: "relative aspect-video overflow-hidden bg-backdrop", children: [
9652
+ /* @__PURE__ */ jsx("img", { src: post.image, alt: "", className: "h-full w-full object-cover transition-transform duration-300 ease-out group-hover:scale-105", loading: "lazy" }),
9653
+ post.tag != null && /* @__PURE__ */ jsx("span", { className: "absolute left-3 top-3", children: /* @__PURE__ */ jsx(Badge, { tone: "accent", variant: "solid", size: "sm", children: post.tag }) })
9654
+ ] }),
9655
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-2 p-5", children: [
9656
+ post.tag != null && !post.image && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Badge, { tone: "accent", variant: "soft", size: "sm", children: post.tag }) }),
9657
+ /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold leading-snug text-foreground transition-colors group-hover:text-accent", children: post.title }),
9658
+ post.excerpt != null && /* @__PURE__ */ jsx("p", { className: "line-clamp-3 text-sm leading-relaxed text-foreground-secondary", children: post.excerpt }),
9659
+ meta.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-auto flex flex-wrap items-center gap-x-2 gap-y-1 pt-3 text-xs text-foreground-muted", children: meta.map((m, j) => /* @__PURE__ */ jsxs(React28.Fragment, { children: [
9660
+ j > 0 && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }),
9661
+ /* @__PURE__ */ jsx("span", { children: m })
9662
+ ] }, j)) })
9663
+ ] })
9664
+ ] });
9665
+ const cardCx = "group flex flex-col overflow-hidden rounded-xl border border-border bg-surface text-left shadow-sm transition-all duration-200 ease-out hover:-translate-y-0.5 hover:border-border-strong hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent";
9666
+ if (post.href) {
9667
+ return /* @__PURE__ */ jsx("a", { href: post.href, className: cardCx, children: inner }, post.key ?? i);
9668
+ }
9669
+ if (post.onClick) {
9670
+ return /* @__PURE__ */ jsx("button", { type: "button", onClick: post.onClick, className: cardCx, children: inner }, post.key ?? i);
9671
+ }
9672
+ return /* @__PURE__ */ jsx("article", { className: cardCx.replace("focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent", ""), children: inner }, post.key ?? i);
9673
+ }) })
9674
+ ] });
9675
+ }
9676
+ var P = ({ d }) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", className: "h-[55%] w-[55%]", children: /* @__PURE__ */ jsx("path", { d }) });
9677
+ var ICONS = {
9678
+ x: /* @__PURE__ */ jsx(P, { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" }),
9679
+ twitter: /* @__PURE__ */ jsx(P, { d: "M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482A13.978 13.978 0 011.64 3.162a4.822 4.822 0 001.523 6.574 4.9 4.9 0 01-2.229-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z" }),
9680
+ github: /* @__PURE__ */ jsx(P, { d: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23a11.5 11.5 0 013.003-.404c1.02.005 2.045.138 3.003.404 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" }),
9681
+ linkedin: /* @__PURE__ */ jsx(P, { d: "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z" }),
9682
+ youtube: /* @__PURE__ */ jsx(P, { d: "M23.498 6.186a3.016 3.016 0 00-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 00.502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 002.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 002.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z" }),
9683
+ instagram: /* @__PURE__ */ jsx(P, { d: "M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z" }),
9684
+ facebook: /* @__PURE__ */ jsx(P, { d: "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z" }),
9685
+ mastodon: /* @__PURE__ */ jsx(P, { d: "M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 00.023-.043v-1.809a.052.052 0 00-.02-.041.053.053 0 00-.046-.01 20.282 20.282 0 01-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 01-.319-1.433.053.053 0 01.066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.301-.547-1.963-1.66-1.963-1.226 0-1.84.79-1.84 2.352v3.408h-2.546V8.68c0-1.563-.615-2.353-1.84-2.353-1.107 0-1.66.662-1.66 1.963v6.218H4.844V8.105c0-1.3.332-2.333.996-3.097.685-.764 1.583-1.156 2.7-1.156 1.29 0 2.265.498 2.916 1.49l.638 1.071.638-1.071c.65-.992 1.626-1.49 2.916-1.49 1.116 0 2.014.392 2.7 1.156.663.764.995 1.797.995 3.097z" }),
9686
+ email: /* @__PURE__ */ jsx(P, { d: "M1.5 4.5h21A1.5 1.5 0 0124 6v12a1.5 1.5 0 01-1.5 1.5h-21A1.5 1.5 0 010 18V6a1.5 1.5 0 011.5-1.5zM12 13.06L2.41 6.5h19.18zm-3.43-1.36L1.5 16.94V7.06zM9.9 12.9l1.55 1.06a.99.99 0 001.1 0l1.55-1.06 6.74 4.6H3.16zm5.53-1.2l7.07-4.64v9.88z" }),
9687
+ website: /* @__PURE__ */ jsx(P, { d: "M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm7.931 7h-3.07a15.4 15.4 0 00-1.32-3.853A8.03 8.03 0 0119.931 7zM12 2.042c.86 1.243 1.535 2.6 1.99 4.958h-3.98C10.465 4.642 11.14 3.285 12 2.042zM2.069 14A8.05 8.05 0 012 12c0-.69.07-1.36.069-2h3.518c-.05.66-.087 1.32-.087 2 0 .68.037 1.34.087 2zm.943 2h3.07a15.4 15.4 0 001.32 3.853A8.03 8.03 0 014.069 17zm3.07-9h-3.07a8.03 8.03 0 014.39-3.853A15.4 15.4 0 006.139 7zM12 21.958c-.86-1.243-1.535-2.6-1.99-4.958h3.98c-.455 2.358-1.13 3.715-1.99 4.958zM14.34 14H9.66c-.055-.66-.095-1.32-.095-2 0-.68.04-1.34.095-2h4.68c.055.66.095 1.32.095 2 0 .68-.04 1.34-.095 2zm.527 5.853A15.4 15.4 0 0016.187 16h3.07a8.03 8.03 0 01-4.39 3.853zM16.413 14c.05-.66.087-1.32.087-2 0-.68-.037-1.34-.087-2h3.518c.05.64.069 1.31.069 2 0 .69-.019 1.36-.069 2z" })
9688
+ };
9689
+ var SIZE6 = { sm: "h-8 w-8", md: "h-10 w-10" };
9690
+ var VARIANT = {
9691
+ ghost: "text-foreground-secondary hover:bg-surface-raised hover:text-foreground",
9692
+ solid: "bg-surface-raised text-foreground-secondary hover:bg-accent hover:text-accent-fg",
9693
+ outline: "border border-border text-foreground-secondary hover:border-border-strong hover:text-foreground"
9694
+ };
9695
+ function Socials({
9696
+ links,
9697
+ variant = "ghost",
9698
+ size = "md",
9699
+ newTab = true,
9700
+ "aria-label": ariaLabel = "Social links",
9701
+ className = "",
9702
+ style
9703
+ }) {
9704
+ return /* @__PURE__ */ jsx("nav", { "aria-label": ariaLabel, className: ["flex flex-wrap items-center gap-2", className].filter(Boolean).join(" "), style, children: links.map((link, i) => {
9705
+ const label = link.label ?? (link.platform ? link.platform[0].toUpperCase() + link.platform.slice(1) : "Link");
9706
+ const icon = link.icon ?? (link.platform ? ICONS[link.platform] : null);
9707
+ const ext = newTab && !link.href.startsWith("mailto:");
9708
+ return /* @__PURE__ */ jsx(
9709
+ "a",
9710
+ {
9711
+ href: link.href,
9712
+ "aria-label": label,
9713
+ title: label,
9714
+ ...ext ? { target: "_blank", rel: "noopener noreferrer" } : {},
9715
+ className: ["flex items-center justify-center rounded-full transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent", SIZE6[size], VARIANT[variant]].join(" "),
9716
+ children: icon
9717
+ },
9718
+ i
9719
+ );
9720
+ }) });
9721
+ }
9722
+ var POS2 = {
9723
+ "bottom": "inset-x-0 bottom-0 sm:inset-x-4 sm:bottom-4",
9724
+ "bottom-left": "inset-x-0 bottom-0 sm:inset-x-auto sm:left-4 sm:bottom-4 sm:max-w-md",
9725
+ "bottom-right": "inset-x-0 bottom-0 sm:inset-x-auto sm:right-4 sm:bottom-4 sm:max-w-md"
9726
+ };
9727
+ function CookieConsent({
9728
+ message = "We use cookies to enhance your experience, analyse traffic, and personalise content.",
9729
+ title,
9730
+ acceptLabel = "Accept all",
9731
+ declineLabel,
9732
+ onAccept,
9733
+ onDecline,
9734
+ learnMoreHref,
9735
+ learnMoreLabel = "Learn more",
9736
+ storageKey = "oxygen-cookie-consent",
9737
+ open,
9738
+ position = "bottom",
9739
+ className = ""
9740
+ }) {
9741
+ const persist = typeof storageKey === "string";
9742
+ const [stored, setStored] = useLocalStorage(persist ? storageKey : "__oxygen_cc_off__", null);
9743
+ const visible = open ?? (persist ? stored == null : true);
9744
+ const choose = (choice, cb) => {
9745
+ if (persist) setStored(choice);
9746
+ cb?.();
9747
+ };
9748
+ if (!visible) return null;
9749
+ return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(
9750
+ "div",
9751
+ {
9752
+ role: "dialog",
9753
+ "aria-label": "Cookie consent",
9754
+ "aria-live": "polite",
9755
+ className: ["fixed z-[60]", POS2[position], className].filter(Boolean).join(" "),
9756
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 border-t border-border bg-surface p-5 shadow-lg sm:flex-row sm:items-center sm:rounded-xl sm:border", children: [
9757
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 text-sm leading-relaxed text-foreground-secondary", children: [
9758
+ title != null && /* @__PURE__ */ jsx("p", { className: "mb-1 font-semibold text-foreground", children: title }),
9759
+ /* @__PURE__ */ jsx("span", { children: message }),
9760
+ learnMoreHref && /* @__PURE__ */ jsxs(Fragment, { children: [
9761
+ " ",
9762
+ /* @__PURE__ */ jsx("a", { href: learnMoreHref, className: "font-medium text-accent underline-offset-2 hover:underline", children: learnMoreLabel })
9763
+ ] })
9764
+ ] }),
9765
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 gap-2", children: [
9766
+ declineLabel && /* @__PURE__ */ jsx(Button_default, { variant: "outline", content: declineLabel, onClick: () => choose("declined", onDecline) }),
9767
+ /* @__PURE__ */ jsx(Button_default, { content: acceptLabel, onClick: () => choose("accepted", onAccept) })
9768
+ ] })
9769
+ ] })
9770
+ }
9771
+ ) });
9772
+ }
9773
+ var GRADIENT2 = "radial-gradient(120% 140% at 50% 0%, color-mix(in oklab, var(--color-accent) 14%, transparent), transparent 70%)";
9774
+ function LeadCapture({
9775
+ title,
9776
+ description,
9777
+ placeholder = "you@company.com",
9778
+ inputLabel = "Email address",
9779
+ buttonLabel = "Subscribe",
9780
+ onSubmit,
9781
+ note,
9782
+ successMessage = "Thanks \u2014 you\u2019re on the list.",
9783
+ background = "gradient",
9784
+ centered = true,
9785
+ className = "",
9786
+ style
9787
+ }) {
9788
+ const [email, setEmail] = useState("");
9789
+ const [done, setDone] = useState(false);
9790
+ const submit = (e) => {
9791
+ e.preventDefault();
9792
+ const value = email.trim();
9793
+ if (!value) return;
9794
+ onSubmit?.(value);
9795
+ setDone(true);
9796
+ };
9797
+ const isGradient = background === "gradient";
9798
+ return /* @__PURE__ */ jsx(
9799
+ "section",
9800
+ {
9801
+ className: ["w-full overflow-hidden rounded-2xl border border-border bg-surface px-6 py-12 sm:px-12 sm:py-16", className].filter(Boolean).join(" "),
9802
+ style: { ...isGradient ? { backgroundImage: GRADIENT2 } : {}, ...style },
9803
+ children: /* @__PURE__ */ jsxs("div", { className: ["mx-auto flex max-w-2xl flex-col gap-4", centered ? "items-center text-center" : "items-start text-left"].join(" "), children: [
9804
+ /* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold tracking-tight text-foreground sm:text-3xl", children: title }),
9805
+ description != null && /* @__PURE__ */ jsx("p", { className: "max-w-xl text-base leading-relaxed text-foreground-secondary", children: description }),
9806
+ done ? /* @__PURE__ */ jsxs("p", { role: "status", className: "mt-2 inline-flex items-center gap-2 text-sm font-medium text-status-success", children: [
9807
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", className: "h-5 w-5", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }) }),
9808
+ successMessage
9809
+ ] }) : /* @__PURE__ */ jsxs("form", { onSubmit: submit, className: ["mt-2 flex w-full max-w-md flex-col gap-2 sm:flex-row", centered ? "sm:justify-center" : ""].join(" "), children: [
9810
+ /* @__PURE__ */ jsx("label", { htmlFor: "oxygen-lead-email", className: "sr-only", children: inputLabel }),
9811
+ /* @__PURE__ */ jsx(
9812
+ "input",
9813
+ {
9814
+ id: "oxygen-lead-email",
9815
+ type: "email",
9816
+ required: true,
9817
+ value: email,
9818
+ onChange: (e) => setEmail(e.target.value),
9819
+ placeholder,
9820
+ autoComplete: "email",
9821
+ className: [fieldShell({ size: "md" }), "flex-1"].join(" ")
9822
+ }
9823
+ ),
9824
+ /* @__PURE__ */ jsx(Button_default, { content: buttonLabel, className: "shrink-0" })
9825
+ ] }),
9826
+ note != null && !done && /* @__PURE__ */ jsx("p", { className: "text-xs text-foreground-muted", children: note })
9827
+ ] })
9828
+ }
9829
+ );
9830
+ }
9440
9831
 
9441
- export { Accordion_default as Accordion, AppShell, AutoComplete, Avatar, Badge, Box, Breadcrumbs, Button_default as Button, CARD_BRANDS, Card_default as Card, CardCarousel, Cart, CartButton, CartProvider, Catalog, CatalogCarousel, CatalogGrid, Chat, Checkbox, Checkout, ColorPicker, ContextMenu, CreditCardForm, DateRangePicker, Drawer, Dropdown, EmptyCart, FAB, FadingBase, FeatureGrid, Field, FieldHelpIcon, FieldLabel, FileInput, Flex, Form, FormContext, FormField, FormStore, Grid2 as Grid, GridCard, icons_default as Icon, IconButton, Jumbotron, Kbd, List2 as List, LoadingSpinner, LogoutTimer, MegaMenu_default as MegaMenu, MenuButton, Modal, NotificationProvider, NumberInput, OpaqueGridCard, OtpInput, Password, PopConfirm, Portal, PricingPlans, RadioGroup, Rating, ScalableContainer, Scheduler, SearchInput_default as SearchInput, SecureLayout, SegmentedControl, Sidebar, SkeletonBox, SkeletonCard, SkeletonCircle, SkeletonText, Slider, Statistic, Stepper, Switch, Table, Tabs_default as Tabs, TagsInput, DatePicker as Temporal, Testimonials, TextArea, TextInput, ThemeProvider, ThemeSwitch, TimePicker, Timeline, Tooltip, TooltipProvider, TopBar, Tree, TreeSelect, Typography, Wizard, cardNumberError, cvvError, detectBrand, expiryError, fieldShell, formatCardNumber, formatExpiry, isRequired, luhnValid, onlyDigits, patterns, runFieldRules, useBreakpoint, useCart, useFieldArray, useForm, useFormField, useFormStore, useJwt, useLocalStorage, useMediaQuery, useNotification };
9832
+ export { Accordion_default as Accordion, AppShell, AutoComplete, Avatar, Badge, Blog, Box, Breadcrumbs, Button_default as Button, CARD_BRANDS, Card_default as Card, CardCarousel, Cart, CartButton, CartProvider, Catalog, CatalogCarousel, CatalogGrid, Chat, Checkbox, Checkout, ColorPicker, ContextMenu, CookieConsent, CreditCardForm, DateRangePicker, Drawer, Dropdown, EmptyCart, FAB, FadingBase, FeatureGrid, Field, FieldHelpIcon, FieldLabel, FileInput, Flex, Form, FormContext, FormField, FormStore, Grid2 as Grid, GridCard, icons_default as Icon, IconButton, Jumbotron, Kbd, LeadCapture, List2 as List, LoadingSpinner, LogoutTimer, MegaMenu_default as MegaMenu, MenuButton, Modal, NotificationProvider, NumberInput, OpaqueGridCard, OtpInput, Parallax, Password, PopConfirm, Portal, PricingPlans, RadioGroup, Rating, ScalableContainer, Scheduler, SearchInput_default as SearchInput, SecureLayout, SegmentedControl, Sidebar, SkeletonBox, SkeletonCard, SkeletonCircle, SkeletonText, SlideShow, Slider, Socials, Statistic, Stepper, Switch, Table, Tabs_default as Tabs, TagsInput, DatePicker as Temporal, Testimonials, TextArea, TextInput, ThemeProvider, ThemeSwitch, TimePicker, Timeline, Tooltip, TooltipProvider, TopBar, Tree, TreeSelect, Typography, Video, Wizard, cardNumberError, cvvError, detectBrand, expiryError, fieldShell, formatCardNumber, formatExpiry, isRequired, luhnValid, onlyDigits, patterns, runFieldRules, useBreakpoint, useCart, useFieldArray, useForm, useFormField, useFormStore, useJwt, useLocalStorage, useMediaQuery, useNotification };
9442
9833
  //# sourceMappingURL=index.js.map
9443
9834
  //# sourceMappingURL=index.js.map