@geomak/ui 7.2.2 → 7.3.1

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.d.cts CHANGED
@@ -2647,12 +2647,20 @@ declare function TopBar({ brand, center, actions, height, className, }: TopBarPr
2647
2647
  /** ─────────────────── types ─────────────────── */
2648
2648
  interface SidebarItem {
2649
2649
  key: string;
2650
- icon: react__default.ReactNode;
2650
+ /** Leading icon. Optional for nested sub-items (they show a dot instead). */
2651
+ icon?: react__default.ReactNode;
2651
2652
  label: string;
2652
2653
  isActive?: boolean;
2653
2654
  onClick?: () => void;
2654
2655
  /** Numeric badge shown on the icon */
2655
2656
  badge?: number;
2657
+ /**
2658
+ * Nested sub-items. When present (and the sidebar is expanded), the item
2659
+ * becomes an expandable group with a chevron; clicking toggles the children.
2660
+ */
2661
+ items?: SidebarItem[];
2662
+ /** Start the sub-menu expanded. Defaults to open when a descendant is active. */
2663
+ defaultOpen?: boolean;
2656
2664
  }
2657
2665
  interface SidebarSection {
2658
2666
  key: string;
package/dist/index.d.ts CHANGED
@@ -2647,12 +2647,20 @@ declare function TopBar({ brand, center, actions, height, className, }: TopBarPr
2647
2647
  /** ─────────────────── types ─────────────────── */
2648
2648
  interface SidebarItem {
2649
2649
  key: string;
2650
- icon: react__default.ReactNode;
2650
+ /** Leading icon. Optional for nested sub-items (they show a dot instead). */
2651
+ icon?: react__default.ReactNode;
2651
2652
  label: string;
2652
2653
  isActive?: boolean;
2653
2654
  onClick?: () => void;
2654
2655
  /** Numeric badge shown on the icon */
2655
2656
  badge?: number;
2657
+ /**
2658
+ * Nested sub-items. When present (and the sidebar is expanded), the item
2659
+ * becomes an expandable group with a chevron; clicking toggles the children.
2660
+ */
2661
+ items?: SidebarItem[];
2662
+ /** Start the sub-menu expanded. Defaults to open when a descendant is active. */
2663
+ defaultOpen?: boolean;
2656
2664
  }
2657
2665
  interface SidebarSection {
2658
2666
  key: string;
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  export { icons_default as Icon, createIcon } from './chunk-KAFJJO5O.js';
2
2
  import { colors_default } from './chunk-I2P4JJDB.js';
3
3
  export { colors_default as COLORS, PALETTE as palette, semanticTokens, vars } from './chunk-I2P4JJDB.js';
4
- import React29, { createContext, useState, useEffect, useMemo, useId, useCallback, useRef, useContext, useSyncExternalStore, useLayoutEffect } from 'react';
4
+ import React30, { createContext, useState, useEffect, useMemo, useId, useCallback, useRef, useContext, useSyncExternalStore, useLayoutEffect } from 'react';
5
5
  import { createPortal } from 'react-dom';
6
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
7
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
8
- import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
8
+ import * as DropdownMenu2 from '@radix-ui/react-dropdown-menu';
9
9
  import * as Dialog from '@radix-ui/react-dialog';
10
10
  import { useReducedMotion, AnimatePresence, motion, useScroll, useTransform } from 'framer-motion';
11
11
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
@@ -555,7 +555,7 @@ var SIZE_CLASSES = {
555
555
  md: "h-9 px-4 text-sm gap-1.5 rounded-lg",
556
556
  lg: "h-11 px-5 text-sm gap-2 rounded-xl"
557
557
  };
558
- var Button = React29.forwardRef(function Button2({
558
+ var Button = React30.forwardRef(function Button2({
559
559
  content,
560
560
  variant = "primary",
561
561
  size = "md",
@@ -636,8 +636,8 @@ function MenuButton({
636
636
  side = "bottom",
637
637
  className = ""
638
638
  }) {
639
- return /* @__PURE__ */ jsxs(DropdownMenu.Root, { children: [
640
- /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
639
+ return /* @__PURE__ */ jsxs(DropdownMenu2.Root, { children: [
640
+ /* @__PURE__ */ jsx(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
641
641
  Button_default,
642
642
  {
643
643
  variant,
@@ -651,8 +651,8 @@ function MenuButton({
651
651
  ] })
652
652
  }
653
653
  ) }),
654
- /* @__PURE__ */ jsx(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx(
655
- DropdownMenu.Content,
654
+ /* @__PURE__ */ jsx(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsx(
655
+ DropdownMenu2.Content,
656
656
  {
657
657
  align,
658
658
  side,
@@ -663,10 +663,10 @@ function MenuButton({
663
663
  "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
664
664
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
665
665
  ].join(" "),
666
- children: items.map((item) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
667
- item.separatorBefore && /* @__PURE__ */ jsx(DropdownMenu.Separator, { className: "my-1 h-px bg-border" }),
666
+ children: items.map((item) => /* @__PURE__ */ jsxs(React30.Fragment, { children: [
667
+ item.separatorBefore && /* @__PURE__ */ jsx(DropdownMenu2.Separator, { className: "my-1 h-px bg-border" }),
668
668
  /* @__PURE__ */ jsxs(
669
- DropdownMenu.Item,
669
+ DropdownMenu2.Item,
670
670
  {
671
671
  disabled: item.disabled,
672
672
  onSelect: () => item.onSelect?.(),
@@ -1666,7 +1666,7 @@ function Stepper({
1666
1666
  const vertical = orientation === "vertical" || forcedVertical;
1667
1667
  const s = SIZES[size];
1668
1668
  const stateOf = (i) => i < current ? "completed" : i === current ? status : "pending";
1669
- const Label = ({ step, state, align }) => /* @__PURE__ */ jsxs("div", { className: align === "center" ? "mt-2 text-center" : "pt-0.5", children: [
1669
+ const Label2 = ({ step, state, align }) => /* @__PURE__ */ jsxs("div", { className: align === "center" ? "mt-2 text-center" : "pt-0.5", children: [
1670
1670
  /* @__PURE__ */ jsx("div", { className: `font-medium leading-tight ${s.title} ${state === "pending" ? "text-foreground-muted" : "text-foreground"}`, children: step.title }),
1671
1671
  step.description && /* @__PURE__ */ jsx("div", { className: `mt-0.5 leading-snug text-foreground-muted ${s.desc}`, children: step.description })
1672
1672
  ] });
@@ -1681,7 +1681,7 @@ function Stepper({
1681
1681
  stepButton(i, /* @__PURE__ */ jsx(Indicator, { state, index: i, step, sizeKey: size })),
1682
1682
  !last && /* @__PURE__ */ jsx(VConnector, { filled: i < current, reduced })
1683
1683
  ] }),
1684
- /* @__PURE__ */ jsx("div", { className: last ? "" : "pb-6", children: stepButton(i, /* @__PURE__ */ jsx(Label, { step, state, align: "left" })) })
1684
+ /* @__PURE__ */ jsx("div", { className: last ? "" : "pb-6", children: stepButton(i, /* @__PURE__ */ jsx(Label2, { step, state, align: "left" })) })
1685
1685
  ] }, step.key);
1686
1686
  }) });
1687
1687
  }
@@ -1700,7 +1700,7 @@ function Stepper({
1700
1700
  ) }),
1701
1701
  stepButton(i, /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center", children: [
1702
1702
  /* @__PURE__ */ jsx(Indicator, { state, index: i, step, sizeKey: size }),
1703
- /* @__PURE__ */ jsx(Label, { step, state, align: "center" })
1703
+ /* @__PURE__ */ jsx(Label2, { step, state, align: "center" })
1704
1704
  ] }))
1705
1705
  ] }, step.key);
1706
1706
  }) });
@@ -1762,7 +1762,7 @@ function Kbd({
1762
1762
  style
1763
1763
  }) {
1764
1764
  if (keys && keys.length > 0) {
1765
- return /* @__PURE__ */ jsx("span", { className: cx("inline-flex items-center gap-1", className), style, children: keys.map((k, i) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
1765
+ return /* @__PURE__ */ jsx("span", { className: cx("inline-flex items-center gap-1", className), style, children: keys.map((k, i) => /* @__PURE__ */ jsxs(React30.Fragment, { children: [
1766
1766
  i > 0 && /* @__PURE__ */ jsx("span", { className: "text-foreground-muted text-xs select-none", children: separator }),
1767
1767
  /* @__PURE__ */ jsx("kbd", { className: [cap, SIZE3[size]].join(" "), children: k })
1768
1768
  ] }, `${k}-${i}`)) });
@@ -1854,7 +1854,7 @@ function FlatCarousel({
1854
1854
  style
1855
1855
  }) {
1856
1856
  const scrollerRef = useRef(null);
1857
- const slides = React29.Children.toArray(children);
1857
+ const slides = React30.Children.toArray(children);
1858
1858
  const [active, setActive] = useState(0);
1859
1859
  const [atStart, setAtStart] = useState(true);
1860
1860
  const [atEnd, setAtEnd] = useState(false);
@@ -1909,7 +1909,7 @@ function RotatingCarousel({
1909
1909
  className = "",
1910
1910
  style
1911
1911
  }) {
1912
- const slides = React29.Children.toArray(children);
1912
+ const slides = React30.Children.toArray(children);
1913
1913
  const count = slides.length;
1914
1914
  const [active, setActive] = useState(0);
1915
1915
  const reduced = useReducedMotion();
@@ -5131,7 +5131,7 @@ function Wizard({
5131
5131
  ] });
5132
5132
  }
5133
5133
  var SearchIcon = /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "w-4 h-4", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z", clipRule: "evenodd" }) });
5134
- var SearchInput = React29.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
5134
+ var SearchInput = React30.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
5135
5135
  return /* @__PURE__ */ jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxs(
5136
5136
  "div",
5137
5137
  {
@@ -5429,7 +5429,7 @@ function TableBody({
5429
5429
  return /* @__PURE__ */ jsx("tbody", { children: rows.map((row, i) => {
5430
5430
  const rowKey = getRowKey(row, i);
5431
5431
  const isExpanded = expanded.has(rowKey);
5432
- return /* @__PURE__ */ jsxs(React29.Fragment, { children: [
5432
+ return /* @__PURE__ */ jsxs(React30.Fragment, { children: [
5433
5433
  /* @__PURE__ */ jsxs(
5434
5434
  "tr",
5435
5435
  {
@@ -5852,41 +5852,106 @@ function TopBar({
5852
5852
  }
5853
5853
  );
5854
5854
  }
5855
+ function hasActiveDescendant(item) {
5856
+ return !!item.items?.some((c) => c.isActive || hasActiveDescendant(c));
5857
+ }
5858
+ var FLYOUT_PANEL = "z-[400] min-w-[11rem] rounded-lg border border-border bg-surface p-1 shadow-lg data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95";
5859
+ function FlyoutItems({ items }) {
5860
+ return /* @__PURE__ */ jsx(Fragment, { children: items.map((child) => {
5861
+ const cls = [
5862
+ "flex items-center gap-2.5 rounded-md px-2.5 py-1.5 text-sm outline-none cursor-pointer select-none transition-colors",
5863
+ child.isActive ? "text-accent data-[highlighted]:bg-accent/10" : "text-foreground data-[highlighted]:bg-surface-raised"
5864
+ ].join(" ");
5865
+ const label = /* @__PURE__ */ jsxs(Fragment, { children: [
5866
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: child.label }),
5867
+ child.badge !== void 0 && child.badge > 0 && /* @__PURE__ */ jsx("span", { className: "flex h-4 min-w-4 items-center justify-center rounded-full bg-status-error px-1 text-[9px] font-bold leading-none text-white", children: child.badge > 99 ? "99+" : child.badge })
5868
+ ] });
5869
+ if (child.items?.length) {
5870
+ return /* @__PURE__ */ jsxs(DropdownMenu2.Sub, { children: [
5871
+ /* @__PURE__ */ jsxs(DropdownMenu2.SubTrigger, { className: cls, children: [
5872
+ label,
5873
+ /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-3.5 w-3.5 flex-shrink-0", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m9 6 6 6-6 6" }) })
5874
+ ] }),
5875
+ /* @__PURE__ */ jsx(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsx(DropdownMenu2.SubContent, { sideOffset: 6, collisionPadding: 8, className: FLYOUT_PANEL, children: /* @__PURE__ */ jsx(FlyoutItems, { items: child.items }) }) })
5876
+ ] }, child.key);
5877
+ }
5878
+ return /* @__PURE__ */ jsx(DropdownMenu2.Item, { onSelect: () => child.onClick?.(), className: cls, children: label }, child.key);
5879
+ }) });
5880
+ }
5855
5881
  function NavItem({
5856
5882
  item,
5857
- isExpanded
5883
+ isExpanded,
5884
+ depth = 0
5858
5885
  }) {
5886
+ const hasChildren = !!(item.items && item.items.length);
5887
+ const [open, setOpen] = useState(item.defaultOpen ?? (hasChildren && hasActiveDescendant(item)));
5888
+ const handleClick = () => {
5889
+ if (hasChildren && isExpanded) setOpen((o) => !o);
5890
+ item.onClick?.();
5891
+ };
5859
5892
  const btn = /* @__PURE__ */ jsxs(
5860
5893
  "button",
5861
5894
  {
5862
5895
  type: "button",
5863
- onClick: item.onClick,
5896
+ onClick: handleClick,
5897
+ "aria-label": !isExpanded && typeof item.label === "string" ? item.label : void 0,
5898
+ "aria-expanded": hasChildren && isExpanded ? open : void 0,
5899
+ style: isExpanded && depth > 0 ? { paddingLeft: 10 + depth * 18 } : void 0,
5864
5900
  className: [
5865
5901
  "group relative flex w-full items-center gap-2.5 rounded-md",
5866
5902
  "px-2.5 py-2 transition-colors duration-100",
5867
5903
  "focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-inset",
5868
- item.isActive ? "bg-accent/10 text-accent" : "text-foreground-secondary hover:bg-surface-raised hover:text-foreground"
5904
+ item.isActive || !isExpanded && hasActiveDescendant(item) ? "bg-accent/10 text-accent" : "text-foreground-secondary hover:bg-surface-raised hover:text-foreground"
5869
5905
  ].join(" "),
5870
5906
  children: [
5871
5907
  /* @__PURE__ */ jsxs("span", { className: "relative flex h-5 w-5 flex-shrink-0 items-center justify-center", children: [
5872
- item.icon,
5908
+ item.icon ?? (depth > 0 ? /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-current opacity-50" }) : null),
5873
5909
  item.badge !== void 0 && item.badge > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -right-1 -top-1 flex h-3.5 w-3.5 items-center justify-center rounded-full bg-status-error text-[9px] font-bold text-white leading-none", children: item.badge > 99 ? "99+" : item.badge })
5874
5910
  ] }),
5875
- isExpanded && /* @__PURE__ */ jsx(
5876
- motion.span,
5911
+ isExpanded && /* @__PURE__ */ jsx(motion.span, { initial: false, animate: { opacity: 1 }, className: "flex-1 truncate text-left text-sm font-medium", children: item.label }),
5912
+ isExpanded && hasChildren && /* @__PURE__ */ jsx(
5913
+ "svg",
5877
5914
  {
5878
- initial: false,
5879
- animate: { opacity: 1 },
5880
- className: "truncate text-sm font-medium",
5881
- children: item.label
5915
+ viewBox: "0 0 24 24",
5916
+ fill: "none",
5917
+ stroke: "currentColor",
5918
+ strokeWidth: 2,
5919
+ "aria-hidden": "true",
5920
+ className: `h-4 w-4 flex-shrink-0 transition-transform duration-200 ${open ? "rotate-180" : ""}`,
5921
+ children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m6 9 6 6 6-6" })
5882
5922
  }
5883
5923
  ),
5884
- item.isActive && /* @__PURE__ */ jsx("span", { className: "absolute inset-y-0 left-0 w-[3px] rounded-r-full bg-accent" })
5924
+ item.isActive && depth === 0 && /* @__PURE__ */ jsx("span", { className: "absolute inset-y-0 left-0 w-[3px] rounded-r-full bg-accent" })
5885
5925
  ]
5886
5926
  }
5887
5927
  );
5888
- if (isExpanded) return btn;
5889
- return /* @__PURE__ */ jsx(Tooltip, { title: item.label, placement: "right", delayDuration: 200, children: btn });
5928
+ if (!isExpanded) {
5929
+ if (hasChildren) {
5930
+ return /* @__PURE__ */ jsxs(DropdownMenu2.Root, { children: [
5931
+ /* @__PURE__ */ jsx(DropdownMenu2.Trigger, { asChild: true, children: btn }),
5932
+ /* @__PURE__ */ jsx(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsxs(DropdownMenu2.Content, { side: "right", align: "start", sideOffset: 8, collisionPadding: 8, className: FLYOUT_PANEL, children: [
5933
+ /* @__PURE__ */ jsx(DropdownMenu2.Label, { className: "px-2.5 pb-1 pt-1.5 text-xs font-semibold text-foreground-muted", children: item.label }),
5934
+ /* @__PURE__ */ jsx(FlyoutItems, { items: item.items })
5935
+ ] }) })
5936
+ ] });
5937
+ }
5938
+ return /* @__PURE__ */ jsx(Tooltip, { title: item.label, placement: "right", delayDuration: 200, children: btn });
5939
+ }
5940
+ if (!hasChildren) return btn;
5941
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5942
+ btn,
5943
+ /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: open && /* @__PURE__ */ jsx(
5944
+ motion.div,
5945
+ {
5946
+ initial: { height: 0, opacity: 0 },
5947
+ animate: { height: "auto", opacity: 1 },
5948
+ exit: { height: 0, opacity: 0 },
5949
+ transition: { duration: 0.2, ease: [0.16, 1, 0.3, 1] },
5950
+ style: { overflow: "hidden" },
5951
+ children: /* @__PURE__ */ jsx("div", { className: "mt-0.5 flex flex-col gap-0.5", children: item.items.map((child) => /* @__PURE__ */ jsx(NavItem, { item: child, isExpanded, depth: depth + 1 }, child.key)) })
5952
+ }
5953
+ ) })
5954
+ ] });
5890
5955
  }
5891
5956
  function Sidebar({
5892
5957
  sections,
@@ -6081,8 +6146,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
6081
6146
  function MegaMenuFeatured({ children, className = "" }) {
6082
6147
  return /* @__PURE__ */ jsx("div", { className: cx("min-w-0 rounded-lg bg-surface-raised border border-border p-4 flex flex-col", className), children });
6083
6148
  }
6084
- var elementsOfType = (children, type) => React29.Children.toArray(children).filter(
6085
- (c) => React29.isValidElement(c) && c.type === type
6149
+ var elementsOfType = (children, type) => React30.Children.toArray(children).filter(
6150
+ (c) => React30.isValidElement(c) && c.type === type
6086
6151
  );
6087
6152
  var MOBILE_CHEVRON = /* @__PURE__ */ jsx(
6088
6153
  "svg",
@@ -6119,9 +6184,9 @@ function MobileLinkRow({ link, onNavigate }) {
6119
6184
  );
6120
6185
  }
6121
6186
  function MobilePanel({ panel, onNavigate }) {
6122
- const nodes = React29.Children.toArray(panel.props.children);
6187
+ const nodes = React30.Children.toArray(panel.props.children);
6123
6188
  return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
6124
- if (!React29.isValidElement(node)) return null;
6189
+ if (!React30.isValidElement(node)) return null;
6125
6190
  const el = node;
6126
6191
  if (el.type === MegaMenuSection) {
6127
6192
  const { title, children } = el.props;
@@ -6530,7 +6595,7 @@ function ThemeProvider({
6530
6595
  className = "",
6531
6596
  style
6532
6597
  }) {
6533
- const id = React29.useId().replace(/:/g, "");
6598
+ const id = React30.useId().replace(/:/g, "");
6534
6599
  const scopeClass = `geo-th-${id}`;
6535
6600
  const divRef = useRef(null);
6536
6601
  useEffect(() => {
@@ -8834,7 +8899,7 @@ function OtpInput({
8834
8899
  emit(valid.join(""));
8835
8900
  focusBox(valid.length);
8836
8901
  };
8837
- return /* @__PURE__ */ jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
8902
+ return /* @__PURE__ */ jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxs(React30.Fragment, { children: [
8838
8903
  /* @__PURE__ */ jsx(
8839
8904
  "input",
8840
8905
  {
@@ -9890,7 +9955,7 @@ function Blog({
9890
9955
  post.tag != null && !post.image && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Badge, { tone: "accent", variant: "soft", size: "sm", children: post.tag }) }),
9891
9956
  /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold leading-snug text-foreground transition-colors group-hover:text-accent", children: post.title }),
9892
9957
  post.excerpt != null && /* @__PURE__ */ jsx("p", { className: "line-clamp-3 text-sm leading-relaxed text-foreground-secondary", children: post.excerpt }),
9893
- 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(React29.Fragment, { children: [
9958
+ 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(React30.Fragment, { children: [
9894
9959
  j > 0 && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }),
9895
9960
  /* @__PURE__ */ jsx("span", { children: m })
9896
9961
  ] }, j)) })