@medialane/ui 0.80.1 → 0.81.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.
@@ -96,7 +96,7 @@ const NavWalletTrigger = React.forwardRef(
96
96
  onClick,
97
97
  "aria-label": rest["aria-label"] ?? (connected ? "Account" : "Connect wallet"),
98
98
  className: (0, import_cn.cn)(
99
- "ml-nav-wallet-trigger relative flex h-11 w-11 items-center justify-center rounded-full",
99
+ "ml-nav-wallet-trigger relative flex h-8 w-8 items-center justify-center rounded-full",
100
100
  "bg-background/10 text-muted-foreground backdrop-blur-xl backdrop-saturate-150",
101
101
  "transition-colors hover:bg-background/20 hover:text-foreground active:scale-[0.97]",
102
102
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60",
@@ -105,7 +105,7 @@ const NavWalletTrigger = React.forwardRef(
105
105
  ),
106
106
  children: [
107
107
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ml-nav-wallet-ring", "aria-hidden": "true" }),
108
- connected && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.User, { className: "h-4 w-4" })
108
+ connected && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.User, { className: "h-3.5 w-3.5" })
109
109
  ]
110
110
  }
111
111
  );
@@ -121,7 +121,7 @@ function useNavAccountSheet() {
121
121
  close: () => document.dispatchEvent(new CustomEvent(ML_ACCOUNT_CLOSE))
122
122
  };
123
123
  }
124
- function NavAccountSheet({ children, title = "Account" }) {
124
+ function NavAccountSheet({ children }) {
125
125
  const [open, setOpen] = React.useState(false);
126
126
  React.useEffect(() => {
127
127
  const onOpen = () => {
@@ -160,27 +160,32 @@ function NavAccountSheet({ children, title = "Account" }) {
160
160
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
161
161
  import_framer_motion.motion.div,
162
162
  {
163
- className: "fixed inset-x-3 bottom-3 z-[101] sm:inset-auto sm:right-4 sm:top-4 sm:w-[360px] lg:right-8",
163
+ className: "fixed inset-0 z-[101] flex items-end justify-center p-3 pb-4 sm:items-center sm:p-4",
164
164
  initial: { opacity: 0, y: 24 },
165
165
  animate: { opacity: 1, y: 0 },
166
166
  exit: { opacity: 0, y: 24 },
167
167
  transition: { duration: 0.18, ease: "easeOut" },
168
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "overflow-hidden rounded-[20px] border border-border/40 bg-background/90 shadow-2xl backdrop-blur-2xl backdrop-saturate-150", children: [
169
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex justify-center pt-2.5 sm:hidden", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "h-1 w-9 rounded-full bg-muted-foreground/30" }) }),
170
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between px-4 pb-1 pt-2 sm:pt-3", children: [
171
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/70", children: title }),
172
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
173
- "button",
174
- {
175
- onClick: () => setOpen(false),
176
- className: "rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted/50",
177
- "aria-label": "Close",
178
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }) })
179
- }
180
- )
181
- ] }),
182
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-3 pb-4 pt-1 sm:pb-3", children })
183
- ] })
168
+ onClick: () => setOpen(false),
169
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
170
+ "div",
171
+ {
172
+ className: "relative w-full max-w-[380px] overflow-hidden rounded-[20px] border border-border/40 bg-background/90 shadow-2xl backdrop-blur-2xl backdrop-saturate-150",
173
+ onClick: (e) => e.stopPropagation(),
174
+ children: [
175
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex justify-center pt-2.5 sm:hidden", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "h-1 w-9 rounded-full bg-muted-foreground/30" }) }),
176
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
177
+ "button",
178
+ {
179
+ onClick: () => setOpen(false),
180
+ className: "absolute right-3 top-3 rounded-md p-1 text-muted-foreground/70 transition-colors hover:bg-muted/50 hover:text-foreground",
181
+ "aria-label": "Close",
182
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }) })
183
+ }
184
+ ),
185
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-4 pb-4 pt-5 sm:pt-6", children })
186
+ ]
187
+ }
188
+ )
184
189
  }
185
190
  )
186
191
  ] }) });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/nav-shell.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { User } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\n// ── Header buttons ────────────────────────────────────────────────────────────\n\nexport interface NavBrandButtonProps {\n /** Defaults to opening the nav command menu (`ml:nav-open`). */\n onClick?: () => void;\n className?: string;\n \"aria-label\"?: string;\n /** Path to the brand icon image (the app's real icon asset). */\n iconSrc?: string;\n}\n\n/**\n * The main header trigger: brand mark + menu glyph in one quiet glass pill.\n * Mobile-first — a single ≥44px tap target instead of two small adjacent icons.\n * With no `onClick`, it opens the NavCommandMenu mounted elsewhere in the app.\n */\nexport function NavBrandButton({ onClick, className, iconSrc = \"/icon.png\", ...rest }: NavBrandButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick ?? (() => document.dispatchEvent(new CustomEvent(ML_NAV_OPEN)))}\n aria-label={rest[\"aria-label\"] ?? \"Open navigation\"}\n className={cn(\n \"group flex h-11 items-center gap-2 rounded-full\",\n \"bg-background/10 pl-2.5 pr-3 backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n className\n )}\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img src={iconSrc} alt=\"Medialane\" width={30} height={30} className=\"h-[30px] w-[30px] shrink-0\" />\n <span className=\"flex flex-col gap-[5px]\" aria-hidden=\"true\">\n <span className=\"h-[1.5px] w-4 rounded-full bg-muted-foreground transition-all group-hover:w-4 group-hover:bg-foreground\" />\n <span className=\"h-[1.5px] w-2.5 rounded-full bg-muted-foreground transition-all group-hover:w-4 group-hover:bg-foreground\" />\n </span>\n </button>\n );\n}\n\nexport interface NavIconButtonProps {\n onClick?: () => void;\n className?: string;\n \"aria-label\": string;\n /** Show a small brand-colored status dot (e.g. wallet connected). */\n indicator?: boolean;\n children: React.ReactNode;\n}\n\n/**\n * Circular glass header button — the right-side counterpart to NavBrandButton\n * (wallet / account trigger).\n */\nexport function NavIconButton({ onClick, className, indicator, children, ...rest }: NavIconButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={rest[\"aria-label\"]}\n className={cn(\n \"relative flex h-11 w-11 items-center justify-center rounded-full\",\n \"bg-background/10 text-muted-foreground backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 hover:text-foreground active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n className\n )}\n >\n {children}\n {indicator && (\n <span className=\"absolute right-[3px] top-[3px] h-2.5 w-2.5 rounded-full border-2 border-background bg-brand-blue\" />\n )}\n </button>\n );\n}\n\nexport interface NavWalletTriggerProps {\n onClick?: () => void;\n className?: string;\n \"aria-label\"?: string;\n /** Whether a wallet is currently connected. */\n connected?: boolean;\n}\n\n/**\n * The right-side counterpart to `NavBrandButton` for a wallet/account entry\n * point: the same glass pill material, with a thin brand-gradient ring\n * traced around the rim instead of a static icon. Not connected — the ring\n * rotates slowly (an ambient \"something opens here\" cue) around an empty\n * center, no glyph, no placeholder avatar. Connected — the ring settles to a\n * static accent and a plain `User` glyph fills the center (never a\n * gradient-filled avatar — this button doesn't know the wallet's real\n * identity, only whether one is attached).\n */\nexport const NavWalletTrigger = React.forwardRef<HTMLButtonElement, NavWalletTriggerProps>(\n function NavWalletTrigger({ onClick, className, connected = false, ...rest }, ref) {\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n aria-label={rest[\"aria-label\"] ?? (connected ? \"Account\" : \"Connect wallet\")}\n className={cn(\n \"ml-nav-wallet-trigger relative flex h-11 w-11 items-center justify-center rounded-full\",\n \"bg-background/10 text-muted-foreground backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 hover:text-foreground active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n connected && \"ml-nav-wallet-trigger--connected\",\n className\n )}\n >\n <span className=\"ml-nav-wallet-ring\" aria-hidden=\"true\" />\n {connected && <User className=\"h-4 w-4\" />}\n </button>\n );\n }\n);\n\n// ── Account sheet ─────────────────────────────────────────────────────────────\n\nconst ML_ACCOUNT_OPEN = \"ml:account-open\";\nconst ML_ACCOUNT_CLOSE = \"ml:account-close\";\nconst ML_NAV_OPEN = \"ml:nav-open\";\nconst ML_NAV_CLOSE = \"ml:nav-close\";\n\nexport function useNavAccountSheet() {\n return {\n open: () => document.dispatchEvent(new CustomEvent(ML_ACCOUNT_OPEN)),\n close: () => document.dispatchEvent(new CustomEvent(ML_ACCOUNT_CLOSE)),\n };\n}\n\nexport interface NavAccountSheetProps {\n /** The app's account/connect panel (Clerk, wallet connectors, …). */\n children: React.ReactNode;\n /** Optional heading above the panel. */\n title?: string;\n}\n\n/**\n * The wallet-side surface: a compact glass sheet anchored to the top-right\n * header button (bottom sheet on mobile). Content is app-owned — pass the same\n * account panel the command menu uses in its accountSlot.\n *\n * Opens via `useNavAccountSheet().open()`. Mutually exclusive with the command\n * menu: opening one closes the other, and the shared `ml:nav-close` event\n * (fired by `useNavCommandMenu().close()`) closes this sheet too, so account\n * panels behave identically in both hosts.\n */\nexport function NavAccountSheet({ children, title = \"Account\" }: NavAccountSheetProps) {\n const [open, setOpen] = React.useState(false);\n\n React.useEffect(() => {\n const onOpen = () => {\n document.dispatchEvent(new CustomEvent(ML_NAV_CLOSE));\n setOpen(true);\n };\n const onClose = () => setOpen(false);\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpen(false);\n };\n document.addEventListener(ML_ACCOUNT_OPEN, onOpen);\n document.addEventListener(ML_ACCOUNT_CLOSE, onClose);\n document.addEventListener(ML_NAV_OPEN, onClose);\n document.addEventListener(ML_NAV_CLOSE, onClose);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(ML_ACCOUNT_OPEN, onOpen);\n document.removeEventListener(ML_ACCOUNT_CLOSE, onClose);\n document.removeEventListener(ML_NAV_OPEN, onClose);\n document.removeEventListener(ML_NAV_CLOSE, onClose);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, []);\n\n return (\n <AnimatePresence>\n {open && (\n <>\n <motion.div\n className=\"nav-canvas-overlay\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n onClick={() => setOpen(false)}\n />\n <motion.div\n className=\"fixed inset-x-3 bottom-3 z-[101] sm:inset-auto sm:right-4 sm:top-4 sm:w-[360px] lg:right-8\"\n initial={{ opacity: 0, y: 24 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 24 }}\n transition={{ duration: 0.18, ease: \"easeOut\" }}\n >\n <div className=\"overflow-hidden rounded-[20px] border border-border/40 bg-background/90 shadow-2xl backdrop-blur-2xl backdrop-saturate-150\">\n <div className=\"flex justify-center pt-2.5 sm:hidden\" aria-hidden=\"true\">\n <span className=\"h-1 w-9 rounded-full bg-muted-foreground/30\" />\n </div>\n <div className=\"flex items-center justify-between px-4 pb-1 pt-2 sm:pt-3\">\n <span className=\"text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/70\">\n {title}\n </span>\n <button\n onClick={() => setOpen(false)}\n className=\"rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted/50\"\n aria-label=\"Close\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n </button>\n </div>\n <div className=\"px-3 pb-4 pt-1 sm:pb-3\">{children}</div>\n </div>\n </motion.div>\n </>\n )}\n </AnimatePresence>\n );\n}\n"],"mappings":"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","names":["NavWalletTrigger"]}
1
+ {"version":3,"sources":["../../src/components/nav-shell.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { User } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\n// ── Header buttons ────────────────────────────────────────────────────────────\n\nexport interface NavBrandButtonProps {\n /** Defaults to opening the nav command menu (`ml:nav-open`). */\n onClick?: () => void;\n className?: string;\n \"aria-label\"?: string;\n /** Path to the brand icon image (the app's real icon asset). */\n iconSrc?: string;\n}\n\n/**\n * The main header trigger: brand mark + menu glyph in one quiet glass pill.\n * Mobile-first — a single ≥44px tap target instead of two small adjacent icons.\n * With no `onClick`, it opens the NavCommandMenu mounted elsewhere in the app.\n */\nexport function NavBrandButton({ onClick, className, iconSrc = \"/icon.png\", ...rest }: NavBrandButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick ?? (() => document.dispatchEvent(new CustomEvent(ML_NAV_OPEN)))}\n aria-label={rest[\"aria-label\"] ?? \"Open navigation\"}\n className={cn(\n \"group flex h-11 items-center gap-2 rounded-full\",\n \"bg-background/10 pl-2.5 pr-3 backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n className\n )}\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img src={iconSrc} alt=\"Medialane\" width={30} height={30} className=\"h-[30px] w-[30px] shrink-0\" />\n <span className=\"flex flex-col gap-[5px]\" aria-hidden=\"true\">\n <span className=\"h-[1.5px] w-4 rounded-full bg-muted-foreground transition-all group-hover:w-4 group-hover:bg-foreground\" />\n <span className=\"h-[1.5px] w-2.5 rounded-full bg-muted-foreground transition-all group-hover:w-4 group-hover:bg-foreground\" />\n </span>\n </button>\n );\n}\n\nexport interface NavIconButtonProps {\n onClick?: () => void;\n className?: string;\n \"aria-label\": string;\n /** Show a small brand-colored status dot (e.g. wallet connected). */\n indicator?: boolean;\n children: React.ReactNode;\n}\n\n/**\n * Circular glass header button — the right-side counterpart to NavBrandButton\n * (wallet / account trigger).\n */\nexport function NavIconButton({ onClick, className, indicator, children, ...rest }: NavIconButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={rest[\"aria-label\"]}\n className={cn(\n \"relative flex h-11 w-11 items-center justify-center rounded-full\",\n \"bg-background/10 text-muted-foreground backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 hover:text-foreground active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n className\n )}\n >\n {children}\n {indicator && (\n <span className=\"absolute right-[3px] top-[3px] h-2.5 w-2.5 rounded-full border-2 border-background bg-brand-blue\" />\n )}\n </button>\n );\n}\n\nexport interface NavWalletTriggerProps {\n onClick?: () => void;\n className?: string;\n \"aria-label\"?: string;\n /** Whether a wallet is currently connected. */\n connected?: boolean;\n}\n\n/**\n * The right-side counterpart to `NavBrandButton` for a wallet/account entry\n * point: the same glass pill material, with a thin brand-gradient ring\n * traced around the rim instead of a static icon. Not connected — the ring\n * rotates slowly (an ambient \"something opens here\" cue) around an empty\n * center, no glyph, no placeholder avatar. Connected — the ring settles to a\n * static accent and a plain `User` glyph fills the center (never a\n * gradient-filled avatar — this button doesn't know the wallet's real\n * identity, only whether one is attached).\n */\nexport const NavWalletTrigger = React.forwardRef<HTMLButtonElement, NavWalletTriggerProps>(\n function NavWalletTrigger({ onClick, className, connected = false, ...rest }, ref) {\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n aria-label={rest[\"aria-label\"] ?? (connected ? \"Account\" : \"Connect wallet\")}\n className={cn(\n \"ml-nav-wallet-trigger relative flex h-8 w-8 items-center justify-center rounded-full\",\n \"bg-background/10 text-muted-foreground backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 hover:text-foreground active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n connected && \"ml-nav-wallet-trigger--connected\",\n className\n )}\n >\n <span className=\"ml-nav-wallet-ring\" aria-hidden=\"true\" />\n {connected && <User className=\"h-3.5 w-3.5\" />}\n </button>\n );\n }\n);\n\n// ── Account sheet ─────────────────────────────────────────────────────────────\n\nconst ML_ACCOUNT_OPEN = \"ml:account-open\";\nconst ML_ACCOUNT_CLOSE = \"ml:account-close\";\nconst ML_NAV_OPEN = \"ml:nav-open\";\nconst ML_NAV_CLOSE = \"ml:nav-close\";\n\nexport function useNavAccountSheet() {\n return {\n open: () => document.dispatchEvent(new CustomEvent(ML_ACCOUNT_OPEN)),\n close: () => document.dispatchEvent(new CustomEvent(ML_ACCOUNT_CLOSE)),\n };\n}\n\nexport interface NavAccountSheetProps {\n /** The app's account/wallet panel content — identity, network, disconnect, etc. */\n children: React.ReactNode;\n}\n\n/**\n * The wallet-side surface: a centered, backdrop-blurred panel — the exact\n * same overlay + card treatment as `NavCommandMenu` (`.nav-canvas-overlay`,\n * `bg-background/90 backdrop-blur-2xl backdrop-saturate-150`), so every\n * global panel in the header reads as one system. No built-in title — this\n * is an account/wallet card, not a menu; content is entirely app-owned.\n *\n * Opens via `useNavAccountSheet().open()`. Mutually exclusive with the\n * command menu: opening one closes the other, and the shared `ml:nav-close`\n * event (fired by `useNavCommandMenu().close()`) closes this too.\n */\nexport function NavAccountSheet({ children }: NavAccountSheetProps) {\n const [open, setOpen] = React.useState(false);\n\n React.useEffect(() => {\n const onOpen = () => {\n document.dispatchEvent(new CustomEvent(ML_NAV_CLOSE));\n setOpen(true);\n };\n const onClose = () => setOpen(false);\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpen(false);\n };\n document.addEventListener(ML_ACCOUNT_OPEN, onOpen);\n document.addEventListener(ML_ACCOUNT_CLOSE, onClose);\n document.addEventListener(ML_NAV_OPEN, onClose);\n document.addEventListener(ML_NAV_CLOSE, onClose);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(ML_ACCOUNT_OPEN, onOpen);\n document.removeEventListener(ML_ACCOUNT_CLOSE, onClose);\n document.removeEventListener(ML_NAV_OPEN, onClose);\n document.removeEventListener(ML_NAV_CLOSE, onClose);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, []);\n\n return (\n <AnimatePresence>\n {open && (\n <>\n {/* Backdrop blur — identical to NavCommandMenu's */}\n <motion.div\n className=\"nav-canvas-overlay\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n onClick={() => setOpen(false)}\n />\n\n {/* Panel — centered on desktop, bottom sheet on mobile, same as NavCommandMenu */}\n <motion.div\n className=\"fixed inset-0 z-[101] flex items-end justify-center p-3 pb-4 sm:items-center sm:p-4\"\n initial={{ opacity: 0, y: 24 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 24 }}\n transition={{ duration: 0.18, ease: \"easeOut\" }}\n onClick={() => setOpen(false)}\n >\n <div\n className=\"relative w-full max-w-[380px] overflow-hidden rounded-[20px] border border-border/40 bg-background/90 shadow-2xl backdrop-blur-2xl backdrop-saturate-150\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"flex justify-center pt-2.5 sm:hidden\" aria-hidden=\"true\">\n <span className=\"h-1 w-9 rounded-full bg-muted-foreground/30\" />\n </div>\n <button\n onClick={() => setOpen(false)}\n className=\"absolute right-3 top-3 rounded-md p-1 text-muted-foreground/70 transition-colors hover:bg-muted/50 hover:text-foreground\"\n aria-label=\"Close\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n </button>\n <div className=\"px-4 pb-4 pt-5 sm:pt-6\">{children}</div>\n </div>\n </motion.div>\n </>\n )}\n </AnimatePresence>\n );\n}\n"],"mappings":"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","names":["NavWalletTrigger"]}
@@ -51,21 +51,20 @@ declare function useNavAccountSheet(): {
51
51
  close: () => boolean;
52
52
  };
53
53
  interface NavAccountSheetProps {
54
- /** The app's account/connect panel (Clerk, wallet connectors, …). */
54
+ /** The app's account/wallet panel content — identity, network, disconnect, etc. */
55
55
  children: React.ReactNode;
56
- /** Optional heading above the panel. */
57
- title?: string;
58
56
  }
59
57
  /**
60
- * The wallet-side surface: a compact glass sheet anchored to the top-right
61
- * header button (bottom sheet on mobile). Content is app-owned — pass the same
62
- * account panel the command menu uses in its accountSlot.
58
+ * The wallet-side surface: a centered, backdrop-blurred panel the exact
59
+ * same overlay + card treatment as `NavCommandMenu` (`.nav-canvas-overlay`,
60
+ * `bg-background/90 backdrop-blur-2xl backdrop-saturate-150`), so every
61
+ * global panel in the header reads as one system. No built-in title — this
62
+ * is an account/wallet card, not a menu; content is entirely app-owned.
63
63
  *
64
- * Opens via `useNavAccountSheet().open()`. Mutually exclusive with the command
65
- * menu: opening one closes the other, and the shared `ml:nav-close` event
66
- * (fired by `useNavCommandMenu().close()`) closes this sheet too, so account
67
- * panels behave identically in both hosts.
64
+ * Opens via `useNavAccountSheet().open()`. Mutually exclusive with the
65
+ * command menu: opening one closes the other, and the shared `ml:nav-close`
66
+ * event (fired by `useNavCommandMenu().close()`) closes this too.
68
67
  */
69
- declare function NavAccountSheet({ children, title }: NavAccountSheetProps): react_jsx_runtime.JSX.Element;
68
+ declare function NavAccountSheet({ children }: NavAccountSheetProps): react_jsx_runtime.JSX.Element;
70
69
 
71
70
  export { NavAccountSheet, type NavAccountSheetProps, NavBrandButton, type NavBrandButtonProps, NavIconButton, type NavIconButtonProps, NavWalletTrigger, type NavWalletTriggerProps, useNavAccountSheet };
@@ -51,21 +51,20 @@ declare function useNavAccountSheet(): {
51
51
  close: () => boolean;
52
52
  };
53
53
  interface NavAccountSheetProps {
54
- /** The app's account/connect panel (Clerk, wallet connectors, …). */
54
+ /** The app's account/wallet panel content — identity, network, disconnect, etc. */
55
55
  children: React.ReactNode;
56
- /** Optional heading above the panel. */
57
- title?: string;
58
56
  }
59
57
  /**
60
- * The wallet-side surface: a compact glass sheet anchored to the top-right
61
- * header button (bottom sheet on mobile). Content is app-owned — pass the same
62
- * account panel the command menu uses in its accountSlot.
58
+ * The wallet-side surface: a centered, backdrop-blurred panel the exact
59
+ * same overlay + card treatment as `NavCommandMenu` (`.nav-canvas-overlay`,
60
+ * `bg-background/90 backdrop-blur-2xl backdrop-saturate-150`), so every
61
+ * global panel in the header reads as one system. No built-in title — this
62
+ * is an account/wallet card, not a menu; content is entirely app-owned.
63
63
  *
64
- * Opens via `useNavAccountSheet().open()`. Mutually exclusive with the command
65
- * menu: opening one closes the other, and the shared `ml:nav-close` event
66
- * (fired by `useNavCommandMenu().close()`) closes this sheet too, so account
67
- * panels behave identically in both hosts.
64
+ * Opens via `useNavAccountSheet().open()`. Mutually exclusive with the
65
+ * command menu: opening one closes the other, and the shared `ml:nav-close`
66
+ * event (fired by `useNavCommandMenu().close()`) closes this too.
68
67
  */
69
- declare function NavAccountSheet({ children, title }: NavAccountSheetProps): react_jsx_runtime.JSX.Element;
68
+ declare function NavAccountSheet({ children }: NavAccountSheetProps): react_jsx_runtime.JSX.Element;
70
69
 
71
70
  export { NavAccountSheet, type NavAccountSheetProps, NavBrandButton, type NavBrandButtonProps, NavIconButton, type NavIconButtonProps, NavWalletTrigger, type NavWalletTriggerProps, useNavAccountSheet };
@@ -59,7 +59,7 @@ const NavWalletTrigger = React.forwardRef(
59
59
  onClick,
60
60
  "aria-label": rest["aria-label"] ?? (connected ? "Account" : "Connect wallet"),
61
61
  className: cn(
62
- "ml-nav-wallet-trigger relative flex h-11 w-11 items-center justify-center rounded-full",
62
+ "ml-nav-wallet-trigger relative flex h-8 w-8 items-center justify-center rounded-full",
63
63
  "bg-background/10 text-muted-foreground backdrop-blur-xl backdrop-saturate-150",
64
64
  "transition-colors hover:bg-background/20 hover:text-foreground active:scale-[0.97]",
65
65
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60",
@@ -68,7 +68,7 @@ const NavWalletTrigger = React.forwardRef(
68
68
  ),
69
69
  children: [
70
70
  /* @__PURE__ */ jsx("span", { className: "ml-nav-wallet-ring", "aria-hidden": "true" }),
71
- connected && /* @__PURE__ */ jsx(User, { className: "h-4 w-4" })
71
+ connected && /* @__PURE__ */ jsx(User, { className: "h-3.5 w-3.5" })
72
72
  ]
73
73
  }
74
74
  );
@@ -84,7 +84,7 @@ function useNavAccountSheet() {
84
84
  close: () => document.dispatchEvent(new CustomEvent(ML_ACCOUNT_CLOSE))
85
85
  };
86
86
  }
87
- function NavAccountSheet({ children, title = "Account" }) {
87
+ function NavAccountSheet({ children }) {
88
88
  const [open, setOpen] = React.useState(false);
89
89
  React.useEffect(() => {
90
90
  const onOpen = () => {
@@ -123,27 +123,32 @@ function NavAccountSheet({ children, title = "Account" }) {
123
123
  /* @__PURE__ */ jsx(
124
124
  motion.div,
125
125
  {
126
- className: "fixed inset-x-3 bottom-3 z-[101] sm:inset-auto sm:right-4 sm:top-4 sm:w-[360px] lg:right-8",
126
+ className: "fixed inset-0 z-[101] flex items-end justify-center p-3 pb-4 sm:items-center sm:p-4",
127
127
  initial: { opacity: 0, y: 24 },
128
128
  animate: { opacity: 1, y: 0 },
129
129
  exit: { opacity: 0, y: 24 },
130
130
  transition: { duration: 0.18, ease: "easeOut" },
131
- children: /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-[20px] border border-border/40 bg-background/90 shadow-2xl backdrop-blur-2xl backdrop-saturate-150", children: [
132
- /* @__PURE__ */ jsx("div", { className: "flex justify-center pt-2.5 sm:hidden", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { className: "h-1 w-9 rounded-full bg-muted-foreground/30" }) }),
133
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 pb-1 pt-2 sm:pt-3", children: [
134
- /* @__PURE__ */ jsx("span", { className: "text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/70", children: title }),
135
- /* @__PURE__ */ jsx(
136
- "button",
137
- {
138
- onClick: () => setOpen(false),
139
- className: "rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted/50",
140
- "aria-label": "Close",
141
- children: /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) })
142
- }
143
- )
144
- ] }),
145
- /* @__PURE__ */ jsx("div", { className: "px-3 pb-4 pt-1 sm:pb-3", children })
146
- ] })
131
+ onClick: () => setOpen(false),
132
+ children: /* @__PURE__ */ jsxs(
133
+ "div",
134
+ {
135
+ className: "relative w-full max-w-[380px] overflow-hidden rounded-[20px] border border-border/40 bg-background/90 shadow-2xl backdrop-blur-2xl backdrop-saturate-150",
136
+ onClick: (e) => e.stopPropagation(),
137
+ children: [
138
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center pt-2.5 sm:hidden", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { className: "h-1 w-9 rounded-full bg-muted-foreground/30" }) }),
139
+ /* @__PURE__ */ jsx(
140
+ "button",
141
+ {
142
+ onClick: () => setOpen(false),
143
+ className: "absolute right-3 top-3 rounded-md p-1 text-muted-foreground/70 transition-colors hover:bg-muted/50 hover:text-foreground",
144
+ "aria-label": "Close",
145
+ children: /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) })
146
+ }
147
+ ),
148
+ /* @__PURE__ */ jsx("div", { className: "px-4 pb-4 pt-5 sm:pt-6", children })
149
+ ]
150
+ }
151
+ )
147
152
  }
148
153
  )
149
154
  ] }) });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/nav-shell.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { User } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\n// ── Header buttons ────────────────────────────────────────────────────────────\n\nexport interface NavBrandButtonProps {\n /** Defaults to opening the nav command menu (`ml:nav-open`). */\n onClick?: () => void;\n className?: string;\n \"aria-label\"?: string;\n /** Path to the brand icon image (the app's real icon asset). */\n iconSrc?: string;\n}\n\n/**\n * The main header trigger: brand mark + menu glyph in one quiet glass pill.\n * Mobile-first — a single ≥44px tap target instead of two small adjacent icons.\n * With no `onClick`, it opens the NavCommandMenu mounted elsewhere in the app.\n */\nexport function NavBrandButton({ onClick, className, iconSrc = \"/icon.png\", ...rest }: NavBrandButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick ?? (() => document.dispatchEvent(new CustomEvent(ML_NAV_OPEN)))}\n aria-label={rest[\"aria-label\"] ?? \"Open navigation\"}\n className={cn(\n \"group flex h-11 items-center gap-2 rounded-full\",\n \"bg-background/10 pl-2.5 pr-3 backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n className\n )}\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img src={iconSrc} alt=\"Medialane\" width={30} height={30} className=\"h-[30px] w-[30px] shrink-0\" />\n <span className=\"flex flex-col gap-[5px]\" aria-hidden=\"true\">\n <span className=\"h-[1.5px] w-4 rounded-full bg-muted-foreground transition-all group-hover:w-4 group-hover:bg-foreground\" />\n <span className=\"h-[1.5px] w-2.5 rounded-full bg-muted-foreground transition-all group-hover:w-4 group-hover:bg-foreground\" />\n </span>\n </button>\n );\n}\n\nexport interface NavIconButtonProps {\n onClick?: () => void;\n className?: string;\n \"aria-label\": string;\n /** Show a small brand-colored status dot (e.g. wallet connected). */\n indicator?: boolean;\n children: React.ReactNode;\n}\n\n/**\n * Circular glass header button — the right-side counterpart to NavBrandButton\n * (wallet / account trigger).\n */\nexport function NavIconButton({ onClick, className, indicator, children, ...rest }: NavIconButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={rest[\"aria-label\"]}\n className={cn(\n \"relative flex h-11 w-11 items-center justify-center rounded-full\",\n \"bg-background/10 text-muted-foreground backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 hover:text-foreground active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n className\n )}\n >\n {children}\n {indicator && (\n <span className=\"absolute right-[3px] top-[3px] h-2.5 w-2.5 rounded-full border-2 border-background bg-brand-blue\" />\n )}\n </button>\n );\n}\n\nexport interface NavWalletTriggerProps {\n onClick?: () => void;\n className?: string;\n \"aria-label\"?: string;\n /** Whether a wallet is currently connected. */\n connected?: boolean;\n}\n\n/**\n * The right-side counterpart to `NavBrandButton` for a wallet/account entry\n * point: the same glass pill material, with a thin brand-gradient ring\n * traced around the rim instead of a static icon. Not connected — the ring\n * rotates slowly (an ambient \"something opens here\" cue) around an empty\n * center, no glyph, no placeholder avatar. Connected — the ring settles to a\n * static accent and a plain `User` glyph fills the center (never a\n * gradient-filled avatar — this button doesn't know the wallet's real\n * identity, only whether one is attached).\n */\nexport const NavWalletTrigger = React.forwardRef<HTMLButtonElement, NavWalletTriggerProps>(\n function NavWalletTrigger({ onClick, className, connected = false, ...rest }, ref) {\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n aria-label={rest[\"aria-label\"] ?? (connected ? \"Account\" : \"Connect wallet\")}\n className={cn(\n \"ml-nav-wallet-trigger relative flex h-11 w-11 items-center justify-center rounded-full\",\n \"bg-background/10 text-muted-foreground backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 hover:text-foreground active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n connected && \"ml-nav-wallet-trigger--connected\",\n className\n )}\n >\n <span className=\"ml-nav-wallet-ring\" aria-hidden=\"true\" />\n {connected && <User className=\"h-4 w-4\" />}\n </button>\n );\n }\n);\n\n// ── Account sheet ─────────────────────────────────────────────────────────────\n\nconst ML_ACCOUNT_OPEN = \"ml:account-open\";\nconst ML_ACCOUNT_CLOSE = \"ml:account-close\";\nconst ML_NAV_OPEN = \"ml:nav-open\";\nconst ML_NAV_CLOSE = \"ml:nav-close\";\n\nexport function useNavAccountSheet() {\n return {\n open: () => document.dispatchEvent(new CustomEvent(ML_ACCOUNT_OPEN)),\n close: () => document.dispatchEvent(new CustomEvent(ML_ACCOUNT_CLOSE)),\n };\n}\n\nexport interface NavAccountSheetProps {\n /** The app's account/connect panel (Clerk, wallet connectors, …). */\n children: React.ReactNode;\n /** Optional heading above the panel. */\n title?: string;\n}\n\n/**\n * The wallet-side surface: a compact glass sheet anchored to the top-right\n * header button (bottom sheet on mobile). Content is app-owned — pass the same\n * account panel the command menu uses in its accountSlot.\n *\n * Opens via `useNavAccountSheet().open()`. Mutually exclusive with the command\n * menu: opening one closes the other, and the shared `ml:nav-close` event\n * (fired by `useNavCommandMenu().close()`) closes this sheet too, so account\n * panels behave identically in both hosts.\n */\nexport function NavAccountSheet({ children, title = \"Account\" }: NavAccountSheetProps) {\n const [open, setOpen] = React.useState(false);\n\n React.useEffect(() => {\n const onOpen = () => {\n document.dispatchEvent(new CustomEvent(ML_NAV_CLOSE));\n setOpen(true);\n };\n const onClose = () => setOpen(false);\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpen(false);\n };\n document.addEventListener(ML_ACCOUNT_OPEN, onOpen);\n document.addEventListener(ML_ACCOUNT_CLOSE, onClose);\n document.addEventListener(ML_NAV_OPEN, onClose);\n document.addEventListener(ML_NAV_CLOSE, onClose);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(ML_ACCOUNT_OPEN, onOpen);\n document.removeEventListener(ML_ACCOUNT_CLOSE, onClose);\n document.removeEventListener(ML_NAV_OPEN, onClose);\n document.removeEventListener(ML_NAV_CLOSE, onClose);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, []);\n\n return (\n <AnimatePresence>\n {open && (\n <>\n <motion.div\n className=\"nav-canvas-overlay\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n onClick={() => setOpen(false)}\n />\n <motion.div\n className=\"fixed inset-x-3 bottom-3 z-[101] sm:inset-auto sm:right-4 sm:top-4 sm:w-[360px] lg:right-8\"\n initial={{ opacity: 0, y: 24 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 24 }}\n transition={{ duration: 0.18, ease: \"easeOut\" }}\n >\n <div className=\"overflow-hidden rounded-[20px] border border-border/40 bg-background/90 shadow-2xl backdrop-blur-2xl backdrop-saturate-150\">\n <div className=\"flex justify-center pt-2.5 sm:hidden\" aria-hidden=\"true\">\n <span className=\"h-1 w-9 rounded-full bg-muted-foreground/30\" />\n </div>\n <div className=\"flex items-center justify-between px-4 pb-1 pt-2 sm:pt-3\">\n <span className=\"text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/70\">\n {title}\n </span>\n <button\n onClick={() => setOpen(false)}\n className=\"rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted/50\"\n aria-label=\"Close\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n </button>\n </div>\n <div className=\"px-3 pb-4 pt-1 sm:pb-3\">{children}</div>\n </div>\n </motion.div>\n </>\n )}\n </AnimatePresence>\n );\n}\n"],"mappings":"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","names":["NavWalletTrigger"]}
1
+ {"version":3,"sources":["../../src/components/nav-shell.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { AnimatePresence, motion } from \"framer-motion\";\nimport { User } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\n// ── Header buttons ────────────────────────────────────────────────────────────\n\nexport interface NavBrandButtonProps {\n /** Defaults to opening the nav command menu (`ml:nav-open`). */\n onClick?: () => void;\n className?: string;\n \"aria-label\"?: string;\n /** Path to the brand icon image (the app's real icon asset). */\n iconSrc?: string;\n}\n\n/**\n * The main header trigger: brand mark + menu glyph in one quiet glass pill.\n * Mobile-first — a single ≥44px tap target instead of two small adjacent icons.\n * With no `onClick`, it opens the NavCommandMenu mounted elsewhere in the app.\n */\nexport function NavBrandButton({ onClick, className, iconSrc = \"/icon.png\", ...rest }: NavBrandButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick ?? (() => document.dispatchEvent(new CustomEvent(ML_NAV_OPEN)))}\n aria-label={rest[\"aria-label\"] ?? \"Open navigation\"}\n className={cn(\n \"group flex h-11 items-center gap-2 rounded-full\",\n \"bg-background/10 pl-2.5 pr-3 backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n className\n )}\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img src={iconSrc} alt=\"Medialane\" width={30} height={30} className=\"h-[30px] w-[30px] shrink-0\" />\n <span className=\"flex flex-col gap-[5px]\" aria-hidden=\"true\">\n <span className=\"h-[1.5px] w-4 rounded-full bg-muted-foreground transition-all group-hover:w-4 group-hover:bg-foreground\" />\n <span className=\"h-[1.5px] w-2.5 rounded-full bg-muted-foreground transition-all group-hover:w-4 group-hover:bg-foreground\" />\n </span>\n </button>\n );\n}\n\nexport interface NavIconButtonProps {\n onClick?: () => void;\n className?: string;\n \"aria-label\": string;\n /** Show a small brand-colored status dot (e.g. wallet connected). */\n indicator?: boolean;\n children: React.ReactNode;\n}\n\n/**\n * Circular glass header button — the right-side counterpart to NavBrandButton\n * (wallet / account trigger).\n */\nexport function NavIconButton({ onClick, className, indicator, children, ...rest }: NavIconButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={rest[\"aria-label\"]}\n className={cn(\n \"relative flex h-11 w-11 items-center justify-center rounded-full\",\n \"bg-background/10 text-muted-foreground backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 hover:text-foreground active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n className\n )}\n >\n {children}\n {indicator && (\n <span className=\"absolute right-[3px] top-[3px] h-2.5 w-2.5 rounded-full border-2 border-background bg-brand-blue\" />\n )}\n </button>\n );\n}\n\nexport interface NavWalletTriggerProps {\n onClick?: () => void;\n className?: string;\n \"aria-label\"?: string;\n /** Whether a wallet is currently connected. */\n connected?: boolean;\n}\n\n/**\n * The right-side counterpart to `NavBrandButton` for a wallet/account entry\n * point: the same glass pill material, with a thin brand-gradient ring\n * traced around the rim instead of a static icon. Not connected — the ring\n * rotates slowly (an ambient \"something opens here\" cue) around an empty\n * center, no glyph, no placeholder avatar. Connected — the ring settles to a\n * static accent and a plain `User` glyph fills the center (never a\n * gradient-filled avatar — this button doesn't know the wallet's real\n * identity, only whether one is attached).\n */\nexport const NavWalletTrigger = React.forwardRef<HTMLButtonElement, NavWalletTriggerProps>(\n function NavWalletTrigger({ onClick, className, connected = false, ...rest }, ref) {\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n aria-label={rest[\"aria-label\"] ?? (connected ? \"Account\" : \"Connect wallet\")}\n className={cn(\n \"ml-nav-wallet-trigger relative flex h-8 w-8 items-center justify-center rounded-full\",\n \"bg-background/10 text-muted-foreground backdrop-blur-xl backdrop-saturate-150\",\n \"transition-colors hover:bg-background/20 hover:text-foreground active:scale-[0.97]\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60\",\n connected && \"ml-nav-wallet-trigger--connected\",\n className\n )}\n >\n <span className=\"ml-nav-wallet-ring\" aria-hidden=\"true\" />\n {connected && <User className=\"h-3.5 w-3.5\" />}\n </button>\n );\n }\n);\n\n// ── Account sheet ─────────────────────────────────────────────────────────────\n\nconst ML_ACCOUNT_OPEN = \"ml:account-open\";\nconst ML_ACCOUNT_CLOSE = \"ml:account-close\";\nconst ML_NAV_OPEN = \"ml:nav-open\";\nconst ML_NAV_CLOSE = \"ml:nav-close\";\n\nexport function useNavAccountSheet() {\n return {\n open: () => document.dispatchEvent(new CustomEvent(ML_ACCOUNT_OPEN)),\n close: () => document.dispatchEvent(new CustomEvent(ML_ACCOUNT_CLOSE)),\n };\n}\n\nexport interface NavAccountSheetProps {\n /** The app's account/wallet panel content — identity, network, disconnect, etc. */\n children: React.ReactNode;\n}\n\n/**\n * The wallet-side surface: a centered, backdrop-blurred panel — the exact\n * same overlay + card treatment as `NavCommandMenu` (`.nav-canvas-overlay`,\n * `bg-background/90 backdrop-blur-2xl backdrop-saturate-150`), so every\n * global panel in the header reads as one system. No built-in title — this\n * is an account/wallet card, not a menu; content is entirely app-owned.\n *\n * Opens via `useNavAccountSheet().open()`. Mutually exclusive with the\n * command menu: opening one closes the other, and the shared `ml:nav-close`\n * event (fired by `useNavCommandMenu().close()`) closes this too.\n */\nexport function NavAccountSheet({ children }: NavAccountSheetProps) {\n const [open, setOpen] = React.useState(false);\n\n React.useEffect(() => {\n const onOpen = () => {\n document.dispatchEvent(new CustomEvent(ML_NAV_CLOSE));\n setOpen(true);\n };\n const onClose = () => setOpen(false);\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setOpen(false);\n };\n document.addEventListener(ML_ACCOUNT_OPEN, onOpen);\n document.addEventListener(ML_ACCOUNT_CLOSE, onClose);\n document.addEventListener(ML_NAV_OPEN, onClose);\n document.addEventListener(ML_NAV_CLOSE, onClose);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(ML_ACCOUNT_OPEN, onOpen);\n document.removeEventListener(ML_ACCOUNT_CLOSE, onClose);\n document.removeEventListener(ML_NAV_OPEN, onClose);\n document.removeEventListener(ML_NAV_CLOSE, onClose);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, []);\n\n return (\n <AnimatePresence>\n {open && (\n <>\n {/* Backdrop blur — identical to NavCommandMenu's */}\n <motion.div\n className=\"nav-canvas-overlay\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n onClick={() => setOpen(false)}\n />\n\n {/* Panel — centered on desktop, bottom sheet on mobile, same as NavCommandMenu */}\n <motion.div\n className=\"fixed inset-0 z-[101] flex items-end justify-center p-3 pb-4 sm:items-center sm:p-4\"\n initial={{ opacity: 0, y: 24 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 24 }}\n transition={{ duration: 0.18, ease: \"easeOut\" }}\n onClick={() => setOpen(false)}\n >\n <div\n className=\"relative w-full max-w-[380px] overflow-hidden rounded-[20px] border border-border/40 bg-background/90 shadow-2xl backdrop-blur-2xl backdrop-saturate-150\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"flex justify-center pt-2.5 sm:hidden\" aria-hidden=\"true\">\n <span className=\"h-1 w-9 rounded-full bg-muted-foreground/30\" />\n </div>\n <button\n onClick={() => setOpen(false)}\n className=\"absolute right-3 top-3 rounded-md p-1 text-muted-foreground/70 transition-colors hover:bg-muted/50 hover:text-foreground\"\n aria-label=\"Close\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\">\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n </button>\n <div className=\"px-4 pb-4 pt-5 sm:pt-6\">{children}</div>\n </div>\n </motion.div>\n </>\n )}\n </AnimatePresence>\n );\n}\n"],"mappings":"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","names":["NavWalletTrigger"]}
@@ -227,7 +227,6 @@ input[type="number"] { -moz-appearance: textfield; }
227
227
  }
228
228
  .ml-nav-wallet-trigger--connected .ml-nav-wallet-ring {
229
229
  animation: none;
230
- opacity: 0.45;
231
230
  }
232
231
 
233
232
  /* ── Hover-only branded gradient border (launchpad cards) ───────────────── */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.80.1",
3
+ "version": "0.81.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",