@zendir/ui 0.1.10 → 0.1.13

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
@@ -53,8 +53,8 @@ import { PacketViewer } from "./react/core/PacketViewer.js";
53
53
  import { Pagination } from "./react/core/Pagination.js";
54
54
  import { PinInput } from "./react/core/PinInput.js";
55
55
  import { Progress } from "./react/astro/Progress.js";
56
+ import { SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX, SideNav } from "./react/core/SideNav.js";
56
57
  import { Select } from "./react/core/Select.js";
57
- import { SideNav } from "./react/core/SideNav.js";
58
58
  import { SidePanel } from "./react/core/SidePanel.js";
59
59
  import { Spacer } from "./react/core/layout/Spacer.js";
60
60
  import { StatusIndicator } from "./react/astro/StatusIndicator.js";
@@ -153,6 +153,7 @@ export {
153
153
  Progress,
154
154
  REGION_BORDER_COLORS,
155
155
  REGION_COLORS,
156
+ SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX,
156
157
  SPACE_SYSTEM_COLORS,
157
158
  STATUS_COLORS,
158
159
  Select,
@@ -24,6 +24,8 @@ export interface SideNavProps {
24
24
  style?: React.CSSProperties;
25
25
  }
26
26
  declare const SideNavRoot: React.NamedExoticComponent<SideNavProps>;
27
+ /** Default height for the logo row so dashboard / operator / other apps align the same mark. */
28
+ export declare const SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX = 44;
27
29
  export interface SideNavHeaderProps {
28
30
  /** Logo element (Icon, image, or ReactNode) */
29
31
  logo?: React.ReactNode;
@@ -37,6 +39,11 @@ export interface SideNavHeaderProps {
37
39
  badge?: string;
38
40
  /** Badge variant for color */
39
41
  badgeVariant?: 'info' | 'success' | 'warning' | 'caution';
42
+ /**
43
+ * Fixed height (px) for the top logo band. Title, subtitle, and badge render below this band
44
+ * so different logo assets still line up across apps (dashboard vs operator).
45
+ */
46
+ logoSlotHeight?: number;
40
47
  /** Children override (advanced: replaces default header content entirely) */
41
48
  children?: React.ReactNode;
42
49
  }
@@ -193,6 +193,7 @@ const SideNavRoot = memo(function SideNav2({
193
193
  }
194
194
  return /* @__PURE__ */ jsx(SideNavContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("nav", { role: "navigation", "aria-label": "Main navigation", style: navStyle, children }) });
195
195
  });
196
+ const SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX = 44;
196
197
  function CollapseToggleButton() {
197
198
  const { tokens } = useTheme();
198
199
  const { collapsed, toggleCollapse } = useContext(SideNavContext);
@@ -249,61 +250,124 @@ const SideNavHeader = memo(function SideNavHeader2({
249
250
  subtitle,
250
251
  badge,
251
252
  badgeVariant = "info",
253
+ logoSlotHeight = SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX,
252
254
  children
253
255
  }) {
254
256
  const { tokens } = useTheme();
255
257
  const { collapsed, mode, showCollapseToggle, toggleCollapse } = useContext(SideNavContext);
256
258
  const displayLogo = collapsed && collapsedLogo ? collapsedLogo : logo;
257
259
  const showToggle = showCollapseToggle && mode !== "mobile";
260
+ const hasMeta = Boolean(title || subtitle || badge);
261
+ const slotH = logoSlotHeight;
258
262
  const badgeColors = {
259
263
  info: tokens.colors.accent.primary,
260
264
  success: tokens.colors.status.normal,
261
265
  warning: tokens.colors.status.caution,
262
266
  caution: tokens.colors.status.serious
263
267
  };
264
- return /* @__PURE__ */ jsx("div", { style: {
268
+ const metaBlock = !collapsed && hasMeta ? /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0, width: "100%" }, children: [
269
+ title ? /* @__PURE__ */ jsx("div", { style: {
270
+ fontSize: tokens.typography.fontSize.sm,
271
+ fontWeight: tokens.typography.fontWeight.bold,
272
+ color: tokens.colors.text.primary,
273
+ lineHeight: tokens.typography.lineHeight.tight,
274
+ whiteSpace: "nowrap",
275
+ overflow: "hidden",
276
+ textOverflow: "ellipsis"
277
+ }, children: title }) : null,
278
+ subtitle || badge ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.xs, marginTop: title ? "2px" : 0, flexWrap: "wrap" }, children: [
279
+ subtitle ? /* @__PURE__ */ jsx("span", { style: {
280
+ fontSize: tokens.typography.fontSize.xxs,
281
+ color: tokens.colors.text.tertiary
282
+ }, children: subtitle }) : null,
283
+ badge ? /* @__PURE__ */ jsx("span", { style: {
284
+ fontSize: "0.6rem",
285
+ fontWeight: tokens.typography.fontWeight.bold,
286
+ color: badgeColors[badgeVariant] || safeAccentText(tokens.colors.accent.primary),
287
+ backgroundColor: `${badgeColors[badgeVariant] || tokens.colors.accent.primary}18`,
288
+ border: `1px solid ${badgeColors[badgeVariant] || tokens.colors.accent.primary}30`,
289
+ padding: "1px 6px",
290
+ borderRadius: tokens.borderRadius.sm,
291
+ textTransform: "uppercase",
292
+ letterSpacing: "0.05em"
293
+ }, children: badge }) : null
294
+ ] }) : null
295
+ ] }) : null;
296
+ const logoSlot = displayLogo ? /* @__PURE__ */ jsx(
297
+ "div",
298
+ {
299
+ style: {
300
+ height: slotH,
301
+ minHeight: slotH,
302
+ maxHeight: slotH,
303
+ width: "100%",
304
+ display: "flex",
305
+ alignItems: "center",
306
+ justifyContent: collapsed ? "center" : "flex-start",
307
+ overflow: "hidden",
308
+ boxSizing: "border-box",
309
+ marginBottom: !collapsed && hasMeta && displayLogo ? tokens.spacing.sm : 0
310
+ },
311
+ children: /* @__PURE__ */ jsx(
312
+ "div",
313
+ {
314
+ style: {
315
+ maxHeight: "100%",
316
+ maxWidth: "100%",
317
+ display: "flex",
318
+ alignItems: "center",
319
+ justifyContent: collapsed ? "center" : "flex-start",
320
+ minWidth: 0,
321
+ cursor: collapsed && showToggle ? "pointer" : void 0
322
+ },
323
+ onClick: collapsed && showToggle ? toggleCollapse : void 0,
324
+ children: displayLogo
325
+ }
326
+ )
327
+ }
328
+ ) : null;
329
+ if (children) {
330
+ return /* @__PURE__ */ jsx("div", { style: {
331
+ padding: `${tokens.spacing.md} 16px ${tokens.spacing.md} 15px`,
332
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
333
+ flexShrink: 0,
334
+ boxSizing: "border-box",
335
+ position: "relative"
336
+ }, children });
337
+ }
338
+ if (collapsed) {
339
+ return /* @__PURE__ */ jsxs("div", { style: {
340
+ display: "flex",
341
+ flexDirection: "column",
342
+ alignItems: "center",
343
+ padding: `${tokens.spacing.md} ${tokens.spacing.sm}`,
344
+ minHeight: slotH + 24,
345
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
346
+ flexShrink: 0,
347
+ boxSizing: "border-box",
348
+ position: "relative",
349
+ justifyContent: "center"
350
+ }, children: [
351
+ logoSlot,
352
+ showToggle ? /* @__PURE__ */ jsx("div", { style: { position: "absolute", right: 4, top: "50%", transform: "translateY(-50%)" }, children: /* @__PURE__ */ jsx(CollapseToggleButton, {}) }) : null
353
+ ] });
354
+ }
355
+ return /* @__PURE__ */ jsxs("div", { style: {
265
356
  display: "flex",
266
- alignItems: "center",
267
- gap: tokens.spacing.sm,
268
- padding: collapsed ? `${tokens.spacing.md} ${tokens.spacing.sm}` : `0 16px 0 15px`,
269
- minHeight: 91,
357
+ flexDirection: "column",
358
+ alignItems: "stretch",
359
+ padding: `${tokens.spacing.md} 16px ${tokens.spacing.md} 15px`,
270
360
  borderBottom: `1px solid ${tokens.colors.border.muted}`,
271
361
  flexShrink: 0,
272
- justifyContent: collapsed ? "center" : "flex-start",
273
362
  boxSizing: "border-box",
274
363
  position: "relative"
275
- }, children: children ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
276
- displayLogo && /* @__PURE__ */ jsx("div", { style: { flexShrink: 0, cursor: collapsed && showToggle ? "pointer" : void 0 }, onClick: collapsed && showToggle ? toggleCollapse : void 0, children: displayLogo }),
277
- !collapsed && /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
278
- title && /* @__PURE__ */ jsx("div", { style: {
279
- fontSize: tokens.typography.fontSize.sm,
280
- fontWeight: tokens.typography.fontWeight.bold,
281
- color: tokens.colors.text.primary,
282
- lineHeight: tokens.typography.lineHeight.tight,
283
- whiteSpace: "nowrap",
284
- overflow: "hidden",
285
- textOverflow: "ellipsis"
286
- }, children: title }),
287
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.xs, marginTop: "2px" }, children: [
288
- subtitle && /* @__PURE__ */ jsx("span", { style: {
289
- fontSize: tokens.typography.fontSize.xxs,
290
- color: tokens.colors.text.tertiary
291
- }, children: subtitle }),
292
- badge && /* @__PURE__ */ jsx("span", { style: {
293
- fontSize: "0.6rem",
294
- fontWeight: tokens.typography.fontWeight.bold,
295
- color: badgeColors[badgeVariant] || safeAccentText(tokens.colors.accent.primary),
296
- backgroundColor: `${badgeColors[badgeVariant] || tokens.colors.accent.primary}18`,
297
- border: `1px solid ${badgeColors[badgeVariant] || tokens.colors.accent.primary}30`,
298
- padding: "1px 6px",
299
- borderRadius: tokens.borderRadius.sm,
300
- textTransform: "uppercase",
301
- letterSpacing: "0.05em"
302
- }, children: badge })
303
- ] })
304
- ] }),
305
- showToggle && (collapsed ? /* @__PURE__ */ jsx("div", { style: { position: "absolute", right: 4, top: "50%", transform: "translateY(-50%)" }, children: /* @__PURE__ */ jsx(CollapseToggleButton, {}) }) : /* @__PURE__ */ jsx(CollapseToggleButton, {}))
306
- ] }) });
364
+ }, children: [
365
+ showToggle ? /* @__PURE__ */ jsx("div", { style: { position: "absolute", top: tokens.spacing.sm, right: tokens.spacing.sm, zIndex: 1 }, children: /* @__PURE__ */ jsx(CollapseToggleButton, {}) }) : null,
366
+ /* @__PURE__ */ jsxs("div", { style: { paddingRight: showToggle ? 36 : 0, width: "100%", minWidth: 0 }, children: [
367
+ logoSlot,
368
+ metaBlock
369
+ ] })
370
+ ] });
307
371
  });
308
372
  const TAG_COLORS = {
309
373
  default: { bg: "#ffffff10", fg: "#9590a8", border: "#ffffff15" },
@@ -331,11 +395,14 @@ const SideNavItem = memo(function SideNavItem2({
331
395
  const { tokens } = useTheme();
332
396
  const { collapsed, setMobileOpen } = useContext(SideNavContext);
333
397
  const [isHovered, setIsHovered] = useState(false);
334
- const handleClick = useCallback(() => {
398
+ const handleClick = useCallback((e) => {
335
399
  if (disabled) return;
400
+ if (onClick && href && !e.metaKey && !e.ctrlKey && !e.shiftKey) {
401
+ e.preventDefault();
402
+ }
336
403
  setMobileOpen(false);
337
404
  onClick == null ? void 0 : onClick();
338
- }, [disabled, onClick, setMobileOpen]);
405
+ }, [disabled, onClick, href, setMobileOpen]);
339
406
  const statusColor = status ? SIDENAV_STATUS_COLORS[status] ?? void 0 : void 0;
340
407
  const accentColor = statusColor && active ? statusColor : safeAccentText(tokens.colors.accent.primary);
341
408
  const hasDescription = !!description && !collapsed;
@@ -548,6 +615,7 @@ const SideNav = Object.assign(SideNavRoot, {
548
615
  Footer: SideNavFooter
549
616
  });
550
617
  export {
618
+ SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX,
551
619
  SideNav
552
620
  };
553
621
  //# sourceMappingURL=SideNav.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SideNav.js","sources":["../../../src/react/core/SideNav.tsx"],"sourcesContent":["/**\r\n * @zendir/ui - SideNav Component\r\n * \r\n * Persistent sidebar navigation for operator dashboards. Compound component\r\n * pattern with Header, Item, Section, Divider, and Footer subcomponents.\r\n * \r\n * Responsive: Full sidebar on desktop, hamburger overlay on mobile.\r\n * \r\n * Astro UX Compliance:\r\n * - Persistent side navigation pattern (AstroUXDS Navigation)\r\n * - Status indicator integration\r\n * - Active state highlighting with accent color\r\n * - Keyboard navigation support\r\n * - Reduced motion support\r\n * \r\n * @example\r\n * ```tsx\r\n * <SideNav>\r\n * <SideNav.Header logo={<Icon name=\"satellite\" size={24} />} title=\"Space Range\" badge=\"Operator\" />\r\n * <SideNav.Section title=\"Operations\">\r\n * <SideNav.Item icon=\"controls\" label=\"Controls\" description=\"System command interface\" href=\"/controls\" active />\r\n * <SideNav.Item icon=\"telemetry\" label=\"Telemetry\" href=\"/telemetry\" badge={3} tag=\"LIVE\" tagVariant=\"success\" />\r\n * <SideNav.Item icon=\"images\" label=\"Images\" href=\"/images\" />\r\n * </SideNav.Section>\r\n * <SideNav.Divider />\r\n * <SideNav.Section title=\"Analysis\">\r\n * <SideNav.Item icon=\"chart\" label=\"Plots\" href=\"/plots\" />\r\n * <SideNav.Item icon=\"map\" label=\"Map\" href=\"/map\" />\r\n * </SideNav.Section>\r\n * <SideNav.Footer>\r\n * <SideNav.Item icon=\"settings\" label=\"Settings\" href=\"/settings\" />\r\n * </SideNav.Footer>\r\n * </SideNav>\r\n * ```\r\n */\r\n\r\nimport React, { memo, useState, createContext, useContext, useCallback, useEffect } from 'react';\r\nimport { useTheme } from '../theme';\r\nimport { safeAccentText } from '../utils';\r\nimport { Icon } from './Icon';\r\nimport type { IconName } from './Icon';\r\n\r\n// ─── Astro UX Status Shape ───────────────────────────────────────────────────\r\n\r\nconst SIDENAV_STATUS_COLORS: Record<string, string> = {\r\n off: '#a4abb6',\r\n standby: '#2dccff',\r\n normal: '#56f000',\r\n caution: '#fce83a',\r\n serious: '#ffb302',\r\n critical: '#ff3838',\r\n};\r\n\r\n/** Astro UX dual-coded status shape (color + geometry). */\r\nfunction NavStatusShape({ status, size = 8 }: { status: string; size?: number }) {\r\n const color = SIDENAV_STATUS_COLORS[status] ?? SIDENAV_STATUS_COLORS.off;\r\n const glow = `${color}50`;\r\n const style = { flexShrink: 0 as const, filter: `drop-shadow(0 0 3px ${glow})` };\r\n\r\n switch (status) {\r\n case 'caution':\r\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><rect x=\"1\" y=\"1\" width=\"10\" height=\"10\" fill={color} /></svg>;\r\n case 'serious':\r\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><polygon points=\"6,1 11,6 6,11 1,6\" fill={color} /></svg>;\r\n case 'critical':\r\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><polygon points=\"6,11 1,2 11,2\" fill={color} /></svg>;\r\n case 'standby':\r\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><circle cx=\"6\" cy=\"6\" r=\"3.5\" fill=\"none\" stroke={color} strokeWidth=\"2\" /></svg>;\r\n case 'off':\r\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><circle cx=\"6\" cy=\"6\" r=\"3\" fill={color} /></svg>;\r\n default: // normal\r\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><circle cx=\"6\" cy=\"6\" r=\"5\" fill={color} /></svg>;\r\n }\r\n}\r\n\r\n// ─── Responsive Breakpoints ──────────────────────────────────────────────────\r\n\r\nconst SIDENAV_BREAKPOINTS = {\r\n mobile: 768,\r\n tablet: 1024,\r\n} as const;\r\n\r\ntype SideNavMode = 'desktop' | 'tablet' | 'mobile';\r\n\r\nfunction getSideNavMode(width: number): SideNavMode {\r\n if (width < SIDENAV_BREAKPOINTS.mobile) return 'mobile';\r\n if (width < SIDENAV_BREAKPOINTS.tablet) return 'tablet';\r\n return 'desktop';\r\n}\r\n\r\n// ─── Context ─────────────────────────────────────────────────────────────────\r\n\r\ninterface SideNavContextValue {\r\n collapsed: boolean;\r\n mobileOpen: boolean;\r\n mode: SideNavMode;\r\n showCollapseToggle: boolean;\r\n setMobileOpen: (open: boolean) => void;\r\n toggleCollapse: () => void;\r\n}\r\n\r\nconst SideNavContext = createContext<SideNavContextValue>({\r\n collapsed: false,\r\n mobileOpen: false,\r\n mode: 'desktop',\r\n showCollapseToggle: true,\r\n setMobileOpen: () => {},\r\n toggleCollapse: () => {},\r\n});\r\n\r\n// ─── SideNav ─────────────────────────────────────────────────────────────────\r\n\r\nexport interface SideNavProps {\r\n /** Collapsed mode (icon-only). When omitted, auto-collapses on tablet viewports. */\r\n collapsed?: boolean;\r\n /** Callback when collapsed state changes (via toggle button or responsive breakpoint). */\r\n onCollapsedChange?: (collapsed: boolean) => void;\r\n /** Show a collapse/expand toggle button in the sidebar (default true). */\r\n showCollapseToggle?: boolean;\r\n /** Width in pixels (default 260) */\r\n width?: number;\r\n /** Collapsed width in pixels (default 64) */\r\n collapsedWidth?: number;\r\n /**\r\n * Mobile viewport behavior.\r\n * - `'drawer'` (default): hamburger button with slide-out overlay drawer.\r\n * - `'collapsed'`: persistent collapsed icon-only strip (same as tablet).\r\n */\r\n mobileVariant?: 'drawer' | 'collapsed';\r\n /** Children (SideNav.Header, SideNav.Item, SideNav.Section, SideNav.Footer) */\r\n children?: React.ReactNode;\r\n /** Custom style */\r\n style?: React.CSSProperties;\r\n}\r\n\r\nconst SideNavRoot = memo(function SideNav({\r\n collapsed,\r\n onCollapsedChange,\r\n showCollapseToggle = true,\r\n width = 260,\r\n collapsedWidth = 64,\r\n mobileVariant = 'drawer',\r\n children,\r\n style,\r\n}: SideNavProps): React.ReactElement {\r\n const { tokens, theme } = useTheme();\r\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\r\n const [mobileOpen, setMobileOpen] = useState(false);\r\n const [userCollapsed, setUserCollapsed] = useState<boolean | null>(null);\r\n const [viewMode, setViewMode] = useState<SideNavMode>(() => {\r\n if (typeof window !== 'undefined') return getSideNavMode(window.innerWidth);\r\n return 'desktop';\r\n });\r\n \r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n let rafId: number;\r\n const handleResize = () => {\r\n cancelAnimationFrame(rafId);\r\n rafId = requestAnimationFrame(() => setViewMode(getSideNavMode(window.innerWidth)));\r\n };\r\n window.addEventListener('resize', handleResize, { passive: true });\r\n return () => {\r\n window.removeEventListener('resize', handleResize);\r\n cancelAnimationFrame(rafId);\r\n };\r\n }, []);\r\n\r\n // When mobileVariant='collapsed', promote mobile to tablet (collapsed inline strip)\r\n const effectiveMode = mobileVariant === 'collapsed' && viewMode === 'mobile' ? 'tablet' : viewMode;\r\n\r\n // Reset user toggle when crossing breakpoints\r\n useEffect(() => {\r\n setUserCollapsed(null);\r\n }, [effectiveMode]);\r\n\r\n // Close mobile drawer when switching away from mobile\r\n useEffect(() => {\r\n if (effectiveMode !== 'mobile' && mobileOpen) setMobileOpen(false);\r\n }, [effectiveMode, mobileOpen]);\r\n \r\n // Close mobile nav on escape\r\n useEffect(() => {\r\n if (!mobileOpen) return;\r\n const handleEsc = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') setMobileOpen(false);\r\n };\r\n document.addEventListener('keydown', handleEsc);\r\n return () => document.removeEventListener('keydown', handleEsc);\r\n }, [mobileOpen]);\r\n\r\n // Resolve collapsed: explicit prop > user toggle > auto (tablet = collapsed)\r\n const autoCollapsed = effectiveMode === 'tablet';\r\n const isCollapsed = collapsed !== undefined\r\n ? collapsed\r\n : userCollapsed !== null\r\n ? userCollapsed\r\n : autoCollapsed;\r\n const isMobile = effectiveMode === 'mobile';\r\n const navWidth = isCollapsed ? collapsedWidth : width;\r\n\r\n const handleToggleCollapse = useCallback(() => {\r\n const next = !isCollapsed;\r\n setUserCollapsed(next);\r\n onCollapsedChange?.(next);\r\n }, [isCollapsed, onCollapsedChange]);\r\n \r\n const navStyle: React.CSSProperties = {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n width: isMobile ? 280 : navWidth,\r\n height: '100%',\r\n backgroundColor: isTransparentTheme\r\n ? 'rgba(15, 12, 30, 0.7)'\r\n : tokens.colors.background.surface,\r\n borderRight: `1px solid ${tokens.colors.border.muted}`,\r\n transition: 'width 0.25s ease, transform 0.25s ease',\r\n overflowX: 'hidden',\r\n overflowY: 'auto',\r\n flexShrink: 0,\r\n fontFamily: tokens.typography.fontFamily.primary,\r\n ...(isTransparentTheme ? {\r\n backdropFilter: 'blur(16px)',\r\n WebkitBackdropFilter: 'blur(16px)',\r\n } : {}),\r\n ...style,\r\n };\r\n \r\n const contextValue: SideNavContextValue = { collapsed: isCollapsed, mobileOpen, mode: effectiveMode, showCollapseToggle, setMobileOpen, toggleCollapse: handleToggleCollapse };\r\n \r\n // Mobile: hamburger button + overlay drawer\r\n if (isMobile) {\r\n return (\r\n <SideNavContext.Provider value={contextValue}>\r\n {/* Hamburger button */}\r\n <button\r\n aria-label=\"Open navigation\"\r\n onClick={() => setMobileOpen(true)}\r\n style={{\r\n position: 'fixed',\r\n top: 6,\r\n left: 6,\r\n zIndex: 1001,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n width: 32,\r\n height: 32,\r\n border: 'none',\r\n borderRadius: tokens.borderRadius.sm,\r\n backgroundColor: 'transparent',\r\n color: tokens.colors.text.primary,\r\n cursor: 'pointer',\r\n padding: 0,\r\n transition: tokens.animation.fast,\r\n }}\r\n >\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\">\r\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\r\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\r\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n \r\n {/* Overlay */}\r\n <div\r\n aria-hidden=\"true\"\r\n style={{\r\n position: 'fixed',\r\n inset: 0,\r\n zIndex: 1002,\r\n backgroundColor: `${tokens.colors.background.base}99`,\r\n backdropFilter: 'blur(4px)',\r\n opacity: mobileOpen ? 1 : 0,\r\n pointerEvents: mobileOpen ? 'auto' : 'none',\r\n transition: 'opacity 0.25s ease',\r\n }}\r\n onClick={() => setMobileOpen(false)}\r\n />\r\n \r\n {/* Slide-out nav */}\r\n <nav\r\n role=\"navigation\"\r\n aria-label=\"Main navigation\"\r\n style={{\r\n ...navStyle,\r\n position: 'fixed',\r\n top: 0,\r\n left: 0,\r\n zIndex: 1003,\r\n transform: mobileOpen ? 'translateX(0)' : 'translateX(-100%)',\r\n boxShadow: mobileOpen ? tokens.shadows.xl : 'none',\r\n }}\r\n >\r\n {children}\r\n </nav>\r\n </SideNavContext.Provider>\r\n );\r\n }\r\n \r\n return (\r\n <SideNavContext.Provider value={contextValue}>\r\n <nav role=\"navigation\" aria-label=\"Main navigation\" style={navStyle}>\r\n {children}\r\n </nav>\r\n </SideNavContext.Provider>\r\n );\r\n});\r\n\r\n// ─── Header ──────────────────────────────────────────────────────────────────\r\n\r\nexport interface SideNavHeaderProps {\r\n /** Logo element (Icon, image, or ReactNode) */\r\n logo?: React.ReactNode;\r\n /** Compact logo shown when sidebar is collapsed or on tablet (e.g., just the icon mark) */\r\n collapsedLogo?: React.ReactNode;\r\n /** App title */\r\n title?: string;\r\n /** Subtitle or version */\r\n subtitle?: string;\r\n /** Role badge (e.g., \"Operator\", \"Admin\") */\r\n badge?: string;\r\n /** Badge variant for color */\r\n badgeVariant?: 'info' | 'success' | 'warning' | 'caution';\r\n /** Children override (advanced: replaces default header content entirely) */\r\n children?: React.ReactNode;\r\n}\r\n\r\n/** Chevron toggle button for collapsing/expanding the sidebar. */\r\nfunction CollapseToggleButton() {\r\n const { tokens } = useTheme();\r\n const { collapsed, toggleCollapse } = useContext(SideNavContext);\r\n const [hovered, setHovered] = useState(false);\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}\r\n onClick={toggleCollapse}\r\n onMouseEnter={() => setHovered(true)}\r\n onMouseLeave={() => setHovered(false)}\r\n style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n width: 28,\r\n height: 28,\r\n border: `1px solid ${hovered ? tokens.colors.border.focus : tokens.colors.border.muted}`,\r\n borderRadius: tokens.borderRadius.md,\r\n backgroundColor: hovered ? `${tokens.colors.accent.primary}15` : 'transparent',\r\n color: hovered ? tokens.colors.accent.primary : tokens.colors.text.tertiary,\r\n cursor: 'pointer',\r\n flexShrink: 0,\r\n padding: 0,\r\n transition: tokens.animation.fast,\r\n outline: 'none',\r\n }}\r\n >\r\n <svg\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n style={{\r\n transition: 'transform 0.25s ease',\r\n transform: collapsed ? 'rotate(180deg)' : 'rotate(0deg)',\r\n }}\r\n >\r\n <polyline points=\"15 18 9 12 15 6\" />\r\n </svg>\r\n </button>\r\n );\r\n}\r\n\r\nconst SideNavHeader = memo(function SideNavHeader({\r\n logo,\r\n collapsedLogo,\r\n title,\r\n subtitle,\r\n badge,\r\n badgeVariant = 'info',\r\n children,\r\n}: SideNavHeaderProps): React.ReactElement {\r\n const { tokens } = useTheme();\r\n const { collapsed, mode, showCollapseToggle, toggleCollapse } = useContext(SideNavContext);\r\n const displayLogo = collapsed && collapsedLogo ? collapsedLogo : logo;\r\n const showToggle = showCollapseToggle && mode !== 'mobile';\r\n \r\n const badgeColors: Record<string, string> = {\r\n info: tokens.colors.accent.primary,\r\n success: tokens.colors.status.normal,\r\n warning: tokens.colors.status.caution,\r\n caution: tokens.colors.status.serious,\r\n };\r\n \r\n return (\r\n <div style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: tokens.spacing.sm,\r\n padding: collapsed ? `${tokens.spacing.md} ${tokens.spacing.sm}` : `0 16px 0 15px`,\r\n minHeight: 91,\r\n borderBottom: `1px solid ${tokens.colors.border.muted}`,\r\n flexShrink: 0,\r\n justifyContent: collapsed ? 'center' : 'flex-start',\r\n boxSizing: 'border-box',\r\n position: 'relative',\r\n }}>\r\n {children ? children : (<>\r\n {displayLogo && <div style={{ flexShrink: 0, cursor: collapsed && showToggle ? 'pointer' : undefined }} onClick={collapsed && showToggle ? toggleCollapse : undefined}>{displayLogo}</div>}\r\n {!collapsed && (\r\n <div style={{ flex: 1, minWidth: 0 }}>\r\n {title && (\r\n <div style={{\r\n fontSize: tokens.typography.fontSize.sm,\r\n fontWeight: tokens.typography.fontWeight.bold,\r\n color: tokens.colors.text.primary,\r\n lineHeight: tokens.typography.lineHeight.tight,\r\n whiteSpace: 'nowrap',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n }}>\r\n {title}\r\n </div>\r\n )}\r\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.xs, marginTop: '2px' }}>\r\n {subtitle && (\r\n <span style={{\r\n fontSize: tokens.typography.fontSize.xxs,\r\n color: tokens.colors.text.tertiary,\r\n }}>\r\n {subtitle}\r\n </span>\r\n )}\r\n {badge && (\r\n <span style={{\r\n fontSize: '0.6rem',\r\n fontWeight: tokens.typography.fontWeight.bold,\r\n color: badgeColors[badgeVariant] || safeAccentText(tokens.colors.accent.primary),\r\n backgroundColor: `${badgeColors[badgeVariant] || tokens.colors.accent.primary}18`,\r\n border: `1px solid ${badgeColors[badgeVariant] || tokens.colors.accent.primary}30`,\r\n padding: '1px 6px',\r\n borderRadius: tokens.borderRadius.sm,\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.05em',\r\n }}>\r\n {badge}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n {showToggle && (\r\n collapsed\r\n ? <div style={{ position: 'absolute', right: 4, top: '50%', transform: 'translateY(-50%)' }}><CollapseToggleButton /></div>\r\n : <CollapseToggleButton />\r\n )}\r\n </>)}\r\n </div>\r\n );\r\n});\r\n\r\n// ─── Item ────────────────────────────────────────────────────────────────────\r\n\r\nexport interface SideNavItemProps {\r\n /** Icon name from zendir-ui icon library */\r\n icon?: IconName | React.ReactNode;\r\n /** Label text */\r\n label: string;\r\n /** Description text displayed beneath the label (hidden in collapsed mode) */\r\n description?: string;\r\n /** Small tag/chip displayed after the label (e.g. \"v2\", \"NEW\", \"BETA\") */\r\n tag?: string;\r\n /** Tag color variant */\r\n tagVariant?: 'default' | 'info' | 'success' | 'warning' | 'danger';\r\n /** Link href (renders <a>) */\r\n href?: string;\r\n /** Click handler (renders <button>) */\r\n onClick?: () => void;\r\n /** Active state */\r\n active?: boolean;\r\n /** Disabled state */\r\n disabled?: boolean;\r\n /** Notification badge count */\r\n badge?: number;\r\n /** External link indicator */\r\n external?: boolean;\r\n /**\r\n * Astro UX status level — renders a dual-coded indicator (color + shape).\r\n * Shapes per official Astro UXDS: normal = ● filled circle, standby = ◎ ring,\r\n * caution = ■ square, serious = ◆ diamond, critical = ▼ triangle, off = · small circle.\r\n */\r\n status?: 'off' | 'standby' | 'normal' | 'caution' | 'serious' | 'critical';\r\n /** Optional status label shown as tooltip or text next to status shape */\r\n statusLabel?: string;\r\n /** Right-side slot — arbitrary ReactNode rendered at the end of the item row */\r\n suffix?: React.ReactNode;\r\n}\r\n\r\nconst TAG_COLORS: Record<string, { bg: string; fg: string; border: string }> = {\r\n default: { bg: '#ffffff10', fg: '#9590a8', border: '#ffffff15' },\r\n info: { bg: '#8a2be218', fg: '#c4a0ff', border: '#8a2be230' },\r\n success: { bg: '#56f00018', fg: '#56f000', border: '#56f00030' },\r\n warning: { bg: '#fce83a18', fg: '#fce83a', border: '#fce83a30' },\r\n danger: { bg: '#ff383818', fg: '#ff3838', border: '#ff383830' },\r\n};\r\n\r\nconst SideNavItem = memo(function SideNavItem({\r\n icon,\r\n label,\r\n description,\r\n tag,\r\n tagVariant = 'default',\r\n href,\r\n onClick,\r\n active = false,\r\n disabled = false,\r\n badge,\r\n external = false,\r\n status,\r\n statusLabel,\r\n suffix,\r\n}: SideNavItemProps): React.ReactElement {\r\n const { tokens } = useTheme();\r\n const { collapsed, setMobileOpen } = useContext(SideNavContext);\r\n const [isHovered, setIsHovered] = useState(false);\r\n \r\n const handleClick = useCallback(() => {\r\n if (disabled) return;\r\n setMobileOpen(false);\r\n onClick?.();\r\n }, [disabled, onClick, setMobileOpen]);\r\n \r\n // Status-aware accent: when an item has a status, tint active/hover with its color\r\n const statusColor = status ? (SIDENAV_STATUS_COLORS[status] ?? undefined) : undefined;\r\n const accentColor = statusColor && active ? statusColor : safeAccentText(tokens.colors.accent.primary);\r\n \r\n const hasDescription = !!description && !collapsed;\r\n \r\n const iconElement = typeof icon === 'string'\r\n ? <Icon name={icon as IconName} size={hasDescription ? 22 : 20} color={active ? accentColor : tokens.colors.text.secondary} />\r\n : icon;\r\n \r\n const itemStyle: React.CSSProperties = {\r\n display: 'flex',\r\n alignItems: hasDescription ? 'flex-start' : 'center',\r\n gap: tokens.spacing.sm,\r\n padding: collapsed\r\n ? `${tokens.spacing.sm} 0`\r\n : hasDescription\r\n ? `10px 16px 10px 12px`\r\n : `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 12px`,\r\n justifyContent: collapsed ? 'center' : 'flex-start',\r\n color: active\r\n ? accentColor\r\n : disabled\r\n ? tokens.colors.text.tertiary\r\n : tokens.colors.text.secondary,\r\n backgroundColor: active\r\n ? `${accentColor}12`\r\n : isHovered && !disabled\r\n ? `${accentColor}08`\r\n : 'transparent',\r\n fontSize: tokens.typography.fontSize.sm,\r\n fontWeight: active ? tokens.typography.fontWeight.semibold : tokens.typography.fontWeight.normal,\r\n fontFamily: tokens.typography.fontFamily.primary,\r\n cursor: disabled ? 'not-allowed' : 'pointer',\r\n textDecoration: 'none',\r\n borderTop: 'none',\r\n borderRight: 'none',\r\n borderBottom: 'none',\r\n borderLeft: active\r\n ? `3px solid ${accentColor}`\r\n : '3px solid transparent',\r\n outline: 'none',\r\n width: '100%',\r\n boxSizing: 'border-box',\r\n transition: tokens.animation.fast,\r\n position: 'relative',\r\n opacity: disabled ? 0.5 : 1,\r\n };\r\n \r\n const tagColors = TAG_COLORS[tagVariant] ?? TAG_COLORS.default;\r\n \r\n const content = (\r\n <>\r\n {/* Icon + collapsed status overlay */}\r\n {iconElement && (\r\n <span style={{ flexShrink: 0, display: 'flex', position: 'relative', marginTop: hasDescription ? '2px' : 0 }}>\r\n {iconElement}\r\n {/* In collapsed mode, show a small status shape overlaid on the icon (top-left) */}\r\n {collapsed && status && (\r\n <span\r\n style={{\r\n position: 'absolute',\r\n top: -3,\r\n left: -4,\r\n lineHeight: 0,\r\n }}\r\n title={statusLabel ?? status}\r\n >\r\n <NavStatusShape status={status} size={7} />\r\n </span>\r\n )}\r\n </span>\r\n )}\r\n {!collapsed && (\r\n <>\r\n {/* Label + description block */}\r\n <span style={{ flex: 1, minWidth: 0, overflow: 'hidden' }}>\r\n <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\r\n <span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>\r\n {label}\r\n </span>\r\n {tag && (\r\n <span style={{\r\n fontSize: '0.6rem',\r\n fontWeight: tokens.typography.fontWeight.bold,\r\n color: tagColors.fg,\r\n backgroundColor: tagColors.bg,\r\n border: `1px solid ${tagColors.border}`,\r\n padding: '1px 5px',\r\n borderRadius: tokens.borderRadius.sm,\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.04em',\r\n flexShrink: 0,\r\n lineHeight: '1.3',\r\n whiteSpace: 'nowrap',\r\n }}>\r\n {tag}\r\n </span>\r\n )}\r\n </span>\r\n {description && (\r\n <span style={{\r\n display: 'block',\r\n fontSize: tokens.typography.fontSize.xxs,\r\n color: tokens.colors.text.tertiary,\r\n lineHeight: tokens.typography.lineHeight.normal,\r\n marginTop: '2px',\r\n whiteSpace: 'nowrap',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n fontWeight: tokens.typography.fontWeight.normal,\r\n }}>\r\n {description}\r\n </span>\r\n )}\r\n </span>\r\n {/* Right-side trailing elements — badge, status, suffix, external icon */}\r\n {(badge !== undefined && badge > 0 || status || suffix || external) && (\r\n <span style={{\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n gap: 8,\r\n flexShrink: 0,\r\n marginTop: hasDescription ? '2px' : 0,\r\n }}>\r\n {/* Badge */}\r\n {badge !== undefined && badge > 0 && (\r\n <span style={{\r\n fontSize: '0.65rem',\r\n fontWeight: tokens.typography.fontWeight.bold,\r\n color: '#fff',\r\n backgroundColor: tokens.colors.status.critical,\r\n borderRadius: tokens.borderRadius.full,\r\n minWidth: '18px',\r\n height: '18px',\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n padding: '0 5px',\r\n flexShrink: 0,\r\n lineHeight: 1,\r\n boxSizing: 'border-box',\r\n }}>\r\n {badge > 99 ? '99+' : badge}\r\n </span>\r\n )}\r\n {/* Status */}\r\n {status && (\r\n <span\r\n style={{ display: 'inline-flex', alignItems: 'center', flexShrink: 0 }}\r\n role=\"status\"\r\n aria-label={`Status: ${statusLabel ?? status}`}\r\n title={statusLabel ?? status}\r\n >\r\n <NavStatusShape status={status} size={8} />\r\n </span>\r\n )}\r\n {/* Suffix */}\r\n {suffix && (\r\n <span style={{ flexShrink: 0, display: 'inline-flex', alignItems: 'center' }}>\r\n {suffix}\r\n </span>\r\n )}\r\n {/* External */}\r\n {external && (\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" style={{ flexShrink: 0, opacity: 0.5 }}>\r\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\r\n <polyline points=\"15 3 21 3 21 9\" />\r\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\r\n </svg>\r\n )}\r\n </span>\r\n )}\r\n </>\r\n )}\r\n </>\r\n );\r\n \r\n const props = {\r\n style: itemStyle,\r\n onMouseEnter: () => setIsHovered(true),\r\n onMouseLeave: () => setIsHovered(false),\r\n title: collapsed ? label : undefined,\r\n 'aria-current': active ? ('page' as const) : undefined,\r\n 'aria-disabled': disabled,\r\n };\r\n \r\n if (href && !disabled) {\r\n return (\r\n <a href={href} onClick={handleClick} target={external ? '_blank' : undefined} rel={external ? 'noopener noreferrer' : undefined} {...props}>\r\n {content}\r\n </a>\r\n );\r\n }\r\n \r\n return (\r\n <button type=\"button\" onClick={handleClick} disabled={disabled} {...props}>\r\n {content}\r\n </button>\r\n );\r\n});\r\n\r\n// ─── Section ─────────────────────────────────────────────────────────────────\r\n\r\nexport interface SideNavSectionProps {\r\n /** Section title */\r\n title?: string;\r\n /** Children (SideNav.Item elements) */\r\n children?: React.ReactNode;\r\n}\r\n\r\nconst SideNavSection = memo(function SideNavSection({\r\n title,\r\n children,\r\n}: SideNavSectionProps): React.ReactElement {\r\n const { tokens } = useTheme();\r\n const { collapsed } = useContext(SideNavContext);\r\n \r\n return (\r\n <div style={{ marginTop: tokens.spacing.sm }}>\r\n {title && !collapsed && (\r\n <div style={{\r\n padding: `${tokens.spacing.xs} 16px ${tokens.spacing.xs} 15px`,\r\n fontSize: tokens.typography.fontSize.xxs,\r\n fontWeight: tokens.typography.fontWeight.bold,\r\n color: tokens.colors.text.tertiary,\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.08em',\r\n }}>\r\n {title}\r\n </div>\r\n )}\r\n {collapsed && title && (\r\n <div style={{\r\n width: '60%',\r\n height: '1px',\r\n backgroundColor: tokens.colors.border.muted,\r\n margin: `${tokens.spacing.xs} auto`,\r\n }} />\r\n )}\r\n {children}\r\n </div>\r\n );\r\n});\r\n\r\n// ─── Divider ─────────────────────────────────────────────────────────────────\r\n\r\nexport interface SideNavDividerProps {\r\n /** Optional label shown in the center of the divider line */\r\n label?: string;\r\n}\r\n\r\nconst SideNavDivider = memo(function SideNavDivider({\r\n label,\r\n}: SideNavDividerProps): React.ReactElement {\r\n const { tokens } = useTheme();\r\n const { collapsed } = useContext(SideNavContext);\r\n\r\n if (collapsed) {\r\n return (\r\n <div style={{\r\n width: '60%',\r\n height: '1px',\r\n backgroundColor: tokens.colors.border.muted,\r\n margin: `${tokens.spacing.sm} auto`,\r\n }} />\r\n );\r\n }\r\n\r\n if (label) {\r\n return (\r\n <div style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: tokens.spacing.sm,\r\n padding: `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 15px`,\r\n }}>\r\n <div style={{ flex: 1, height: '1px', backgroundColor: tokens.colors.border.muted }} />\r\n <span style={{\r\n fontSize: tokens.typography.fontSize.xxs,\r\n color: tokens.colors.text.tertiary,\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.06em',\r\n whiteSpace: 'nowrap',\r\n }}>\r\n {label}\r\n </span>\r\n <div style={{ flex: 1, height: '1px', backgroundColor: tokens.colors.border.muted }} />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div style={{\r\n height: '1px',\r\n backgroundColor: tokens.colors.border.muted,\r\n margin: `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 15px`,\r\n }} />\r\n );\r\n});\r\n\r\n// ─── Footer ──────────────────────────────────────────────────────────────────\r\n\r\nexport interface SideNavFooterProps {\r\n children?: React.ReactNode;\r\n}\r\n\r\nconst SideNavFooter = memo(function SideNavFooter({\r\n children,\r\n}: SideNavFooterProps): React.ReactElement {\r\n const { tokens } = useTheme();\r\n \r\n return (\r\n <div style={{\r\n marginTop: 'auto',\r\n borderTop: `1px solid ${tokens.colors.border.muted}`,\r\n paddingTop: tokens.spacing.xs,\r\n paddingBottom: tokens.spacing.xs,\r\n }}>\r\n {children}\r\n </div>\r\n );\r\n});\r\n\r\n// ─── Compound Export ─────────────────────────────────────────────────────────\r\n\r\ntype SideNavComponent = typeof SideNavRoot & {\r\n Header: typeof SideNavHeader;\r\n Item: typeof SideNavItem;\r\n Section: typeof SideNavSection;\r\n Divider: typeof SideNavDivider;\r\n Footer: typeof SideNavFooter;\r\n};\r\n\r\nexport const SideNav: SideNavComponent = Object.assign(SideNavRoot, {\r\n Header: SideNavHeader,\r\n Item: SideNavItem,\r\n Section: SideNavSection,\r\n Divider: SideNavDivider,\r\n Footer: SideNavFooter,\r\n});\r\n\r\nexport default SideNav;\r\n"],"names":["SideNav","SideNavHeader","SideNavItem","SideNavSection","SideNavDivider","SideNavFooter"],"mappings":"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"}
1
+ {"version":3,"file":"SideNav.js","sources":["../../../src/react/core/SideNav.tsx"],"sourcesContent":["/**\n * @zendir/ui - SideNav Component\n * \n * Persistent sidebar navigation for operator dashboards. Compound component\n * pattern with Header, Item, Section, Divider, and Footer subcomponents.\n * \n * Responsive: Full sidebar on desktop, hamburger overlay on mobile.\n * \n * Astro UX Compliance:\n * - Persistent side navigation pattern (AstroUXDS Navigation)\n * - Status indicator integration\n * - Active state highlighting with accent color\n * - Keyboard navigation support\n * - Reduced motion support\n * \n * @example\n * ```tsx\n * <SideNav>\n * <SideNav.Header logo={<Icon name=\"satellite\" size={24} />} title=\"Space Range\" badge=\"Operator\" />\n * <SideNav.Section title=\"Operations\">\n * <SideNav.Item icon=\"controls\" label=\"Controls\" description=\"System command interface\" href=\"/controls\" active />\n * <SideNav.Item icon=\"telemetry\" label=\"Telemetry\" href=\"/telemetry\" badge={3} tag=\"LIVE\" tagVariant=\"success\" />\n * <SideNav.Item icon=\"images\" label=\"Images\" href=\"/images\" />\n * </SideNav.Section>\n * <SideNav.Divider />\n * <SideNav.Section title=\"Analysis\">\n * <SideNav.Item icon=\"chart\" label=\"Plots\" href=\"/plots\" />\n * <SideNav.Item icon=\"map\" label=\"Map\" href=\"/map\" />\n * </SideNav.Section>\n * <SideNav.Footer>\n * <SideNav.Item icon=\"settings\" label=\"Settings\" href=\"/settings\" />\n * </SideNav.Footer>\n * </SideNav>\n * ```\n */\n\nimport React, { memo, useState, createContext, useContext, useCallback, useEffect } from 'react';\nimport { useTheme } from '../theme';\nimport { safeAccentText } from '../utils';\nimport { Icon } from './Icon';\nimport type { IconName } from './Icon';\n\n// ─── Astro UX Status Shape ───────────────────────────────────────────────────\n\nconst SIDENAV_STATUS_COLORS: Record<string, string> = {\n off: '#a4abb6',\n standby: '#2dccff',\n normal: '#56f000',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n};\n\n/** Astro UX dual-coded status shape (color + geometry). */\nfunction NavStatusShape({ status, size = 8 }: { status: string; size?: number }) {\n const color = SIDENAV_STATUS_COLORS[status] ?? SIDENAV_STATUS_COLORS.off;\n const glow = `${color}50`;\n const style = { flexShrink: 0 as const, filter: `drop-shadow(0 0 3px ${glow})` };\n\n switch (status) {\n case 'caution':\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><rect x=\"1\" y=\"1\" width=\"10\" height=\"10\" fill={color} /></svg>;\n case 'serious':\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><polygon points=\"6,1 11,6 6,11 1,6\" fill={color} /></svg>;\n case 'critical':\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><polygon points=\"6,11 1,2 11,2\" fill={color} /></svg>;\n case 'standby':\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><circle cx=\"6\" cy=\"6\" r=\"3.5\" fill=\"none\" stroke={color} strokeWidth=\"2\" /></svg>;\n case 'off':\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><circle cx=\"6\" cy=\"6\" r=\"3\" fill={color} /></svg>;\n default: // normal\n return <svg viewBox=\"0 0 12 12\" width={size} height={size} style={style} aria-hidden=\"true\"><circle cx=\"6\" cy=\"6\" r=\"5\" fill={color} /></svg>;\n }\n}\n\n// ─── Responsive Breakpoints ──────────────────────────────────────────────────\n\nconst SIDENAV_BREAKPOINTS = {\n mobile: 768,\n tablet: 1024,\n} as const;\n\ntype SideNavMode = 'desktop' | 'tablet' | 'mobile';\n\nfunction getSideNavMode(width: number): SideNavMode {\n if (width < SIDENAV_BREAKPOINTS.mobile) return 'mobile';\n if (width < SIDENAV_BREAKPOINTS.tablet) return 'tablet';\n return 'desktop';\n}\n\n// ─── Context ─────────────────────────────────────────────────────────────────\n\ninterface SideNavContextValue {\n collapsed: boolean;\n mobileOpen: boolean;\n mode: SideNavMode;\n showCollapseToggle: boolean;\n setMobileOpen: (open: boolean) => void;\n toggleCollapse: () => void;\n}\n\nconst SideNavContext = createContext<SideNavContextValue>({\n collapsed: false,\n mobileOpen: false,\n mode: 'desktop',\n showCollapseToggle: true,\n setMobileOpen: () => {},\n toggleCollapse: () => {},\n});\n\n// ─── SideNav ─────────────────────────────────────────────────────────────────\n\nexport interface SideNavProps {\n /** Collapsed mode (icon-only). When omitted, auto-collapses on tablet viewports. */\n collapsed?: boolean;\n /** Callback when collapsed state changes (via toggle button or responsive breakpoint). */\n onCollapsedChange?: (collapsed: boolean) => void;\n /** Show a collapse/expand toggle button in the sidebar (default true). */\n showCollapseToggle?: boolean;\n /** Width in pixels (default 260) */\n width?: number;\n /** Collapsed width in pixels (default 64) */\n collapsedWidth?: number;\n /**\n * Mobile viewport behavior.\n * - `'drawer'` (default): hamburger button with slide-out overlay drawer.\n * - `'collapsed'`: persistent collapsed icon-only strip (same as tablet).\n */\n mobileVariant?: 'drawer' | 'collapsed';\n /** Children (SideNav.Header, SideNav.Item, SideNav.Section, SideNav.Footer) */\n children?: React.ReactNode;\n /** Custom style */\n style?: React.CSSProperties;\n}\n\nconst SideNavRoot = memo(function SideNav({\n collapsed,\n onCollapsedChange,\n showCollapseToggle = true,\n width = 260,\n collapsedWidth = 64,\n mobileVariant = 'drawer',\n children,\n style,\n}: SideNavProps): React.ReactElement {\n const { tokens, theme } = useTheme();\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const [mobileOpen, setMobileOpen] = useState(false);\n const [userCollapsed, setUserCollapsed] = useState<boolean | null>(null);\n const [viewMode, setViewMode] = useState<SideNavMode>(() => {\n if (typeof window !== 'undefined') return getSideNavMode(window.innerWidth);\n return 'desktop';\n });\n \n useEffect(() => {\n if (typeof window === 'undefined') return;\n let rafId: number;\n const handleResize = () => {\n cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(() => setViewMode(getSideNavMode(window.innerWidth)));\n };\n window.addEventListener('resize', handleResize, { passive: true });\n return () => {\n window.removeEventListener('resize', handleResize);\n cancelAnimationFrame(rafId);\n };\n }, []);\n\n // When mobileVariant='collapsed', promote mobile to tablet (collapsed inline strip)\n const effectiveMode = mobileVariant === 'collapsed' && viewMode === 'mobile' ? 'tablet' : viewMode;\n\n // Reset user toggle when crossing breakpoints\n useEffect(() => {\n setUserCollapsed(null);\n }, [effectiveMode]);\n\n // Close mobile drawer when switching away from mobile\n useEffect(() => {\n if (effectiveMode !== 'mobile' && mobileOpen) setMobileOpen(false);\n }, [effectiveMode, mobileOpen]);\n \n // Close mobile nav on escape\n useEffect(() => {\n if (!mobileOpen) return;\n const handleEsc = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setMobileOpen(false);\n };\n document.addEventListener('keydown', handleEsc);\n return () => document.removeEventListener('keydown', handleEsc);\n }, [mobileOpen]);\n\n // Resolve collapsed: explicit prop > user toggle > auto (tablet = collapsed)\n const autoCollapsed = effectiveMode === 'tablet';\n const isCollapsed = collapsed !== undefined\n ? collapsed\n : userCollapsed !== null\n ? userCollapsed\n : autoCollapsed;\n const isMobile = effectiveMode === 'mobile';\n const navWidth = isCollapsed ? collapsedWidth : width;\n\n const handleToggleCollapse = useCallback(() => {\n const next = !isCollapsed;\n setUserCollapsed(next);\n onCollapsedChange?.(next);\n }, [isCollapsed, onCollapsedChange]);\n \n const navStyle: React.CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n width: isMobile ? 280 : navWidth,\n height: '100%',\n backgroundColor: isTransparentTheme\n ? 'rgba(15, 12, 30, 0.7)'\n : tokens.colors.background.surface,\n borderRight: `1px solid ${tokens.colors.border.muted}`,\n transition: 'width 0.25s ease, transform 0.25s ease',\n overflowX: 'hidden',\n overflowY: 'auto',\n flexShrink: 0,\n fontFamily: tokens.typography.fontFamily.primary,\n ...(isTransparentTheme ? {\n backdropFilter: 'blur(16px)',\n WebkitBackdropFilter: 'blur(16px)',\n } : {}),\n ...style,\n };\n \n const contextValue: SideNavContextValue = { collapsed: isCollapsed, mobileOpen, mode: effectiveMode, showCollapseToggle, setMobileOpen, toggleCollapse: handleToggleCollapse };\n \n // Mobile: hamburger button + overlay drawer\n if (isMobile) {\n return (\n <SideNavContext.Provider value={contextValue}>\n {/* Hamburger button */}\n <button\n aria-label=\"Open navigation\"\n onClick={() => setMobileOpen(true)}\n style={{\n position: 'fixed',\n top: 6,\n left: 6,\n zIndex: 1001,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 32,\n height: 32,\n border: 'none',\n borderRadius: tokens.borderRadius.sm,\n backgroundColor: 'transparent',\n color: tokens.colors.text.primary,\n cursor: 'pointer',\n padding: 0,\n transition: tokens.animation.fast,\n }}\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\">\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\" />\n </svg>\n </button>\n \n {/* Overlay */}\n <div\n aria-hidden=\"true\"\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 1002,\n backgroundColor: `${tokens.colors.background.base}99`,\n backdropFilter: 'blur(4px)',\n opacity: mobileOpen ? 1 : 0,\n pointerEvents: mobileOpen ? 'auto' : 'none',\n transition: 'opacity 0.25s ease',\n }}\n onClick={() => setMobileOpen(false)}\n />\n \n {/* Slide-out nav */}\n <nav\n role=\"navigation\"\n aria-label=\"Main navigation\"\n style={{\n ...navStyle,\n position: 'fixed',\n top: 0,\n left: 0,\n zIndex: 1003,\n transform: mobileOpen ? 'translateX(0)' : 'translateX(-100%)',\n boxShadow: mobileOpen ? tokens.shadows.xl : 'none',\n }}\n >\n {children}\n </nav>\n </SideNavContext.Provider>\n );\n }\n \n return (\n <SideNavContext.Provider value={contextValue}>\n <nav role=\"navigation\" aria-label=\"Main navigation\" style={navStyle}>\n {children}\n </nav>\n </SideNavContext.Provider>\n );\n});\n\n// ─── Header ──────────────────────────────────────────────────────────────────\n\n/** Default height for the logo row so dashboard / operator / other apps align the same mark. */\nexport const SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX = 44;\n\nexport interface SideNavHeaderProps {\n /** Logo element (Icon, image, or ReactNode) */\n logo?: React.ReactNode;\n /** Compact logo shown when sidebar is collapsed or on tablet (e.g., just the icon mark) */\n collapsedLogo?: React.ReactNode;\n /** App title */\n title?: string;\n /** Subtitle or version */\n subtitle?: string;\n /** Role badge (e.g., \"Operator\", \"Admin\") */\n badge?: string;\n /** Badge variant for color */\n badgeVariant?: 'info' | 'success' | 'warning' | 'caution';\n /**\n * Fixed height (px) for the top logo band. Title, subtitle, and badge render below this band\n * so different logo assets still line up across apps (dashboard vs operator).\n */\n logoSlotHeight?: number;\n /** Children override (advanced: replaces default header content entirely) */\n children?: React.ReactNode;\n}\n\n/** Chevron toggle button for collapsing/expanding the sidebar. */\nfunction CollapseToggleButton() {\n const { tokens } = useTheme();\n const { collapsed, toggleCollapse } = useContext(SideNavContext);\n const [hovered, setHovered] = useState(false);\n\n return (\n <button\n type=\"button\"\n aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}\n onClick={toggleCollapse}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 28,\n height: 28,\n border: `1px solid ${hovered ? tokens.colors.border.focus : tokens.colors.border.muted}`,\n borderRadius: tokens.borderRadius.md,\n backgroundColor: hovered ? `${tokens.colors.accent.primary}15` : 'transparent',\n color: hovered ? tokens.colors.accent.primary : tokens.colors.text.tertiary,\n cursor: 'pointer',\n flexShrink: 0,\n padding: 0,\n transition: tokens.animation.fast,\n outline: 'none',\n }}\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n transition: 'transform 0.25s ease',\n transform: collapsed ? 'rotate(180deg)' : 'rotate(0deg)',\n }}\n >\n <polyline points=\"15 18 9 12 15 6\" />\n </svg>\n </button>\n );\n}\n\nconst SideNavHeader = memo(function SideNavHeader({\n logo,\n collapsedLogo,\n title,\n subtitle,\n badge,\n badgeVariant = 'info',\n logoSlotHeight = SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX,\n children,\n}: SideNavHeaderProps): React.ReactElement {\n const { tokens } = useTheme();\n const { collapsed, mode, showCollapseToggle, toggleCollapse } = useContext(SideNavContext);\n const displayLogo = collapsed && collapsedLogo ? collapsedLogo : logo;\n const showToggle = showCollapseToggle && mode !== 'mobile';\n const hasMeta = Boolean(title || subtitle || badge);\n const slotH = logoSlotHeight;\n\n const badgeColors: Record<string, string> = {\n info: tokens.colors.accent.primary,\n success: tokens.colors.status.normal,\n warning: tokens.colors.status.caution,\n caution: tokens.colors.status.serious,\n };\n\n const metaBlock = !collapsed && hasMeta ? (\n <div style={{ flex: 1, minWidth: 0, width: '100%' }}>\n {title ? (\n <div style={{\n fontSize: tokens.typography.fontSize.sm,\n fontWeight: tokens.typography.fontWeight.bold,\n color: tokens.colors.text.primary,\n lineHeight: tokens.typography.lineHeight.tight,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}>\n {title}\n </div>\n ) : null}\n {(subtitle || badge) ? (\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.xs, marginTop: title ? '2px' : 0, flexWrap: 'wrap' }}>\n {subtitle ? (\n <span style={{\n fontSize: tokens.typography.fontSize.xxs,\n color: tokens.colors.text.tertiary,\n }}>\n {subtitle}\n </span>\n ) : null}\n {badge ? (\n <span style={{\n fontSize: '0.6rem',\n fontWeight: tokens.typography.fontWeight.bold,\n color: badgeColors[badgeVariant] || safeAccentText(tokens.colors.accent.primary),\n backgroundColor: `${badgeColors[badgeVariant] || tokens.colors.accent.primary}18`,\n border: `1px solid ${badgeColors[badgeVariant] || tokens.colors.accent.primary}30`,\n padding: '1px 6px',\n borderRadius: tokens.borderRadius.sm,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}>\n {badge}\n </span>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null;\n\n const logoSlot = displayLogo ? (\n <div\n style={{\n height: slotH,\n minHeight: slotH,\n maxHeight: slotH,\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: collapsed ? 'center' : 'flex-start',\n overflow: 'hidden',\n boxSizing: 'border-box',\n marginBottom: !collapsed && hasMeta && displayLogo ? tokens.spacing.sm : 0,\n }}\n >\n <div\n style={{\n maxHeight: '100%',\n maxWidth: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: collapsed ? 'center' : 'flex-start',\n minWidth: 0,\n cursor: collapsed && showToggle ? 'pointer' : undefined,\n }}\n onClick={collapsed && showToggle ? toggleCollapse : undefined}\n >\n {displayLogo}\n </div>\n </div>\n ) : null;\n\n if (children) {\n return (\n <div style={{\n padding: `${tokens.spacing.md} 16px ${tokens.spacing.md} 15px`,\n borderBottom: `1px solid ${tokens.colors.border.muted}`,\n flexShrink: 0,\n boxSizing: 'border-box',\n position: 'relative',\n }}>\n {children}\n </div>\n );\n }\n\n // Collapsed: centered logo in the same fixed slot height as expanded (visual parity with operator).\n if (collapsed) {\n return (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n padding: `${tokens.spacing.md} ${tokens.spacing.sm}`,\n minHeight: slotH + 24,\n borderBottom: `1px solid ${tokens.colors.border.muted}`,\n flexShrink: 0,\n boxSizing: 'border-box',\n position: 'relative',\n justifyContent: 'center',\n }}>\n {logoSlot}\n {showToggle ? (\n <div style={{ position: 'absolute', right: 4, top: '50%', transform: 'translateY(-50%)' }}>\n <CollapseToggleButton />\n </div>\n ) : null}\n </div>\n );\n }\n\n return (\n <div style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'stretch',\n padding: `${tokens.spacing.md} 16px ${tokens.spacing.md} 15px`,\n borderBottom: `1px solid ${tokens.colors.border.muted}`,\n flexShrink: 0,\n boxSizing: 'border-box',\n position: 'relative',\n }}>\n {showToggle ? (\n <div style={{ position: 'absolute', top: tokens.spacing.sm, right: tokens.spacing.sm, zIndex: 1 }}>\n <CollapseToggleButton />\n </div>\n ) : null}\n <div style={{ paddingRight: showToggle ? 36 : 0, width: '100%', minWidth: 0 }}>\n {logoSlot}\n {metaBlock}\n </div>\n </div>\n );\n});\n\n// ─── Item ────────────────────────────────────────────────────────────────────\n\nexport interface SideNavItemProps {\n /** Icon name from zendir-ui icon library */\n icon?: IconName | React.ReactNode;\n /** Label text */\n label: string;\n /** Description text displayed beneath the label (hidden in collapsed mode) */\n description?: string;\n /** Small tag/chip displayed after the label (e.g. \"v2\", \"NEW\", \"BETA\") */\n tag?: string;\n /** Tag color variant */\n tagVariant?: 'default' | 'info' | 'success' | 'warning' | 'danger';\n /** Link href (renders <a>) */\n href?: string;\n /** Click handler (renders <button>) */\n onClick?: () => void;\n /** Active state */\n active?: boolean;\n /** Disabled state */\n disabled?: boolean;\n /** Notification badge count */\n badge?: number;\n /** External link indicator */\n external?: boolean;\n /**\n * Astro UX status level — renders a dual-coded indicator (color + shape).\n * Shapes per official Astro UXDS: normal = ● filled circle, standby = ◎ ring,\n * caution = ■ square, serious = ◆ diamond, critical = ▼ triangle, off = · small circle.\n */\n status?: 'off' | 'standby' | 'normal' | 'caution' | 'serious' | 'critical';\n /** Optional status label shown as tooltip or text next to status shape */\n statusLabel?: string;\n /** Right-side slot — arbitrary ReactNode rendered at the end of the item row */\n suffix?: React.ReactNode;\n}\n\nconst TAG_COLORS: Record<string, { bg: string; fg: string; border: string }> = {\n default: { bg: '#ffffff10', fg: '#9590a8', border: '#ffffff15' },\n info: { bg: '#8a2be218', fg: '#c4a0ff', border: '#8a2be230' },\n success: { bg: '#56f00018', fg: '#56f000', border: '#56f00030' },\n warning: { bg: '#fce83a18', fg: '#fce83a', border: '#fce83a30' },\n danger: { bg: '#ff383818', fg: '#ff3838', border: '#ff383830' },\n};\n\nconst SideNavItem = memo(function SideNavItem({\n icon,\n label,\n description,\n tag,\n tagVariant = 'default',\n href,\n onClick,\n active = false,\n disabled = false,\n badge,\n external = false,\n status,\n statusLabel,\n suffix,\n}: SideNavItemProps): React.ReactElement {\n const { tokens } = useTheme();\n const { collapsed, setMobileOpen } = useContext(SideNavContext);\n const [isHovered, setIsHovered] = useState(false);\n \n const handleClick = useCallback((e: React.MouseEvent) => {\n if (disabled) return;\n if (onClick && href && !e.metaKey && !e.ctrlKey && !e.shiftKey) {\n e.preventDefault();\n }\n setMobileOpen(false);\n onClick?.();\n }, [disabled, onClick, href, setMobileOpen]);\n \n // Status-aware accent: when an item has a status, tint active/hover with its color\n const statusColor = status ? (SIDENAV_STATUS_COLORS[status] ?? undefined) : undefined;\n const accentColor = statusColor && active ? statusColor : safeAccentText(tokens.colors.accent.primary);\n \n const hasDescription = !!description && !collapsed;\n \n const iconElement = typeof icon === 'string'\n ? <Icon name={icon as IconName} size={hasDescription ? 22 : 20} color={active ? accentColor : tokens.colors.text.secondary} />\n : icon;\n \n const itemStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: hasDescription ? 'flex-start' : 'center',\n gap: tokens.spacing.sm,\n padding: collapsed\n ? `${tokens.spacing.sm} 0`\n : hasDescription\n ? `10px 16px 10px 12px`\n : `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 12px`,\n justifyContent: collapsed ? 'center' : 'flex-start',\n color: active\n ? accentColor\n : disabled\n ? tokens.colors.text.tertiary\n : tokens.colors.text.secondary,\n backgroundColor: active\n ? `${accentColor}12`\n : isHovered && !disabled\n ? `${accentColor}08`\n : 'transparent',\n fontSize: tokens.typography.fontSize.sm,\n fontWeight: active ? tokens.typography.fontWeight.semibold : tokens.typography.fontWeight.normal,\n fontFamily: tokens.typography.fontFamily.primary,\n cursor: disabled ? 'not-allowed' : 'pointer',\n textDecoration: 'none',\n borderTop: 'none',\n borderRight: 'none',\n borderBottom: 'none',\n borderLeft: active\n ? `3px solid ${accentColor}`\n : '3px solid transparent',\n outline: 'none',\n width: '100%',\n boxSizing: 'border-box',\n transition: tokens.animation.fast,\n position: 'relative',\n opacity: disabled ? 0.5 : 1,\n };\n \n const tagColors = TAG_COLORS[tagVariant] ?? TAG_COLORS.default;\n \n const content = (\n <>\n {/* Icon + collapsed status overlay */}\n {iconElement && (\n <span style={{ flexShrink: 0, display: 'flex', position: 'relative', marginTop: hasDescription ? '2px' : 0 }}>\n {iconElement}\n {/* In collapsed mode, show a small status shape overlaid on the icon (top-left) */}\n {collapsed && status && (\n <span\n style={{\n position: 'absolute',\n top: -3,\n left: -4,\n lineHeight: 0,\n }}\n title={statusLabel ?? status}\n >\n <NavStatusShape status={status} size={7} />\n </span>\n )}\n </span>\n )}\n {!collapsed && (\n <>\n {/* Label + description block */}\n <span style={{ flex: 1, minWidth: 0, overflow: 'hidden' }}>\n <span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <span style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>\n {label}\n </span>\n {tag && (\n <span style={{\n fontSize: '0.6rem',\n fontWeight: tokens.typography.fontWeight.bold,\n color: tagColors.fg,\n backgroundColor: tagColors.bg,\n border: `1px solid ${tagColors.border}`,\n padding: '1px 5px',\n borderRadius: tokens.borderRadius.sm,\n textTransform: 'uppercase',\n letterSpacing: '0.04em',\n flexShrink: 0,\n lineHeight: '1.3',\n whiteSpace: 'nowrap',\n }}>\n {tag}\n </span>\n )}\n </span>\n {description && (\n <span style={{\n display: 'block',\n fontSize: tokens.typography.fontSize.xxs,\n color: tokens.colors.text.tertiary,\n lineHeight: tokens.typography.lineHeight.normal,\n marginTop: '2px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n fontWeight: tokens.typography.fontWeight.normal,\n }}>\n {description}\n </span>\n )}\n </span>\n {/* Right-side trailing elements — badge, status, suffix, external icon */}\n {(badge !== undefined && badge > 0 || status || suffix || external) && (\n <span style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 8,\n flexShrink: 0,\n marginTop: hasDescription ? '2px' : 0,\n }}>\n {/* Badge */}\n {badge !== undefined && badge > 0 && (\n <span style={{\n fontSize: '0.65rem',\n fontWeight: tokens.typography.fontWeight.bold,\n color: '#fff',\n backgroundColor: tokens.colors.status.critical,\n borderRadius: tokens.borderRadius.full,\n minWidth: '18px',\n height: '18px',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '0 5px',\n flexShrink: 0,\n lineHeight: 1,\n boxSizing: 'border-box',\n }}>\n {badge > 99 ? '99+' : badge}\n </span>\n )}\n {/* Status */}\n {status && (\n <span\n style={{ display: 'inline-flex', alignItems: 'center', flexShrink: 0 }}\n role=\"status\"\n aria-label={`Status: ${statusLabel ?? status}`}\n title={statusLabel ?? status}\n >\n <NavStatusShape status={status} size={8} />\n </span>\n )}\n {/* Suffix */}\n {suffix && (\n <span style={{ flexShrink: 0, display: 'inline-flex', alignItems: 'center' }}>\n {suffix}\n </span>\n )}\n {/* External */}\n {external && (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" style={{ flexShrink: 0, opacity: 0.5 }}>\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n )}\n </span>\n )}\n </>\n )}\n </>\n );\n \n const props = {\n style: itemStyle,\n onMouseEnter: () => setIsHovered(true),\n onMouseLeave: () => setIsHovered(false),\n title: collapsed ? label : undefined,\n 'aria-current': active ? ('page' as const) : undefined,\n 'aria-disabled': disabled,\n };\n \n if (href && !disabled) {\n return (\n <a href={href} onClick={handleClick} target={external ? '_blank' : undefined} rel={external ? 'noopener noreferrer' : undefined} {...props}>\n {content}\n </a>\n );\n }\n \n return (\n <button type=\"button\" onClick={handleClick} disabled={disabled} {...props}>\n {content}\n </button>\n );\n});\n\n// ─── Section ─────────────────────────────────────────────────────────────────\n\nexport interface SideNavSectionProps {\n /** Section title */\n title?: string;\n /** Children (SideNav.Item elements) */\n children?: React.ReactNode;\n}\n\nconst SideNavSection = memo(function SideNavSection({\n title,\n children,\n}: SideNavSectionProps): React.ReactElement {\n const { tokens } = useTheme();\n const { collapsed } = useContext(SideNavContext);\n \n return (\n <div style={{ marginTop: tokens.spacing.sm }}>\n {title && !collapsed && (\n <div style={{\n padding: `${tokens.spacing.xs} 16px ${tokens.spacing.xs} 15px`,\n fontSize: tokens.typography.fontSize.xxs,\n fontWeight: tokens.typography.fontWeight.bold,\n color: tokens.colors.text.tertiary,\n textTransform: 'uppercase',\n letterSpacing: '0.08em',\n }}>\n {title}\n </div>\n )}\n {collapsed && title && (\n <div style={{\n width: '60%',\n height: '1px',\n backgroundColor: tokens.colors.border.muted,\n margin: `${tokens.spacing.xs} auto`,\n }} />\n )}\n {children}\n </div>\n );\n});\n\n// ─── Divider ─────────────────────────────────────────────────────────────────\n\nexport interface SideNavDividerProps {\n /** Optional label shown in the center of the divider line */\n label?: string;\n}\n\nconst SideNavDivider = memo(function SideNavDivider({\n label,\n}: SideNavDividerProps): React.ReactElement {\n const { tokens } = useTheme();\n const { collapsed } = useContext(SideNavContext);\n\n if (collapsed) {\n return (\n <div style={{\n width: '60%',\n height: '1px',\n backgroundColor: tokens.colors.border.muted,\n margin: `${tokens.spacing.sm} auto`,\n }} />\n );\n }\n\n if (label) {\n return (\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacing.sm,\n padding: `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 15px`,\n }}>\n <div style={{ flex: 1, height: '1px', backgroundColor: tokens.colors.border.muted }} />\n <span style={{\n fontSize: tokens.typography.fontSize.xxs,\n color: tokens.colors.text.tertiary,\n textTransform: 'uppercase',\n letterSpacing: '0.06em',\n whiteSpace: 'nowrap',\n }}>\n {label}\n </span>\n <div style={{ flex: 1, height: '1px', backgroundColor: tokens.colors.border.muted }} />\n </div>\n );\n }\n\n return (\n <div style={{\n height: '1px',\n backgroundColor: tokens.colors.border.muted,\n margin: `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 15px`,\n }} />\n );\n});\n\n// ─── Footer ──────────────────────────────────────────────────────────────────\n\nexport interface SideNavFooterProps {\n children?: React.ReactNode;\n}\n\nconst SideNavFooter = memo(function SideNavFooter({\n children,\n}: SideNavFooterProps): React.ReactElement {\n const { tokens } = useTheme();\n \n return (\n <div style={{\n marginTop: 'auto',\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n paddingTop: tokens.spacing.xs,\n paddingBottom: tokens.spacing.xs,\n }}>\n {children}\n </div>\n );\n});\n\n// ─── Compound Export ─────────────────────────────────────────────────────────\n\ntype SideNavComponent = typeof SideNavRoot & {\n Header: typeof SideNavHeader;\n Item: typeof SideNavItem;\n Section: typeof SideNavSection;\n Divider: typeof SideNavDivider;\n Footer: typeof SideNavFooter;\n};\n\nexport const SideNav: SideNavComponent = Object.assign(SideNavRoot, {\n Header: SideNavHeader,\n Item: SideNavItem,\n Section: SideNavSection,\n Divider: SideNavDivider,\n Footer: SideNavFooter,\n});\n\nexport default SideNav;\n"],"names":["SideNav","SideNavHeader","SideNavItem","SideNavSection","SideNavDivider","SideNavFooter"],"mappings":"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"}
@@ -49,7 +49,7 @@ export { Typography, Display1, Display2, H1, H2, H3, H4, H5, H6, Body1, Body2, B
49
49
  export type { TypographyProps, TypographyVariant, TypographyElement, TypographyColor, } from './Typography';
50
50
  export { NumberInput } from './NumberInput';
51
51
  export type { NumberInputProps, NumberInputSize, SliderStatus } from './NumberInput';
52
- export { SideNav } from './SideNav';
52
+ export { SideNav, SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX } from './SideNav';
53
53
  export type { SideNavProps, SideNavHeaderProps, SideNavItemProps, SideNavSectionProps, SideNavFooterProps } from './SideNav';
54
54
  export { ToastProvider, useToast, useToastManager } from './Toast';
55
55
  export type { ToastOptions, ToastStatus, ToastPosition, ToastProviderProps } from './Toast';
@@ -14,7 +14,7 @@
14
14
  * Note: @zendir/sdk is optional. All types are provided locally.
15
15
  * Install @zendir/sdk for API client functionality.
16
16
  */
17
- export { Icon, getIconNames, isValidIconName, Button, Input, Select, Toggle, Checkbox, Tooltip, Dialog, Badge, Container, Tabs, Pagination, GlassCard, GLASS_COLOR_OVERLAYS, DataValue, DataValueGroup, MessageStream, AppBar, ColorPickerPanel, getPropertyConfig, formatPropertyLabel, deriveStatus, deriveBatteryStatus, formatPropertyValue, createPropertyConfig, getPropertiesByCategory, PROPERTY_PRESETS, CATEGORY_ICONS, CATEGORY_LABELS, NumberInput, SideNav, ToastProvider, useToast, useToastManager, Popover, Menu, Box, Flex, Grid, Stack, HStack, VStack, Center, Spacer, Divider, useBreakpoint, BREAKPOINTS, resolveResponsive, resolveSpacing, ConfirmDialog, ConfirmProvider, useConfirm, PinInput, CopyButton, useCopyToClipboard, DataTable, DataTableRowDetail, ImageGallery, ChatPanel, parseChatResponse, createChatResponseParser, parseMcpToolResult, CHAT_RESPONSE_TOOL_SCHEMA, CHAT_RESPONSE_MCP_TOOL, CHAT_RESPONSE_JSON_PROMPT, CHAT_RESPONSE_YAML_PROMPT, CHAT_STATUS_RULES_PROMPT, ConnectionForm, SidePanel, HexViewer, REGION_COLORS, REGION_BORDER_COLORS, LimitsBar, LogViewer, PacketViewer, CommandBuilder, FileExplorer, MissionCalendar, ActivityPlanner, Typography, Display1, Display2, H1, H2, H3, H4, H5, H6, Body1, Body2, Body3, Compact, Micro, Mono, DataText, Label, FONT_FAMILY_PRIMARY, FONT_FAMILY_MONO, FONT_WEIGHTS, CardHeader, HeaderIconWithStatus, } from './core';
17
+ export { Icon, getIconNames, isValidIconName, Button, Input, Select, Toggle, Checkbox, Tooltip, Dialog, Badge, Container, Tabs, Pagination, GlassCard, GLASS_COLOR_OVERLAYS, DataValue, DataValueGroup, MessageStream, AppBar, ColorPickerPanel, getPropertyConfig, formatPropertyLabel, deriveStatus, deriveBatteryStatus, formatPropertyValue, createPropertyConfig, getPropertiesByCategory, PROPERTY_PRESETS, CATEGORY_ICONS, CATEGORY_LABELS, NumberInput, SideNav, SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX, ToastProvider, useToast, useToastManager, Popover, Menu, Box, Flex, Grid, Stack, HStack, VStack, Center, Spacer, Divider, useBreakpoint, BREAKPOINTS, resolveResponsive, resolveSpacing, ConfirmDialog, ConfirmProvider, useConfirm, PinInput, CopyButton, useCopyToClipboard, DataTable, DataTableRowDetail, ImageGallery, ChatPanel, parseChatResponse, createChatResponseParser, parseMcpToolResult, CHAT_RESPONSE_TOOL_SCHEMA, CHAT_RESPONSE_MCP_TOOL, CHAT_RESPONSE_JSON_PROMPT, CHAT_RESPONSE_YAML_PROMPT, CHAT_STATUS_RULES_PROMPT, ConnectionForm, SidePanel, HexViewer, REGION_COLORS, REGION_BORDER_COLORS, LimitsBar, LogViewer, PacketViewer, CommandBuilder, FileExplorer, MissionCalendar, ActivityPlanner, Typography, Display1, Display2, H1, H2, H3, H4, H5, H6, Body1, Body2, Body3, Compact, Micro, Mono, DataText, Label, FONT_FAMILY_PRIMARY, FONT_FAMILY_MONO, FONT_WEIGHTS, CardHeader, HeaderIconWithStatus, } from './core';
18
18
  export type { NumberInputProps, NumberInputSize, SliderStatus, StatusThresholds, SideNavProps, SideNavHeaderProps, SideNavItemProps, SideNavSectionProps, SideNavFooterProps, ToastOptions, ToastStatus, ToastPosition, ToastProviderProps, PopoverProps, PopoverPlacement, MenuProps, MenuItemProps, BoxProps, FlexProps, GridProps, StackProps, CenterProps, SpacerProps, DividerProps, Breakpoint, ResponsiveValue, SpacingToken, ConfirmDialogProps, ConfirmOptions, ConfirmStatus, PinInputProps, CopyButtonProps, UseCopyToClipboardReturn, DataTableProps, DataTableColumn, DataTableRowDetailProps, DataTableRowDetailField, ImageGalleryProps, GalleryImage, ChatPanelProps, ChatMessage, ChatBlock, ChatBlockEvent, ChatBlockAlert, ChatBlockTelemetry, ChatBlockProgress, ChatBlockTable, ChatBlockActions, ChatBlockChoice, ChatBlockConfirm, ChatBlockCommand, ChatBlockKV, ChatResponseFormat, ChatResponsePayload, ChatResponseParserOptions, McpToolContent, McpToolResult, ConnectionFormProps, ConnectionConfig, SidePanelProps, SidePanelPosition, HexViewerProps, HexHighlight, HexRegion, DecodedField, PacketHeaderEntry, ByteGrouping, OffsetBase, Endianness, LimitsBarProps, LimitsState, LogViewerProps, LogEntry, LogSeverity, PacketViewerProps, PacketItem, PacketItemLimits, PacketItemLimitsState, PacketViewMode, CommandBuilderProps, CommandParameter, CommandParamType, CommandHistoryEntry, FileExplorerProps, FileNode, FileViewMode, FileSortBy, MissionCalendarProps, CalendarEvent, CalendarTimeline, CalendarViewMode, ActivityStatus, ActivityType, ActivityPlannerProps, ActivityFormData, TypographyProps, TypographyVariant, TypographyElement, TypographyColor, CardHeaderProps, HeaderIconWithStatusProps, IconProps, IconName, ButtonProps, ButtonVariant, ButtonSize, InputProps, InputSize, LabelPlacement, SelectProps, SelectOption, ToggleProps, CheckboxProps, TooltipProps, TooltipPlacement, DialogProps, DialogActionsProps, DialogSize, BadgeProps, BadgeVariant, BadgeSize, ContainerProps, ContainerVariant, ContainerPadding, TabsProps, TabsListProps, TabProps, TabsPanelProps, PaginationProps, GlassCardProps, GlassColorOverlay, DataValueProps, DataValueGroupProps, DataValueVariant, DataValueSize, MessageStreamProps, StreamMessage, AppBarProps, AppBarBranding, ColorPickerPanelProps, PropertyConfig, PropertyKey, PropertyCategory, GlassAccentPosition, } from './core';
19
19
  export { ThemeProvider, useTheme, useThemeTokens, useScrollbarStyles, CardAccentProvider, useCardAccent, getSystemAccentColor, getAccentColorOptions, CARD_ACCENT_COLORS, SPACE_SYSTEM_COLORS, } from './theme';
20
20
  export type { ThemeProviderProps, ThemeContextValue, ThemeVariant, ThemeMode, ThemeTokens, ThemeColors, ThemeAnimation, ThemeFocus, LayoutTokens, BorderTokens, CardAccentKey, CardAccentColor, CardAccentContextValue, CardAccentProviderProps, } from './theme';
@@ -335,8 +335,12 @@ export interface ThemeProviderProps {
335
335
  children: ReactNode;
336
336
  /** Default theme variant */
337
337
  theme?: ThemeVariant;
338
+ /** Alias for `theme` */
339
+ defaultVariant?: ThemeVariant;
338
340
  /** Default color mode */
339
341
  mode?: ThemeMode;
342
+ /** Alias for `mode` */
343
+ defaultMode?: ThemeMode;
340
344
  /** Persist preferences to localStorage */
341
345
  persist?: boolean;
342
346
  }
@@ -367,7 +371,7 @@ export declare function useScrollbarStyles(): React.CSSProperties;
367
371
  * </ThemeProvider>
368
372
  * ```
369
373
  */
370
- export declare function ThemeProvider({ children, theme: defaultTheme, mode: defaultMode, persist, }: ThemeProviderProps): React.ReactElement;
374
+ export declare function ThemeProvider({ children, theme: themeProp, defaultVariant, mode: modeProp, defaultMode: defaultModeProp, persist, }: ThemeProviderProps): React.ReactElement;
371
375
  /**
372
376
  * useTheme - Access theme context
373
377
  *
@@ -891,10 +891,14 @@ function useScrollbarStyles() {
891
891
  }
892
892
  function ThemeProvider({
893
893
  children,
894
- theme: defaultTheme = "hybrid",
895
- mode: defaultMode = "dark",
894
+ theme: themeProp,
895
+ defaultVariant,
896
+ mode: modeProp,
897
+ defaultMode: defaultModeProp,
896
898
  persist = true
897
899
  }) {
900
+ const defaultTheme = themeProp ?? defaultVariant ?? "hybrid";
901
+ const defaultMode = modeProp ?? defaultModeProp ?? "dark";
898
902
  const [theme, setThemeState] = useState(() => {
899
903
  if (persist && typeof window !== "undefined") {
900
904
  const saved = localStorage.getItem("zendir-ui-theme");
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeProvider.js","sources":["../../../src/react/theme/ThemeProvider.tsx"],"sourcesContent":["/**\n * @zendir/ui - Theme Provider\n * \n * Enterprise-grade theming system supporting Astro UX Design System and Zendir themes.\n * Full Tier 3 compliance with official Astro tokens (dark + light themes).\n * \n * Features:\n * - Multiple theme variants (Zen Hybrid default, astro, purple-hue, transparent)\n * - Light and dark modes\n * - Animation tokens with reduced-motion support\n * - Focus ring styles for accessibility\n * - CSS variable injection\n * - Local storage persistence\n */\n\nimport React, { createContext, useContext, useState, useEffect, useMemo, ReactNode } from 'react';\n\nfunction adjustHexBrightness(hex: string, factor: number): string {\n const normalized = hex.replace('#', '').trim();\n const expanded = normalized.length === 3\n ? normalized.split('').map(ch => ch + ch).join('')\n : normalized;\n\n if (!/^[0-9a-fA-F]{6}$/.test(expanded)) {\n return hex;\n }\n\n const clamp = (value: number) => Math.max(0, Math.min(255, Math.round(value)));\n const r = clamp(parseInt(expanded.slice(0, 2), 16) * factor);\n const g = clamp(parseInt(expanded.slice(2, 4), 16) * factor);\n const b = clamp(parseInt(expanded.slice(4, 6), 16) * factor);\n\n const toHex = (value: number) => value.toString(16).padStart(2, '0');\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\nexport type ThemeVariant = 'astro' | 'purple-hue' | 'hybrid' | 'transparent' | 'transparent-bold' | 'transparent-minimal';\nexport type ThemeMode = 'light' | 'dark';\n\nexport interface ThemeColors {\n background: {\n base: string;\n surface: string;\n elevated: string;\n overlay: string;\n };\n border: {\n default: string;\n muted: string;\n focus: string;\n /** Transparent theme: thin faded top-to-bottom border (box-shadow, use with border: 'none') */\n fadedBoxShadow?: string;\n /** Card border style (computed from theme – solid or transparent faded). Use ...tokens.colors.border.cardStyle */\n cardStyle?: React.CSSProperties;\n /** Card border for dashed/empty state. Use ...tokens.colors.border.cardStyleDashed */\n cardStyleDashed?: React.CSSProperties;\n /** Card border using default color (e.g. NavBall, EclipseTimer). Use ...tokens.colors.border.cardStyleDefault */\n cardStyleDefault?: React.CSSProperties;\n };\n text: {\n primary: string;\n secondary: string;\n tertiary: string;\n /** Muted/placeholder text (alias for tertiary when not set) */\n muted?: string;\n inverse: string;\n };\n status: {\n normal: string;\n standby: string;\n caution: string;\n serious: string;\n critical: string;\n off: string;\n };\n semantic: {\n success: string;\n warning: string;\n error: string;\n info: string;\n };\n accent: {\n primary: string;\n secondary: string;\n tertiary: string;\n };\n interactive: {\n default: string;\n hover: string;\n active: string;\n disabled: string;\n /** Transparent theme: button/control bg (low opacity purple) when not hovered */\n transparentDefault?: string;\n /** Transparent theme: button/control bg on hover (higher opacity purple) */\n transparentHover?: string;\n /** Transparent theme: input field bg (semi-transparent purple tint) */\n transparentInputBg?: string;\n };\n}\n\nexport interface ThemeAnimation {\n /** Fast transitions (hover states) - 150ms */\n fast: string;\n /** Normal transitions (most interactions) - 250ms */\n normal: string;\n /** Slow transitions (page/mode changes) - 400ms */\n slow: string;\n /** Spring animation for playful interactions */\n spring: string;\n /** Easing function */\n easing: {\n default: string;\n in: string;\n out: string;\n inOut: string;\n };\n /** Duration values in milliseconds */\n duration: {\n instant: number;\n fast: number;\n normal: number;\n slow: number;\n };\n}\n\nexport interface ThemeFocus {\n /** Focus ring color */\n color: string;\n /** Focus ring width */\n width: string;\n /** Focus ring offset */\n offset: string;\n /** Full focus ring CSS */\n ring: string;\n /** Focus ring style object */\n style: React.CSSProperties;\n}\n\n/**\n * Astro UX Typography Style Token\n * Based on https://www.astrouxds.com/foundations/typography/\n */\nexport interface TypographyStyle {\n fontSize: string;\n fontWeight: number;\n letterSpacing: string;\n lineHeight: string;\n}\n\nexport interface ThemeTokens {\n colors: ThemeColors;\n spacing: {\n /** 2px — micro adjustments, decorative offsets */\n xxs: string;\n /** 4px — tight gaps, icon padding */\n xs: string;\n /** 8px — compact spacing, small gaps */\n sm: string;\n /** 12px — form fields, compact cards (between sm and md) */\n smd: string;\n /** 16px — default card padding, section gaps */\n md: string;\n /** 20px — slightly generous spacing */\n mdl: string;\n /** 24px — generous spacing, content area padding */\n lg: string;\n /** 32px — large section gaps */\n xl: string;\n /** 48px — extra large spacing */\n xxl: string;\n };\n borderRadius: {\n none: string;\n /** 1px — very subtle rounding */\n xs: string;\n /** 2px — small elements, badges, tooltips */\n sm: string;\n /** 4px — inputs, selects, standard controls */\n md: string;\n /** 8px — cards, containers */\n lg: string;\n /** 12px — prominent surfaces, modals */\n xl: string;\n /** 9999px — pills, fully rounded */\n full: string;\n };\n /** Standardised element heights for interactive controls */\n elementSize: {\n /** 28px — compact controls */\n sm: string;\n /** 36px — default controls */\n md: string;\n /** 44px — prominent controls, touch targets */\n lg: string;\n };\n typography: {\n fontFamily: {\n primary: string;\n mono: string;\n };\n // Astro UX Typography Tokens (rem-based)\n // https://www.astrouxds.com/foundations/typography/\n display: {\n 1: TypographyStyle;\n 2: TypographyStyle;\n };\n heading: {\n 1: TypographyStyle;\n '1Bold': TypographyStyle;\n 2: TypographyStyle;\n 3: TypographyStyle;\n 4: TypographyStyle;\n 5: TypographyStyle;\n 6: TypographyStyle;\n };\n body: {\n 1: TypographyStyle;\n '1Bold': TypographyStyle;\n 2: TypographyStyle;\n '2Bold': TypographyStyle;\n 3: TypographyStyle;\n '3Bold': TypographyStyle;\n };\n control: {\n 1: TypographyStyle;\n '1Bold': TypographyStyle;\n };\n // Legacy/convenience tokens (keeping for backward compatibility)\n fontSize: {\n micro: string; // 9px - very tight spaces\n xxs: string; // 10px - compact labels\n xs: string;\n sm: string;\n base: string;\n md: string;\n lg: string;\n xl: string;\n xxl: string;\n xxxl: string;\n };\n fontWeight: {\n light: number;\n normal: number;\n medium: number;\n semibold: number;\n bold: number;\n };\n lineHeight: {\n tight: string;\n normal: string;\n relaxed: string;\n };\n letterSpacing: {\n tight: string;\n normal: string;\n wide: string;\n };\n };\n shadows: {\n none: string;\n sm: string;\n md: string;\n lg: string;\n xl: string;\n glow: (color: string) => string;\n };\n animation: ThemeAnimation;\n focus: ThemeFocus;\n /** Semantic layout tokens for consistent spacing across cards, forms, and sections */\n layout: LayoutTokens;\n /** Semantic border tokens for consistent element styling (derived from theme colors) */\n borders: BorderTokens;\n}\n\n// ============================================================================\n// Layout Tokens Interface\n// Semantic spacing for cards, sections, forms, and nested surfaces.\n// These decouple layout intent from raw pixel values, enabling consistent\n// spacing across all consuming applications.\n// ============================================================================\n\nexport interface LayoutTokens {\n /** Card / panel container spacing */\n card: {\n /** Internal padding of card containers */\n padding: string;\n /** Gap between cards in grid layouts (desktop) */\n gap: string;\n /** Gap between cards in grid layouts (mobile / compact) */\n gapCompact: string;\n /** Card heading: icon size, title typography, gap — single system for all cards/charts */\n heading: {\n iconSize: number;\n iconSizeCompact: number;\n titleFontSize: string;\n /** Smaller title for chart headers (e.g. Power Trends) so they match card visual weight */\n titleFontSizeChart: string;\n titleFontWeight: number;\n gap: number;\n };\n };\n /** Section heading spacing (heading + divider + content) */\n section: {\n /** Padding below heading text, above the divider border */\n headerPaddingBottom: string;\n /** Margin below the divider border, before content */\n headerMarginBottom: string;\n /** Padding above the first content element after heading */\n contentPaddingTop: string;\n };\n /** Form and input field spacing */\n form: {\n /** Vertical gap between stacked form fields */\n fieldGap: string;\n /** Horizontal gap between side-by-side inline fields */\n inlineGap: string;\n /** Padding inside grouped / nested field containers */\n groupPadding: string;\n /** Gap between items within a field group */\n groupGap: string;\n /** Gap between label text and helper icons (e.g. tooltip) */\n labelGap: string;\n };\n /** Nested surface / panel spacing (e.g. grouped fields within a card) */\n surface: {\n /** Internal padding of nested surfaces */\n padding: string;\n /** Border radius of nested surfaces */\n borderRadius: string;\n /** Gap between items in compact nested surfaces */\n gap: string;\n };\n}\n\n// ============================================================================\n// Border Tokens Interface\n// Standardised border widths, element borders, focus rings, and dividers.\n// These are DERIVED from theme colors at runtime via computeBorderTokens().\n// ============================================================================\n\nexport interface BorderTokens {\n /** Border widths — standardised across all interactive elements */\n width: {\n /** Thin (1px) — inputs, cards, dividers, dropdowns */\n thin: string;\n /** Medium (1.5px) — secondary buttons, emphasised inputs */\n medium: string;\n /** Thick (2px) — checkboxes, accent borders, active tabs */\n thick: string;\n };\n /** Pre-computed input / control borders (width + style + color) */\n input: {\n /** Default resting state */\n default: string;\n /** Hover state (accent at 50% opacity) */\n hover: string;\n /** Focused state (full accent) */\n focus: string;\n /** Error / critical state */\n error: string;\n };\n /** Focus ring box-shadow values for interactive elements */\n focusRing: {\n /** Standard ring for inputs and selects */\n default: string;\n /** Ring for buttons (double-ring pattern) */\n button: string;\n /** Subtle ring for checkboxes, tabs, toggles */\n subtle: string;\n };\n /** Section divider border (headings, dialog headers/footers, tab bars) */\n divider: string;\n /** Dropdown / popover container border */\n dropdown: string;\n /** Separator line inside elements (unit separators, table rows) */\n separator: string;\n}\n\n/**\n * Derives border tokens from a theme's resolved colors.\n * Called once per theme change inside the ThemeProvider useMemo.\n */\nfunction computeBorderTokens(colors: ThemeColors): BorderTokens {\n const thin = '1px';\n const medium = '1.5px';\n const thick = '2px';\n const accent = colors.accent.primary;\n const muted = colors.border.muted;\n const critical = colors.status.critical;\n const bgBase = colors.background.base;\n\n return {\n width: { thin, medium, thick },\n input: {\n default: `${thin} solid ${muted}`,\n hover: `${thin} solid ${accent}80`,\n focus: `${thin} solid ${accent}`,\n error: `${thin} solid ${critical}`,\n },\n focusRing: {\n // WCAG 2.4.13: focus indicators ≥ 3:1 contrast — raised from 20%/30% to 50%/60%\n default: `0 0 0 3px ${accent}50, 0 0 20px ${accent}15`,\n button: `0 0 0 2px ${bgBase}, 0 0 0 4px ${accent}`,\n subtle: `0 0 0 2px ${accent}60`,\n },\n divider: `${thin} solid ${muted}`,\n dropdown: `${thin} solid ${accent}30`,\n separator: `${thin} solid ${muted}`,\n };\n}\n\n/**\n * Base theme type used for static theme definitions.\n * `borders` is omitted because it is derived from colors at runtime\n * inside the ThemeProvider useMemo (see computeBorderTokens).\n */\ntype ThemeTokensBase = Omit<ThemeTokens, 'borders'>;\n\n// ============================================================================\n// Animation Tokens (Shared)\n// ============================================================================\n\nconst animationTokens: ThemeAnimation = {\n fast: 'all 150ms cubic-bezier(0.4, 0, 0.2, 1)',\n normal: 'all 250ms cubic-bezier(0.4, 0, 0.2, 1)',\n slow: 'all 400ms cubic-bezier(0.4, 0, 0.2, 1)',\n spring: 'all 300ms cubic-bezier(0.34, 1.56, 0.64, 1)',\n easing: {\n default: 'cubic-bezier(0.4, 0, 0.2, 1)',\n in: 'ease-in',\n out: 'ease-out',\n inOut: 'ease-in-out',\n },\n duration: {\n instant: 0,\n fast: 150,\n normal: 250,\n slow: 400,\n },\n};\n\n// ============================================================================\n// Focus Tokens (Dark)\n// ============================================================================\n\nconst focusTokensDark: ThemeFocus = {\n color: '#4dacff',\n width: '2px',\n offset: '2px',\n ring: '0 0 0 2px #4dacff',\n style: {\n outline: '2px solid #4dacff',\n outlineOffset: '2px',\n },\n};\n\nconst focusTokensLight: ThemeFocus = {\n color: '#0066cc',\n width: '2px',\n offset: '2px',\n ring: '0 0 0 2px #0066cc',\n style: {\n outline: '2px solid #0066cc',\n outlineOffset: '2px',\n },\n};\n\n// ============================================================================\n// Shadow Tokens\n// ============================================================================\n\nconst shadowsDark = {\n none: 'none',\n sm: '0 1px 2px rgba(0, 0, 0, 0.3)',\n md: '0 4px 8px rgba(0, 0, 0, 0.4)',\n lg: '0 8px 16px rgba(0, 0, 0, 0.5)',\n xl: '0 16px 32px rgba(0, 0, 0, 0.6)',\n glow: (color: string) => `0 0 20px ${color}40, 0 0 40px ${color}20`,\n};\n\nconst shadowsLight = {\n none: 'none',\n sm: '0 1px 2px rgba(0, 0, 0, 0.1)',\n md: '0 4px 8px rgba(0, 0, 0, 0.15)',\n lg: '0 8px 16px rgba(0, 0, 0, 0.2)',\n xl: '0 16px 32px rgba(0, 0, 0, 0.25)',\n glow: (color: string) => `0 0 20px ${color}30, 0 0 40px ${color}15`,\n};\n\n// ============================================================================\n// Layout Tokens (Shared)\n// Semantic layout spacing based on 4px grid. Shared across all themes.\n// ============================================================================\n\nconst layoutTokens: LayoutTokens = {\n card: {\n padding: '16px', // 4 × 4px\n gap: '24px', // 6 × 4px — desktop grid gap (matches outer padding)\n gapCompact: '16px', // 4 × 4px — mobile grid gap\n heading: {\n iconSize: 18, // default card header icon (px) — matches ISS/Telemetry card header size\n iconSizeCompact: 16, // compact (e.g. chart inline header)\n titleFontSize: '1rem', // card titles (ISS, Telemetry, Mission) — reduced from 1.125rem\n titleFontSizeChart: '0.875rem', // chart titles (Power Trends) — slightly smaller\n titleFontWeight: 500,\n gap: 8, // gap between icon and title (px)\n },\n },\n section: {\n headerPaddingBottom: '8px', // 2 × 4px\n headerMarginBottom: '0px',\n contentPaddingTop: '8px', // 2 × 4px\n },\n form: {\n fieldGap: '12px', // 3 × 4px — between stacked fields\n inlineGap: '12px', // 3 × 4px — between side-by-side fields\n groupPadding: '12px', // 3 × 4px — inside grouped containers\n groupGap: '12px', // 3 × 4px — within group items\n labelGap: '3px', // label text ↔ tooltip icon\n },\n surface: {\n padding: '12px', // 3 × 4px\n borderRadius: '12px', // 3 × 4px\n gap: '8px', // 2 × 4px\n },\n};\n\n// ============================================================================\n// Astro UX Dark Theme\n// ============================================================================\n\nconst astroThemeDark: ThemeTokensBase = {\n colors: {\n background: {\n base: '#101923',\n surface: '#1b2d3e',\n elevated: '#243b53',\n overlay: 'rgba(16, 25, 35, 0.95)',\n },\n border: {\n default: '#2b659b',\n muted: '#172635',\n focus: '#4dacff',\n },\n text: {\n primary: '#ffffff',\n secondary: '#b7c5d3',\n tertiary: '#8fa4b7',\n muted: '#8fa4b7',\n inverse: '#1b2d3e',\n },\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#4dacff',\n },\n accent: {\n primary: '#4dacff',\n secondary: '#56f000',\n tertiary: '#a371f7',\n },\n interactive: {\n default: '#4dacff',\n hover: '#92cbff',\n active: '#0066cc',\n disabled: '#6b7280',\n },\n },\n spacing: {\n xxs: '2px',\n xs: '4px',\n sm: '8px',\n smd: '12px',\n md: '16px',\n mdl: '20px',\n lg: '24px',\n xl: '32px',\n xxl: '48px',\n },\n borderRadius: {\n none: '0',\n xs: '1px',\n sm: '2px',\n md: '4px',\n lg: '8px',\n xl: '12px',\n full: '9999px',\n },\n elementSize: {\n sm: '28px',\n md: '36px',\n lg: '44px',\n },\n typography: {\n /**\n * Font families per AstroUXDS specification\n * @see https://www.astrouxds.com/foundations/typography/\n */\n fontFamily: {\n /** Primary font: Roboto with comprehensive system fallbacks */\n primary: '\"Roboto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif',\n /** Monospace font: Roboto Mono for data/code with system fallbacks */\n mono: '\"Roboto Mono\", \"SF Mono\", \"Consolas\", \"Liberation Mono\", monospace',\n },\n // Astro UX Display Styles\n // https://www.astrouxds.com/foundations/typography/\n display: {\n 1: { fontSize: '3.75rem', fontWeight: 300, letterSpacing: '-0.5px', lineHeight: '4.375rem' },\n 2: { fontSize: '3rem', fontWeight: 400, letterSpacing: '0', lineHeight: '3.5rem' },\n },\n // Astro UX Heading Styles\n heading: {\n 1: { fontSize: '2.125rem', fontWeight: 400, letterSpacing: '0.25px', lineHeight: '2.5rem' },\n '1Bold': { fontSize: '2.125rem', fontWeight: 700, letterSpacing: '0.25px', lineHeight: '2rem' },\n 2: { fontSize: '1.5rem', fontWeight: 400, letterSpacing: '0', lineHeight: '1.75rem' },\n 3: { fontSize: '1.25rem', fontWeight: 500, letterSpacing: '0.15px', lineHeight: '1.5rem' },\n 4: { fontSize: '1.25rem', fontWeight: 300, letterSpacing: '0.15px', lineHeight: '1.5rem' },\n 5: { fontSize: '1.125rem', fontWeight: 400, letterSpacing: '0', lineHeight: '1.5rem' },\n 6: { fontSize: '1.125rem', fontWeight: 300, letterSpacing: '0', lineHeight: '1.5rem' },\n },\n // Astro UX Body Styles\n body: {\n 1: { fontSize: '1rem', fontWeight: 400, letterSpacing: '0.5px', lineHeight: '1.5rem' },\n '1Bold': { fontSize: '1rem', fontWeight: 700, letterSpacing: '0.5px', lineHeight: '1.5rem' },\n 2: { fontSize: '0.875rem', fontWeight: 400, letterSpacing: '0.5px', lineHeight: '1.25rem' },\n '2Bold': { fontSize: '0.875rem', fontWeight: 700, letterSpacing: '0.5px', lineHeight: '1.25rem' },\n 3: { fontSize: '0.75rem', fontWeight: 400, letterSpacing: '0', lineHeight: '1rem' },\n '3Bold': { fontSize: '0.75rem', fontWeight: 700, letterSpacing: '0', lineHeight: '1rem' },\n },\n // Astro UX Control Body Styles\n control: {\n 1: { fontSize: '1rem', fontWeight: 400, letterSpacing: '0.5px', lineHeight: '1.25rem' },\n '1Bold': { fontSize: '1rem', fontWeight: 700, letterSpacing: '0.5px', lineHeight: '1.25rem' },\n },\n // Legacy convenience tokens (rem-based for Astro compliance)\n // Note: Use Typography component for new code\n fontSize: {\n micro: '0.5625rem', // 9px - very tight spaces\n xxs: '0.625rem', // 10px - compact labels (xs in old system)\n xs: '0.625rem', // 10px - compact (kept for backward compatibility)\n sm: '0.75rem', // 12px (Body 3)\n base: '0.875rem', // 14px (Body 2)\n md: '0.875rem', // 14px (Body 2)\n lg: '1rem', // 16px (Body 1)\n xl: '1.25rem', // 20px (Heading 3/4)\n xxl: '1.5rem', // 24px (Heading 2)\n xxxl: '2.125rem', // 34px (Heading 1)\n },\n /**\n * Font weights per AstroUXDS specification\n * Only 300, 400, 500, 700 are officially supported\n * @see https://www.astrouxds.com/foundations/typography/\n */\n fontWeight: {\n light: 300,\n normal: 400,\n medium: 500,\n /** @deprecated Use medium (500) instead - Astro spec only supports 300, 400, 500, 700 */\n semibold: 500, // Changed from 600 to 500 for Astro compliance\n bold: 700,\n },\n lineHeight: {\n tight: '1.25rem',\n normal: '1.5rem',\n relaxed: '1.75rem',\n },\n letterSpacing: {\n tight: '-0.5px',\n normal: '0',\n wide: '0.5px',\n },\n },\n shadows: shadowsDark,\n animation: animationTokens,\n focus: focusTokensDark,\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Astro UX Light Theme\n// ============================================================================\n\nconst astroThemeLight: ThemeTokensBase = {\n colors: {\n background: {\n base: '#eaeef4',\n surface: '#f5f8fc',\n elevated: '#ffffff',\n overlay: 'rgba(234, 238, 244, 0.95)',\n },\n border: {\n default: '#2b659b',\n muted: '#d1d5db',\n focus: '#0066cc',\n },\n text: {\n primary: '#1b2d3e',\n secondary: '#51667c',\n tertiary: '#556a7c', // WCAG AA: 4.81:1 on #eaeef4, 5.24:1 on #f5f8fc, 5.61:1 on #fff (was #8fa4b7 → 2.25:1 FAIL)\n muted: '#556a7c', // WCAG AA compliant (was #8fa4b7)\n inverse: '#ffffff',\n },\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#4dacff',\n },\n accent: {\n primary: '#0066cc',\n secondary: '#56f000',\n tertiary: '#7c3aed',\n },\n interactive: {\n default: '#0066cc',\n hover: '#0052a3',\n active: '#003d7a',\n disabled: '#a4abb6',\n },\n },\n spacing: astroThemeDark.spacing,\n borderRadius: astroThemeDark.borderRadius,\n elementSize: astroThemeDark.elementSize,\n typography: astroThemeDark.typography,\n shadows: shadowsLight,\n animation: animationTokens,\n focus: focusTokensLight,\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Hybrid Theme (Zendir Background + Astro Status + Purple Accents)\n// Modern, award-winning design with Zendir purple personality\n// ============================================================================\n\nconst focusTokensPurpleHue: ThemeFocus = {\n color: '#8b5cf6',\n width: '2px',\n offset: '2px',\n ring: '0 0 0 2px #8b5cf6',\n style: {\n outline: '2px solid #8b5cf6',\n outlineOffset: '2px',\n },\n};\n\nconst hybridTheme: ThemeTokensBase = {\n colors: {\n background: {\n base: '#09090b',\n surface: 'rgba(24, 24, 27, 0.98)',\n elevated: 'rgba(39, 39, 42, 0.98)',\n overlay: 'rgba(0, 0, 0, 0.85)',\n },\n border: {\n default: 'rgba(139, 92, 246, 0.3)', // Purple tint\n muted: 'rgba(63, 63, 70, 0.5)',\n focus: '#8b5cf6', // Zendir purple\n },\n text: {\n primary: '#ffffff',\n secondary: '#a1a1aa',\n tertiary: '#8e8e96', // WCAG AA: 6.12:1 on #09090b, 5.45:1 on #18181b, 4.58:1 on #27272a (was #71717a → 4.07:1 FAIL)\n muted: '#8e8e96', // WCAG AA compliant (was #71717a)\n inverse: '#09090b',\n },\n // Astro UXD Status Colors (unchanged for compliance)\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#8b5cf6', // Purple for info\n },\n // Zendir Purple Accent Palette\n accent: {\n primary: '#8b5cf6', // Vibrant purple\n secondary: '#a78bfa', // Light purple\n tertiary: '#7c3aed', // Deep purple\n },\n interactive: {\n default: '#8b5cf6',\n hover: '#a78bfa',\n active: '#7c3aed',\n disabled: '#52525b',\n },\n },\n spacing: astroThemeDark.spacing,\n borderRadius: {\n none: '0',\n xs: '2px',\n sm: '4px',\n md: '6px',\n lg: '10px',\n xl: '14px',\n full: '9999px',\n },\n elementSize: astroThemeDark.elementSize,\n typography: astroThemeDark.typography,\n shadows: {\n ...shadowsDark,\n glow: (color: string) => `0 0 20px ${color}50, 0 0 40px ${color}25, 0 4px 12px ${color}20`,\n },\n animation: animationTokens,\n focus: focusTokensPurpleHue,\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Purple-Hue Theme - Full Purple Personality\n// Award-winning dark theme with purple accents\n// ============================================================================\n\nconst purpleHueTheme: ThemeTokensBase = {\n colors: {\n background: {\n base: '#0a0a0f',\n surface: 'rgba(18, 18, 28, 0.98)',\n elevated: 'rgba(28, 28, 42, 0.98)',\n overlay: 'rgba(0, 0, 0, 0.9)',\n },\n border: {\n default: 'rgba(139, 92, 246, 0.25)',\n muted: 'rgba(55, 48, 82, 0.5)',\n focus: '#8b5cf6',\n },\n text: {\n primary: '#fafafa',\n secondary: '#a1a1aa',\n tertiary: '#8e8e96', // WCAG AA: 6.08:1 on #0a0a0f, 5.02:1 on elevated (was #71717a → 4.05:1 FAIL)\n muted: '#8e8e96', // WCAG AA compliant (was #71717a)\n inverse: '#0a0a0f',\n },\n // Astro UXD Status Colors (for compliance)\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#a78bfa',\n },\n // Zendir Purple Accent Palette\n accent: {\n primary: '#8b5cf6', // Vibrant purple\n secondary: '#a78bfa', // Light purple\n tertiary: '#7c3aed', // Deep purple\n },\n interactive: {\n default: '#8b5cf6',\n hover: '#a78bfa',\n active: '#7c3aed',\n disabled: '#52525b',\n },\n },\n spacing: astroThemeDark.spacing,\n borderRadius: {\n none: '0',\n xs: '2px',\n sm: '4px',\n md: '6px',\n lg: '10px',\n xl: '14px',\n full: '9999px',\n },\n elementSize: astroThemeDark.elementSize,\n // Same typography as hybrid (Astro UX font stack with full fallbacks) for consistent card font across themes\n typography: astroThemeDark.typography,\n shadows: {\n ...shadowsDark,\n glow: (color: string) => `0 0 25px ${color}60, 0 0 50px ${color}30, 0 4px 16px ${color}25`,\n },\n animation: animationTokens,\n focus: {\n ...focusTokensPurpleHue,\n },\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Transparent Purple-Hue Theme - Glassmorphic Panels\n// Optimized for glass card overlays with transparent backgrounds\n// ============================================================================\n\nconst transparentTheme: ThemeTokensBase = {\n colors: {\n background: {\n // Highly transparent backgrounds for glass effect\n base: 'rgba(8, 12, 20, 0.95)',\n surface: 'rgba(15, 20, 35, 0.85)',\n elevated: 'rgba(25, 35, 55, 0.80)',\n overlay: 'rgba(0, 0, 0, 0.75)',\n },\n border: {\n // Purple accent borders (Zendir brand)\n default: 'rgba(139, 92, 246, 0.25)',\n muted: 'rgba(139, 92, 246, 0.15)',\n focus: '#8b5cf6',\n // Thin faded card border with purple hint\n fadedBoxShadow: 'inset 0 1px 0 rgba(139, 92, 246, 0.12), inset 0 -1px 0 rgba(0, 0, 0, 0.05), inset 1px 0 0 rgba(139, 92, 246, 0.06), inset -1px 0 0 rgba(139, 92, 246, 0.06)',\n },\n text: {\n primary: '#f0f4f8',\n secondary: '#94a3b8',\n tertiary: '#7b8da1', // WCAG AA: 5.71:1 on base, 5.34:1 on elevated (was #64748b → 3.66:1 FAIL)\n muted: '#7b8da1', // WCAG AA compliant (was #64748b)\n inverse: '#0f172a',\n },\n // Astro UXD Status Colors\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#8b5cf6',\n },\n // Purple accent (matching hybrid theme for consistency)\n accent: {\n primary: '#8b5cf6', // Vibrant purple\n secondary: '#a78bfa', // Light purple\n tertiary: '#7c3aed', // Deep purple\n },\n interactive: {\n default: '#8b5cf6', // Purple for interactive elements\n hover: '#a78bfa', // Light purple on hover\n active: '#7c3aed', // Deep purple on active\n disabled: '#475569',\n // Purple-hue transparent backgrounds for buttons/inputs (transparent + transparent-bold)\n transparentDefault: 'rgba(139, 92, 246, 0.12)',\n transparentHover: 'rgba(139, 92, 246, 0.32)',\n transparentInputBg: 'rgba(139, 92, 246, 0.08)',\n },\n },\n spacing: astroThemeDark.spacing,\n borderRadius: {\n none: '0',\n xs: '2px',\n sm: '4px',\n md: '8px',\n lg: '12px',\n xl: '16px',\n full: '9999px',\n },\n elementSize: astroThemeDark.elementSize,\n // Same typography as hybrid for consistent card font across themes\n typography: astroThemeDark.typography,\n shadows: {\n ...shadowsDark,\n // Enhanced glow shadows for glass effect\n glow: (color: string) => `0 0 30px ${color}50, 0 0 60px ${color}25, 0 4px 20px rgba(0,0,0,0.4)`,\n },\n animation: animationTokens,\n focus: {\n color: '#8b5cf6', // Purple focus ring\n width: '2px',\n offset: '2px',\n ring: '0 0 0 2px #8b5cf6',\n style: {\n outline: '2px solid #8b5cf6',\n outlineOffset: '2px',\n },\n },\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Transparent Minimal Theme - Ultra-clean glassmorphic panels\n// Extremely subtle borders, minimal visual noise, clean dark surfaces\n// ============================================================================\n\nconst transparentMinimalTheme: ThemeTokensBase = {\n colors: {\n background: {\n // Same as transparent theme\n base: 'rgba(8, 12, 20, 0.95)',\n surface: 'rgba(15, 20, 35, 0.85)',\n elevated: 'rgba(25, 35, 55, 0.80)',\n overlay: 'rgba(0, 0, 0, 0.75)',\n },\n border: {\n // Accent-colored borders for minimal theme (Zendir purple)\n default: 'rgba(139, 92, 246, 0.25)',\n muted: 'rgba(139, 92, 246, 0.15)',\n focus: '#8b5cf6',\n // Subtle card border using accent color\n fadedBoxShadow: 'inset 0 1px 0 rgba(139, 92, 246, 0.1), inset 0 -1px 0 rgba(0, 0, 0, 0.1), inset 1px 0 0 rgba(139, 92, 246, 0.05), inset -1px 0 0 rgba(139, 92, 246, 0.05)',\n },\n text: {\n primary: '#f0f4f8',\n secondary: '#94a3b8',\n tertiary: '#7b8da1', // WCAG AA: 5.71:1 on base, 5.34:1 on elevated (was #64748b → 3.66:1 FAIL)\n muted: '#7b8da1', // WCAG AA compliant (was #64748b)\n inverse: '#0f172a',\n },\n // Astro UXD Status Colors\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#8b5cf6',\n },\n // Purple accent (matching transparent theme for consistency)\n accent: {\n primary: '#8b5cf6', // Vibrant purple\n secondary: '#a78bfa', // Light purple\n tertiary: '#7c3aed', // Deep purple\n },\n interactive: {\n default: '#8b5cf6', // Purple for interactive elements\n hover: '#a78bfa', // Light purple on hover\n active: '#7c3aed', // Deep purple on active\n disabled: '#475569',\n // Purple-hue transparent backgrounds for buttons/inputs (same as transparent theme)\n transparentDefault: 'rgba(139, 92, 246, 0.12)',\n transparentHover: 'rgba(139, 92, 246, 0.32)',\n transparentInputBg: 'rgba(139, 92, 246, 0.08)',\n },\n },\n spacing: astroThemeDark.spacing,\n borderRadius: {\n none: '0',\n xs: '2px',\n sm: '4px',\n md: '8px',\n lg: '12px',\n xl: '16px',\n full: '9999px',\n },\n elementSize: astroThemeDark.elementSize,\n // Same typography as hybrid for consistent card font across themes\n typography: astroThemeDark.typography,\n shadows: {\n ...shadowsDark,\n // Same glow as transparent theme\n glow: (color: string) => `0 0 30px ${color}50, 0 0 60px ${color}25, 0 4px 20px rgba(0,0,0,0.4)`,\n },\n animation: animationTokens,\n focus: {\n color: '#8b5cf6', // Purple focus ring\n width: '2px',\n offset: '2px',\n ring: '0 0 0 2px #8b5cf6',\n style: {\n outline: '2px solid #8b5cf6',\n outlineOffset: '2px',\n },\n },\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Theme Context\n// ============================================================================\n\nexport interface ThemeContextValue {\n theme: ThemeVariant;\n mode: ThemeMode;\n tokens: ThemeTokens;\n prefersReducedMotion: boolean;\n /** Custom accent color override (null = use theme default) */\n accentColor: string | null;\n setTheme: (theme: ThemeVariant) => void;\n setMode: (mode: ThemeMode) => void;\n toggleMode: () => void;\n /** Override the accent color for the current theme */\n setAccentColor: (color: string | null) => void;\n}\n\nconst ThemeContext = createContext<ThemeContextValue | undefined>(undefined);\n\nexport interface ThemeProviderProps {\n children: ReactNode;\n /** Default theme variant */\n theme?: ThemeVariant;\n /** Default color mode */\n mode?: ThemeMode;\n /** Persist preferences to localStorage */\n persist?: boolean;\n}\n\n// ============================================================================\n// Scrollbar Styling System\n// ============================================================================\n// Generates global CSS for thin, elegant, theme-aware scrollbars.\n//\n// Features:\n// - Ultra-thin (6px) scrollbar tracks with soft border radius\n// - Accent-colored thumb with hover/active brightness shifts\n// - Semi-transparent track that blends into the surface\n// - Auto-hide behaviour on modern browsers (overlay mode)\n// - Firefox support via scrollbar-width / scrollbar-color\n// - WCAG 2.1 AA compliant: sufficient contrast, respects reduced-motion\n// - Smooth transitions (disabled when prefers-reduced-motion)\n// - Scoped .zendir-scroll utility class for individual containers\n// ============================================================================\n\n/**\n * Converts a hex color to an rgba string helper.\n * Accepts 3/6/8-char hex codes (#rgb, #rrggbb, #rrggbbaa).\n */\nfunction hexToRgba(hex: string, alpha: number): string {\n const clean = hex.replace('#', '');\n let r: number, g: number, b: number;\n if (clean.length === 3) {\n r = parseInt(clean[0] + clean[0], 16);\n g = parseInt(clean[1] + clean[1], 16);\n b = parseInt(clean[2] + clean[2], 16);\n } else {\n r = parseInt(clean.slice(0, 2), 16);\n g = parseInt(clean.slice(2, 4), 16);\n b = parseInt(clean.slice(4, 6), 16);\n }\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\nfunction buildScrollbarCSS(tokens: ThemeTokens, mode: ThemeMode, reducedMotion: boolean): string {\n const accent = tokens.colors.accent.primary;\n const _surface = tokens.colors.background.surface; // eslint-disable-line @typescript-eslint/no-unused-vars -- reserved for future scrollbar track customisation\n const _base = tokens.colors.background.base; // eslint-disable-line @typescript-eslint/no-unused-vars -- reserved for future scrollbar corner styling\n const isLight = mode === 'light';\n\n // Thumb colors: accent-tinted, low opacity at rest, stronger on hover/active\n const thumbRest = isLight ? hexToRgba(accent, 0.28) : hexToRgba(accent, 0.35);\n const thumbHover = isLight ? hexToRgba(accent, 0.48) : hexToRgba(accent, 0.55);\n const thumbActive = isLight ? hexToRgba(accent, 0.64) : hexToRgba(accent, 0.72);\n\n // Track: nearly invisible surface blend\n const trackColor = isLight ? hexToRgba(accent, 0.04) : hexToRgba(accent, 0.06);\n const trackHover = isLight ? hexToRgba(accent, 0.08) : hexToRgba(accent, 0.10);\n\n const transition = reducedMotion ? 'none' : 'background-color 200ms ease, width 200ms ease, opacity 200ms ease';\n const thumbRadius = '9999px'; // pill shape\n\n // Firefox colors (two-value syntax: thumb track)\n const ffThumb = thumbRest;\n const ffTrack = trackColor;\n\n return `\n/* ═══════════════════════════════════════════════════════════════════════════\n Zendir Scrollbar System — Thin · Elegant · Theme-Connected\n ═══════════════════════════════════════════════════════════════════════════ */\n\n/* ── Firefox ────────────────────────────────────────────────────────────── */\n*,\n.zendir-scroll {\n scrollbar-width: thin;\n scrollbar-color: ${ffThumb} ${ffTrack};\n}\n\n/* ── Webkit / Blink (Chrome, Edge, Safari, Opera) ───────────────────────── */\n\n/* Global thin scrollbar */\n::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n background: transparent;\n}\n\n/* Track — nearly invisible, subtle on hover */\n::-webkit-scrollbar-track {\n background: ${trackColor};\n border-radius: ${thumbRadius};\n margin: 2px;\n}\n::-webkit-scrollbar-track:hover {\n background: ${trackHover};\n}\n\n/* Thumb — accent-tinted pill */\n::-webkit-scrollbar-thumb {\n background: ${thumbRest};\n border-radius: ${thumbRadius};\n border: 1px solid transparent;\n background-clip: padding-box;\n transition: ${transition};\n min-height: 32px;\n}\n::-webkit-scrollbar-thumb:hover {\n background: ${thumbHover};\n border-color: transparent;\n background-clip: padding-box;\n}\n::-webkit-scrollbar-thumb:active {\n background: ${thumbActive};\n border-color: transparent;\n background-clip: padding-box;\n}\n\n/* Corner — where horizontal & vertical scrollbars meet */\n::-webkit-scrollbar-corner {\n background: transparent;\n}\n\n/* ── Utility class: zendir-scroll ────────────────────────────────────────\n Apply to individual containers for scoped thin scrollbar.\n Also enables overlay behaviour where supported.\n e.g. <div className=\"zendir-scroll\" style={{overflow:'auto'}}>…</div>\n ─────────────────────────────────────────────────────────────────────── */\n.zendir-scroll {\n overflow: auto;\n overflow: overlay; /* Chrome / Edge: auto-hide scrollbar */\n}\n.zendir-scroll::-webkit-scrollbar {\n width: 5px;\n height: 5px;\n}\n.zendir-scroll::-webkit-scrollbar-track {\n background: transparent;\n border-radius: ${thumbRadius};\n}\n.zendir-scroll::-webkit-scrollbar-thumb {\n background: ${thumbRest};\n border-radius: ${thumbRadius};\n transition: ${transition};\n}\n.zendir-scroll::-webkit-scrollbar-thumb:hover {\n background: ${thumbHover};\n}\n.zendir-scroll::-webkit-scrollbar-thumb:active {\n background: ${thumbActive};\n}\n\n/* ── Utility: zendir-scroll--hidden ─────────────────────────────────────\n Hides scrollbar visually but keeps scroll behaviour (accessible).\n Content remains scrollable via mouse wheel / touch / keyboard.\n ─────────────────────────────────────────────────────────────────────── */\n.zendir-scroll--hidden {\n overflow: auto;\n -ms-overflow-style: none;\n scrollbar-width: none;\n}\n.zendir-scroll--hidden::-webkit-scrollbar {\n display: none;\n}\n\n/* ── Focus-visible: keyboard users can still scroll with focus ─────────── */\n.zendir-scroll:focus-visible {\n outline: 2px solid ${accent};\n outline-offset: -2px;\n border-radius: ${tokens.borderRadius.md};\n}\n\n/* ── Reduced Motion: disable scrollbar transitions ─────────────────────── */\n@media (prefers-reduced-motion: reduce) {\n ::-webkit-scrollbar-thumb,\n .zendir-scroll::-webkit-scrollbar-thumb {\n transition: none !important;\n }\n}\n\n/* ── High Contrast Mode: ensure scrollbar is visible ───────────────────── */\n@media (forced-colors: active) {\n ::-webkit-scrollbar-thumb {\n background: ButtonText !important;\n }\n ::-webkit-scrollbar-track {\n background: Canvas !important;\n }\n}\n`.trim();\n}\n\n/**\n * useScrollbarStyles — returns inline React.CSSProperties for a\n * scrollable container that matches the current Zendir theme.\n *\n * Use when you need programmatic control rather than the\n * `zendir-scroll` CSS class.\n *\n * @example\n * ```tsx\n * const scrollStyle = useScrollbarStyles();\n * <div style={{ maxHeight: 400, ...scrollStyle }}>…</div>\n * ```\n */\nexport function useScrollbarStyles(): React.CSSProperties {\n const { tokens, mode } = useTheme();\n return useMemo((): React.CSSProperties => {\n const accent = tokens.colors.accent.primary;\n const isLight = mode === 'light';\n const thumbColor = isLight ? hexToRgba(accent, 0.28) : hexToRgba(accent, 0.35);\n const trackColor = isLight ? hexToRgba(accent, 0.04) : hexToRgba(accent, 0.06);\n return {\n // Firefox\n scrollbarWidth: 'thin' as const,\n scrollbarColor: `${thumbColor} ${trackColor}`,\n overflow: 'auto',\n };\n }, [tokens, mode]);\n}\n\n/**\n * ThemeProvider - Enterprise theme context provider\n * \n * Provides theme tokens, mode switching, and accessibility features\n * to all child components.\n * \n * @example\n * ```tsx\n * <ThemeProvider theme=\"hybrid\" mode=\"dark\"> // Zen (Hybrid) is the default\n * <App />\n * </ThemeProvider>\n * ```\n */\nexport function ThemeProvider({\n children,\n theme: defaultTheme = 'hybrid',\n mode: defaultMode = 'dark',\n persist = true,\n}: ThemeProviderProps): React.ReactElement {\n // Initialize theme from localStorage or defaults\n const [theme, setThemeState] = useState<ThemeVariant>(() => {\n if (persist && typeof window !== 'undefined') {\n const saved = localStorage.getItem('zendir-ui-theme');\n if (saved === 'astro' || saved === 'zendir' || saved === 'hybrid' || saved === 'transparent' || saved === 'transparent-bold' || saved === 'transparent-minimal') {\n return saved as ThemeVariant;\n }\n }\n return defaultTheme;\n });\n\n const [mode, setModeState] = useState<ThemeMode>(() => {\n if (persist && typeof window !== 'undefined') {\n const saved = localStorage.getItem('zendir-ui-mode');\n if (saved === 'light' || saved === 'dark') {\n return saved;\n }\n }\n return defaultMode;\n });\n\n // Detect reduced motion preference\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handler = (e: MediaQueryListEvent) => setPrefersReducedMotion(e.matches);\n mediaQuery.addEventListener('change', handler);\n return () => mediaQuery.removeEventListener('change', handler);\n }, []);\n\n // Theme setters\n const setTheme = (newTheme: ThemeVariant) => {\n setThemeState(newTheme);\n if (persist && typeof window !== 'undefined') {\n localStorage.setItem('zendir-ui-theme', newTheme);\n }\n };\n\n const setMode = (newMode: ThemeMode) => {\n setModeState(newMode);\n if (persist && typeof window !== 'undefined') {\n localStorage.setItem('zendir-ui-mode', newMode);\n }\n };\n\n const toggleMode = () => {\n setMode(mode === 'dark' ? 'light' : 'dark');\n };\n\n // Accent color override\n const [accentColor, setAccentColorState] = useState<string | null>(() => {\n if (persist && typeof window !== 'undefined') {\n return localStorage.getItem('zendir-ui-accent') || null;\n }\n return null;\n });\n\n const setAccentColor = (color: string | null) => {\n setAccentColorState(color);\n if (persist && typeof window !== 'undefined') {\n if (color) {\n localStorage.setItem('zendir-ui-accent', color);\n } else {\n localStorage.removeItem('zendir-ui-accent');\n }\n }\n };\n\n // Get theme tokens (card border styles computed so all cards use theme-driven borders)\n const tokens = useMemo((): ThemeTokens => {\n // If light mode is selected, always use Astro Light theme (unified light mode)\n // regardless of the selected theme variant\n const base =\n mode === 'light'\n ? astroThemeLight\n : theme === 'astro'\n ? astroThemeDark\n : theme === 'hybrid'\n ? hybridTheme\n : theme === 'transparent' || theme === 'transparent-bold'\n ? transparentTheme\n : theme === 'transparent-minimal'\n ? transparentMinimalTheme\n : purpleHueTheme;\n const isTransparent =\n theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const isMinimal = theme === 'transparent-minimal';\n \n // For transparent-minimal: use visible accent-colored borders.\n // For other transparent themes: use subtle fadedBoxShadow.\n // Accent overrides are intentionally scoped to transparent variants only,\n // so switching to Astro/Hybrid/Purple-Hue restores each theme's native accent.\n const resolvedAccent = (isTransparent && accentColor)\n ? {\n primary: accentColor,\n secondary: adjustHexBrightness(accentColor, 1.2),\n tertiary: adjustHexBrightness(accentColor, 0.85),\n }\n : base.colors.accent;\n\n const accentPrimary = resolvedAccent.primary;\n const accentBorderMuted = `${accentPrimary}40`; // 25% opacity\n const accentBorderDefault = `${accentPrimary}66`; // 40% opacity\n const accentFadedBoxShadow = `inset 0 1px 0 ${hexToRgba(accentPrimary, 0.12)}, inset 0 -1px 0 rgba(0, 0, 0, 0.05), inset 1px 0 0 ${hexToRgba(accentPrimary, 0.06)}, inset -1px 0 0 ${hexToRgba(accentPrimary, 0.06)}`;\n \n const cardStyle = isMinimal\n ? { border: `1px solid ${accentBorderMuted}` }\n : isTransparent\n ? { border: 'none' as const, boxShadow: accentFadedBoxShadow }\n : { border: `1px solid ${base.colors.border.muted}` };\n const cardStyleDashed = isMinimal\n ? { border: `1px dashed ${accentBorderMuted}` }\n : isTransparent\n ? { border: 'none' as const, boxShadow: accentFadedBoxShadow }\n : { border: `1px dashed ${base.colors.border.muted}` };\n const cardStyleDefault = isMinimal\n ? { border: `1px solid ${accentBorderDefault}` }\n : isTransparent\n ? { border: 'none' as const, boxShadow: accentFadedBoxShadow }\n : { border: `1px solid ${base.colors.border.default}` };\n // Compute border tokens from the resolved theme colors\n const resolvedColors: ThemeColors = {\n ...base.colors,\n accent: resolvedAccent,\n border: {\n ...base.colors.border,\n cardStyle,\n cardStyleDashed,\n cardStyleDefault,\n },\n };\n\n return {\n ...base,\n colors: resolvedColors,\n borders: computeBorderTokens(resolvedColors),\n } as ThemeTokens;\n }, [theme, mode, accentColor]);\n\n // Apply CSS variables to document\n useEffect(() => {\n if (typeof document === 'undefined') return;\n\n const root = document.documentElement;\n const { colors, typography, spacing, borderRadius, animation, focus, shadows } = tokens;\n\n // Theme mode attribute\n root.setAttribute('data-theme', mode);\n root.setAttribute('data-variant', theme);\n\n // Background colors\n root.style.setProperty('--color-background-base', colors.background.base);\n root.style.setProperty('--color-background-surface', colors.background.surface);\n root.style.setProperty('--color-background-elevated', colors.background.elevated);\n root.style.setProperty('--color-background-overlay', colors.background.overlay);\n\n // Border colors\n root.style.setProperty('--color-border', colors.border.default);\n root.style.setProperty('--color-border-muted', colors.border.muted);\n root.style.setProperty('--color-border-focus', colors.border.focus);\n\n // Text colors\n root.style.setProperty('--color-text-primary', colors.text.primary);\n root.style.setProperty('--color-text-secondary', colors.text.secondary);\n root.style.setProperty('--color-text-tertiary', colors.text.tertiary);\n root.style.setProperty('--color-text-inverse', colors.text.inverse);\n\n // Status colors\n root.style.setProperty('--color-status-normal', colors.status.normal);\n root.style.setProperty('--color-status-standby', colors.status.standby);\n root.style.setProperty('--color-status-caution', colors.status.caution);\n root.style.setProperty('--color-status-serious', colors.status.serious);\n root.style.setProperty('--color-status-critical', colors.status.critical);\n root.style.setProperty('--color-status-off', colors.status.off);\n\n // Interactive colors\n root.style.setProperty('--color-interactive-default', colors.interactive.default);\n root.style.setProperty('--color-interactive-hover', colors.interactive.hover);\n root.style.setProperty('--color-interactive-active', colors.interactive.active);\n root.style.setProperty('--color-interactive-disabled', colors.interactive.disabled);\n\n // Accent colors\n root.style.setProperty('--color-accent-primary', colors.accent.primary);\n root.style.setProperty('--color-accent-secondary', colors.accent.secondary);\n root.style.setProperty('--color-accent-tertiary', colors.accent.tertiary);\n\n // Typography\n // @ts-expect-error - heading may not be strictly typed on older builds\n root.style.setProperty('--font-family-heading', typography.fontFamily.heading || typography.fontFamily.primary);\n root.style.setProperty('--font-family-primary', typography.fontFamily.primary);\n root.style.setProperty('--font-family-mono', typography.fontFamily.mono);\n\n // Spacing (full scale so CSS and layout can pull from SDK)\n root.style.setProperty('--spacing-xxs', spacing.xxs);\n root.style.setProperty('--spacing-xs', spacing.xs);\n root.style.setProperty('--spacing-sm', spacing.sm);\n root.style.setProperty('--spacing-smd', spacing.smd);\n root.style.setProperty('--spacing-md', spacing.md);\n root.style.setProperty('--spacing-mdl', spacing.mdl);\n root.style.setProperty('--spacing-lg', spacing.lg);\n root.style.setProperty('--spacing-xl', spacing.xl);\n root.style.setProperty('--spacing-xxl', spacing.xxl);\n\n // Border radius\n root.style.setProperty('--radius-sm', borderRadius.sm);\n root.style.setProperty('--radius-md', borderRadius.md);\n root.style.setProperty('--radius-lg', borderRadius.lg);\n root.style.setProperty('--radius-xl', borderRadius.xl);\n\n // Animation (respect reduced motion)\n const motionMultiplier = prefersReducedMotion ? 0 : 1;\n root.style.setProperty('--animation-fast', prefersReducedMotion ? 'none' : animation.fast);\n root.style.setProperty('--animation-normal', prefersReducedMotion ? 'none' : animation.normal);\n root.style.setProperty('--animation-slow', prefersReducedMotion ? 'none' : animation.slow);\n root.style.setProperty('--duration-fast', `${animation.duration.fast * motionMultiplier}ms`);\n root.style.setProperty('--duration-normal', `${animation.duration.normal * motionMultiplier}ms`);\n root.style.setProperty('--duration-slow', `${animation.duration.slow * motionMultiplier}ms`);\n\n // Focus\n root.style.setProperty('--focus-ring-color', focus.color);\n root.style.setProperty('--focus-ring-width', focus.width);\n root.style.setProperty('--focus-ring-offset', focus.offset);\n\n // Shadows\n root.style.setProperty('--shadow-sm', shadows.sm);\n root.style.setProperty('--shadow-md', shadows.md);\n root.style.setProperty('--shadow-lg', shadows.lg);\n root.style.setProperty('--shadow-xl', shadows.xl);\n\n // Apply base styles to body\n document.body.style.backgroundColor = colors.background.base;\n document.body.style.color = colors.text.primary;\n document.body.style.fontFamily = typography.fontFamily.primary;\n }, [tokens, theme, mode, prefersReducedMotion]);\n\n // ──────────────────────────────────────────────────────────────────────────\n // Scrollbar Styles — thin, elegant, theme-connected, fully accessible\n // ──────────────────────────────────────────────────────────────────────────\n const scrollbarCSS = useMemo(() => buildScrollbarCSS(tokens, mode, prefersReducedMotion), [tokens, mode, prefersReducedMotion]);\n\n const value: ThemeContextValue = useMemo(\n () => ({\n theme,\n mode,\n tokens,\n prefersReducedMotion,\n accentColor,\n setTheme,\n setMode,\n toggleMode,\n setAccentColor,\n }),\n [theme, mode, tokens, prefersReducedMotion, accentColor]\n );\n\n // Global reduced-motion rule — ensures ALL animations and transitions across\n // every Zendir component respect the OS preference (WCAG 2.3.3).\n // Uses 0.01ms (not 0) so animation-end events still fire correctly.\n const reducedMotionCSS = `@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n scroll-behavior: auto !important;\n }\n}`;\n\n return (\n <ThemeContext.Provider value={value}>\n <style data-zendir-scrollbar=\"\" dangerouslySetInnerHTML={{ __html: scrollbarCSS }} />\n <style data-zendir-reduced-motion=\"\" dangerouslySetInnerHTML={{ __html: reducedMotionCSS }} />\n {children}\n </ThemeContext.Provider>\n );\n}\n\n/**\n * useTheme - Access theme context\n * \n * @throws Error if used outside ThemeProvider\n * \n * @example\n * ```tsx\n * const { tokens, mode, toggleMode } = useTheme();\n * ```\n */\nexport function useTheme(): ThemeContextValue {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n}\n\n/**\n * useThemeTokens - Access only theme tokens (for memoization)\n */\nexport function useThemeTokens(): ThemeTokens {\n return useTheme().tokens;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ThemeProvider.js","sources":["../../../src/react/theme/ThemeProvider.tsx"],"sourcesContent":["/**\n * @zendir/ui - Theme Provider\n * \n * Enterprise-grade theming system supporting Astro UX Design System and Zendir themes.\n * Full Tier 3 compliance with official Astro tokens (dark + light themes).\n * \n * Features:\n * - Multiple theme variants (Zen Hybrid default, astro, purple-hue, transparent)\n * - Light and dark modes\n * - Animation tokens with reduced-motion support\n * - Focus ring styles for accessibility\n * - CSS variable injection\n * - Local storage persistence\n */\n\nimport React, { createContext, useContext, useState, useEffect, useMemo, ReactNode } from 'react';\n\nfunction adjustHexBrightness(hex: string, factor: number): string {\n const normalized = hex.replace('#', '').trim();\n const expanded = normalized.length === 3\n ? normalized.split('').map(ch => ch + ch).join('')\n : normalized;\n\n if (!/^[0-9a-fA-F]{6}$/.test(expanded)) {\n return hex;\n }\n\n const clamp = (value: number) => Math.max(0, Math.min(255, Math.round(value)));\n const r = clamp(parseInt(expanded.slice(0, 2), 16) * factor);\n const g = clamp(parseInt(expanded.slice(2, 4), 16) * factor);\n const b = clamp(parseInt(expanded.slice(4, 6), 16) * factor);\n\n const toHex = (value: number) => value.toString(16).padStart(2, '0');\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\nexport type ThemeVariant = 'astro' | 'purple-hue' | 'hybrid' | 'transparent' | 'transparent-bold' | 'transparent-minimal';\nexport type ThemeMode = 'light' | 'dark';\n\nexport interface ThemeColors {\n background: {\n base: string;\n surface: string;\n elevated: string;\n overlay: string;\n };\n border: {\n default: string;\n muted: string;\n focus: string;\n /** Transparent theme: thin faded top-to-bottom border (box-shadow, use with border: 'none') */\n fadedBoxShadow?: string;\n /** Card border style (computed from theme – solid or transparent faded). Use ...tokens.colors.border.cardStyle */\n cardStyle?: React.CSSProperties;\n /** Card border for dashed/empty state. Use ...tokens.colors.border.cardStyleDashed */\n cardStyleDashed?: React.CSSProperties;\n /** Card border using default color (e.g. NavBall, EclipseTimer). Use ...tokens.colors.border.cardStyleDefault */\n cardStyleDefault?: React.CSSProperties;\n };\n text: {\n primary: string;\n secondary: string;\n tertiary: string;\n /** Muted/placeholder text (alias for tertiary when not set) */\n muted?: string;\n inverse: string;\n };\n status: {\n normal: string;\n standby: string;\n caution: string;\n serious: string;\n critical: string;\n off: string;\n };\n semantic: {\n success: string;\n warning: string;\n error: string;\n info: string;\n };\n accent: {\n primary: string;\n secondary: string;\n tertiary: string;\n };\n interactive: {\n default: string;\n hover: string;\n active: string;\n disabled: string;\n /** Transparent theme: button/control bg (low opacity purple) when not hovered */\n transparentDefault?: string;\n /** Transparent theme: button/control bg on hover (higher opacity purple) */\n transparentHover?: string;\n /** Transparent theme: input field bg (semi-transparent purple tint) */\n transparentInputBg?: string;\n };\n}\n\nexport interface ThemeAnimation {\n /** Fast transitions (hover states) - 150ms */\n fast: string;\n /** Normal transitions (most interactions) - 250ms */\n normal: string;\n /** Slow transitions (page/mode changes) - 400ms */\n slow: string;\n /** Spring animation for playful interactions */\n spring: string;\n /** Easing function */\n easing: {\n default: string;\n in: string;\n out: string;\n inOut: string;\n };\n /** Duration values in milliseconds */\n duration: {\n instant: number;\n fast: number;\n normal: number;\n slow: number;\n };\n}\n\nexport interface ThemeFocus {\n /** Focus ring color */\n color: string;\n /** Focus ring width */\n width: string;\n /** Focus ring offset */\n offset: string;\n /** Full focus ring CSS */\n ring: string;\n /** Focus ring style object */\n style: React.CSSProperties;\n}\n\n/**\n * Astro UX Typography Style Token\n * Based on https://www.astrouxds.com/foundations/typography/\n */\nexport interface TypographyStyle {\n fontSize: string;\n fontWeight: number;\n letterSpacing: string;\n lineHeight: string;\n}\n\nexport interface ThemeTokens {\n colors: ThemeColors;\n spacing: {\n /** 2px — micro adjustments, decorative offsets */\n xxs: string;\n /** 4px — tight gaps, icon padding */\n xs: string;\n /** 8px — compact spacing, small gaps */\n sm: string;\n /** 12px — form fields, compact cards (between sm and md) */\n smd: string;\n /** 16px — default card padding, section gaps */\n md: string;\n /** 20px — slightly generous spacing */\n mdl: string;\n /** 24px — generous spacing, content area padding */\n lg: string;\n /** 32px — large section gaps */\n xl: string;\n /** 48px — extra large spacing */\n xxl: string;\n };\n borderRadius: {\n none: string;\n /** 1px — very subtle rounding */\n xs: string;\n /** 2px — small elements, badges, tooltips */\n sm: string;\n /** 4px — inputs, selects, standard controls */\n md: string;\n /** 8px — cards, containers */\n lg: string;\n /** 12px — prominent surfaces, modals */\n xl: string;\n /** 9999px — pills, fully rounded */\n full: string;\n };\n /** Standardised element heights for interactive controls */\n elementSize: {\n /** 28px — compact controls */\n sm: string;\n /** 36px — default controls */\n md: string;\n /** 44px — prominent controls, touch targets */\n lg: string;\n };\n typography: {\n fontFamily: {\n primary: string;\n mono: string;\n };\n // Astro UX Typography Tokens (rem-based)\n // https://www.astrouxds.com/foundations/typography/\n display: {\n 1: TypographyStyle;\n 2: TypographyStyle;\n };\n heading: {\n 1: TypographyStyle;\n '1Bold': TypographyStyle;\n 2: TypographyStyle;\n 3: TypographyStyle;\n 4: TypographyStyle;\n 5: TypographyStyle;\n 6: TypographyStyle;\n };\n body: {\n 1: TypographyStyle;\n '1Bold': TypographyStyle;\n 2: TypographyStyle;\n '2Bold': TypographyStyle;\n 3: TypographyStyle;\n '3Bold': TypographyStyle;\n };\n control: {\n 1: TypographyStyle;\n '1Bold': TypographyStyle;\n };\n // Legacy/convenience tokens (keeping for backward compatibility)\n fontSize: {\n micro: string; // 9px - very tight spaces\n xxs: string; // 10px - compact labels\n xs: string;\n sm: string;\n base: string;\n md: string;\n lg: string;\n xl: string;\n xxl: string;\n xxxl: string;\n };\n fontWeight: {\n light: number;\n normal: number;\n medium: number;\n semibold: number;\n bold: number;\n };\n lineHeight: {\n tight: string;\n normal: string;\n relaxed: string;\n };\n letterSpacing: {\n tight: string;\n normal: string;\n wide: string;\n };\n };\n shadows: {\n none: string;\n sm: string;\n md: string;\n lg: string;\n xl: string;\n glow: (color: string) => string;\n };\n animation: ThemeAnimation;\n focus: ThemeFocus;\n /** Semantic layout tokens for consistent spacing across cards, forms, and sections */\n layout: LayoutTokens;\n /** Semantic border tokens for consistent element styling (derived from theme colors) */\n borders: BorderTokens;\n}\n\n// ============================================================================\n// Layout Tokens Interface\n// Semantic spacing for cards, sections, forms, and nested surfaces.\n// These decouple layout intent from raw pixel values, enabling consistent\n// spacing across all consuming applications.\n// ============================================================================\n\nexport interface LayoutTokens {\n /** Card / panel container spacing */\n card: {\n /** Internal padding of card containers */\n padding: string;\n /** Gap between cards in grid layouts (desktop) */\n gap: string;\n /** Gap between cards in grid layouts (mobile / compact) */\n gapCompact: string;\n /** Card heading: icon size, title typography, gap — single system for all cards/charts */\n heading: {\n iconSize: number;\n iconSizeCompact: number;\n titleFontSize: string;\n /** Smaller title for chart headers (e.g. Power Trends) so they match card visual weight */\n titleFontSizeChart: string;\n titleFontWeight: number;\n gap: number;\n };\n };\n /** Section heading spacing (heading + divider + content) */\n section: {\n /** Padding below heading text, above the divider border */\n headerPaddingBottom: string;\n /** Margin below the divider border, before content */\n headerMarginBottom: string;\n /** Padding above the first content element after heading */\n contentPaddingTop: string;\n };\n /** Form and input field spacing */\n form: {\n /** Vertical gap between stacked form fields */\n fieldGap: string;\n /** Horizontal gap between side-by-side inline fields */\n inlineGap: string;\n /** Padding inside grouped / nested field containers */\n groupPadding: string;\n /** Gap between items within a field group */\n groupGap: string;\n /** Gap between label text and helper icons (e.g. tooltip) */\n labelGap: string;\n };\n /** Nested surface / panel spacing (e.g. grouped fields within a card) */\n surface: {\n /** Internal padding of nested surfaces */\n padding: string;\n /** Border radius of nested surfaces */\n borderRadius: string;\n /** Gap between items in compact nested surfaces */\n gap: string;\n };\n}\n\n// ============================================================================\n// Border Tokens Interface\n// Standardised border widths, element borders, focus rings, and dividers.\n// These are DERIVED from theme colors at runtime via computeBorderTokens().\n// ============================================================================\n\nexport interface BorderTokens {\n /** Border widths — standardised across all interactive elements */\n width: {\n /** Thin (1px) — inputs, cards, dividers, dropdowns */\n thin: string;\n /** Medium (1.5px) — secondary buttons, emphasised inputs */\n medium: string;\n /** Thick (2px) — checkboxes, accent borders, active tabs */\n thick: string;\n };\n /** Pre-computed input / control borders (width + style + color) */\n input: {\n /** Default resting state */\n default: string;\n /** Hover state (accent at 50% opacity) */\n hover: string;\n /** Focused state (full accent) */\n focus: string;\n /** Error / critical state */\n error: string;\n };\n /** Focus ring box-shadow values for interactive elements */\n focusRing: {\n /** Standard ring for inputs and selects */\n default: string;\n /** Ring for buttons (double-ring pattern) */\n button: string;\n /** Subtle ring for checkboxes, tabs, toggles */\n subtle: string;\n };\n /** Section divider border (headings, dialog headers/footers, tab bars) */\n divider: string;\n /** Dropdown / popover container border */\n dropdown: string;\n /** Separator line inside elements (unit separators, table rows) */\n separator: string;\n}\n\n/**\n * Derives border tokens from a theme's resolved colors.\n * Called once per theme change inside the ThemeProvider useMemo.\n */\nfunction computeBorderTokens(colors: ThemeColors): BorderTokens {\n const thin = '1px';\n const medium = '1.5px';\n const thick = '2px';\n const accent = colors.accent.primary;\n const muted = colors.border.muted;\n const critical = colors.status.critical;\n const bgBase = colors.background.base;\n\n return {\n width: { thin, medium, thick },\n input: {\n default: `${thin} solid ${muted}`,\n hover: `${thin} solid ${accent}80`,\n focus: `${thin} solid ${accent}`,\n error: `${thin} solid ${critical}`,\n },\n focusRing: {\n // WCAG 2.4.13: focus indicators ≥ 3:1 contrast — raised from 20%/30% to 50%/60%\n default: `0 0 0 3px ${accent}50, 0 0 20px ${accent}15`,\n button: `0 0 0 2px ${bgBase}, 0 0 0 4px ${accent}`,\n subtle: `0 0 0 2px ${accent}60`,\n },\n divider: `${thin} solid ${muted}`,\n dropdown: `${thin} solid ${accent}30`,\n separator: `${thin} solid ${muted}`,\n };\n}\n\n/**\n * Base theme type used for static theme definitions.\n * `borders` is omitted because it is derived from colors at runtime\n * inside the ThemeProvider useMemo (see computeBorderTokens).\n */\ntype ThemeTokensBase = Omit<ThemeTokens, 'borders'>;\n\n// ============================================================================\n// Animation Tokens (Shared)\n// ============================================================================\n\nconst animationTokens: ThemeAnimation = {\n fast: 'all 150ms cubic-bezier(0.4, 0, 0.2, 1)',\n normal: 'all 250ms cubic-bezier(0.4, 0, 0.2, 1)',\n slow: 'all 400ms cubic-bezier(0.4, 0, 0.2, 1)',\n spring: 'all 300ms cubic-bezier(0.34, 1.56, 0.64, 1)',\n easing: {\n default: 'cubic-bezier(0.4, 0, 0.2, 1)',\n in: 'ease-in',\n out: 'ease-out',\n inOut: 'ease-in-out',\n },\n duration: {\n instant: 0,\n fast: 150,\n normal: 250,\n slow: 400,\n },\n};\n\n// ============================================================================\n// Focus Tokens (Dark)\n// ============================================================================\n\nconst focusTokensDark: ThemeFocus = {\n color: '#4dacff',\n width: '2px',\n offset: '2px',\n ring: '0 0 0 2px #4dacff',\n style: {\n outline: '2px solid #4dacff',\n outlineOffset: '2px',\n },\n};\n\nconst focusTokensLight: ThemeFocus = {\n color: '#0066cc',\n width: '2px',\n offset: '2px',\n ring: '0 0 0 2px #0066cc',\n style: {\n outline: '2px solid #0066cc',\n outlineOffset: '2px',\n },\n};\n\n// ============================================================================\n// Shadow Tokens\n// ============================================================================\n\nconst shadowsDark = {\n none: 'none',\n sm: '0 1px 2px rgba(0, 0, 0, 0.3)',\n md: '0 4px 8px rgba(0, 0, 0, 0.4)',\n lg: '0 8px 16px rgba(0, 0, 0, 0.5)',\n xl: '0 16px 32px rgba(0, 0, 0, 0.6)',\n glow: (color: string) => `0 0 20px ${color}40, 0 0 40px ${color}20`,\n};\n\nconst shadowsLight = {\n none: 'none',\n sm: '0 1px 2px rgba(0, 0, 0, 0.1)',\n md: '0 4px 8px rgba(0, 0, 0, 0.15)',\n lg: '0 8px 16px rgba(0, 0, 0, 0.2)',\n xl: '0 16px 32px rgba(0, 0, 0, 0.25)',\n glow: (color: string) => `0 0 20px ${color}30, 0 0 40px ${color}15`,\n};\n\n// ============================================================================\n// Layout Tokens (Shared)\n// Semantic layout spacing based on 4px grid. Shared across all themes.\n// ============================================================================\n\nconst layoutTokens: LayoutTokens = {\n card: {\n padding: '16px', // 4 × 4px\n gap: '24px', // 6 × 4px — desktop grid gap (matches outer padding)\n gapCompact: '16px', // 4 × 4px — mobile grid gap\n heading: {\n iconSize: 18, // default card header icon (px) — matches ISS/Telemetry card header size\n iconSizeCompact: 16, // compact (e.g. chart inline header)\n titleFontSize: '1rem', // card titles (ISS, Telemetry, Mission) — reduced from 1.125rem\n titleFontSizeChart: '0.875rem', // chart titles (Power Trends) — slightly smaller\n titleFontWeight: 500,\n gap: 8, // gap between icon and title (px)\n },\n },\n section: {\n headerPaddingBottom: '8px', // 2 × 4px\n headerMarginBottom: '0px',\n contentPaddingTop: '8px', // 2 × 4px\n },\n form: {\n fieldGap: '12px', // 3 × 4px — between stacked fields\n inlineGap: '12px', // 3 × 4px — between side-by-side fields\n groupPadding: '12px', // 3 × 4px — inside grouped containers\n groupGap: '12px', // 3 × 4px — within group items\n labelGap: '3px', // label text ↔ tooltip icon\n },\n surface: {\n padding: '12px', // 3 × 4px\n borderRadius: '12px', // 3 × 4px\n gap: '8px', // 2 × 4px\n },\n};\n\n// ============================================================================\n// Astro UX Dark Theme\n// ============================================================================\n\nconst astroThemeDark: ThemeTokensBase = {\n colors: {\n background: {\n base: '#101923',\n surface: '#1b2d3e',\n elevated: '#243b53',\n overlay: 'rgba(16, 25, 35, 0.95)',\n },\n border: {\n default: '#2b659b',\n muted: '#172635',\n focus: '#4dacff',\n },\n text: {\n primary: '#ffffff',\n secondary: '#b7c5d3',\n tertiary: '#8fa4b7',\n muted: '#8fa4b7',\n inverse: '#1b2d3e',\n },\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#4dacff',\n },\n accent: {\n primary: '#4dacff',\n secondary: '#56f000',\n tertiary: '#a371f7',\n },\n interactive: {\n default: '#4dacff',\n hover: '#92cbff',\n active: '#0066cc',\n disabled: '#6b7280',\n },\n },\n spacing: {\n xxs: '2px',\n xs: '4px',\n sm: '8px',\n smd: '12px',\n md: '16px',\n mdl: '20px',\n lg: '24px',\n xl: '32px',\n xxl: '48px',\n },\n borderRadius: {\n none: '0',\n xs: '1px',\n sm: '2px',\n md: '4px',\n lg: '8px',\n xl: '12px',\n full: '9999px',\n },\n elementSize: {\n sm: '28px',\n md: '36px',\n lg: '44px',\n },\n typography: {\n /**\n * Font families per AstroUXDS specification\n * @see https://www.astrouxds.com/foundations/typography/\n */\n fontFamily: {\n /** Primary font: Roboto with comprehensive system fallbacks */\n primary: '\"Roboto\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif',\n /** Monospace font: Roboto Mono for data/code with system fallbacks */\n mono: '\"Roboto Mono\", \"SF Mono\", \"Consolas\", \"Liberation Mono\", monospace',\n },\n // Astro UX Display Styles\n // https://www.astrouxds.com/foundations/typography/\n display: {\n 1: { fontSize: '3.75rem', fontWeight: 300, letterSpacing: '-0.5px', lineHeight: '4.375rem' },\n 2: { fontSize: '3rem', fontWeight: 400, letterSpacing: '0', lineHeight: '3.5rem' },\n },\n // Astro UX Heading Styles\n heading: {\n 1: { fontSize: '2.125rem', fontWeight: 400, letterSpacing: '0.25px', lineHeight: '2.5rem' },\n '1Bold': { fontSize: '2.125rem', fontWeight: 700, letterSpacing: '0.25px', lineHeight: '2rem' },\n 2: { fontSize: '1.5rem', fontWeight: 400, letterSpacing: '0', lineHeight: '1.75rem' },\n 3: { fontSize: '1.25rem', fontWeight: 500, letterSpacing: '0.15px', lineHeight: '1.5rem' },\n 4: { fontSize: '1.25rem', fontWeight: 300, letterSpacing: '0.15px', lineHeight: '1.5rem' },\n 5: { fontSize: '1.125rem', fontWeight: 400, letterSpacing: '0', lineHeight: '1.5rem' },\n 6: { fontSize: '1.125rem', fontWeight: 300, letterSpacing: '0', lineHeight: '1.5rem' },\n },\n // Astro UX Body Styles\n body: {\n 1: { fontSize: '1rem', fontWeight: 400, letterSpacing: '0.5px', lineHeight: '1.5rem' },\n '1Bold': { fontSize: '1rem', fontWeight: 700, letterSpacing: '0.5px', lineHeight: '1.5rem' },\n 2: { fontSize: '0.875rem', fontWeight: 400, letterSpacing: '0.5px', lineHeight: '1.25rem' },\n '2Bold': { fontSize: '0.875rem', fontWeight: 700, letterSpacing: '0.5px', lineHeight: '1.25rem' },\n 3: { fontSize: '0.75rem', fontWeight: 400, letterSpacing: '0', lineHeight: '1rem' },\n '3Bold': { fontSize: '0.75rem', fontWeight: 700, letterSpacing: '0', lineHeight: '1rem' },\n },\n // Astro UX Control Body Styles\n control: {\n 1: { fontSize: '1rem', fontWeight: 400, letterSpacing: '0.5px', lineHeight: '1.25rem' },\n '1Bold': { fontSize: '1rem', fontWeight: 700, letterSpacing: '0.5px', lineHeight: '1.25rem' },\n },\n // Legacy convenience tokens (rem-based for Astro compliance)\n // Note: Use Typography component for new code\n fontSize: {\n micro: '0.5625rem', // 9px - very tight spaces\n xxs: '0.625rem', // 10px - compact labels (xs in old system)\n xs: '0.625rem', // 10px - compact (kept for backward compatibility)\n sm: '0.75rem', // 12px (Body 3)\n base: '0.875rem', // 14px (Body 2)\n md: '0.875rem', // 14px (Body 2)\n lg: '1rem', // 16px (Body 1)\n xl: '1.25rem', // 20px (Heading 3/4)\n xxl: '1.5rem', // 24px (Heading 2)\n xxxl: '2.125rem', // 34px (Heading 1)\n },\n /**\n * Font weights per AstroUXDS specification\n * Only 300, 400, 500, 700 are officially supported\n * @see https://www.astrouxds.com/foundations/typography/\n */\n fontWeight: {\n light: 300,\n normal: 400,\n medium: 500,\n /** @deprecated Use medium (500) instead - Astro spec only supports 300, 400, 500, 700 */\n semibold: 500, // Changed from 600 to 500 for Astro compliance\n bold: 700,\n },\n lineHeight: {\n tight: '1.25rem',\n normal: '1.5rem',\n relaxed: '1.75rem',\n },\n letterSpacing: {\n tight: '-0.5px',\n normal: '0',\n wide: '0.5px',\n },\n },\n shadows: shadowsDark,\n animation: animationTokens,\n focus: focusTokensDark,\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Astro UX Light Theme\n// ============================================================================\n\nconst astroThemeLight: ThemeTokensBase = {\n colors: {\n background: {\n base: '#eaeef4',\n surface: '#f5f8fc',\n elevated: '#ffffff',\n overlay: 'rgba(234, 238, 244, 0.95)',\n },\n border: {\n default: '#2b659b',\n muted: '#d1d5db',\n focus: '#0066cc',\n },\n text: {\n primary: '#1b2d3e',\n secondary: '#51667c',\n tertiary: '#556a7c', // WCAG AA: 4.81:1 on #eaeef4, 5.24:1 on #f5f8fc, 5.61:1 on #fff (was #8fa4b7 → 2.25:1 FAIL)\n muted: '#556a7c', // WCAG AA compliant (was #8fa4b7)\n inverse: '#ffffff',\n },\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#4dacff',\n },\n accent: {\n primary: '#0066cc',\n secondary: '#56f000',\n tertiary: '#7c3aed',\n },\n interactive: {\n default: '#0066cc',\n hover: '#0052a3',\n active: '#003d7a',\n disabled: '#a4abb6',\n },\n },\n spacing: astroThemeDark.spacing,\n borderRadius: astroThemeDark.borderRadius,\n elementSize: astroThemeDark.elementSize,\n typography: astroThemeDark.typography,\n shadows: shadowsLight,\n animation: animationTokens,\n focus: focusTokensLight,\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Hybrid Theme (Zendir Background + Astro Status + Purple Accents)\n// Modern, award-winning design with Zendir purple personality\n// ============================================================================\n\nconst focusTokensPurpleHue: ThemeFocus = {\n color: '#8b5cf6',\n width: '2px',\n offset: '2px',\n ring: '0 0 0 2px #8b5cf6',\n style: {\n outline: '2px solid #8b5cf6',\n outlineOffset: '2px',\n },\n};\n\nconst hybridTheme: ThemeTokensBase = {\n colors: {\n background: {\n base: '#09090b',\n surface: 'rgba(24, 24, 27, 0.98)',\n elevated: 'rgba(39, 39, 42, 0.98)',\n overlay: 'rgba(0, 0, 0, 0.85)',\n },\n border: {\n default: 'rgba(139, 92, 246, 0.3)', // Purple tint\n muted: 'rgba(63, 63, 70, 0.5)',\n focus: '#8b5cf6', // Zendir purple\n },\n text: {\n primary: '#ffffff',\n secondary: '#a1a1aa',\n tertiary: '#8e8e96', // WCAG AA: 6.12:1 on #09090b, 5.45:1 on #18181b, 4.58:1 on #27272a (was #71717a → 4.07:1 FAIL)\n muted: '#8e8e96', // WCAG AA compliant (was #71717a)\n inverse: '#09090b',\n },\n // Astro UXD Status Colors (unchanged for compliance)\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#8b5cf6', // Purple for info\n },\n // Zendir Purple Accent Palette\n accent: {\n primary: '#8b5cf6', // Vibrant purple\n secondary: '#a78bfa', // Light purple\n tertiary: '#7c3aed', // Deep purple\n },\n interactive: {\n default: '#8b5cf6',\n hover: '#a78bfa',\n active: '#7c3aed',\n disabled: '#52525b',\n },\n },\n spacing: astroThemeDark.spacing,\n borderRadius: {\n none: '0',\n xs: '2px',\n sm: '4px',\n md: '6px',\n lg: '10px',\n xl: '14px',\n full: '9999px',\n },\n elementSize: astroThemeDark.elementSize,\n typography: astroThemeDark.typography,\n shadows: {\n ...shadowsDark,\n glow: (color: string) => `0 0 20px ${color}50, 0 0 40px ${color}25, 0 4px 12px ${color}20`,\n },\n animation: animationTokens,\n focus: focusTokensPurpleHue,\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Purple-Hue Theme - Full Purple Personality\n// Award-winning dark theme with purple accents\n// ============================================================================\n\nconst purpleHueTheme: ThemeTokensBase = {\n colors: {\n background: {\n base: '#0a0a0f',\n surface: 'rgba(18, 18, 28, 0.98)',\n elevated: 'rgba(28, 28, 42, 0.98)',\n overlay: 'rgba(0, 0, 0, 0.9)',\n },\n border: {\n default: 'rgba(139, 92, 246, 0.25)',\n muted: 'rgba(55, 48, 82, 0.5)',\n focus: '#8b5cf6',\n },\n text: {\n primary: '#fafafa',\n secondary: '#a1a1aa',\n tertiary: '#8e8e96', // WCAG AA: 6.08:1 on #0a0a0f, 5.02:1 on elevated (was #71717a → 4.05:1 FAIL)\n muted: '#8e8e96', // WCAG AA compliant (was #71717a)\n inverse: '#0a0a0f',\n },\n // Astro UXD Status Colors (for compliance)\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#a78bfa',\n },\n // Zendir Purple Accent Palette\n accent: {\n primary: '#8b5cf6', // Vibrant purple\n secondary: '#a78bfa', // Light purple\n tertiary: '#7c3aed', // Deep purple\n },\n interactive: {\n default: '#8b5cf6',\n hover: '#a78bfa',\n active: '#7c3aed',\n disabled: '#52525b',\n },\n },\n spacing: astroThemeDark.spacing,\n borderRadius: {\n none: '0',\n xs: '2px',\n sm: '4px',\n md: '6px',\n lg: '10px',\n xl: '14px',\n full: '9999px',\n },\n elementSize: astroThemeDark.elementSize,\n // Same typography as hybrid (Astro UX font stack with full fallbacks) for consistent card font across themes\n typography: astroThemeDark.typography,\n shadows: {\n ...shadowsDark,\n glow: (color: string) => `0 0 25px ${color}60, 0 0 50px ${color}30, 0 4px 16px ${color}25`,\n },\n animation: animationTokens,\n focus: {\n ...focusTokensPurpleHue,\n },\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Transparent Purple-Hue Theme - Glassmorphic Panels\n// Optimized for glass card overlays with transparent backgrounds\n// ============================================================================\n\nconst transparentTheme: ThemeTokensBase = {\n colors: {\n background: {\n // Highly transparent backgrounds for glass effect\n base: 'rgba(8, 12, 20, 0.95)',\n surface: 'rgba(15, 20, 35, 0.85)',\n elevated: 'rgba(25, 35, 55, 0.80)',\n overlay: 'rgba(0, 0, 0, 0.75)',\n },\n border: {\n // Purple accent borders (Zendir brand)\n default: 'rgba(139, 92, 246, 0.25)',\n muted: 'rgba(139, 92, 246, 0.15)',\n focus: '#8b5cf6',\n // Thin faded card border with purple hint\n fadedBoxShadow: 'inset 0 1px 0 rgba(139, 92, 246, 0.12), inset 0 -1px 0 rgba(0, 0, 0, 0.05), inset 1px 0 0 rgba(139, 92, 246, 0.06), inset -1px 0 0 rgba(139, 92, 246, 0.06)',\n },\n text: {\n primary: '#f0f4f8',\n secondary: '#94a3b8',\n tertiary: '#7b8da1', // WCAG AA: 5.71:1 on base, 5.34:1 on elevated (was #64748b → 3.66:1 FAIL)\n muted: '#7b8da1', // WCAG AA compliant (was #64748b)\n inverse: '#0f172a',\n },\n // Astro UXD Status Colors\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#8b5cf6',\n },\n // Purple accent (matching hybrid theme for consistency)\n accent: {\n primary: '#8b5cf6', // Vibrant purple\n secondary: '#a78bfa', // Light purple\n tertiary: '#7c3aed', // Deep purple\n },\n interactive: {\n default: '#8b5cf6', // Purple for interactive elements\n hover: '#a78bfa', // Light purple on hover\n active: '#7c3aed', // Deep purple on active\n disabled: '#475569',\n // Purple-hue transparent backgrounds for buttons/inputs (transparent + transparent-bold)\n transparentDefault: 'rgba(139, 92, 246, 0.12)',\n transparentHover: 'rgba(139, 92, 246, 0.32)',\n transparentInputBg: 'rgba(139, 92, 246, 0.08)',\n },\n },\n spacing: astroThemeDark.spacing,\n borderRadius: {\n none: '0',\n xs: '2px',\n sm: '4px',\n md: '8px',\n lg: '12px',\n xl: '16px',\n full: '9999px',\n },\n elementSize: astroThemeDark.elementSize,\n // Same typography as hybrid for consistent card font across themes\n typography: astroThemeDark.typography,\n shadows: {\n ...shadowsDark,\n // Enhanced glow shadows for glass effect\n glow: (color: string) => `0 0 30px ${color}50, 0 0 60px ${color}25, 0 4px 20px rgba(0,0,0,0.4)`,\n },\n animation: animationTokens,\n focus: {\n color: '#8b5cf6', // Purple focus ring\n width: '2px',\n offset: '2px',\n ring: '0 0 0 2px #8b5cf6',\n style: {\n outline: '2px solid #8b5cf6',\n outlineOffset: '2px',\n },\n },\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Transparent Minimal Theme - Ultra-clean glassmorphic panels\n// Extremely subtle borders, minimal visual noise, clean dark surfaces\n// ============================================================================\n\nconst transparentMinimalTheme: ThemeTokensBase = {\n colors: {\n background: {\n // Same as transparent theme\n base: 'rgba(8, 12, 20, 0.95)',\n surface: 'rgba(15, 20, 35, 0.85)',\n elevated: 'rgba(25, 35, 55, 0.80)',\n overlay: 'rgba(0, 0, 0, 0.75)',\n },\n border: {\n // Accent-colored borders for minimal theme (Zendir purple)\n default: 'rgba(139, 92, 246, 0.25)',\n muted: 'rgba(139, 92, 246, 0.15)',\n focus: '#8b5cf6',\n // Subtle card border using accent color\n fadedBoxShadow: 'inset 0 1px 0 rgba(139, 92, 246, 0.1), inset 0 -1px 0 rgba(0, 0, 0, 0.1), inset 1px 0 0 rgba(139, 92, 246, 0.05), inset -1px 0 0 rgba(139, 92, 246, 0.05)',\n },\n text: {\n primary: '#f0f4f8',\n secondary: '#94a3b8',\n tertiary: '#7b8da1', // WCAG AA: 5.71:1 on base, 5.34:1 on elevated (was #64748b → 3.66:1 FAIL)\n muted: '#7b8da1', // WCAG AA compliant (was #64748b)\n inverse: '#0f172a',\n },\n // Astro UXD Status Colors\n status: {\n normal: '#56f000',\n standby: '#2dccff',\n caution: '#fce83a',\n serious: '#ffb302',\n critical: '#ff3838',\n off: '#a4abb6',\n },\n semantic: {\n success: '#56f000',\n warning: '#fce83a',\n error: '#ff3838',\n info: '#8b5cf6',\n },\n // Purple accent (matching transparent theme for consistency)\n accent: {\n primary: '#8b5cf6', // Vibrant purple\n secondary: '#a78bfa', // Light purple\n tertiary: '#7c3aed', // Deep purple\n },\n interactive: {\n default: '#8b5cf6', // Purple for interactive elements\n hover: '#a78bfa', // Light purple on hover\n active: '#7c3aed', // Deep purple on active\n disabled: '#475569',\n // Purple-hue transparent backgrounds for buttons/inputs (same as transparent theme)\n transparentDefault: 'rgba(139, 92, 246, 0.12)',\n transparentHover: 'rgba(139, 92, 246, 0.32)',\n transparentInputBg: 'rgba(139, 92, 246, 0.08)',\n },\n },\n spacing: astroThemeDark.spacing,\n borderRadius: {\n none: '0',\n xs: '2px',\n sm: '4px',\n md: '8px',\n lg: '12px',\n xl: '16px',\n full: '9999px',\n },\n elementSize: astroThemeDark.elementSize,\n // Same typography as hybrid for consistent card font across themes\n typography: astroThemeDark.typography,\n shadows: {\n ...shadowsDark,\n // Same glow as transparent theme\n glow: (color: string) => `0 0 30px ${color}50, 0 0 60px ${color}25, 0 4px 20px rgba(0,0,0,0.4)`,\n },\n animation: animationTokens,\n focus: {\n color: '#8b5cf6', // Purple focus ring\n width: '2px',\n offset: '2px',\n ring: '0 0 0 2px #8b5cf6',\n style: {\n outline: '2px solid #8b5cf6',\n outlineOffset: '2px',\n },\n },\n layout: layoutTokens,\n};\n\n// ============================================================================\n// Theme Context\n// ============================================================================\n\nexport interface ThemeContextValue {\n theme: ThemeVariant;\n mode: ThemeMode;\n tokens: ThemeTokens;\n prefersReducedMotion: boolean;\n /** Custom accent color override (null = use theme default) */\n accentColor: string | null;\n setTheme: (theme: ThemeVariant) => void;\n setMode: (mode: ThemeMode) => void;\n toggleMode: () => void;\n /** Override the accent color for the current theme */\n setAccentColor: (color: string | null) => void;\n}\n\nconst ThemeContext = createContext<ThemeContextValue | undefined>(undefined);\n\nexport interface ThemeProviderProps {\n children: ReactNode;\n /** Default theme variant */\n theme?: ThemeVariant;\n /** Alias for `theme` */\n defaultVariant?: ThemeVariant;\n /** Default color mode */\n mode?: ThemeMode;\n /** Alias for `mode` */\n defaultMode?: ThemeMode;\n /** Persist preferences to localStorage */\n persist?: boolean;\n}\n\n// ============================================================================\n// Scrollbar Styling System\n// ============================================================================\n// Generates global CSS for thin, elegant, theme-aware scrollbars.\n//\n// Features:\n// - Ultra-thin (6px) scrollbar tracks with soft border radius\n// - Accent-colored thumb with hover/active brightness shifts\n// - Semi-transparent track that blends into the surface\n// - Auto-hide behaviour on modern browsers (overlay mode)\n// - Firefox support via scrollbar-width / scrollbar-color\n// - WCAG 2.1 AA compliant: sufficient contrast, respects reduced-motion\n// - Smooth transitions (disabled when prefers-reduced-motion)\n// - Scoped .zendir-scroll utility class for individual containers\n// ============================================================================\n\n/**\n * Converts a hex color to an rgba string helper.\n * Accepts 3/6/8-char hex codes (#rgb, #rrggbb, #rrggbbaa).\n */\nfunction hexToRgba(hex: string, alpha: number): string {\n const clean = hex.replace('#', '');\n let r: number, g: number, b: number;\n if (clean.length === 3) {\n r = parseInt(clean[0] + clean[0], 16);\n g = parseInt(clean[1] + clean[1], 16);\n b = parseInt(clean[2] + clean[2], 16);\n } else {\n r = parseInt(clean.slice(0, 2), 16);\n g = parseInt(clean.slice(2, 4), 16);\n b = parseInt(clean.slice(4, 6), 16);\n }\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\nfunction buildScrollbarCSS(tokens: ThemeTokens, mode: ThemeMode, reducedMotion: boolean): string {\n const accent = tokens.colors.accent.primary;\n const _surface = tokens.colors.background.surface; // eslint-disable-line @typescript-eslint/no-unused-vars -- reserved for future scrollbar track customisation\n const _base = tokens.colors.background.base; // eslint-disable-line @typescript-eslint/no-unused-vars -- reserved for future scrollbar corner styling\n const isLight = mode === 'light';\n\n // Thumb colors: accent-tinted, low opacity at rest, stronger on hover/active\n const thumbRest = isLight ? hexToRgba(accent, 0.28) : hexToRgba(accent, 0.35);\n const thumbHover = isLight ? hexToRgba(accent, 0.48) : hexToRgba(accent, 0.55);\n const thumbActive = isLight ? hexToRgba(accent, 0.64) : hexToRgba(accent, 0.72);\n\n // Track: nearly invisible surface blend\n const trackColor = isLight ? hexToRgba(accent, 0.04) : hexToRgba(accent, 0.06);\n const trackHover = isLight ? hexToRgba(accent, 0.08) : hexToRgba(accent, 0.10);\n\n const transition = reducedMotion ? 'none' : 'background-color 200ms ease, width 200ms ease, opacity 200ms ease';\n const thumbRadius = '9999px'; // pill shape\n\n // Firefox colors (two-value syntax: thumb track)\n const ffThumb = thumbRest;\n const ffTrack = trackColor;\n\n return `\n/* ═══════════════════════════════════════════════════════════════════════════\n Zendir Scrollbar System — Thin · Elegant · Theme-Connected\n ═══════════════════════════════════════════════════════════════════════════ */\n\n/* ── Firefox ────────────────────────────────────────────────────────────── */\n*,\n.zendir-scroll {\n scrollbar-width: thin;\n scrollbar-color: ${ffThumb} ${ffTrack};\n}\n\n/* ── Webkit / Blink (Chrome, Edge, Safari, Opera) ───────────────────────── */\n\n/* Global thin scrollbar */\n::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n background: transparent;\n}\n\n/* Track — nearly invisible, subtle on hover */\n::-webkit-scrollbar-track {\n background: ${trackColor};\n border-radius: ${thumbRadius};\n margin: 2px;\n}\n::-webkit-scrollbar-track:hover {\n background: ${trackHover};\n}\n\n/* Thumb — accent-tinted pill */\n::-webkit-scrollbar-thumb {\n background: ${thumbRest};\n border-radius: ${thumbRadius};\n border: 1px solid transparent;\n background-clip: padding-box;\n transition: ${transition};\n min-height: 32px;\n}\n::-webkit-scrollbar-thumb:hover {\n background: ${thumbHover};\n border-color: transparent;\n background-clip: padding-box;\n}\n::-webkit-scrollbar-thumb:active {\n background: ${thumbActive};\n border-color: transparent;\n background-clip: padding-box;\n}\n\n/* Corner — where horizontal & vertical scrollbars meet */\n::-webkit-scrollbar-corner {\n background: transparent;\n}\n\n/* ── Utility class: zendir-scroll ────────────────────────────────────────\n Apply to individual containers for scoped thin scrollbar.\n Also enables overlay behaviour where supported.\n e.g. <div className=\"zendir-scroll\" style={{overflow:'auto'}}>…</div>\n ─────────────────────────────────────────────────────────────────────── */\n.zendir-scroll {\n overflow: auto;\n overflow: overlay; /* Chrome / Edge: auto-hide scrollbar */\n}\n.zendir-scroll::-webkit-scrollbar {\n width: 5px;\n height: 5px;\n}\n.zendir-scroll::-webkit-scrollbar-track {\n background: transparent;\n border-radius: ${thumbRadius};\n}\n.zendir-scroll::-webkit-scrollbar-thumb {\n background: ${thumbRest};\n border-radius: ${thumbRadius};\n transition: ${transition};\n}\n.zendir-scroll::-webkit-scrollbar-thumb:hover {\n background: ${thumbHover};\n}\n.zendir-scroll::-webkit-scrollbar-thumb:active {\n background: ${thumbActive};\n}\n\n/* ── Utility: zendir-scroll--hidden ─────────────────────────────────────\n Hides scrollbar visually but keeps scroll behaviour (accessible).\n Content remains scrollable via mouse wheel / touch / keyboard.\n ─────────────────────────────────────────────────────────────────────── */\n.zendir-scroll--hidden {\n overflow: auto;\n -ms-overflow-style: none;\n scrollbar-width: none;\n}\n.zendir-scroll--hidden::-webkit-scrollbar {\n display: none;\n}\n\n/* ── Focus-visible: keyboard users can still scroll with focus ─────────── */\n.zendir-scroll:focus-visible {\n outline: 2px solid ${accent};\n outline-offset: -2px;\n border-radius: ${tokens.borderRadius.md};\n}\n\n/* ── Reduced Motion: disable scrollbar transitions ─────────────────────── */\n@media (prefers-reduced-motion: reduce) {\n ::-webkit-scrollbar-thumb,\n .zendir-scroll::-webkit-scrollbar-thumb {\n transition: none !important;\n }\n}\n\n/* ── High Contrast Mode: ensure scrollbar is visible ───────────────────── */\n@media (forced-colors: active) {\n ::-webkit-scrollbar-thumb {\n background: ButtonText !important;\n }\n ::-webkit-scrollbar-track {\n background: Canvas !important;\n }\n}\n`.trim();\n}\n\n/**\n * useScrollbarStyles — returns inline React.CSSProperties for a\n * scrollable container that matches the current Zendir theme.\n *\n * Use when you need programmatic control rather than the\n * `zendir-scroll` CSS class.\n *\n * @example\n * ```tsx\n * const scrollStyle = useScrollbarStyles();\n * <div style={{ maxHeight: 400, ...scrollStyle }}>…</div>\n * ```\n */\nexport function useScrollbarStyles(): React.CSSProperties {\n const { tokens, mode } = useTheme();\n return useMemo((): React.CSSProperties => {\n const accent = tokens.colors.accent.primary;\n const isLight = mode === 'light';\n const thumbColor = isLight ? hexToRgba(accent, 0.28) : hexToRgba(accent, 0.35);\n const trackColor = isLight ? hexToRgba(accent, 0.04) : hexToRgba(accent, 0.06);\n return {\n // Firefox\n scrollbarWidth: 'thin' as const,\n scrollbarColor: `${thumbColor} ${trackColor}`,\n overflow: 'auto',\n };\n }, [tokens, mode]);\n}\n\n/**\n * ThemeProvider - Enterprise theme context provider\n * \n * Provides theme tokens, mode switching, and accessibility features\n * to all child components.\n * \n * @example\n * ```tsx\n * <ThemeProvider theme=\"hybrid\" mode=\"dark\"> // Zen (Hybrid) is the default\n * <App />\n * </ThemeProvider>\n * ```\n */\nexport function ThemeProvider({\n children,\n theme: themeProp,\n defaultVariant,\n mode: modeProp,\n defaultMode: defaultModeProp,\n persist = true,\n}: ThemeProviderProps): React.ReactElement {\n const defaultTheme = themeProp ?? defaultVariant ?? 'hybrid';\n const defaultMode = modeProp ?? defaultModeProp ?? 'dark';\n // Initialize theme from localStorage or defaults\n const [theme, setThemeState] = useState<ThemeVariant>(() => {\n if (persist && typeof window !== 'undefined') {\n const saved = localStorage.getItem('zendir-ui-theme');\n if (saved === 'astro' || saved === 'zendir' || saved === 'hybrid' || saved === 'transparent' || saved === 'transparent-bold' || saved === 'transparent-minimal') {\n return saved as ThemeVariant;\n }\n }\n return defaultTheme;\n });\n\n const [mode, setModeState] = useState<ThemeMode>(() => {\n if (persist && typeof window !== 'undefined') {\n const saved = localStorage.getItem('zendir-ui-mode');\n if (saved === 'light' || saved === 'dark') {\n return saved;\n }\n }\n return defaultMode;\n });\n\n // Detect reduced motion preference\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handler = (e: MediaQueryListEvent) => setPrefersReducedMotion(e.matches);\n mediaQuery.addEventListener('change', handler);\n return () => mediaQuery.removeEventListener('change', handler);\n }, []);\n\n // Theme setters\n const setTheme = (newTheme: ThemeVariant) => {\n setThemeState(newTheme);\n if (persist && typeof window !== 'undefined') {\n localStorage.setItem('zendir-ui-theme', newTheme);\n }\n };\n\n const setMode = (newMode: ThemeMode) => {\n setModeState(newMode);\n if (persist && typeof window !== 'undefined') {\n localStorage.setItem('zendir-ui-mode', newMode);\n }\n };\n\n const toggleMode = () => {\n setMode(mode === 'dark' ? 'light' : 'dark');\n };\n\n // Accent color override\n const [accentColor, setAccentColorState] = useState<string | null>(() => {\n if (persist && typeof window !== 'undefined') {\n return localStorage.getItem('zendir-ui-accent') || null;\n }\n return null;\n });\n\n const setAccentColor = (color: string | null) => {\n setAccentColorState(color);\n if (persist && typeof window !== 'undefined') {\n if (color) {\n localStorage.setItem('zendir-ui-accent', color);\n } else {\n localStorage.removeItem('zendir-ui-accent');\n }\n }\n };\n\n // Get theme tokens (card border styles computed so all cards use theme-driven borders)\n const tokens = useMemo((): ThemeTokens => {\n // If light mode is selected, always use Astro Light theme (unified light mode)\n // regardless of the selected theme variant\n const base =\n mode === 'light'\n ? astroThemeLight\n : theme === 'astro'\n ? astroThemeDark\n : theme === 'hybrid'\n ? hybridTheme\n : theme === 'transparent' || theme === 'transparent-bold'\n ? transparentTheme\n : theme === 'transparent-minimal'\n ? transparentMinimalTheme\n : purpleHueTheme;\n const isTransparent =\n theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const isMinimal = theme === 'transparent-minimal';\n \n // For transparent-minimal: use visible accent-colored borders.\n // For other transparent themes: use subtle fadedBoxShadow.\n // Accent overrides are intentionally scoped to transparent variants only,\n // so switching to Astro/Hybrid/Purple-Hue restores each theme's native accent.\n const resolvedAccent = (isTransparent && accentColor)\n ? {\n primary: accentColor,\n secondary: adjustHexBrightness(accentColor, 1.2),\n tertiary: adjustHexBrightness(accentColor, 0.85),\n }\n : base.colors.accent;\n\n const accentPrimary = resolvedAccent.primary;\n const accentBorderMuted = `${accentPrimary}40`; // 25% opacity\n const accentBorderDefault = `${accentPrimary}66`; // 40% opacity\n const accentFadedBoxShadow = `inset 0 1px 0 ${hexToRgba(accentPrimary, 0.12)}, inset 0 -1px 0 rgba(0, 0, 0, 0.05), inset 1px 0 0 ${hexToRgba(accentPrimary, 0.06)}, inset -1px 0 0 ${hexToRgba(accentPrimary, 0.06)}`;\n \n const cardStyle = isMinimal\n ? { border: `1px solid ${accentBorderMuted}` }\n : isTransparent\n ? { border: 'none' as const, boxShadow: accentFadedBoxShadow }\n : { border: `1px solid ${base.colors.border.muted}` };\n const cardStyleDashed = isMinimal\n ? { border: `1px dashed ${accentBorderMuted}` }\n : isTransparent\n ? { border: 'none' as const, boxShadow: accentFadedBoxShadow }\n : { border: `1px dashed ${base.colors.border.muted}` };\n const cardStyleDefault = isMinimal\n ? { border: `1px solid ${accentBorderDefault}` }\n : isTransparent\n ? { border: 'none' as const, boxShadow: accentFadedBoxShadow }\n : { border: `1px solid ${base.colors.border.default}` };\n // Compute border tokens from the resolved theme colors\n const resolvedColors: ThemeColors = {\n ...base.colors,\n accent: resolvedAccent,\n border: {\n ...base.colors.border,\n cardStyle,\n cardStyleDashed,\n cardStyleDefault,\n },\n };\n\n return {\n ...base,\n colors: resolvedColors,\n borders: computeBorderTokens(resolvedColors),\n } as ThemeTokens;\n }, [theme, mode, accentColor]);\n\n // Apply CSS variables to document\n useEffect(() => {\n if (typeof document === 'undefined') return;\n\n const root = document.documentElement;\n const { colors, typography, spacing, borderRadius, animation, focus, shadows } = tokens;\n\n // Theme mode attribute\n root.setAttribute('data-theme', mode);\n root.setAttribute('data-variant', theme);\n\n // Background colors\n root.style.setProperty('--color-background-base', colors.background.base);\n root.style.setProperty('--color-background-surface', colors.background.surface);\n root.style.setProperty('--color-background-elevated', colors.background.elevated);\n root.style.setProperty('--color-background-overlay', colors.background.overlay);\n\n // Border colors\n root.style.setProperty('--color-border', colors.border.default);\n root.style.setProperty('--color-border-muted', colors.border.muted);\n root.style.setProperty('--color-border-focus', colors.border.focus);\n\n // Text colors\n root.style.setProperty('--color-text-primary', colors.text.primary);\n root.style.setProperty('--color-text-secondary', colors.text.secondary);\n root.style.setProperty('--color-text-tertiary', colors.text.tertiary);\n root.style.setProperty('--color-text-inverse', colors.text.inverse);\n\n // Status colors\n root.style.setProperty('--color-status-normal', colors.status.normal);\n root.style.setProperty('--color-status-standby', colors.status.standby);\n root.style.setProperty('--color-status-caution', colors.status.caution);\n root.style.setProperty('--color-status-serious', colors.status.serious);\n root.style.setProperty('--color-status-critical', colors.status.critical);\n root.style.setProperty('--color-status-off', colors.status.off);\n\n // Interactive colors\n root.style.setProperty('--color-interactive-default', colors.interactive.default);\n root.style.setProperty('--color-interactive-hover', colors.interactive.hover);\n root.style.setProperty('--color-interactive-active', colors.interactive.active);\n root.style.setProperty('--color-interactive-disabled', colors.interactive.disabled);\n\n // Accent colors\n root.style.setProperty('--color-accent-primary', colors.accent.primary);\n root.style.setProperty('--color-accent-secondary', colors.accent.secondary);\n root.style.setProperty('--color-accent-tertiary', colors.accent.tertiary);\n\n // Typography\n // @ts-expect-error - heading may not be strictly typed on older builds\n root.style.setProperty('--font-family-heading', typography.fontFamily.heading || typography.fontFamily.primary);\n root.style.setProperty('--font-family-primary', typography.fontFamily.primary);\n root.style.setProperty('--font-family-mono', typography.fontFamily.mono);\n\n // Spacing (full scale so CSS and layout can pull from SDK)\n root.style.setProperty('--spacing-xxs', spacing.xxs);\n root.style.setProperty('--spacing-xs', spacing.xs);\n root.style.setProperty('--spacing-sm', spacing.sm);\n root.style.setProperty('--spacing-smd', spacing.smd);\n root.style.setProperty('--spacing-md', spacing.md);\n root.style.setProperty('--spacing-mdl', spacing.mdl);\n root.style.setProperty('--spacing-lg', spacing.lg);\n root.style.setProperty('--spacing-xl', spacing.xl);\n root.style.setProperty('--spacing-xxl', spacing.xxl);\n\n // Border radius\n root.style.setProperty('--radius-sm', borderRadius.sm);\n root.style.setProperty('--radius-md', borderRadius.md);\n root.style.setProperty('--radius-lg', borderRadius.lg);\n root.style.setProperty('--radius-xl', borderRadius.xl);\n\n // Animation (respect reduced motion)\n const motionMultiplier = prefersReducedMotion ? 0 : 1;\n root.style.setProperty('--animation-fast', prefersReducedMotion ? 'none' : animation.fast);\n root.style.setProperty('--animation-normal', prefersReducedMotion ? 'none' : animation.normal);\n root.style.setProperty('--animation-slow', prefersReducedMotion ? 'none' : animation.slow);\n root.style.setProperty('--duration-fast', `${animation.duration.fast * motionMultiplier}ms`);\n root.style.setProperty('--duration-normal', `${animation.duration.normal * motionMultiplier}ms`);\n root.style.setProperty('--duration-slow', `${animation.duration.slow * motionMultiplier}ms`);\n\n // Focus\n root.style.setProperty('--focus-ring-color', focus.color);\n root.style.setProperty('--focus-ring-width', focus.width);\n root.style.setProperty('--focus-ring-offset', focus.offset);\n\n // Shadows\n root.style.setProperty('--shadow-sm', shadows.sm);\n root.style.setProperty('--shadow-md', shadows.md);\n root.style.setProperty('--shadow-lg', shadows.lg);\n root.style.setProperty('--shadow-xl', shadows.xl);\n\n // Apply base styles to body\n document.body.style.backgroundColor = colors.background.base;\n document.body.style.color = colors.text.primary;\n document.body.style.fontFamily = typography.fontFamily.primary;\n }, [tokens, theme, mode, prefersReducedMotion]);\n\n // ──────────────────────────────────────────────────────────────────────────\n // Scrollbar Styles — thin, elegant, theme-connected, fully accessible\n // ──────────────────────────────────────────────────────────────────────────\n const scrollbarCSS = useMemo(() => buildScrollbarCSS(tokens, mode, prefersReducedMotion), [tokens, mode, prefersReducedMotion]);\n\n const value: ThemeContextValue = useMemo(\n () => ({\n theme,\n mode,\n tokens,\n prefersReducedMotion,\n accentColor,\n setTheme,\n setMode,\n toggleMode,\n setAccentColor,\n }),\n [theme, mode, tokens, prefersReducedMotion, accentColor]\n );\n\n // Global reduced-motion rule — ensures ALL animations and transitions across\n // every Zendir component respect the OS preference (WCAG 2.3.3).\n // Uses 0.01ms (not 0) so animation-end events still fire correctly.\n const reducedMotionCSS = `@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n scroll-behavior: auto !important;\n }\n}`;\n\n return (\n <ThemeContext.Provider value={value}>\n <style data-zendir-scrollbar=\"\" dangerouslySetInnerHTML={{ __html: scrollbarCSS }} />\n <style data-zendir-reduced-motion=\"\" dangerouslySetInnerHTML={{ __html: reducedMotionCSS }} />\n {children}\n </ThemeContext.Provider>\n );\n}\n\n/**\n * useTheme - Access theme context\n * \n * @throws Error if used outside ThemeProvider\n * \n * @example\n * ```tsx\n * const { tokens, mode, toggleMode } = useTheme();\n * ```\n */\nexport function useTheme(): ThemeContextValue {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n}\n\n/**\n * useThemeTokens - Access only theme tokens (for memoization)\n */\nexport function useThemeTokens(): ThemeTokens {\n return useTheme().tokens;\n}\n"],"names":[],"mappings":"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"}
package/dist/react.js CHANGED
@@ -53,8 +53,8 @@ import { PacketViewer } from "./react/core/PacketViewer.js";
53
53
  import { Pagination } from "./react/core/Pagination.js";
54
54
  import { PinInput } from "./react/core/PinInput.js";
55
55
  import { Progress } from "./react/astro/Progress.js";
56
+ import { SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX, SideNav } from "./react/core/SideNav.js";
56
57
  import { Select } from "./react/core/Select.js";
57
- import { SideNav } from "./react/core/SideNav.js";
58
58
  import { SidePanel } from "./react/core/SidePanel.js";
59
59
  import { Spacer } from "./react/core/layout/Spacer.js";
60
60
  import { StatusIndicator } from "./react/astro/StatusIndicator.js";
@@ -153,6 +153,7 @@ export {
153
153
  Progress,
154
154
  REGION_BORDER_COLORS,
155
155
  REGION_COLORS,
156
+ SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX,
156
157
  SPACE_SYSTEM_COLORS,
157
158
  STATUS_COLORS,
158
159
  Select,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zendir/ui",
3
- "version": "0.1.10",
3
+ "version": "0.1.13",
4
4
  "description": "React UI components for space operations, built on the Astro UX Design System",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",