@pablo2410/shared-ui 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DashboardLayout-Bors1KO3.d.ts +160 -0
- package/dist/chunk-MAKRKBBI.js +850 -0
- package/dist/chunk-MAKRKBBI.js.map +1 -0
- package/dist/layout/index.d.ts +4 -158
- package/dist/layout/index.js +20 -828
- package/dist/layout/index.js.map +1 -1
- package/dist/shell/index.d.ts +81 -0
- package/dist/shell/index.js +12 -0
- package/dist/shell/index.js.map +1 -0
- package/dist/shell/oplytics-shell.css +2 -0
- package/dist/theme/oplytics-theme.css +86 -0
- package/package.json +12 -3
package/dist/layout/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/layout/SharedSidebar.tsx","../../src/layout/DashboardLayout.tsx","../../src/layout/DashboardLayoutSkeleton.tsx","../../src/layout/SharedPageHeader.tsx","../../src/layout/SharedFooter.tsx","../../src/layout/ServiceFooter.tsx","../../src/layout/createServiceLayout.tsx","../../src/layout/serviceConfigs.ts"],"sourcesContent":["/**\n * SharedSidebar — Config-driven sidebar component for all Oplytics subdomains.\n *\n * Replaces per-subdomain DashboardLayout sidebar implementations with a single\n * shared component. Each subdomain provides its own configuration (menu items,\n * service name, feature flags) and gets a consistent sidebar experience.\n *\n * Features:\n * - Resizable sidebar with localStorage persistence\n * - Collapsible icon mode with tooltips\n * - Service branding (icon + name) in header\n * - \"Back to Service Hub/Portal\" link (configurable)\n * - Grouped menu sections with optional section labels\n * - Admin-only menu items (role-gated)\n * - User avatar footer with optional logout dropdown\n * - Mobile-responsive with auto-collapse\n *\n * Usage:\n * import { createServiceLayout } from \"@shared/components/SharedSidebar\";\n * const MyLayout = createServiceLayout({ serviceName: \"SQDCP\", ... });\n * // Then use <MyLayout>{children}</MyLayout> in your routes\n *\n * @module shared/components/SharedSidebar\n */\n\nimport React, { CSSProperties, useEffect, useRef, useState } from \"react\";\n\n/* ── Types ── */\n\nexport interface MenuItem {\n icon: React.ComponentType<{ className?: string }>;\n label: string;\n path: string;\n /** Optional badge text (e.g. count) */\n badge?: string | number;\n}\n\nexport interface MenuSection {\n /** Section label displayed above items */\n label?: string;\n /** Alias for label — used by DashboardLayout */\n title?: string;\n items: MenuItem[];\n adminOnly?: boolean;\n}\n\nexport interface SharedSidebarConfig {\n /** Display name shown in sidebar header */\n serviceName: string;\n /** Icon component rendered next to service name */\n serviceIcon: React.ReactNode;\n /** Primary navigation items */\n menuSections: MenuSection[];\n /** Show \"Back to Service Hub\" / \"Back to Portal\" link at top of nav */\n backLink?: {\n label: string;\n path: string;\n };\n /** localStorage key prefix for sidebar width persistence */\n storageKeyPrefix?: string;\n /** Default sidebar width in pixels (default: 260) */\n defaultWidth?: number;\n /** Minimum sidebar width in pixels (default: 200) */\n minWidth?: number;\n /** Maximum sidebar width in pixels (default: 480) */\n maxWidth?: number;\n}\n\nexport interface SharedSidebarProps {\n config: SharedSidebarConfig;\n /** Current route location */\n location: string;\n /** Navigate to a path */\n setLocation: (path: string) => void;\n /** Current user object (null if not authenticated) */\n user: { name?: string; email?: string; role?: string } | null;\n /** Logout handler */\n onLogout?: () => void;\n /** Whether sidebar is collapsed */\n isCollapsed: boolean;\n /** Toggle sidebar collapsed state */\n toggleSidebar: () => void;\n /** Whether user has admin role */\n isAdmin: boolean;\n /** Children rendered in SidebarInset main area */\n children: React.ReactNode;\n}\n\n/* ── Constants ── */\n\nconst ADMIN_ROLES = [\"enterprise_admin\", \"platform_admin\", \"admin\", \"superuser\"];\n\n/* ── Helpers ── */\n\nexport function isAdminRole(role?: string): boolean {\n return !!role && ADMIN_ROLES.includes(role);\n}\n\nexport function getInitials(name?: string): string {\n if (!name) return \"U\";\n return name\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n}\n\n/**\n * Determines if a menu item is active based on current location.\n * Exact match for root paths, startsWith for nested paths.\n */\nexport function isMenuItemActive(itemPath: string, location: string, basePath?: string): boolean {\n if (basePath) {\n // For subdomain routes with a base path (e.g., /app/policy-deployment)\n if (itemPath === basePath) return location === basePath;\n return location.startsWith(itemPath);\n }\n // For root-level routes\n if (itemPath === \"/\") return location === \"/\";\n return location.startsWith(itemPath);\n}\n\n/* ── Resize Hook ── */\n\nexport function useSidebarResize(config: {\n storageKey: string;\n defaultWidth: number;\n minWidth: number;\n maxWidth: number;\n}) {\n const [width, setWidth] = useState(() => {\n if (typeof window === \"undefined\") return config.defaultWidth;\n const saved = localStorage.getItem(config.storageKey);\n return saved ? parseInt(saved, 10) : config.defaultWidth;\n });\n const [isResizing, setIsResizing] = useState(false);\n const startX = useRef(0);\n const startWidth = useRef(config.defaultWidth);\n\n useEffect(() => {\n localStorage.setItem(config.storageKey, String(width));\n }, [width, config.storageKey]);\n\n useEffect(() => {\n if (!isResizing) return;\n const onMove = (e: MouseEvent) => {\n const newWidth = Math.min(\n config.maxWidth,\n Math.max(config.minWidth, startWidth.current + (e.clientX - startX.current))\n );\n setWidth(newWidth);\n };\n const onUp = () => {\n setIsResizing(false);\n };\n document.addEventListener(\"mousemove\", onMove);\n document.addEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n return () => {\n document.removeEventListener(\"mousemove\", onMove);\n document.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n };\n }, [isResizing, config.minWidth, config.maxWidth]);\n\n const startResize = (e: React.MouseEvent) => {\n setIsResizing(true);\n startX.current = e.clientX;\n startWidth.current = width;\n };\n\n return { width, isResizing, startResize };\n}\n\n/* ── Export config type for subdomain use ── */\nexport type { SharedSidebarConfig as SidebarConfig };\n","/**\n * DashboardLayout — the canonical sidebar + header shell for every Oplytics\n * subdomain (the \"Policy Deployment\" gold-standard layout, consolidated).\n *\n * Built on the shadcn `Sidebar` primitives shipped from `@pablo2410/shared-ui/primitives`.\n * It renders an identical chrome across services:\n * - Collapsible icon sidebar with a brand header (icon + service name)\n * - \"← Service Hub\" link pinned to the top of the nav\n * - Grouped, optionally admin-gated menu sections\n * - Settings footer\n * - Sticky top header with a hierarchy-breadcrumb slot, enterprise badge,\n * reporting-toolbar slot, and a user menu\n *\n * The component is intentionally app-agnostic: it imports no app hooks\n * (`useAuth`, `useHierarchy`, router). Apps pass identity, navigation state,\n * and their hierarchy navigator / reporting toolbar in as props/slots.\n *\n * Oplytics dark theme: #0D1220 header, #1E2738 border, #8C34E9 accent.\n */\nimport { type ReactNode } from \"react\";\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarInset,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n SidebarTrigger,\n useSidebar,\n Avatar,\n AvatarFallback,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../primitives\";\nimport { useIsMobile } from \"../primitives/useMobile\";\nimport { ArrowLeft, ExternalLink, LogOut, PanelLeft, Settings } from \"lucide-react\";\nimport { cn } from \"../utils/cn\";\nimport { type MenuItem, type MenuSection, isMenuItemActive } from \"./SharedSidebar\";\n\n/* ── Re-export sidebar types ── */\nexport type { MenuItem, MenuSection };\n\n/* ── Types ── */\n\nexport interface DashboardLayoutUser {\n name?: string;\n email?: string;\n role?: string;\n avatarUrl?: string;\n}\n\nexport interface DashboardLayoutEnterprise {\n name: string;\n code?: string;\n}\n\nexport interface DashboardLayoutProps {\n /** Service/module name shown in the sidebar brand header (e.g. \"OEE Manager\"). */\n serviceName: string;\n /** Service icon (a lucide icon element), shown in the sidebar brand + header. */\n serviceIcon?: ReactNode;\n /** Primary navigation sections. */\n menuSections: MenuSection[];\n /** Admin-only navigation sections, rendered when `isAdmin` is true. */\n adminSections?: MenuSection[];\n /** Whether the current user may see `adminSections`. */\n isAdmin?: boolean;\n /** Current route (the app's router supplies this). */\n activePath: string;\n /** Navigate handler (the app's router supplies this). */\n onNavigate: (path: string) => void;\n /** Optional override for active-item detection. */\n isActive?: (itemPath: string, activePath: string) => boolean;\n /** URL for the \"← Service Hub\" link at the top of the nav (full-page nav). */\n serviceHubUrl?: string;\n /** Footer \"Settings\" route. Omit to hide the footer. */\n settingsPath?: string;\n /** Authenticated user (drives the header user menu). */\n user?: DashboardLayoutUser | null;\n /** Sign-out handler invoked from the user menu. */\n onLogout?: () => void;\n /** \"User Settings\" target in the user menu (full-page nav). */\n userSettingsUrl?: string;\n /** App-provided hierarchy navigator rendered in the header breadcrumb slot. */\n hierarchyNavigator?: ReactNode;\n /** Selected enterprise — drives the header enterprise badge. */\n enterprise?: DashboardLayoutEnterprise | null;\n /** App-provided reporting toolbar rendered on the right of the header. */\n reportingToolbar?: ReactNode;\n /** Whether the sidebar starts expanded. Defaults to `!isMobile`. */\n defaultOpen?: boolean;\n /** Extra footer rendered fixed at the bottom (e.g. a debug/health bar). */\n footer?: ReactNode;\n /** Main content. */\n children: ReactNode;\n}\n\nconst DEFAULT_SERVICE_HUB_URL = \"https://portal.oplytics.digital/app\";\nconst DEFAULT_USER_SETTINGS_URL = \"https://portal.oplytics.digital/account\";\n\n/* ── Header: user menu ── */\n\nfunction UserMenu({\n user,\n onLogout,\n userSettingsUrl = DEFAULT_USER_SETTINGS_URL,\n}: {\n user: DashboardLayoutUser;\n onLogout?: () => void;\n userSettingsUrl?: string;\n}) {\n const initials = (user.name || \"U\")\n .split(\" \")\n .map((n) => n[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button className=\"flex items-center gap-2 rounded-md px-2 py-1 hover:bg-[#1E2738] transition-colors outline-none focus-visible:ring-1 focus-visible:ring-[#8C34E9]\">\n <Avatar className=\"h-7 w-7 border border-[#2A2A3E]\">\n <AvatarFallback className=\"text-[10px] font-medium bg-[#8C34E9]/20 text-[#C084FC]\">\n {initials}\n </AvatarFallback>\n </Avatar>\n <span className=\"hidden md:block text-xs text-[#E2E8F0] truncate max-w-[100px]\">\n {user.name || \"User\"}\n </span>\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-48 bg-[#0D1220] border-[#1E2738]\">\n <div className=\"px-3 py-2 border-b border-[#1E2738]\">\n <p className=\"text-xs font-medium text-[#E2E8F0] truncate\">{user.name}</p>\n <p className=\"text-[10px] text-[#596475] truncate\">{user.role}</p>\n </div>\n <DropdownMenuItem\n onClick={() => {\n window.location.href = userSettingsUrl;\n }}\n className=\"text-xs text-[#E2E8F0] hover:bg-[#1E2738] cursor-pointer focus:bg-[#1E2738]\"\n >\n <Settings className=\"h-3.5 w-3.5 mr-2 text-[#8890A0]\" />\n User Settings\n </DropdownMenuItem>\n <DropdownMenuSeparator className=\"bg-[#1E2738]\" />\n <DropdownMenuItem\n onClick={() => onLogout?.()}\n className=\"text-xs text-[#EF4444] hover:bg-[#EF4444]/10 cursor-pointer focus:bg-[#EF4444]/10 focus:text-[#EF4444]\"\n >\n <LogOut className=\"h-3.5 w-3.5 mr-2\" />\n Sign Out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\n/* ── Header: enterprise badge ── */\n\nfunction EnterpriseBadge({ enterprise }: { enterprise?: DashboardLayoutEnterprise | null }) {\n if (!enterprise) return null;\n return (\n <div className=\"hidden lg:flex items-center gap-1.5 px-2 py-1 rounded-md bg-[#8C34E9]/10 border border-[#8C34E9]/20\">\n <div className=\"h-4 w-4 rounded-sm bg-[#8C34E9]/30 flex items-center justify-center\">\n <span className=\"text-[8px] font-bold text-[#C084FC]\">\n {enterprise.name.charAt(0).toUpperCase()}\n </span>\n </div>\n <span className=\"text-[10px] font-medium text-[#C084FC] truncate max-w-[80px]\">\n {enterprise.code || enterprise.name}\n </span>\n </div>\n );\n}\n\n/* ── Sidebar nav section ── */\n\nfunction NavSection({\n section,\n marginTop,\n isCollapsed,\n resolveActive,\n onNavigate,\n}: {\n section: MenuSection;\n marginTop?: boolean;\n isCollapsed: boolean;\n resolveActive: (path: string) => boolean;\n onNavigate: (path: string) => void;\n}) {\n const label = section.title ?? section.label;\n return (\n <>\n {label && (\n <div className={cn(\"px-4 py-2\", marginTop && \"mt-2\")}>\n {!isCollapsed && (\n <span className=\"text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {label}\n </span>\n )}\n </div>\n )}\n <SidebarMenu className=\"px-2 py-1\">\n {section.items.map((item: MenuItem) => {\n const active = resolveActive(item.path);\n const Icon = item.icon;\n return (\n <SidebarMenuItem key={item.path}>\n <SidebarMenuButton\n isActive={active}\n onClick={() => onNavigate(item.path)}\n tooltip={item.label}\n className=\"h-10 transition-all font-normal\"\n >\n {Icon && <Icon className={cn(\"h-4 w-4\", active && \"text-primary\")} />}\n <span>{item.label}</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n );\n })}\n </SidebarMenu>\n </>\n );\n}\n\n/* ── Inner shell (runs inside SidebarProvider, so it can call useSidebar) ── */\n\nfunction DashboardShell({\n serviceName,\n serviceIcon,\n menuSections,\n adminSections,\n isAdmin = false,\n activePath,\n onNavigate,\n isActive,\n serviceHubUrl = DEFAULT_SERVICE_HUB_URL,\n settingsPath,\n user,\n onLogout,\n userSettingsUrl,\n hierarchyNavigator,\n enterprise,\n reportingToolbar,\n footer,\n children,\n}: DashboardLayoutProps) {\n const { toggleSidebar, state } = useSidebar();\n const isCollapsed = state === \"collapsed\";\n\n const navigate = onNavigate;\n const resolveActive = (path: string) =>\n isActive ? isActive(path, activePath) : isMenuItemActive(path, activePath);\n\n return (\n <>\n <Sidebar collapsible=\"icon\" className=\"border-r-0\">\n <SidebarHeader className=\"h-16 justify-center\">\n <div className=\"flex items-center gap-3 px-2 transition-all w-full\">\n <button\n onClick={toggleSidebar}\n className=\"h-8 w-8 flex items-center justify-center hover:bg-accent rounded-lg transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-ring shrink-0\"\n aria-label=\"Toggle navigation\"\n >\n <PanelLeft className=\"h-4 w-4 text-muted-foreground\" />\n </button>\n {!isCollapsed ? (\n <div className=\"flex items-center gap-2 min-w-0\">\n {serviceIcon && (\n <span className=\"text-[#8C34E9] shrink-0\">{serviceIcon}</span>\n )}\n <span className=\"font-semibold tracking-tight truncate\">\n {serviceName}\n </span>\n </div>\n ) : null}\n </div>\n </SidebarHeader>\n\n <SidebarContent className=\"gap-0\">\n {/* Service Hub — pinned to the top of the nav */}\n {serviceHubUrl && (\n <SidebarMenu className=\"px-2 pt-2 pb-1\">\n <SidebarMenuItem>\n <SidebarMenuButton\n onClick={() => {\n window.location.href = serviceHubUrl;\n }}\n tooltip=\"Back to Service Hub\"\n className=\"h-10 transition-all font-normal text-muted-foreground hover:text-foreground\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n <span>Service Hub</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n )}\n\n {/* Primary navigation */}\n {menuSections.map((section, i) => (\n <NavSection\n key={section.title ?? section.label ?? `section-${i}`}\n section={section}\n isCollapsed={isCollapsed}\n resolveActive={resolveActive}\n onNavigate={navigate}\n />\n ))}\n\n {/* Admin-only navigation */}\n {isAdmin &&\n adminSections?.map((section, i) => (\n <NavSection\n key={section.title ?? section.label ?? `admin-${i}`}\n section={section}\n marginTop\n isCollapsed={isCollapsed}\n resolveActive={resolveActive}\n onNavigate={navigate}\n />\n ))}\n </SidebarContent>\n\n {settingsPath && (\n <SidebarFooter className=\"p-2\">\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton\n onClick={() => navigate(settingsPath)}\n tooltip=\"Settings\"\n className=\"h-10 transition-all font-normal text-muted-foreground hover:text-foreground\"\n >\n <Settings className=\"h-4 w-4\" />\n <span>Settings</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n )}\n </Sidebar>\n\n <SidebarInset>\n <header\n className={cn(\n \"flex items-center justify-between h-14 px-4\",\n \"bg-[#0D1220]/95 border-b border-[#1E2738]\",\n \"backdrop-blur supports-[backdrop-filter]:backdrop-blur\",\n \"sticky top-0 z-40\"\n )}\n >\n {/* LEFT: mobile trigger + service icon + hierarchy breadcrumb */}\n <div className=\"flex items-center gap-2 min-w-0 flex-1\">\n <SidebarTrigger className=\"h-9 w-9 rounded-lg bg-background shrink-0 md:hidden\" />\n {serviceIcon && (\n <span className=\"text-[#8C34E9] shrink-0 hidden sm:block\">{serviceIcon}</span>\n )}\n {hierarchyNavigator && (\n <div className=\"min-w-0 overflow-x-auto scrollbar-none\">{hierarchyNavigator}</div>\n )}\n </div>\n\n {/* RIGHT: reporting toolbar + enterprise badge + user menu */}\n <div className=\"flex items-center gap-2 shrink-0\">\n {reportingToolbar}\n <EnterpriseBadge enterprise={enterprise} />\n <div className=\"w-px h-6 bg-[#1E2738] hidden md:block\" />\n {user && (\n <UserMenu user={user} onLogout={onLogout} userSettingsUrl={userSettingsUrl} />\n )}\n </div>\n </header>\n\n <main className=\"flex-1 p-4 md:p-6 pb-14\">{children}</main>\n </SidebarInset>\n\n {footer}\n </>\n );\n}\n\n/* ── Public component ── */\n\nexport function DashboardLayout(props: DashboardLayoutProps) {\n const isMobile = useIsMobile();\n return (\n <SidebarProvider defaultOpen={props.defaultOpen ?? !isMobile}>\n <DashboardShell {...props} />\n </SidebarProvider>\n );\n}\n","/**\n * DashboardLayoutSkeleton — loading skeleton for DashboardLayout.\n *\n * Shows a sidebar + content skeleton while auth state is loading.\n * Oplytics dark theme.\n */\nimport { cn } from \"../utils/cn\";\n\nfunction Skeleton({ className }: { className?: string }) {\n return (\n <div\n className={cn(\n \"animate-pulse rounded-md bg-[#1E2738]\",\n className\n )}\n />\n );\n}\n\nexport interface DashboardLayoutSkeletonProps {\n className?: string;\n}\n\nexport function DashboardLayoutSkeleton({ className }: DashboardLayoutSkeletonProps) {\n return (\n <div className={cn(\"flex min-h-screen bg-[#0A0E1A]\", className)}>\n {/* Sidebar skeleton */}\n <div className=\"w-[260px] border-r border-[#1E2738] bg-[#0D1220] p-4 space-y-6\">\n {/* Logo area */}\n <div className=\"flex items-center gap-3 px-2\">\n <Skeleton className=\"h-8 w-8 rounded-md\" />\n <Skeleton className=\"h-4 w-24\" />\n </div>\n\n {/* Menu items */}\n <div className=\"space-y-2 px-2\">\n <Skeleton className=\"h-9 w-full rounded-lg\" />\n <Skeleton className=\"h-9 w-full rounded-lg\" />\n <Skeleton className=\"h-9 w-full rounded-lg\" />\n <Skeleton className=\"h-9 w-full rounded-lg\" />\n </div>\n\n {/* Section divider */}\n <div className=\"px-2\">\n <Skeleton className=\"h-3 w-16 mb-3\" />\n <Skeleton className=\"h-9 w-full rounded-lg\" />\n <Skeleton className=\"h-9 w-full rounded-lg mt-2\" />\n </div>\n\n {/* User profile area at bottom */}\n <div className=\"absolute bottom-4 left-4 right-4\">\n <div className=\"flex items-center gap-3 px-1\">\n <Skeleton className=\"h-8 w-8 rounded-full\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-3 w-20\" />\n <Skeleton className=\"h-2 w-32\" />\n </div>\n </div>\n </div>\n </div>\n\n {/* Main content skeleton */}\n <div className=\"flex-1 p-6 space-y-4\">\n {/* Page header */}\n <div className=\"flex items-center justify-between\">\n <Skeleton className=\"h-8 w-48 rounded-lg\" />\n <Skeleton className=\"h-9 w-24 rounded-lg\" />\n </div>\n\n {/* Stats cards */}\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n <Skeleton className=\"h-24 rounded-xl\" />\n <Skeleton className=\"h-24 rounded-xl\" />\n <Skeleton className=\"h-24 rounded-xl\" />\n <Skeleton className=\"h-24 rounded-xl\" />\n </div>\n\n {/* Main content area */}\n <Skeleton className=\"h-64 rounded-xl\" />\n\n {/* Table-like area */}\n <div className=\"space-y-2\">\n <Skeleton className=\"h-10 w-full rounded-lg\" />\n <Skeleton className=\"h-10 w-full rounded-lg\" />\n <Skeleton className=\"h-10 w-full rounded-lg\" />\n </div>\n </div>\n </div>\n );\n}\n","/**\n * SharedPageHeader — standard page header for all Oplytics subdomains.\n *\n * Displays: page title, optional subtitle, optional breadcrumbs,\n * optional action buttons, and optional HierarchyNavigator.\n *\n * Oplytics dark theme: #0A0E1A bg, #8C34E9 accent, #E2E8F0 text, #8890A0 muted\n */\nimport { cn } from \"../utils/cn\";\nimport { ChevronLeft } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\n\nexport interface SharedPageHeaderProps {\n /** Page title */\n title: string;\n /** Optional subtitle / description */\n subtitle?: string;\n /** Optional icon to display before the title */\n icon?: ReactNode;\n /** Optional back button handler — shows a back arrow when provided */\n onBack?: () => void;\n /** Optional action buttons to render on the right side */\n actions?: ReactNode;\n /** Optional breadcrumb trail (e.g. HierarchyNavigator) */\n breadcrumbs?: ReactNode;\n /** Whether to show a bottom border (default: true) */\n showBorder?: boolean;\n /** Compact mode — smaller spacing and text (default: false) */\n compact?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children rendered below the header row */\n children?: ReactNode;\n}\n\nexport function SharedPageHeader({\n title,\n subtitle,\n icon,\n onBack,\n actions,\n breadcrumbs,\n showBorder = true,\n compact = false,\n className,\n children,\n}: SharedPageHeaderProps) {\n return (\n <div\n className={cn(\n \"w-full\",\n showBorder && \"border-b border-[#1E2738]\",\n compact ? \"px-4 py-3\" : \"px-6 py-4\",\n className\n )}\n >\n {/* Breadcrumbs row */}\n {breadcrumbs && (\n <div className={cn(\"mb-2\", compact && \"mb-1\")}>\n {breadcrumbs}\n </div>\n )}\n\n {/* Main header row */}\n <div className=\"flex items-center justify-between gap-4\">\n <div className=\"flex items-center gap-3 min-w-0\">\n {/* Back button */}\n {onBack && (\n <button\n onClick={onBack}\n className={cn(\n \"shrink-0 p-1.5 rounded-md\",\n \"text-[#8890A0] hover:text-[#E2E8F0] hover:bg-[#1E2738]\",\n \"transition-colors cursor-pointer\",\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[#8C34E9]\"\n )}\n aria-label=\"Go back\"\n >\n <ChevronLeft className={compact ? \"h-4 w-4\" : \"h-5 w-5\"} />\n </button>\n )}\n\n {/* Icon */}\n {icon && (\n <div className=\"shrink-0 text-[#8C34E9]\">\n {icon}\n </div>\n )}\n\n {/* Title + subtitle */}\n <div className=\"min-w-0\">\n <h1\n className={cn(\n \"font-semibold text-[#E2E8F0] truncate\",\n \"font-[Montserrat,sans-serif]\",\n compact ? \"text-lg\" : \"text-xl\"\n )}\n >\n {title}\n </h1>\n {subtitle && (\n <p\n className={cn(\n \"text-[#8890A0] truncate mt-0.5\",\n \"font-[Space_Grotesk,sans-serif]\",\n compact ? \"text-xs\" : \"text-sm\"\n )}\n >\n {subtitle}\n </p>\n )}\n </div>\n </div>\n\n {/* Action buttons */}\n {actions && (\n <div className=\"shrink-0 flex items-center gap-2\">\n {actions}\n </div>\n )}\n </div>\n\n {/* Optional children below header */}\n {children && (\n <div className={cn(\"mt-3\", compact && \"mt-2\")}>\n {children}\n </div>\n )}\n </div>\n );\n}\n","/**\n * SharedFooter — standard footer for all Oplytics subdomains.\n *\n * Displays: Oplytics branding, service links, legal links, copyright.\n * Consistent across all subdomains.\n *\n * Oplytics dark theme: #0D1220 bg, #1E2738 border, #8890A0 text, #8C34E9 accent\n */\nimport { cn } from \"../utils/cn\";\nimport type { ReactNode } from \"react\";\n\ndeclare const __APP_VERSION__: string;\n\n/* ── Service definitions ── */\n\nexport interface FooterService {\n name: string;\n slug: string;\n /** Local route within the portal (e.g. /services/sqdcp) */\n localRoute: string;\n /** External URL for the subdomain (e.g. https://sqdcp.oplytics.digital) */\n externalUrl?: string;\n}\n\n/** Standard Oplytics service list */\nexport const FOOTER_SERVICES: FooterService[] = [\n { name: \"SQDCP\", slug: \"sqdcp\", localRoute: \"/services/sqdcp\", externalUrl: \"https://sqdcp.oplytics.digital\" },\n { name: \"OEE Manager\", slug: \"oee-manager\", localRoute: \"/services/oee-manager\", externalUrl: \"https://oee.oplytics.digital\" },\n { name: \"Policy Deployment\", slug: \"policy-deployment\", localRoute: \"/services/policy-deployment\", externalUrl: \"https://policy.oplytics.digital\" },\n { name: \"Action Manager\", slug: \"action-manager\", localRoute: \"/services/action-manager\", externalUrl: \"https://actions.oplytics.digital\" },\n { name: \"Safety Manager\", slug: \"safety-manager\", localRoute: \"/services/safety-manager\" },\n { name: \"Connect\", slug: \"connect\", localRoute: \"/services/connect\", externalUrl: \"https://connect.oplytics.digital\" },\n];\n\n/* ── Footer props ── */\n\nexport interface SharedFooterProps {\n /** Override the default service list */\n services?: FooterService[];\n /** Show pricing link (default: true) */\n showPricing?: boolean;\n /** Show sign-in link (default: true) */\n showSignIn?: boolean;\n /** Handler for service link clicks — receives the service */\n onServiceClick?: (service: FooterService, e: React.MouseEvent) => void;\n /** Handler for pricing link click */\n onPricingClick?: (e: React.MouseEvent) => void;\n /** Handler for sign-in link click */\n onSignInClick?: (e: React.MouseEvent) => void;\n /** Additional content to render in the footer */\n children?: ReactNode;\n /** CSS class for the footer container */\n className?: string;\n /** Whether to use external URLs (subdomain links) or local routes */\n useExternalUrls?: boolean;\n /** Current year override (default: auto) */\n year?: number;\n}\n\n/* ── Component ── */\n\nexport function SharedFooter({\n services = FOOTER_SERVICES,\n showPricing = true,\n showSignIn = true,\n onServiceClick,\n onPricingClick,\n onSignInClick,\n children,\n className,\n useExternalUrls = false,\n year,\n}: SharedFooterProps) {\n const currentYear = year ?? new Date().getFullYear();\n\n return (\n <footer\n className={cn(\n \"w-full border-t border-[#1E2738]\",\n \"bg-[#0D1220] text-[#8890A0]\",\n \"font-[Space_Grotesk,sans-serif]\",\n className\n )}\n >\n <div className=\"max-w-7xl mx-auto px-6 py-10\">\n {/* Top section: Logo + columns */}\n <div className=\"grid grid-cols-1 md:grid-cols-4 gap-8 mb-8\">\n {/* Brand column */}\n <div className=\"md:col-span-1\">\n <div className=\"flex items-center gap-2 mb-3\">\n <div\n className=\"w-7 h-7 rounded-full flex items-center justify-center\"\n style={{ background: \"#8C34E9\" }}\n >\n <span className=\"text-white font-bold text-xs\">O</span>\n </div>\n <span className=\"text-[#E2E8F0] font-semibold text-sm font-[Montserrat,sans-serif]\">\n Oplytics.digital\n </span>\n </div>\n <p className=\"text-xs text-[#596475] leading-relaxed\">\n Operational intelligence platform for manufacturing excellence.\n </p>\n </div>\n\n {/* Services column */}\n <div>\n <h4 className=\"text-[#E2E8F0] font-medium text-xs uppercase tracking-wider mb-3 font-[Montserrat,sans-serif]\">\n Services\n </h4>\n <ul className=\"space-y-2\">\n {services.map((service) => (\n <li key={service.slug}>\n <a\n href={useExternalUrls && service.externalUrl ? service.externalUrl : service.localRoute}\n onClick={onServiceClick ? (e) => onServiceClick(service, e) : undefined}\n className=\"text-xs text-[#8890A0] hover:text-[#E2E8F0] transition-colors\"\n >\n {service.name}\n </a>\n </li>\n ))}\n </ul>\n </div>\n\n {/* Company column */}\n <div>\n <h4 className=\"text-[#E2E8F0] font-medium text-xs uppercase tracking-wider mb-3 font-[Montserrat,sans-serif]\">\n Company\n </h4>\n <ul className=\"space-y-2\">\n {showPricing && (\n <li>\n <a\n href=\"/pricing\"\n onClick={onPricingClick}\n className=\"text-xs text-[#8890A0] hover:text-[#E2E8F0] transition-colors\"\n >\n Pricing\n </a>\n </li>\n )}\n <li>\n <a\n href=\"/about\"\n className=\"text-xs text-[#8890A0] hover:text-[#E2E8F0] transition-colors\"\n >\n About\n </a>\n </li>\n <li>\n <a\n href=\"/contact\"\n className=\"text-xs text-[#8890A0] hover:text-[#E2E8F0] transition-colors\"\n >\n Contact\n </a>\n </li>\n </ul>\n </div>\n\n {/* Legal column */}\n <div>\n <h4 className=\"text-[#E2E8F0] font-medium text-xs uppercase tracking-wider mb-3 font-[Montserrat,sans-serif]\">\n Legal\n </h4>\n <ul className=\"space-y-2\">\n <li>\n <a\n href=\"/privacy\"\n className=\"text-xs text-[#8890A0] hover:text-[#E2E8F0] transition-colors\"\n >\n Privacy Policy\n </a>\n </li>\n <li>\n <a\n href=\"/terms\"\n className=\"text-xs text-[#8890A0] hover:text-[#E2E8F0] transition-colors\"\n >\n Terms of Service\n </a>\n </li>\n </ul>\n {showSignIn && (\n <div className=\"mt-4\">\n <a\n href=\"/login\"\n onClick={onSignInClick}\n className=\"text-xs text-[#8C34E9] hover:text-[#A855F7] transition-colors font-medium\"\n >\n Sign In\n </a>\n </div>\n )}\n </div>\n </div>\n\n {/* Custom content */}\n {children}\n\n {/* Bottom bar */}\n <div className=\"pt-6 border-t border-[#1E2738] flex flex-col sm:flex-row items-center justify-between gap-3\">\n <p className=\"text-xs text-[#596475]\">\n © {currentYear} Oplytics.digital. All rights reserved.\n </p>\n <p className=\"text-xs text-[#3E4A5C]\">\n Built for manufacturing excellence\n </p>\n {typeof __APP_VERSION__ !== \"undefined\" && (\n <p className=\"text-xs text-[#3E4A5C]\">\n Platform v{__APP_VERSION__}\n </p>\n )}\n </div>\n </div>\n </footer>\n );\n}\n","/**\n * ServiceFooter — slim status bar for all Oplytics subdomain services.\n *\n * ~36px horizontal strip: [Logo + Tagline] [Health Monitor] [Copyright + Version]\n * Health monitor is visible only when showHealthMonitor is true (typically platform_admin).\n *\n * Oplytics dark theme: #0D1220 bg, #1E2738 border, #596475/#3E4A5C text, #8C34E9 accent\n */\nimport { cn } from \"../utils/cn\";\n\ndeclare const __APP_VERSION__: string;\n\nexport interface ServiceFooterProps {\n /** Enterprise ID for health monitor */\n enterpriseId?: number | null;\n /** Enterprise display name */\n enterpriseName?: string;\n /** Current user's role */\n userRole?: string;\n /** Current user's email */\n userEmail?: string;\n /** Deployment environment */\n environment?: \"production\" | \"staging\" | \"development\";\n /** Build version / commit hash */\n buildVersion?: string;\n /** Show health monitor strip (default: false) */\n showHealthMonitor?: boolean;\n /** CSS class for the footer container */\n className?: string;\n}\n\nconst ENV_LABELS: Record<string, { label: string; color: string }> = {\n production: { label: \"prod\", color: \"#10b981\" },\n staging: { label: \"stg\", color: \"#f59e0b\" },\n development: { label: \"dev\", color: \"#8C34E9\" },\n};\n\nexport function ServiceFooter({\n enterpriseId,\n enterpriseName,\n userRole,\n userEmail,\n environment,\n buildVersion,\n showHealthMonitor = false,\n className,\n}: ServiceFooterProps) {\n const currentYear = new Date().getFullYear();\n const env = environment ? ENV_LABELS[environment] : null;\n const version = buildVersion ?? (typeof __APP_VERSION__ !== \"undefined\" ? __APP_VERSION__ : undefined);\n\n return (\n <footer\n className={cn(\n \"w-full border-t border-[#1E2738] bg-[#0D1220]\",\n \"flex items-center justify-between px-4\",\n \"h-9 min-h-[36px] shrink-0\",\n \"font-[Montserrat,sans-serif]\",\n className,\n )}\n >\n {/* Left: Logo + Tagline */}\n <div className=\"flex items-center gap-2 min-w-0\">\n <div\n className=\"w-5 h-5 rounded-full flex items-center justify-center shrink-0\"\n style={{ background: \"#8C34E9\" }}\n >\n <span className=\"text-white font-bold\" style={{ fontSize: 9 }}>O</span>\n </div>\n <span className=\"text-[10px] text-[#596475] whitespace-nowrap hidden sm:inline\">\n Operational Excellence. One Digital Platform.\n </span>\n </div>\n\n {/* Center: Health Monitor (admin only) */}\n {showHealthMonitor && (\n <div className=\"flex items-center gap-1.5 text-[10px] text-[#3E4A5C] min-w-0 overflow-hidden\">\n {enterpriseName && (\n <>\n <span className=\"whitespace-nowrap\">\n <span className=\"text-[#596475]\">{enterpriseName}</span>\n {enterpriseId != null && (\n <span className=\"text-[#3E4A5C]\"> ({enterpriseId})</span>\n )}\n </span>\n <Separator />\n </>\n )}\n {userEmail && (\n <>\n <span className=\"whitespace-nowrap text-[#596475]\">{userEmail}</span>\n {userRole && (\n <span className=\"text-[#3E4A5C]\"> ({userRole})</span>\n )}\n <Separator />\n </>\n )}\n {env && (\n <>\n <span className=\"whitespace-nowrap\">\n ENV:{\" \"}\n <span style={{ color: env.color }} className=\"font-semibold\">\n {env.label}\n </span>\n </span>\n <Separator />\n </>\n )}\n {version && (\n <span className=\"whitespace-nowrap text-[#3E4A5C] font-mono\">\n v.{version}\n </span>\n )}\n </div>\n )}\n\n {/* Right: Copyright + Version (when health monitor hidden) */}\n <div className=\"flex items-center gap-2 text-[10px] text-[#3E4A5C] whitespace-nowrap shrink-0\">\n <span>© {currentYear} Oplytics.digital</span>\n {!showHealthMonitor && version && (\n <>\n <Separator />\n <span className=\"font-mono\">v.{version}</span>\n </>\n )}\n </div>\n </footer>\n );\n}\n\nfunction Separator() {\n return (\n <span className=\"text-[#1E2738] select-none\" aria-hidden>\n |\n </span>\n );\n}\n","/**\n * createServiceLayout — Factory function that generates a complete DashboardLayout\n * for any Oplytics subdomain from a SharedSidebarConfig.\n *\n * This is the primary API for subdomains. Instead of each subdomain maintaining\n * its own 200-350 line DashboardLayout, they call:\n *\n * const SQDCPLayout = createServiceLayout({ serviceName: \"SQDCP\", ... });\n *\n * And get a fully-featured layout with:\n * - Resizable sidebar with all standard features\n * - SharedPageHeader integration\n * - ReportingToolbar integration (optional)\n * - HierarchyProvider wrapping (optional)\n * - Auth gate with loading skeleton + sign-in fallback (optional)\n * - User footer with logout dropdown\n *\n * @module shared/components/createServiceLayout\n */\n\nimport React from \"react\";\nimport type { SharedSidebarConfig, MenuSection } from \"./SharedSidebar\";\nimport { isAdminRole, getInitials, isMenuItemActive, useSidebarResize } from \"./SharedSidebar\";\n\n/* ── Service Layout Configuration ── */\n\nexport interface ServiceLayoutConfig extends SharedSidebarConfig {\n /** Show SharedPageHeader above content (default: true) */\n showPageHeader?: boolean;\n /** SharedPageHeader props — passed through when showPageHeader is true */\n pageHeaderProps?: {\n showHierarchy?: boolean;\n hierarchyMaxDepth?: number;\n showSidebarTrigger?: boolean;\n };\n /** Show ReportingToolbar in the header (default: false) */\n showReportingToolbar?: boolean;\n /** Module name passed to ReportingToolbar */\n reportingModuleName?: string;\n /** Wrap layout in HierarchyProvider (default: false) */\n wrapHierarchyProvider?: boolean;\n /** Show auth gate — loading skeleton + sign-in fallback (default: true) */\n showAuthGate?: boolean;\n /** Report submit handler */\n onReportSubmit?: (report: any) => Promise<void> | void;\n /** Feedback submit handler */\n onFeedbackSubmit?: (feedback: any) => Promise<void> | void;\n}\n\n/**\n * Creates a service-specific layout component from configuration.\n *\n * NOTE: This is a blueprint/factory specification. The actual React component\n * is assembled by each subdomain using their local UI primitives (Sidebar,\n * SidebarProvider, etc.) since these are not shared across subdomains yet.\n *\n * When subdomain consolidation (#311) is complete, this factory will directly\n * render the shared UI primitives. Until then, subdomains use this config\n * to standardise their DashboardLayout implementations.\n *\n * @example\n * ```tsx\n * // In SQDCP's DashboardLayout.tsx:\n * import { sqdcpLayoutConfig } from \"./sqdcp-config\";\n * // Use sqdcpLayoutConfig.menuSections, .backLink, etc. to build the layout\n * ```\n */\nexport function defineServiceLayout(config: ServiceLayoutConfig): ServiceLayoutConfig {\n return {\n defaultWidth: 260,\n minWidth: 200,\n maxWidth: 480,\n showPageHeader: true,\n showReportingToolbar: false,\n wrapHierarchyProvider: false,\n showAuthGate: true,\n ...config,\n storageKeyPrefix: config.storageKeyPrefix || config.serviceName.toLowerCase().replace(/\\s+/g, \"-\"),\n };\n}\n\n/* ── Pre-built Service Configurations ── */\n\n// These are the canonical configurations for each subdomain.\n// Subdomains should import and use these instead of defining their own.\n\nexport { isAdminRole, getInitials, isMenuItemActive, useSidebarResize };\n","/**\n * Canonical Service Layout Configurations for all Oplytics subdomains.\n *\n * Each subdomain imports its config from here and uses it to build its\n * DashboardLayout. This ensures consistency across all services while\n * allowing per-service customisation (menu items, features, etc.).\n *\n * When subdomain consolidation (#311) is complete, these configs will\n * drive the shared createServiceLayout factory directly.\n *\n * @module shared/components/serviceConfigs\n */\n\nimport type { ServiceLayoutConfig } from \"./createServiceLayout\";\n\n/* ── Icon placeholder types ── */\n// Icons are imported locally by each subdomain from lucide-react.\n// These configs use string identifiers that map to icon components.\n\nexport interface MenuItemConfig {\n iconName: string;\n label: string;\n path: string;\n}\n\nexport interface MenuSectionConfig {\n label?: string;\n items: MenuItemConfig[];\n adminOnly?: boolean;\n}\n\nexport interface ServiceConfig {\n serviceName: string;\n serviceAbbreviation: string;\n serviceIconName: string;\n menuSections: MenuSectionConfig[];\n backLink?: {\n label: string;\n path: string;\n };\n showPageHeader: boolean;\n showReportingToolbar: boolean;\n reportingModuleName?: string;\n wrapHierarchyProvider: boolean;\n showAuthGate: boolean;\n storageKeyPrefix: string;\n defaultWidth: number;\n minWidth: number;\n maxWidth: number;\n}\n\n/* ── SQDCP ── */\n\nexport const sqdcpConfig: ServiceConfig = {\n serviceName: \"SQDCP\",\n serviceAbbreviation: \"S\",\n serviceIconName: \"BarChart3\",\n menuSections: [\n {\n items: [\n { iconName: \"LayoutDashboard\", label: \"Dashboard\", path: \"/\" },\n { iconName: \"PenLine\", label: \"Data Entry\", path: \"/entry\" },\n { iconName: \"ClipboardList\", label: \"Action Tracker\", path: \"/actions\" },\n { iconName: \"FileText\", label: \"Reports\", path: \"/reports\" },\n { iconName: \"Settings\", label: \"Admin\", path: \"/admin\" },\n ],\n },\n ],\n showPageHeader: true,\n showReportingToolbar: true,\n reportingModuleName: \"SQDCP\",\n wrapHierarchyProvider: false,\n showAuthGate: false,\n storageKeyPrefix: \"sqdcp-sidebar\",\n defaultWidth: 260,\n minWidth: 200,\n maxWidth: 480,\n};\n\n/* ── OEE Manager ── */\n\nexport const oeeManagerConfig: ServiceConfig = {\n serviceName: \"OEE Manager\",\n serviceAbbreviation: \"o\",\n serviceIconName: \"BarChart3\",\n menuSections: [\n {\n items: [\n { iconName: \"BarChart3\", label: \"Dashboard\", path: \"/\" },\n { iconName: \"Database\", label: \"Data Input\", path: \"/data-input\" },\n { iconName: \"Clock\", label: \"Downtime\", path: \"/downtime\" },\n { iconName: \"Settings\", label: \"Settings\", path: \"/settings\" },\n ],\n },\n ],\n backLink: {\n label: \"Back to Portal\",\n path: \"https://portal.oplytics.digital\",\n },\n showPageHeader: true,\n showReportingToolbar: true,\n reportingModuleName: \"OEE Enterprise Manager\",\n wrapHierarchyProvider: false,\n showAuthGate: false,\n storageKeyPrefix: \"oee-sidebar\",\n defaultWidth: 240,\n minWidth: 200,\n maxWidth: 400,\n};\n\n/* ── Action Manager ── */\n\nexport const actionManagerConfig: ServiceConfig = {\n serviceName: \"Action Manager\",\n serviceAbbreviation: \"A\",\n serviceIconName: \"LayoutDashboard\",\n menuSections: [\n {\n items: [\n { iconName: \"LayoutDashboard\", label: \"Dashboard\", path: \"/\" },\n { iconName: \"Users\", label: \"Teams\", path: \"/teams\" },\n ],\n },\n ],\n showPageHeader: true,\n showReportingToolbar: false,\n reportingModuleName: \"Action Manager\",\n wrapHierarchyProvider: false,\n showAuthGate: true,\n storageKeyPrefix: \"actionmanager-sidebar\",\n defaultWidth: 280,\n minWidth: 200,\n maxWidth: 480,\n};\n\n/* ── Business Hub ── */\n\nexport const businessHubConfig: ServiceConfig = {\n serviceName: \"Business Hub\",\n serviceAbbreviation: \"B\",\n serviceIconName: \"LayoutDashboard\",\n menuSections: [\n {\n items: [\n { iconName: \"LayoutDashboard\", label: \"Dashboard\", path: \"/\" },\n { iconName: \"Users\", label: \"Analytics\", path: \"/analytics\" },\n ],\n },\n ],\n showPageHeader: true,\n showReportingToolbar: false,\n reportingModuleName: \"Business Hub\",\n wrapHierarchyProvider: false,\n showAuthGate: true,\n storageKeyPrefix: \"businesshub-sidebar\",\n defaultWidth: 280,\n minWidth: 200,\n maxWidth: 480,\n};\n\n/* ── Policy Deployment ── */\n\nexport const policyDeploymentConfig: ServiceConfig = {\n serviceName: \"Policy Deployment\",\n serviceAbbreviation: \"PD\",\n serviceIconName: \"FileStack\",\n menuSections: [\n {\n label: \"Analysis\",\n items: [\n { iconName: \"LayoutGrid\", label: \"Dashboard\", path: \"/app/policy-deployment\" },\n { iconName: \"Grid3X3\", label: \"X-Matrix\", path: \"/app/policy-deployment/xmatrix\" },\n { iconName: \"BarChart3\", label: \"Bowling Chart\", path: \"/app/policy-deployment/bowling\" },\n { iconName: \"FolderKanban\", label: \"Action Plans\", path: \"/app/policy-deployment/actions\" },\n { iconName: \"GitBranchPlus\", label: \"Catchball\", path: \"/app/policy-deployment/catchball\" },\n { iconName: \"Target\", label: \"Deployments\", path: \"/app/policy-deployment/deployments\" },\n ],\n },\n {\n label: \"Administration\",\n adminOnly: true,\n items: [\n { iconName: \"Settings\", label: \"Manage Policy\", path: \"/app/policy-deployment/manage\" },\n { iconName: \"Plug\", label: \"Integrations\", path: \"/app/policy-deployment/integrations\" },\n ],\n },\n ],\n backLink: {\n label: \"Service Hub\",\n path: \"/app\",\n },\n showPageHeader: true,\n showReportingToolbar: true,\n reportingModuleName: \"Policy Deployment\",\n wrapHierarchyProvider: true,\n showAuthGate: true,\n storageKeyPrefix: \"policy-sidebar\",\n defaultWidth: 260,\n minWidth: 200,\n maxWidth: 480,\n};\n\n/* ── All configs indexed by service key ── */\n\nexport const SERVICE_CONFIGS = {\n sqdcp: sqdcpConfig,\n oeeManager: oeeManagerConfig,\n actionManager: actionManagerConfig,\n businessHub: businessHubConfig,\n policyDeployment: policyDeploymentConfig,\n} as const;\n\nexport type ServiceKey = keyof typeof SERVICE_CONFIGS;\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { D as DashboardLayout, a as DashboardLayoutEnterprise, b as DashboardLayoutProps, c as DashboardLayoutUser } from '../DashboardLayout-Bors1KO3.js';
|
|
2
|
+
export { M as MenuItem, d as MenuSection } from '../DashboardLayout-Bors1KO3.js';
|
|
3
|
+
import 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @pablo2410/shared-ui/shell — Oplytics Service Shell
|
|
8
|
+
*
|
|
9
|
+
* The single composed chrome (sidebar + header + breadcrumb + reporting +
|
|
10
|
+
* footer + user menu) used by every Oplytics subdomain. Subdomains become
|
|
11
|
+
* a ~50-line adapter that supplies *data and identity*, nothing visual.
|
|
12
|
+
* One PR to shared-ui + a coordinated version bump propagates a chrome
|
|
13
|
+
* change to every service.
|
|
14
|
+
*
|
|
15
|
+
* Composition: re-exports the existing `DashboardLayout` from
|
|
16
|
+
* `@pablo2410/shared-ui/layout` under the clearer canonical name
|
|
17
|
+
* `OplyticsServiceShell`. The two are the same component; consumers
|
|
18
|
+
* should prefer `/shell` going forward — `/layout` will be marked
|
|
19
|
+
* `@deprecated` once every subdomain has migrated and removed in
|
|
20
|
+
* shared-ui v1.0 (see oplytics-subdomains tracking epic).
|
|
21
|
+
*
|
|
22
|
+
* CSS: ship `dist/shell/oplytics-shell.css` containing every Tailwind v4
|
|
23
|
+
* utility this shell uses (built by `pnpm build:shell-css`). Consumers
|
|
24
|
+
* `@import` it once in their own `index.css` and never need an
|
|
25
|
+
* `@source` directive.
|
|
26
|
+
*
|
|
27
|
+
* ```css
|
|
28
|
+
* @import "tailwindcss";
|
|
29
|
+
* @import "@pablo2410/shared-ui/theme/oplytics-theme.css";
|
|
30
|
+
* @import "@pablo2410/shared-ui/shell/oplytics-shell.css";
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Usage:
|
|
34
|
+
*
|
|
35
|
+
* ```tsx
|
|
36
|
+
* import { OplyticsServiceShell } from "@pablo2410/shared-ui/shell";
|
|
37
|
+
*
|
|
38
|
+
* <OplyticsServiceShell
|
|
39
|
+
* serviceName="Connect"
|
|
40
|
+
* serviceIcon={<Zap />}
|
|
41
|
+
* menuSections={menuSections}
|
|
42
|
+
* adminSections={adminSections}
|
|
43
|
+
* isAdmin={user?.role === "platform_admin"}
|
|
44
|
+
* activePath={location}
|
|
45
|
+
* onNavigate={setLocation}
|
|
46
|
+
* user={user}
|
|
47
|
+
* onLogout={logout}
|
|
48
|
+
* enterprise={selection.enterprise}
|
|
49
|
+
* hierarchyNavigator={<HierarchyNavigator hierarchy={hierarchy} />}
|
|
50
|
+
* reportingToolbar={<ReportingToolbar … />}
|
|
51
|
+
* >
|
|
52
|
+
* <Routes />
|
|
53
|
+
* </OplyticsServiceShell>
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The canonical composed Oplytics chrome.
|
|
59
|
+
*
|
|
60
|
+
* This is the same React component as `DashboardLayout` in
|
|
61
|
+
* `@pablo2410/shared-ui/layout`, re-exported under a clearer name.
|
|
62
|
+
* Consumers should prefer `OplyticsServiceShell` going forward.
|
|
63
|
+
*/
|
|
64
|
+
declare const OplyticsServiceShell: typeof DashboardLayout;
|
|
65
|
+
/**
|
|
66
|
+
* Props accepted by `OplyticsServiceShell`.
|
|
67
|
+
* (Alias of `DashboardLayoutProps`.)
|
|
68
|
+
*/
|
|
69
|
+
type ServiceShellProps = DashboardLayoutProps;
|
|
70
|
+
/**
|
|
71
|
+
* Authenticated user passed to the shell. Small enough to fit both
|
|
72
|
+
* stateless-JWT subdomains (Connect, Policy Deployment) and DB-backed
|
|
73
|
+
* ones (OEE Manager).
|
|
74
|
+
*/
|
|
75
|
+
type ServiceShellUser = DashboardLayoutUser;
|
|
76
|
+
/**
|
|
77
|
+
* Currently-scoped enterprise — drives the header enterprise badge.
|
|
78
|
+
*/
|
|
79
|
+
type ServiceShellEnterprise = DashboardLayoutEnterprise;
|
|
80
|
+
|
|
81
|
+
export { OplyticsServiceShell, type ServiceShellEnterprise, type ServiceShellProps, type ServiceShellUser };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DashboardLayout
|
|
3
|
+
} from "../chunk-MAKRKBBI.js";
|
|
4
|
+
import "../chunk-JT3XLKKD.js";
|
|
5
|
+
import "../chunk-LTUYIBMA.js";
|
|
6
|
+
|
|
7
|
+
// src/shell/index.ts
|
|
8
|
+
var OplyticsServiceShell = DashboardLayout;
|
|
9
|
+
export {
|
|
10
|
+
OplyticsServiceShell
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/shell/index.ts"],"sourcesContent":["/**\n * @pablo2410/shared-ui/shell — Oplytics Service Shell\n *\n * The single composed chrome (sidebar + header + breadcrumb + reporting +\n * footer + user menu) used by every Oplytics subdomain. Subdomains become\n * a ~50-line adapter that supplies *data and identity*, nothing visual.\n * One PR to shared-ui + a coordinated version bump propagates a chrome\n * change to every service.\n *\n * Composition: re-exports the existing `DashboardLayout` from\n * `@pablo2410/shared-ui/layout` under the clearer canonical name\n * `OplyticsServiceShell`. The two are the same component; consumers\n * should prefer `/shell` going forward — `/layout` will be marked\n * `@deprecated` once every subdomain has migrated and removed in\n * shared-ui v1.0 (see oplytics-subdomains tracking epic).\n *\n * CSS: ship `dist/shell/oplytics-shell.css` containing every Tailwind v4\n * utility this shell uses (built by `pnpm build:shell-css`). Consumers\n * `@import` it once in their own `index.css` and never need an\n * `@source` directive.\n *\n * ```css\n * @import \"tailwindcss\";\n * @import \"@pablo2410/shared-ui/theme/oplytics-theme.css\";\n * @import \"@pablo2410/shared-ui/shell/oplytics-shell.css\";\n * ```\n *\n * Usage:\n *\n * ```tsx\n * import { OplyticsServiceShell } from \"@pablo2410/shared-ui/shell\";\n *\n * <OplyticsServiceShell\n * serviceName=\"Connect\"\n * serviceIcon={<Zap />}\n * menuSections={menuSections}\n * adminSections={adminSections}\n * isAdmin={user?.role === \"platform_admin\"}\n * activePath={location}\n * onNavigate={setLocation}\n * user={user}\n * onLogout={logout}\n * enterprise={selection.enterprise}\n * hierarchyNavigator={<HierarchyNavigator hierarchy={hierarchy} />}\n * reportingToolbar={<ReportingToolbar … />}\n * >\n * <Routes />\n * </OplyticsServiceShell>\n * ```\n */\n\nimport {\n DashboardLayout,\n type DashboardLayoutProps,\n type DashboardLayoutUser,\n type DashboardLayoutEnterprise,\n type MenuItem,\n type MenuSection,\n} from \"../layout\";\n\n/**\n * The canonical composed Oplytics chrome.\n *\n * This is the same React component as `DashboardLayout` in\n * `@pablo2410/shared-ui/layout`, re-exported under a clearer name.\n * Consumers should prefer `OplyticsServiceShell` going forward.\n */\nconst OplyticsServiceShell = DashboardLayout;\n\n/**\n * Props accepted by `OplyticsServiceShell`.\n * (Alias of `DashboardLayoutProps`.)\n */\ntype ServiceShellProps = DashboardLayoutProps;\n\n/**\n * Authenticated user passed to the shell. Small enough to fit both\n * stateless-JWT subdomains (Connect, Policy Deployment) and DB-backed\n * ones (OEE Manager).\n */\ntype ServiceShellUser = DashboardLayoutUser;\n\n/**\n * Currently-scoped enterprise — drives the header enterprise badge.\n */\ntype ServiceShellEnterprise = DashboardLayoutEnterprise;\n\nexport {\n OplyticsServiceShell,\n type ServiceShellProps,\n type ServiceShellUser,\n type ServiceShellEnterprise,\n type MenuItem,\n type MenuSection,\n};\n"],"mappings":";;;;;;;AAmEA,IAAM,uBAAuB;","names":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-xs:.125rem;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--blur-sm:8px;--aspect-video:16 / 9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.\@container\/card-header{container:card-header/inline-size}.\@container\/field-group{container:field-group/inline-size}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.inset-x-0{inset-inline:calc(var(--spacing) * 0)}.inset-y-0{inset-block:calc(var(--spacing) * 0)}.-top-12{top:calc(var(--spacing) * -12)}.top-0{top:calc(var(--spacing) * 0)}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-1\/2{top:50%}.top-3\.5{top:calc(var(--spacing) * 3.5)}.top-4{top:calc(var(--spacing) * 4)}.top-\[1px\]{top:1px}.top-\[50\%\]{top:50%}.top-\[60\%\]{top:60%}.top-full{top:100%}.-right-12{right:calc(var(--spacing) * -12)}.right-0{right:calc(var(--spacing) * 0)}.right-1{right:calc(var(--spacing) * 1)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.right-4{right:calc(var(--spacing) * 4)}.right-6{right:calc(var(--spacing) * 6)}.-bottom-12{bottom:calc(var(--spacing) * -12)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-4{bottom:calc(var(--spacing) * 4)}.bottom-6{bottom:calc(var(--spacing) * 6)}.-left-12{left:calc(var(--spacing) * -12)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.left-4{left:calc(var(--spacing) * 4)}.left-\[50\%\]{left:50%}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.z-\[1\]{z-index:1}.order-first{order:-9999}.order-last{order:9999}.col-start-2{grid-column-start:2}.row-span-2{grid-row:span 2/span 2}.row-start-1{grid-row-start:1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.\!m-0{margin:calc(var(--spacing) * 0)!important}.m-auto{margin:auto}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-1{margin-inline:calc(var(--spacing) * 1)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-3\.5{margin-inline:calc(var(--spacing) * 3.5)}.mx-auto{margin-inline:auto}.-my-2{margin-block:calc(var(--spacing) * -2)}.my-0{margin-block:calc(var(--spacing) * 0)}.my-0\.5{margin-block:calc(var(--spacing) * .5)}.my-1{margin-block:calc(var(--spacing) * 1)}.-mt-1{margin-top:calc(var(--spacing) * -1)}.-mt-4{margin-top:calc(var(--spacing) * -4)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-auto{margin-top:auto}.-mr-1{margin-right:calc(var(--spacing) * -1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.-ml-4{margin-left:calc(var(--spacing) * -4)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-row{display:table-row}.field-sizing-content{field-sizing:content}.aspect-square{aspect-ratio:1}.aspect-video{aspect-ratio:var(--aspect-video)}.size-\(--cell-size\){width:var(--cell-size);height:var(--cell-size)}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.size-auto{width:auto;height:auto}.size-full{width:100%;height:100%}.h-\(--cell-size\){height:var(--cell-size)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-24{height:calc(var(--spacing) * 24)}.h-64{height:calc(var(--spacing) * 64)}.h-\[1\.15rem\]{height:1.15rem}.h-\[500px\]{height:500px}.h-\[calc\(100\%-1px\)\]{height:calc(100% - 1px)}.h-\[var\(--radix-navigation-menu-viewport-height\)\]{height:var(--radix-navigation-menu-viewport-height)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-svh{height:100svh}.max-h-\(--radix-context-menu-content-available-height\){max-height:var(--radix-context-menu-content-available-height)}.max-h-\(--radix-dropdown-menu-content-available-height\){max-height:var(--radix-dropdown-menu-content-available-height)}.max-h-\(--radix-select-content-available-height\){max-height:var(--radix-select-content-available-height)}.max-h-\[300px\]{max-height:300px}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-4{min-height:calc(var(--spacing) * 4)}.min-h-16{min-height:calc(var(--spacing) * 16)}.min-h-\[36px\]{min-height:36px}.min-h-\[400px\]{min-height:400px}.min-h-screen{min-height:100vh}.min-h-svh{min-height:100svh}.w-\(--cell-size\){width:var(--cell-size)}.w-\(--sidebar-width\){width:var(--sidebar-width)}.w-0{width:calc(var(--spacing) * 0)}.w-1{width:calc(var(--spacing) * 1)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-3\/4{width:75%}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-32{width:calc(var(--spacing) * 32)}.w-48{width:calc(var(--spacing) * 48)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-\[100px\]{width:100px}.w-\[260px\]{width:260px}.w-\[380px\]{width:380px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-max{width:max-content}.w-px{width:1px}.max-w-\(--skeleton-width\){max-width:var(--skeleton-width)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-\[80\%\]{max-width:80%}.max-w-\[80px\]{max-width:80px}.max-w-\[100px\]{max-width:100px}.max-w-\[120px\]{max-width:120px}.max-w-\[calc\(100\%-2rem\)\]{max-width:calc(100% - 2rem)}.max-w-full{max-width:100%}.max-w-max{max-width:max-content}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-\(--cell-size\){min-width:var(--cell-size)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-5{min-width:calc(var(--spacing) * 5)}.min-w-8{min-width:calc(var(--spacing) * 8)}.min-w-9{min-width:calc(var(--spacing) * 9)}.min-w-10{min-width:calc(var(--spacing) * 10)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[12rem\]{min-width:12rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.grow-0{flex-grow:0}.basis-full{flex-basis:100%}.caption-bottom{caption-side:bottom}.border-collapse{border-collapse:collapse}.origin-\(--radix-context-menu-content-transform-origin\){transform-origin:var(--radix-context-menu-content-transform-origin)}.origin-\(--radix-dropdown-menu-content-transform-origin\){transform-origin:var(--radix-dropdown-menu-content-transform-origin)}.origin-\(--radix-hover-card-content-transform-origin\){transform-origin:var(--radix-hover-card-content-transform-origin)}.origin-\(--radix-menubar-content-transform-origin\){transform-origin:var(--radix-menubar-content-transform-origin)}.origin-\(--radix-popover-content-transform-origin\){transform-origin:var(--radix-popover-content-transform-origin)}.origin-\(--radix-select-content-transform-origin\){transform-origin:var(--radix-select-content-transform-origin)}.origin-\(--radix-tooltip-content-transform-origin\){transform-origin:var(--radix-tooltip-content-transform-origin)}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-px{--tw-translate-x:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-px{--tw-translate-x:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-0\.5{--tw-translate-y:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\[-50\%\]{--tw-translate-y:-50%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\[calc\(-50\%_-_2px\)\]{--tw-translate-y:calc(-50% - 2px);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-45{rotate:45deg}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-text{cursor:text}.touch-none{touch-action:none}.resize-none{resize:none}.scroll-my-1{scroll-margin-block:calc(var(--spacing) * 1)}.scroll-py-1{scroll-padding-block:calc(var(--spacing) * 1)}.scrollbar-none{scrollbar-width:none}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.auto-rows-min{grid-auto-rows:min-content}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-\[0_1fr\]{grid-template-columns:0 1fr}.grid-rows-\[auto_auto\]{grid-template-rows:auto auto}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.justify-items-start{justify-items:start}.gap-0{gap:calc(var(--spacing) * 0)}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-7{gap:calc(var(--spacing) * 7)}.gap-8{gap:calc(var(--spacing) * 8)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.gap-y-0\.5{row-gap:calc(var(--spacing) * .5)}.self-start{align-self:flex-start}.self-stretch{align-self:stretch}.justify-self-end{justify-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[2px\]{border-radius:2px}.rounded-\[4px\]{border-radius:4px}.rounded-\[calc\(var\(--radius\)-5px\)\]{border-radius:calc(var(--radius) - 5px)}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-none{border-radius:0}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-xs{border-radius:var(--radius-xs)}.rounded-l-md{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.rounded-tl-sm{border-top-left-radius:var(--radius-sm)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.rounded-tr-sm{border-top-right-radius:var(--radius-sm)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-r-0{border-right-style:var(--tw-border-style);border-right-width:0}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\(--color-border\){border-color:var(--color-border)}.border-\[\#1E2738\]{border-color:#1e2738}.border-\[\#2A2A3E\]{border-color:#2a2a3e}.border-\[\#8C34E9\]\/20{border-color:oklab(54.9462% .12476 -.21612/.2)}.border-\[\#f59e0b\]\/20{border-color:oklab(76.8591% .0560995 .154808/.2)}.border-transparent{border-color:#0000}.border-t-transparent{border-top-color:#0000}.border-l-transparent{border-left-color:#0000}.bg-\(--color-bg\){background-color:var(--color-bg)}.bg-\[\#0A0E1A\]{background-color:#0a0e1a}.bg-\[\#0D1220\]{background-color:#0d1220}.bg-\[\#0D1220\]\/95{background-color:oklab(18.4838% -.000825129 -.0298502/.95)}.bg-\[\#0F1525\]{background-color:#0f1525}.bg-\[\#1E2738\]{background-color:#1e2738}.bg-\[\#8C34E9\]{background-color:#8c34e9}.bg-\[\#8C34E9\]\/10{background-color:oklab(54.9462% .12476 -.21612/.1)}.bg-\[\#8C34E9\]\/15{background-color:oklab(54.9462% .12476 -.21612/.15)}.bg-\[\#8C34E9\]\/20{background-color:oklab(54.9462% .12476 -.21612/.2)}.bg-\[\#8C34E9\]\/30{background-color:oklab(54.9462% .12476 -.21612/.3)}.bg-\[\#14b8a6\]\/20{background-color:oklab(70.3753% -.122901 -.00537139/.2)}.bg-\[\#ef4444\]\/10{background-color:oklab(63.6834% .187864 .0889286/.1)}.bg-\[\#f59e0b\]\/10{background-color:oklab(76.8591% .0560995 .154808/.1)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.fill-current{fill:currentColor}.p-0{padding:calc(var(--spacing) * 0)}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.p-\[3px\]{padding:3px}.p-px{padding:1px}.px-\(--cell-size\){padding-inline:var(--cell-size)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-2\.5{padding-right:calc(var(--spacing) * 2.5)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.pb-14{padding-bottom:calc(var(--spacing) * 14)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.align-text-bottom{vertical-align:text-bottom}.font-\[JetBrains_Mono\,monospace\]{font-family:JetBrains Mono,monospace}.font-\[Montserrat\,sans-serif\]{font-family:Montserrat,sans-serif}.font-\[Space_Grotesk\,sans-serif\]{font-family:Space Grotesk,sans-serif}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-sm\/relaxed{font-size:var(--text-sm);line-height:var(--leading-relaxed)}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.8rem\]{font-size:.8rem}.text-\[8px\]{font-size:8px}.text-\[10px\]{font-size:10px}.text-\[120px\]{font-size:120px}.leading-none{--tw-leading:1;line-height:1}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.text-balance{text-wrap:balance}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#1E2738\]{color:#1e2738}.text-\[\#3E4A5C\]{color:#3e4a5c}.text-\[\#8C34E9\]{color:#8c34e9}.text-\[\#14b8a6\]{color:#14b8a6}.text-\[\#8890A0\]{color:#8890a0}.text-\[\#596475\]{color:#596475}.text-\[\#A855F7\]{color:#a855f7}.text-\[\#C4CDD9\]{color:#c4cdd9}.text-\[\#C084FC\]{color:#c084fc}.text-\[\#E2E8F0\]{color:#e2e8f0}.text-\[\#EF4444\],.text-\[\#ef4444\]{color:#ef4444}.text-\[\#f59e0b\]{color:#f59e0b}.text-current{color:currentColor}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_0_1px_hsl\(var\(--sidebar-border\)\)\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,hsl(var(--sidebar-border)));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-0{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,box-shadow\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[left\,right\,width\]{transition-property:left,right,width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[margin\,opacity\]{transition-property:margin,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\,height\,padding\]{transition-property:width,height,padding;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-none{transition-property:none}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-1000{--tw-duration:1s;transition-duration:1s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-linear{--tw-ease:linear;transition-timing-function:linear}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[--cell-size\:--spacing\(8\)\]{--cell-size:calc(var(--spacing) * 8)}.group-focus-within\/menu-item\:opacity-100:is(:where(.group\/menu-item):focus-within *){opacity:1}@media (hover:hover){.group-hover\/menu-item\:opacity-100:is(:where(.group\/menu-item):hover *){opacity:1}}.group-has-data-\[sidebar\=menu-action\]\/menu-item\:pr-8:is(:where(.group\/menu-item):has([data-sidebar=menu-action]) *){padding-right:calc(var(--spacing) * 8)}.group-has-\[\[data-orientation\=horizontal\]\]\/field\:text-balance:is(:where(.group\/field):has([data-orientation=horizontal]) *){text-wrap:balance}.group-has-\[\[data-slot\=item-description\]\]\/item\:translate-y-0\.5:is(:where(.group\/item):has([data-slot=item-description]) *){--tw-translate-y:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.group-has-\[\[data-slot\=item-description\]\]\/item\:self-start:is(:where(.group\/item):has([data-slot=item-description]) *){align-self:flex-start}.group-has-\[\>input\]\/input-group\:pt-2\.5:is(:where(.group\/input-group):has(>input) *){padding-top:calc(var(--spacing) * 2.5)}.group-has-\[\>input\]\/input-group\:pb-2\.5:is(:where(.group\/input-group):has(>input) *){padding-bottom:calc(var(--spacing) * 2.5)}.group-data-\[collapsible\=icon\]\:-mt-8:is(:where(.group)[data-collapsible=icon] *){margin-top:calc(var(--spacing) * -8)}.group-data-\[collapsible\=icon\]\:hidden:is(:where(.group)[data-collapsible=icon] *){display:none}.group-data-\[collapsible\=icon\]\:size-8\!:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--spacing) * 8)!important;height:calc(var(--spacing) * 8)!important}.group-data-\[collapsible\=icon\]\:w-\(--sidebar-width-icon\):is(:where(.group)[data-collapsible=icon] *){width:var(--sidebar-width-icon)}.group-data-\[collapsible\=icon\]\:w-\[calc\(var\(--sidebar-width-icon\)\+\(--spacing\(4\)\)\)\]:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)))}.group-data-\[collapsible\=icon\]\:w-\[calc\(var\(--sidebar-width-icon\)\+\(--spacing\(4\)\)\+2px\)\]:is(:where(.group)[data-collapsible=icon] *){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)) + 2px)}.group-data-\[collapsible\=icon\]\:overflow-hidden:is(:where(.group)[data-collapsible=icon] *){overflow:hidden}.group-data-\[collapsible\=icon\]\:p-0\!:is(:where(.group)[data-collapsible=icon] *){padding:calc(var(--spacing) * 0)!important}.group-data-\[collapsible\=icon\]\:p-2\!:is(:where(.group)[data-collapsible=icon] *){padding:calc(var(--spacing) * 2)!important}.group-data-\[collapsible\=icon\]\:opacity-0:is(:where(.group)[data-collapsible=icon] *){opacity:0}.group-data-\[collapsible\=offcanvas\]\:right-\[calc\(var\(--sidebar-width\)\*-1\)\]:is(:where(.group)[data-collapsible=offcanvas] *){right:calc(var(--sidebar-width) * -1)}.group-data-\[collapsible\=offcanvas\]\:left-\[calc\(var\(--sidebar-width\)\*-1\)\]:is(:where(.group)[data-collapsible=offcanvas] *){left:calc(var(--sidebar-width) * -1)}.group-data-\[collapsible\=offcanvas\]\:w-0:is(:where(.group)[data-collapsible=offcanvas] *){width:calc(var(--spacing) * 0)}.group-data-\[collapsible\=offcanvas\]\:translate-x-0:is(:where(.group)[data-collapsible=offcanvas] *){--tw-translate-x:calc(var(--spacing) * 0);translate:var(--tw-translate-x) var(--tw-translate-y)}.group-data-\[disabled\=true\]\:pointer-events-none:is(:where(.group)[data-disabled=true] *){pointer-events:none}.group-data-\[disabled\=true\]\:opacity-50:is(:where(.group)[data-disabled=true] *),.group-data-\[disabled\=true\]\/field\:opacity-50:is(:where(.group\/field)[data-disabled=true] *),.group-data-\[disabled\=true\]\/input-group\:opacity-50:is(:where(.group\/input-group)[data-disabled=true] *){opacity:.5}.group-data-\[focused\=true\]\/day\:relative:is(:where(.group\/day)[data-focused=true] *){position:relative}.group-data-\[focused\=true\]\/day\:z-10:is(:where(.group\/day)[data-focused=true] *){z-index:10}.group-data-\[focused\=true\]\/day\:ring-\[3px\]:is(:where(.group\/day)[data-focused=true] *){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.group-data-\[side\=left\]\:-right-4:is(:where(.group)[data-side=left] *){right:calc(var(--spacing) * -4)}.group-data-\[side\=left\]\:border-r:is(:where(.group)[data-side=left] *){border-right-style:var(--tw-border-style);border-right-width:1px}.group-data-\[side\=right\]\:left-0:is(:where(.group)[data-side=right] *){left:calc(var(--spacing) * 0)}.group-data-\[side\=right\]\:rotate-180:is(:where(.group)[data-side=right] *){rotate:180deg}.group-data-\[side\=right\]\:border-l:is(:where(.group)[data-side=right] *){border-left-style:var(--tw-border-style);border-left-width:1px}.group-data-\[state\=open\]\:rotate-180:is(:where(.group)[data-state=open] *){rotate:180deg}.group-data-\[variant\=floating\]\:rounded-lg:is(:where(.group)[data-variant=floating] *){border-radius:var(--radius-lg)}.group-data-\[variant\=floating\]\:border:is(:where(.group)[data-variant=floating] *){border-style:var(--tw-border-style);border-width:1px}.group-data-\[variant\=floating\]\:shadow-sm:is(:where(.group)[data-variant=floating] *){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.group-data-\[variant\=outline\]\/field-group\:-mb-2:is(:where(.group\/field-group)[data-variant=outline] *){margin-bottom:calc(var(--spacing) * -2)}.group-data-\[vaul-drawer-direction\=bottom\]\/drawer-content\:block:is(:where(.group\/drawer-content)[data-vaul-drawer-direction=bottom] *){display:block}.group-data-\[vaul-drawer-direction\=bottom\]\/drawer-content\:text-center:is(:where(.group\/drawer-content)[data-vaul-drawer-direction=bottom] *),.group-data-\[vaul-drawer-direction\=top\]\/drawer-content\:text-center:is(:where(.group\/drawer-content)[data-vaul-drawer-direction=top] *){text-align:center}.group-data-\[viewport\=false\]\/navigation-menu\:top-full:is(:where(.group\/navigation-menu)[data-viewport=false] *){top:100%}.group-data-\[viewport\=false\]\/navigation-menu\:mt-1\.5:is(:where(.group\/navigation-menu)[data-viewport=false] *){margin-top:calc(var(--spacing) * 1.5)}.group-data-\[viewport\=false\]\/navigation-menu\:overflow-hidden:is(:where(.group\/navigation-menu)[data-viewport=false] *){overflow:hidden}.group-data-\[viewport\=false\]\/navigation-menu\:rounded-md:is(:where(.group\/navigation-menu)[data-viewport=false] *){border-radius:var(--radius-md)}.group-data-\[viewport\=false\]\/navigation-menu\:border:is(:where(.group\/navigation-menu)[data-viewport=false] *){border-style:var(--tw-border-style);border-width:1px}.group-data-\[viewport\=false\]\/navigation-menu\:shadow:is(:where(.group\/navigation-menu)[data-viewport=false] *){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.group-data-\[viewport\=false\]\/navigation-menu\:duration-200:is(:where(.group\/navigation-menu)[data-viewport=false] *){--tw-duration:.2s;transition-duration:.2s}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-50:is(:where(.peer):disabled~*){opacity:.5}.peer-data-\[size\=default\]\/menu-button\:top-1\.5:is(:where(.peer\/menu-button)[data-size=default]~*){top:calc(var(--spacing) * 1.5)}.peer-data-\[size\=lg\]\/menu-button\:top-2\.5:is(:where(.peer\/menu-button)[data-size=lg]~*){top:calc(var(--spacing) * 2.5)}.peer-data-\[size\=sm\]\/menu-button\:top-1:is(:where(.peer\/menu-button)[data-size=sm]~*){top:calc(var(--spacing) * 1)}.file\:inline-flex::file-selector-button{display:inline-flex}.file\:h-7::file-selector-button{height:calc(var(--spacing) * 7)}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.placeholder\:text-\[\#596475\]::placeholder{color:#596475}.backdrop\:bg-black\/60::backdrop{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.backdrop\:bg-black\/60::backdrop{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.backdrop\:backdrop-blur-sm::backdrop{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:-inset-2:after{content:var(--tw-content);inset:calc(var(--spacing) * -2)}.after\:inset-y-0:after{content:var(--tw-content);inset-block:calc(var(--spacing) * 0)}.after\:left-1\/2:after{content:var(--tw-content);left:50%}.after\:w-1:after{content:var(--tw-content);width:calc(var(--spacing) * 1)}.after\:w-\[2px\]:after{content:var(--tw-content);width:2px}.after\:-translate-x-1\/2:after{content:var(--tw-content);--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.group-data-\[collapsible\=offcanvas\]\:after\:left-full:is(:where(.group)[data-collapsible=offcanvas] *):after{content:var(--tw-content);left:100%}.first\:rounded-l-md:first-child{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.first\:border-l:first-child{border-left-style:var(--tw-border-style);border-left-width:1px}.last\:mt-0:last-child{margin-top:calc(var(--spacing) * 0)}.last\:rounded-r-md:last-child{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media (hover:hover){.hover\:border-\[\#596475\]:hover{border-color:#596475}.hover\:bg-\[\#1E2738\]:hover{background-color:#1e2738}.hover\:bg-\[\#7928d4\]:hover{background-color:#7928d4}.hover\:bg-\[\#EF4444\]\/10:hover{background-color:oklab(63.6834% .187864 .0889286/.1)}.hover\:text-\[\#8890A0\]:hover{color:#8890a0}.hover\:text-\[\#A855F7\]:hover{color:#a855f7}.hover\:text-\[\#E2E8F0\]:hover{color:#e2e8f0}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-90:hover{opacity:.9}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-\[0_0_0_1px_hsl\(var\(--sidebar-accent\)\)\]:hover{--tw-shadow:0 0 0 1px var(--tw-shadow-color,hsl(var(--sidebar-accent)));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hover\:ring-4:hover{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\:z-10:focus{z-index:10}.focus\:border-\[\#8C34E9\]:focus{border-color:#8c34e9}.focus\:bg-\[\#1E2738\]:focus{background-color:#1e2738}.focus\:bg-\[\#EF4444\]\/10:focus{background-color:oklab(63.6834% .187864 .0889286/.1)}.focus\:text-\[\#EF4444\]:focus{color:#ef4444}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:z-10:focus-visible{z-index:10}.focus-visible\:ring-0:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-4:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-\[\#8C34E9\]:focus-visible{--tw-ring-color:#8c34e9}.focus-visible\:ring-offset-1:focus-visible{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:ring-offset-\[\#0A0E1A\]:focus-visible{--tw-ring-offset-color:#0a0e1a}.focus-visible\:outline-hidden:focus-visible{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus-visible\:outline-hidden:focus-visible{outline-offset:2px;outline:2px solid #0000}}.focus-visible\:outline-1:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}:where([data-side=left]) .in-data-\[side\=left\]\:cursor-w-resize{cursor:w-resize}:where([data-side=right]) .in-data-\[side\=right\]\:cursor-e-resize{cursor:e-resize}.has-focus\:ring-\[3px\]:has(:focus){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-disabled\:opacity-50:has(:disabled){opacity:.5}.has-data-\[slot\=card-action\]\:grid-cols-\[1fr_auto\]:has([data-slot=card-action]){grid-template-columns:1fr auto}.has-\[\[data-slot\=input-group-control\]\:focus-visible\]\:ring-\[3px\]:has([data-slot=input-group-control]:focus-visible){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-\[\>\[data-align\=block-end\]\]\:h-auto:has(>[data-align=block-end]){height:auto}.has-\[\>\[data-align\=block-end\]\]\:flex-col:has(>[data-align=block-end]){flex-direction:column}.has-\[\>\[data-align\=block-start\]\]\:h-auto:has(>[data-align=block-start]){height:auto}.has-\[\>\[data-align\=block-start\]\]\:flex-col:has(>[data-align=block-start]){flex-direction:column}.has-\[\>\[data-slot\=button-group\]\]\:gap-2:has(>[data-slot=button-group]){gap:calc(var(--spacing) * 2)}.has-\[\>\[data-slot\=checkbox-group\]\]\:gap-3:has(>[data-slot=checkbox-group]){gap:calc(var(--spacing) * 3)}.has-\[\>\[data-slot\=field-content\]\]\:items-start:has(>[data-slot=field-content]){align-items:flex-start}.has-\[\>\[data-slot\=field\]\]\:w-full:has(>[data-slot=field]){width:100%}.has-\[\>\[data-slot\=field\]\]\:flex-col:has(>[data-slot=field]){flex-direction:column}.has-\[\>\[data-slot\=field\]\]\:rounded-md:has(>[data-slot=field]){border-radius:var(--radius-md)}.has-\[\>\[data-slot\=field\]\]\:border:has(>[data-slot=field]){border-style:var(--tw-border-style);border-width:1px}.has-\[\>\[data-slot\=radio-group\]\]\:gap-3:has(>[data-slot=radio-group]){gap:calc(var(--spacing) * 3)}.has-\[\>button\]\:mr-\[-0\.45rem\]:has(>button){margin-right:-.45rem}.has-\[\>button\]\:ml-\[-0\.45rem\]:has(>button){margin-left:-.45rem}.has-\[\>kbd\]\:mr-\[-0\.35rem\]:has(>kbd){margin-right:-.35rem}.has-\[\>kbd\]\:ml-\[-0\.35rem\]:has(>kbd){margin-left:-.35rem}.has-\[\>svg\]\:grid-cols-\[calc\(var\(--spacing\)\*4\)_1fr\]:has(>svg){grid-template-columns:calc(var(--spacing) * 4) 1fr}.has-\[\>svg\]\:gap-x-3:has(>svg){column-gap:calc(var(--spacing) * 3)}.has-\[\>svg\]\:p-0:has(>svg){padding:calc(var(--spacing) * 0)}.has-\[\>svg\]\:px-2:has(>svg){padding-inline:calc(var(--spacing) * 2)}.has-\[\>svg\]\:px-2\.5:has(>svg){padding-inline:calc(var(--spacing) * 2.5)}.has-\[\>svg\]\:px-3:has(>svg){padding-inline:calc(var(--spacing) * 3)}.has-\[\>svg\]\:px-4:has(>svg){padding-inline:calc(var(--spacing) * 4)}.has-\[\>textarea\]\:h-auto:has(>textarea){height:auto}.aria-disabled\:pointer-events-none[aria-disabled=true]{pointer-events:none}.aria-disabled\:opacity-50[aria-disabled=true]{opacity:.5}.data-\[active\=true\]\:z-10[data-active=true]{z-index:10}.data-\[active\=true\]\:font-medium[data-active=true]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.data-\[active\=true\]\:ring-\[3px\][data-active=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}.data-\[inset\]\:pl-8[data-inset]{padding-left:calc(var(--spacing) * 8)}.data-\[orientation\=horizontal\]\:h-1\.5[data-orientation=horizontal]{height:calc(var(--spacing) * 1.5)}.data-\[orientation\=horizontal\]\:h-full[data-orientation=horizontal]{height:100%}.data-\[orientation\=horizontal\]\:h-px[data-orientation=horizontal]{height:1px}.data-\[orientation\=horizontal\]\:w-full[data-orientation=horizontal]{width:100%}.data-\[orientation\=vertical\]\:h-auto[data-orientation=vertical]{height:auto}.data-\[orientation\=vertical\]\:h-full[data-orientation=vertical]{height:100%}.data-\[orientation\=vertical\]\:min-h-44[data-orientation=vertical]{min-height:calc(var(--spacing) * 44)}.data-\[orientation\=vertical\]\:w-1\.5[data-orientation=vertical]{width:calc(var(--spacing) * 1.5)}.data-\[orientation\=vertical\]\:w-auto[data-orientation=vertical]{width:auto}.data-\[orientation\=vertical\]\:w-full[data-orientation=vertical]{width:100%}.data-\[orientation\=vertical\]\:w-px[data-orientation=vertical]{width:1px}.data-\[orientation\=vertical\]\:flex-col[data-orientation=vertical]{flex-direction:column}.data-\[panel-group-direction\=vertical\]\:h-px[data-panel-group-direction=vertical]{height:1px}.data-\[panel-group-direction\=vertical\]\:w-full[data-panel-group-direction=vertical]{width:100%}.data-\[panel-group-direction\=vertical\]\:flex-col[data-panel-group-direction=vertical]{flex-direction:column}.data-\[panel-group-direction\=vertical\]\:after\:left-0[data-panel-group-direction=vertical]:after{content:var(--tw-content);left:calc(var(--spacing) * 0)}.data-\[panel-group-direction\=vertical\]\:after\:h-1[data-panel-group-direction=vertical]:after{content:var(--tw-content);height:calc(var(--spacing) * 1)}.data-\[panel-group-direction\=vertical\]\:after\:w-full[data-panel-group-direction=vertical]:after{content:var(--tw-content);width:100%}.data-\[panel-group-direction\=vertical\]\:after\:translate-x-0[data-panel-group-direction=vertical]:after{content:var(--tw-content);--tw-translate-x:calc(var(--spacing) * 0);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[panel-group-direction\=vertical\]\:after\:-translate-y-1\/2[data-panel-group-direction=vertical]:after{content:var(--tw-content);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[range-end\=true\]\:rounded-md[data-range-end=true]{border-radius:var(--radius-md)}.data-\[range-end\=true\]\:rounded-r-md[data-range-end=true]{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.data-\[range-middle\=true\]\:rounded-none[data-range-middle=true]{border-radius:0}.data-\[range-start\=true\]\:rounded-md[data-range-start=true]{border-radius:var(--radius-md)}.data-\[range-start\=true\]\:rounded-l-md[data-range-start=true]{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.data-\[selected\=true\]\:rounded-none[data-selected=true]{border-radius:0}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:calc(var(--spacing) * 1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:calc(var(--spacing) * 1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[size\=default\]\:h-9[data-size=default]{height:calc(var(--spacing) * 9)}.data-\[size\=sm\]\:h-8[data-size=sm]{height:calc(var(--spacing) * 8)}.data-\[slot\=checkbox-group\]\:gap-3[data-slot=checkbox-group]{gap:calc(var(--spacing) * 3)}:is(.\*\*\:data-\[slot\=command-input-wrapper\]\:h-12 *)[data-slot=command-input-wrapper]{height:calc(var(--spacing) * 12)}:is(.\*\*\:data-\[slot\=navigation-menu-link\]\:focus\:ring-0 *)[data-slot=navigation-menu-link]:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(.\*\*\:data-\[slot\=navigation-menu-link\]\:focus\:outline-none *)[data-slot=navigation-menu-link]:focus{--tw-outline-style:none;outline-style:none}:is(.\*\:data-\[slot\=select-value\]\:line-clamp-1>*)[data-slot=select-value]{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}:is(.\*\:data-\[slot\=select-value\]\:flex>*)[data-slot=select-value]{display:flex}:is(.\*\:data-\[slot\=select-value\]\:items-center>*)[data-slot=select-value]{align-items:center}:is(.\*\:data-\[slot\=select-value\]\:gap-2>*)[data-slot=select-value]{gap:calc(var(--spacing) * 2)}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-\[state\=checked\]\:translate-x-\[calc\(100\%-2px\)\][data-state=checked]{--tw-translate-x:calc(100% - 2px);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[state\=closed\]\:duration-300[data-state=closed]{--tw-duration:.3s;transition-duration:.3s}.data-\[state\=open\]\:opacity-100[data-state=open]{opacity:1}.data-\[state\=open\]\:duration-500[data-state=open]{--tw-duration:.5s;transition-duration:.5s}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked]{--tw-translate-x:calc(var(--spacing) * 0);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[variant\=label\]\:text-sm[data-variant=label]{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.data-\[variant\=legend\]\:text-base[data-variant=legend]{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.data-\[variant\=outline\]\:border-l-0[data-variant=outline]{border-left-style:var(--tw-border-style);border-left-width:0}.data-\[variant\=outline\]\:shadow-xs[data-variant=outline]{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-\[variant\=outline\]\:first\:border-l[data-variant=outline]:first-child{border-left-style:var(--tw-border-style);border-left-width:1px}.data-\[vaul-drawer-direction\=bottom\]\:inset-x-0[data-vaul-drawer-direction=bottom]{inset-inline:calc(var(--spacing) * 0)}.data-\[vaul-drawer-direction\=bottom\]\:bottom-0[data-vaul-drawer-direction=bottom]{bottom:calc(var(--spacing) * 0)}.data-\[vaul-drawer-direction\=bottom\]\:mt-24[data-vaul-drawer-direction=bottom]{margin-top:calc(var(--spacing) * 24)}.data-\[vaul-drawer-direction\=bottom\]\:max-h-\[80vh\][data-vaul-drawer-direction=bottom]{max-height:80vh}.data-\[vaul-drawer-direction\=bottom\]\:rounded-t-lg[data-vaul-drawer-direction=bottom]{border-top-left-radius:var(--radius-lg);border-top-right-radius:var(--radius-lg)}.data-\[vaul-drawer-direction\=bottom\]\:border-t[data-vaul-drawer-direction=bottom]{border-top-style:var(--tw-border-style);border-top-width:1px}.data-\[vaul-drawer-direction\=left\]\:inset-y-0[data-vaul-drawer-direction=left]{inset-block:calc(var(--spacing) * 0)}.data-\[vaul-drawer-direction\=left\]\:left-0[data-vaul-drawer-direction=left]{left:calc(var(--spacing) * 0)}.data-\[vaul-drawer-direction\=left\]\:w-3\/4[data-vaul-drawer-direction=left]{width:75%}.data-\[vaul-drawer-direction\=left\]\:border-r[data-vaul-drawer-direction=left]{border-right-style:var(--tw-border-style);border-right-width:1px}.data-\[vaul-drawer-direction\=right\]\:inset-y-0[data-vaul-drawer-direction=right]{inset-block:calc(var(--spacing) * 0)}.data-\[vaul-drawer-direction\=right\]\:right-0[data-vaul-drawer-direction=right]{right:calc(var(--spacing) * 0)}.data-\[vaul-drawer-direction\=right\]\:w-3\/4[data-vaul-drawer-direction=right]{width:75%}.data-\[vaul-drawer-direction\=right\]\:border-l[data-vaul-drawer-direction=right]{border-left-style:var(--tw-border-style);border-left-width:1px}.data-\[vaul-drawer-direction\=top\]\:inset-x-0[data-vaul-drawer-direction=top]{inset-inline:calc(var(--spacing) * 0)}.data-\[vaul-drawer-direction\=top\]\:top-0[data-vaul-drawer-direction=top]{top:calc(var(--spacing) * 0)}.data-\[vaul-drawer-direction\=top\]\:mb-24[data-vaul-drawer-direction=top]{margin-bottom:calc(var(--spacing) * 24)}.data-\[vaul-drawer-direction\=top\]\:max-h-\[80vh\][data-vaul-drawer-direction=top]{max-height:80vh}.data-\[vaul-drawer-direction\=top\]\:rounded-b-lg[data-vaul-drawer-direction=top]{border-bottom-right-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.data-\[vaul-drawer-direction\=top\]\:border-b[data-vaul-drawer-direction=top]{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.nth-last-2\:-mt-1:nth-last-child(2){margin-top:calc(var(--spacing) * -1)}@supports ((-webkit-backdrop-filter:var(--tw)) or (backdrop-filter:var(--tw))){.supports-\[backdrop-filter\]\:backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}}@media (min-width:40rem){.sm\:block{display:block}.sm\:flex{display:flex}.sm\:inline{display:inline}.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:max-w-sm{max-width:var(--container-sm)}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:gap-2\.5{gap:calc(var(--spacing) * 2.5)}.sm\:pr-2\.5{padding-right:calc(var(--spacing) * 2.5)}.sm\:pl-2\.5{padding-left:calc(var(--spacing) * 2.5)}.sm\:text-left{text-align:left}.data-\[vaul-drawer-direction\=left\]\:sm\:max-w-sm[data-vaul-drawer-direction=left],.data-\[vaul-drawer-direction\=right\]\:sm\:max-w-sm[data-vaul-drawer-direction=right]{max-width:var(--container-sm)}}@media (min-width:48rem){.md\:absolute{position:absolute}.md\:col-span-1{grid-column:span 1/span 1}.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:w-\[var\(--radix-navigation-menu-viewport-width\)\]{width:var(--radix-navigation-menu-viewport-width)}.md\:w-auto{width:auto}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:gap-1\.5{gap:calc(var(--spacing) * 1.5)}.md\:p-6{padding:calc(var(--spacing) * 6)}.md\:p-12{padding:calc(var(--spacing) * 12)}.md\:text-left{text-align:left}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.md\:opacity-0{opacity:0}.md\:peer-data-\[variant\=inset\]\:m-2:is(:where(.peer)[data-variant=inset]~*){margin:calc(var(--spacing) * 2)}.md\:peer-data-\[variant\=inset\]\:ml-0:is(:where(.peer)[data-variant=inset]~*){margin-left:calc(var(--spacing) * 0)}.md\:peer-data-\[variant\=inset\]\:rounded-xl:is(:where(.peer)[data-variant=inset]~*){border-radius:var(--radius-xl)}.md\:peer-data-\[variant\=inset\]\:shadow-sm:is(:where(.peer)[data-variant=inset]~*){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.md\:peer-data-\[variant\=inset\]\:peer-data-\[state\=collapsed\]\:ml-2:is(:where(.peer)[data-variant=inset]~*):is(:where(.peer)[data-state=collapsed]~*){margin-left:calc(var(--spacing) * 2)}.md\:after\:hidden:after{content:var(--tw-content);display:none}}@media (min-width:64rem){.lg\:flex{display:flex}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@container field-group (min-width:28rem){.\@md\/field-group\:flex-row{flex-direction:row}.\@md\/field-group\:items-center{align-items:center}.\@md\/field-group\:has-\[\>\[data-slot\=field-content\]\]\:items-start:has(>[data-slot=field-content]){align-items:flex-start}}@media (prefers-color-scheme:dark){.dark\:bg-transparent{background-color:#0000}}.\[\&_\.recharts-dot\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-dot[stroke=\#fff]{stroke:#0000}.\[\&_\.recharts-layer\]\:outline-hidden .recharts-layer{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.\[\&_\.recharts-layer\]\:outline-hidden .recharts-layer{outline-offset:2px;outline:2px solid #0000}}.\[\&_\.recharts-sector\]\:outline-hidden .recharts-sector{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.\[\&_\.recharts-sector\]\:outline-hidden .recharts-sector{outline-offset:2px;outline:2px solid #0000}}.\[\&_\.recharts-sector\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-sector[stroke=\#fff]{stroke:#0000}.\[\&_\.recharts-surface\]\:outline-hidden .recharts-surface{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.\[\&_\.recharts-surface\]\:outline-hidden .recharts-surface{outline-offset:2px;outline:2px solid #0000}}.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading]{padding-inline:calc(var(--spacing) * 2)}.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading]{padding-block:calc(var(--spacing) * 1.5)}.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading]{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group]{padding-inline:calc(var(--spacing) * 2)}.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden])~[cmdk-group]{padding-top:calc(var(--spacing) * 0)}.\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg{height:calc(var(--spacing) * 5)}.\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg{width:calc(var(--spacing) * 5)}.\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input]{height:calc(var(--spacing) * 12)}.\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item]{padding-inline:calc(var(--spacing) * 2)}.\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item]{padding-block:calc(var(--spacing) * 3)}.\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg{height:calc(var(--spacing) * 5)}.\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg{width:calc(var(--spacing) * 5)}.\[\&_img\]\:size-full img{width:100%;height:100%}.\[\&_img\]\:object-cover img{object-fit:cover}.\[\&_p\]\:leading-relaxed p{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-3 svg:not([class*=size-]){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-6 svg:not([class*=size-]){width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\+\[data-slot\=item-content\]\]\:flex-none+[data-slot=item-content]{flex:none}.\[\&\:first-child\[data-selected\=true\]_button\]\:rounded-l-md:first-child[data-selected=true] button{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing) * 0)}.\[\.border-b\]\:pb-3.border-b{padding-bottom:calc(var(--spacing) * 3)}.\[\.border-b\]\:pb-6.border-b{padding-bottom:calc(var(--spacing) * 6)}.\[\.border-t\]\:pt-3.border-t{padding-top:calc(var(--spacing) * 3)}.\[\.border-t\]\:pt-6.border-t{padding-top:calc(var(--spacing) * 6)}:is(.rtl\:\*\*\:\[\.rdp-button\\_next\>svg\]\:rotate-180:where(:dir(rtl),[dir=rtl],[dir=rtl] *) *):is(.rdp-button_next>svg),:is(.rtl\:\*\*\:\[\.rdp-button\\_previous\>svg\]\:rotate-180:where(:dir(rtl),[dir=rtl],[dir=rtl] *) *):is(.rdp-button_previous>svg){rotate:180deg}.\[a\]\:transition-colors:is(a){transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}:is(.\*\:\[span\]\:last\:flex>*):is(span):last-child{display:flex}:is(.\*\:\[span\]\:last\:items-center>*):is(span):last-child{align-items:center}:is(.\*\:\[span\]\:last\:gap-2>*):is(span):last-child{gap:calc(var(--spacing) * 2)}.\[\&\:last-child\[data-selected\=true\]_button\]\:rounded-r-md:last-child[data-selected=true] button{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.\[\&\>\*\]\:w-full>*{width:100%}.\[\&\>\*\]\:focus-visible\:relative>:focus-visible{position:relative}.\[\&\>\*\]\:focus-visible\:z-10>:focus-visible{z-index:10}.\[\&\>\*\]\:data-\[slot\=field\]\:p-4>[data-slot=field]{padding:calc(var(--spacing) * 4)}@container field-group (min-width:28rem){.\@md\/field-group\:\[\&\>\*\]\:w-auto>*{width:auto}}.\[\&\>\*\:not\(\:first-child\)\]\:rounded-t-none>:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.\[\&\>\*\:not\(\:first-child\)\]\:rounded-l-none>:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.\[\&\>\*\:not\(\:first-child\)\]\:border-t-0>:not(:first-child){border-top-style:var(--tw-border-style);border-top-width:0}.\[\&\>\*\:not\(\:first-child\)\]\:border-l-0>:not(:first-child){border-left-style:var(--tw-border-style);border-left-width:0}.\[\&\>\*\:not\(\:last-child\)\]\:rounded-r-none>:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.\[\&\>\*\:not\(\:last-child\)\]\:rounded-b-none>:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0}.\[\&\>\.sr-only\]\:w-auto>.sr-only{width:auto}.\[\&\>\[data-slot\=field-group\]\]\:gap-4>[data-slot=field-group]{gap:calc(var(--spacing) * 4)}.\[\&\>\[data-slot\=field-label\]\]\:flex-auto>[data-slot=field-label]{flex:auto}@container field-group (min-width:28rem){.\@md\/field-group\:\[\&\>\[data-slot\=field-label\]\]\:flex-auto>[data-slot=field-label]{flex:auto}}.has-\[select\[aria-hidden\=true\]\:last-child\]\:\[\&\>\[data-slot\=select-trigger\]\:last-of-type\]\:rounded-r-md:has(:is(select[aria-hidden=true]:last-child))>[data-slot=select-trigger]:last-of-type{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.\[\&\>\[data-slot\=select-trigger\]\:not\(\[class\*\=\'w-\'\]\)\]\:w-fit>[data-slot=select-trigger]:not([class*=w-]){width:fit-content}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x) var(--tw-translate-y)}.has-\[\>\[data-slot\=field-content\]\]\:\[\&\>\[role\=checkbox\]\,\[role\=radio\]\]\:mt-px:has(>[data-slot=field-content])>[role=checkbox],.has-\[\>\[data-slot\=field-content\]\]\:\[\&\>\[role\=checkbox\]\,\[role\=radio\]\]\:mt-px:has(>[data-slot=field-content]) [role=radio]{margin-top:1px}@container field-group (min-width:28rem){.\@md\/field-group\:has-\[\>\[data-slot\=field-content\]\]\:\[\&\>\[role\=checkbox\]\,\[role\=radio\]\]\:mt-px:has(>[data-slot=field-content])>[role=checkbox],.\@md\/field-group\:has-\[\>\[data-slot\=field-content\]\]\:\[\&\>\[role\=checkbox\]\,\[role\=radio\]\]\:mt-px:has(>[data-slot=field-content]) [role=radio]{margin-top:1px}}.\[\&\>a\]\:underline>a{text-decoration-line:underline}.\[\&\>a\]\:underline-offset-4>a{text-underline-offset:4px}.\[\&\>button\]\:hidden>button{display:none}.\[\&\>input\]\:flex-1>input{flex:1}.has-\[\>\[data-align\=block-end\]\]\:\[\&\>input\]\:pt-3:has(>[data-align=block-end])>input{padding-top:calc(var(--spacing) * 3)}.has-\[\>\[data-align\=block-start\]\]\:\[\&\>input\]\:pb-3:has(>[data-align=block-start])>input{padding-bottom:calc(var(--spacing) * 3)}.has-\[\>\[data-align\=inline-end\]\]\:\[\&\>input\]\:pr-2:has(>[data-align=inline-end])>input{padding-right:calc(var(--spacing) * 2)}.has-\[\>\[data-align\=inline-start\]\]\:\[\&\>input\]\:pl-2:has(>[data-align=inline-start])>input{padding-left:calc(var(--spacing) * 2)}.\[\&\>kbd\]\:rounded-\[calc\(var\(--radius\)-5px\)\]>kbd{border-radius:calc(var(--radius) - 5px)}.\[\&\>span\]\:text-xs>span{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&\>span\]\:opacity-70>span{opacity:.7}.\[\&\>span\:last-child\]\:truncate>span:last-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\[\&\>svg\]\:pointer-events-none>svg{pointer-events:none}.\[\&\>svg\]\:size-3>svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&\>svg\]\:size-3\.5>svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:h-2\.5>svg{height:calc(var(--spacing) * 2.5)}.\[\&\>svg\]\:h-3>svg{height:calc(var(--spacing) * 3)}.\[\&\>svg\]\:w-2\.5>svg{width:calc(var(--spacing) * 2.5)}.\[\&\>svg\]\:w-3>svg{width:calc(var(--spacing) * 3)}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>svg\]\:translate-y-0\.5>svg{--tw-translate-y:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.\[\&\>svg\]\:text-current>svg{color:currentColor}.\[\&\>svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-3\.5>svg:not([class*=size-]){width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&\>svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4>svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.\[\&\[data-panel-group-direction\=vertical\]\>div\]\:rotate-90[data-panel-group-direction=vertical]>div{rotate:90deg}.\[\&\[data-state\=open\]\>svg\]\:rotate-180[data-state=open]>svg{rotate:180deg}[data-side=left][data-collapsible=offcanvas] .\[\[data-side\=left\]\[data-collapsible\=offcanvas\]_\&\]\:-right-2{right:calc(var(--spacing) * -2)}[data-side=left][data-state=collapsed] .\[\[data-side\=left\]\[data-state\=collapsed\]_\&\]\:cursor-e-resize{cursor:e-resize}[data-side=right][data-collapsible=offcanvas] .\[\[data-side\=right\]\[data-collapsible\=offcanvas\]_\&\]\:-left-2{left:calc(var(--spacing) * -2)}[data-side=right][data-state=collapsed] .\[\[data-side\=right\]\[data-state\=collapsed\]_\&\]\:cursor-w-resize{cursor:w-resize}[data-slot=card-content] .\[\[data-slot\=card-content\]_\&\]\:bg-transparent,[data-slot=popover-content] .\[\[data-slot\=popover-content\]_\&\]\:bg-transparent{background-color:#0000}[data-variant=legend]+.\[\[data-variant\=legend\]\+\&\]\:-mt-1\.5{margin-top:calc(var(--spacing) * -1.5)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Oplytics.digital — Canonical Dark Theme
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for CSS variables used across all subdomains.
|
|
5
|
+
* Import this file in your subdomain's index.css or main entry point:
|
|
6
|
+
*
|
|
7
|
+
* @import '@oplytics/shared-ui/theme/oplytics-theme.css';
|
|
8
|
+
*
|
|
9
|
+
* All color values use the Oplytics brand system:
|
|
10
|
+
* - Deep industrial-tech aesthetic
|
|
11
|
+
* - Near-black backgrounds (#0a0e1a)
|
|
12
|
+
* - Purple accent (#8C34E9)
|
|
13
|
+
* - Teal secondary (#14b8a6)
|
|
14
|
+
* - Clean geometric typography (Montserrat headings, Space Grotesk body)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
:root {
|
|
18
|
+
/* ── Backgrounds ── */
|
|
19
|
+
--oplytics-bg-primary: #0a0e1a;
|
|
20
|
+
--oplytics-bg-secondary: #0d1220;
|
|
21
|
+
--oplytics-bg-tertiary: #111827;
|
|
22
|
+
--oplytics-bg-card: #0f1525;
|
|
23
|
+
--oplytics-bg-card-hover: #141b2d;
|
|
24
|
+
--oplytics-bg-surface: #1a2236;
|
|
25
|
+
|
|
26
|
+
/* ── Borders ── */
|
|
27
|
+
--oplytics-border-default: #1e2738;
|
|
28
|
+
--oplytics-border-subtle: #161e2e;
|
|
29
|
+
--oplytics-border-hover: #2a3548;
|
|
30
|
+
|
|
31
|
+
/* ── Text ── */
|
|
32
|
+
--oplytics-text-primary: #ffffff;
|
|
33
|
+
--oplytics-text-secondary: #c4cdd9;
|
|
34
|
+
--oplytics-text-muted: #596475;
|
|
35
|
+
--oplytics-text-dim: #3e4a5c;
|
|
36
|
+
|
|
37
|
+
/* ── Accent — Purple (Primary) ── */
|
|
38
|
+
--oplytics-accent-purple: #8C34E9;
|
|
39
|
+
--oplytics-accent-purple-hover: #7928d4;
|
|
40
|
+
--oplytics-accent-purple-light: #a855f7;
|
|
41
|
+
--oplytics-accent-purple-bg: rgba(140, 52, 233, 0.1);
|
|
42
|
+
|
|
43
|
+
/* ── Accent — Teal (Secondary) ── */
|
|
44
|
+
--oplytics-accent-teal: #14b8a6;
|
|
45
|
+
--oplytics-accent-teal-hover: #0d9488;
|
|
46
|
+
--oplytics-accent-teal-light: #2dd4bf;
|
|
47
|
+
--oplytics-accent-teal-bg: rgba(20, 184, 166, 0.1);
|
|
48
|
+
|
|
49
|
+
/* ── Status ── */
|
|
50
|
+
--oplytics-status-success: #22c55e;
|
|
51
|
+
--oplytics-status-warning: #f59e0b;
|
|
52
|
+
--oplytics-status-error: #ef4444;
|
|
53
|
+
--oplytics-status-info: #3b82f6;
|
|
54
|
+
|
|
55
|
+
/* ── Overlay ── */
|
|
56
|
+
--oplytics-overlay-bg: rgba(0, 0, 0, 0.5);
|
|
57
|
+
|
|
58
|
+
/* ── Typography ── */
|
|
59
|
+
--oplytics-font-heading: 'Montserrat', sans-serif;
|
|
60
|
+
--oplytics-font-body: 'Space Grotesk', sans-serif;
|
|
61
|
+
--oplytics-font-mono: 'JetBrains Mono', monospace;
|
|
62
|
+
|
|
63
|
+
/* ── Spacing ── */
|
|
64
|
+
--oplytics-space-xs: 0.25rem;
|
|
65
|
+
--oplytics-space-sm: 0.5rem;
|
|
66
|
+
--oplytics-space-md: 1rem;
|
|
67
|
+
--oplytics-space-lg: 1.5rem;
|
|
68
|
+
--oplytics-space-xl: 2rem;
|
|
69
|
+
--oplytics-space-2xl: 3rem;
|
|
70
|
+
--oplytics-space-3xl: 4rem;
|
|
71
|
+
|
|
72
|
+
/* ── Radius ── */
|
|
73
|
+
--oplytics-radius-sm: 0.375rem;
|
|
74
|
+
--oplytics-radius-md: 0.5rem;
|
|
75
|
+
--oplytics-radius-lg: 0.75rem;
|
|
76
|
+
--oplytics-radius-xl: 1rem;
|
|
77
|
+
--oplytics-radius-full: 9999px;
|
|
78
|
+
|
|
79
|
+
/* ── Shadows ── */
|
|
80
|
+
--oplytics-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
81
|
+
--oplytics-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.3);
|
|
82
|
+
--oplytics-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.3);
|
|
83
|
+
--oplytics-shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.3);
|
|
84
|
+
--oplytics-shadow-card: 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
85
|
+
--oplytics-shadow-glow: 0 0 20px rgba(140, 52, 233, 0.15);
|
|
86
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pablo2410/shared-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Shared UI component library for all Oplytics.digital subdomains",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -44,7 +44,12 @@
|
|
|
44
44
|
"./services": {
|
|
45
45
|
"types": "./dist/services/index.d.ts",
|
|
46
46
|
"import": "./dist/services/index.js"
|
|
47
|
-
}
|
|
47
|
+
},
|
|
48
|
+
"./shell": {
|
|
49
|
+
"types": "./dist/shell/index.d.ts",
|
|
50
|
+
"import": "./dist/shell/index.js"
|
|
51
|
+
},
|
|
52
|
+
"./shell/oplytics-shell.css": "./dist/shell/oplytics-shell.css"
|
|
48
53
|
},
|
|
49
54
|
"files": [
|
|
50
55
|
"dist",
|
|
@@ -52,7 +57,9 @@
|
|
|
52
57
|
],
|
|
53
58
|
"scripts": {
|
|
54
59
|
"prepare": "pnpm build",
|
|
55
|
-
"build": "tsup",
|
|
60
|
+
"build": "tsup && pnpm build:shell-css && pnpm build:copy-css",
|
|
61
|
+
"build:shell-css": "tailwindcss -i src/shell/styles.css -o dist/shell/oplytics-shell.css --minify",
|
|
62
|
+
"build:copy-css": "mkdir -p dist/theme && cp src/theme/oplytics-theme.css dist/theme/oplytics-theme.css",
|
|
56
63
|
"dev": "tsup --watch",
|
|
57
64
|
"typecheck": "tsc --noEmit",
|
|
58
65
|
"lint": "eslint src/",
|
|
@@ -64,11 +71,13 @@
|
|
|
64
71
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
65
72
|
},
|
|
66
73
|
"devDependencies": {
|
|
74
|
+
"@tailwindcss/cli": "^4.1.14",
|
|
67
75
|
"@types/google.maps": "^3.58.0",
|
|
68
76
|
"@types/react": "^19.0.0",
|
|
69
77
|
"@types/react-dom": "^19.0.0",
|
|
70
78
|
"react": "^19.0.0",
|
|
71
79
|
"react-dom": "^19.0.0",
|
|
80
|
+
"tailwindcss": "^4.1.14",
|
|
72
81
|
"tsup": "^8.0.0",
|
|
73
82
|
"typescript": "^5.9.0",
|
|
74
83
|
"vitest": "^3.0.0"
|