diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json
index b8f66f6..8f95859 100644
--- a/apps/dashboard/package.json
+++ b/apps/dashboard/package.json
@@ -20,6 +20,7 @@
},
"dependencies": {
"@cloudflare/vite-plugin": "^1.26.0",
+ "@quickhub/icons": "workspace:*",
"@quickhub/ui": "workspace:*",
"@tailwindcss/vite": "^4.1.18",
"@tanstack/react-devtools": "latest",
@@ -32,6 +33,7 @@
"better-auth": "^1.6.0",
"drizzle-orm": "^0.45.2",
"lucide-react": "^0.545.0",
+ "next-themes": "^0.4.6",
"octokit": "^5.0.5",
"react": "^19.2.0",
"react-dom": "^19.2.0",
diff --git a/apps/dashboard/src/components/layouts/dashboard-layout.tsx b/apps/dashboard/src/components/layouts/dashboard-layout.tsx
new file mode 100644
index 0000000..d671b24
--- /dev/null
+++ b/apps/dashboard/src/components/layouts/dashboard-layout.tsx
@@ -0,0 +1,19 @@
+import { getRouteApi, Outlet } from "@tanstack/react-router";
+import { DashboardTopbar } from "./dashboard-topbar";
+
+const routeApi = getRouteApi("/_protected");
+
+export function DashboardLayout() {
+ const { user } = routeApi.useRouteContext();
+
+ return (
+
+ );
+}
diff --git a/apps/dashboard/src/components/layouts/dashboard-topbar.tsx b/apps/dashboard/src/components/layouts/dashboard-topbar.tsx
new file mode 100644
index 0000000..59e61f7
--- /dev/null
+++ b/apps/dashboard/src/components/layouts/dashboard-topbar.tsx
@@ -0,0 +1,156 @@
+import {
+ GitPullRequestIcon,
+ HomeIcon,
+ IssuesIcon,
+ MoonIcon,
+ MoreHorizontalIcon,
+ ReviewsIcon,
+ SunIcon,
+ SystemIcon,
+} from "@quickhub/icons";
+import {
+ Avatar,
+ AvatarFallback,
+ AvatarImage,
+} from "@quickhub/ui/components/avatar";
+import { Button } from "@quickhub/ui/components/button";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuShortcut,
+ DropdownMenuTrigger,
+} from "@quickhub/ui/components/dropdown-menu";
+import { Link } from "@tanstack/react-router";
+import { useTheme } from "next-themes";
+import { signOut } from "#/lib/auth.client";
+
+interface DashboardTopbarProps {
+ user: {
+ name?: string | null;
+ email: string;
+ image?: string | null;
+ };
+}
+
+const navItems = [
+ { to: "/", label: "Overview", icon: HomeIcon },
+ { to: "/pull-requests", label: "Pull Requests", icon: GitPullRequestIcon },
+ { to: "/issues", label: "Issues", icon: IssuesIcon },
+ { to: "/reviews", label: "Reviews", icon: ReviewsIcon },
+] as const;
+
+const themeOptions = [
+ { value: "light", icon: SunIcon, label: "Light" },
+ { value: "dark", icon: MoonIcon, label: "Dark" },
+ { value: "system", icon: SystemIcon, label: "System" },
+] as const;
+
+export function DashboardTopbar({ user }: DashboardTopbarProps) {
+ const { theme, setTheme } = useTheme();
+ const displayName = user.name ?? user.email;
+ const initials = displayName
+ .split(" ")
+ .map((part) => part[0])
+ .join("")
+ .slice(0, 2)
+ .toUpperCase();
+
+ return (
+
+
+
+
+
+
+ {initials}
+
+
+
+
+
+
+
{displayName}
+
{user.email}
+
+
+ {themeOptions.map((opt) => (
+ setTheme(opt.value)}
+ className={`flex size-6 items-center justify-center rounded-sm transition-colors ${
+ theme === opt.value
+ ? "bg-surface-1 text-foreground"
+ : "text-muted-foreground hover:text-foreground"
+ }`}
+ title={opt.label}
+ >
+
+
+ ))}
+
+
+
+
+
+ Profile
+
+
+
+ Settings
+
+
+
+
+
+ signOut().then(() => {
+ window.location.href = "/login";
+ })
+ }
+ >
+ Sign out
+
+
+
+
+
+ {navItems.map((item) => (
+
+
+
+ {item.label}
+
+
+ ))}
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/dashboard/src/routeTree.gen.ts b/apps/dashboard/src/routeTree.gen.ts
index efc0fe4..82bfb57 100644
--- a/apps/dashboard/src/routeTree.gen.ts
+++ b/apps/dashboard/src/routeTree.gen.ts
@@ -11,8 +11,7 @@
import { Route as rootRouteImport } from './routes/__root'
import { Route as LoginRouteImport } from './routes/login'
import { Route as ProtectedRouteImport } from './routes/_protected'
-import { Route as IndexRouteImport } from './routes/index'
-import { Route as ProtectedDashboardRouteImport } from './routes/_protected/dashboard'
+import { Route as ProtectedIndexRouteImport } from './routes/_protected/index'
import { Route as ApiAuthSplatRouteImport } from './routes/api/auth/$'
const LoginRoute = LoginRouteImport.update({
@@ -24,14 +23,9 @@ const ProtectedRoute = ProtectedRouteImport.update({
id: '/_protected',
getParentRoute: () => rootRouteImport,
} as any)
-const IndexRoute = IndexRouteImport.update({
+const ProtectedIndexRoute = ProtectedIndexRouteImport.update({
id: '/',
path: '/',
- getParentRoute: () => rootRouteImport,
-} as any)
-const ProtectedDashboardRoute = ProtectedDashboardRouteImport.update({
- id: '/dashboard',
- path: '/dashboard',
getParentRoute: () => ProtectedRoute,
} as any)
const ApiAuthSplatRoute = ApiAuthSplatRouteImport.update({
@@ -41,41 +35,31 @@ const ApiAuthSplatRoute = ApiAuthSplatRouteImport.update({
} as any)
export interface FileRoutesByFullPath {
- '/': typeof IndexRoute
+ '/': typeof ProtectedIndexRoute
'/login': typeof LoginRoute
- '/dashboard': typeof ProtectedDashboardRoute
'/api/auth/$': typeof ApiAuthSplatRoute
}
export interface FileRoutesByTo {
- '/': typeof IndexRoute
'/login': typeof LoginRoute
- '/dashboard': typeof ProtectedDashboardRoute
+ '/': typeof ProtectedIndexRoute
'/api/auth/$': typeof ApiAuthSplatRoute
}
export interface FileRoutesById {
__root__: typeof rootRouteImport
- '/': typeof IndexRoute
'/_protected': typeof ProtectedRouteWithChildren
'/login': typeof LoginRoute
- '/_protected/dashboard': typeof ProtectedDashboardRoute
+ '/_protected/': typeof ProtectedIndexRoute
'/api/auth/$': typeof ApiAuthSplatRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
- fullPaths: '/' | '/login' | '/dashboard' | '/api/auth/$'
+ fullPaths: '/' | '/login' | '/api/auth/$'
fileRoutesByTo: FileRoutesByTo
- to: '/' | '/login' | '/dashboard' | '/api/auth/$'
- id:
- | '__root__'
- | '/'
- | '/_protected'
- | '/login'
- | '/_protected/dashboard'
- | '/api/auth/$'
+ to: '/login' | '/' | '/api/auth/$'
+ id: '__root__' | '/_protected' | '/login' | '/_protected/' | '/api/auth/$'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
- IndexRoute: typeof IndexRoute
ProtectedRoute: typeof ProtectedRouteWithChildren
LoginRoute: typeof LoginRoute
ApiAuthSplatRoute: typeof ApiAuthSplatRoute
@@ -97,18 +81,11 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ProtectedRouteImport
parentRoute: typeof rootRouteImport
}
- '/': {
- id: '/'
+ '/_protected/': {
+ id: '/_protected/'
path: '/'
fullPath: '/'
- preLoaderRoute: typeof IndexRouteImport
- parentRoute: typeof rootRouteImport
- }
- '/_protected/dashboard': {
- id: '/_protected/dashboard'
- path: '/dashboard'
- fullPath: '/dashboard'
- preLoaderRoute: typeof ProtectedDashboardRouteImport
+ preLoaderRoute: typeof ProtectedIndexRouteImport
parentRoute: typeof ProtectedRoute
}
'/api/auth/$': {
@@ -122,11 +99,11 @@ declare module '@tanstack/react-router' {
}
interface ProtectedRouteChildren {
- ProtectedDashboardRoute: typeof ProtectedDashboardRoute
+ ProtectedIndexRoute: typeof ProtectedIndexRoute
}
const ProtectedRouteChildren: ProtectedRouteChildren = {
- ProtectedDashboardRoute: ProtectedDashboardRoute,
+ ProtectedIndexRoute: ProtectedIndexRoute,
}
const ProtectedRouteWithChildren = ProtectedRoute._addFileChildren(
@@ -134,7 +111,6 @@ const ProtectedRouteWithChildren = ProtectedRoute._addFileChildren(
)
const rootRouteChildren: RootRouteChildren = {
- IndexRoute: IndexRoute,
ProtectedRoute: ProtectedRouteWithChildren,
LoginRoute: LoginRoute,
ApiAuthSplatRoute: ApiAuthSplatRoute,
diff --git a/apps/dashboard/src/routes/__root.tsx b/apps/dashboard/src/routes/__root.tsx
index 09a9bb0..fd50291 100644
--- a/apps/dashboard/src/routes/__root.tsx
+++ b/apps/dashboard/src/routes/__root.tsx
@@ -7,6 +7,7 @@ import {
} from "@tanstack/react-router";
import { TanStackRouterDevtoolsPanel } from "@tanstack/react-router-devtools";
import { Agentation } from "agentation";
+import { ThemeProvider } from "next-themes";
import appCss from "../styles.css?url";
@@ -48,5 +49,9 @@ function RootDocument({ children }: { children: React.ReactNode }) {
}
function RootComponent() {
- return ;
+ return (
+
+
+
+ );
}
diff --git a/apps/dashboard/src/routes/_protected.tsx b/apps/dashboard/src/routes/_protected.tsx
index 1784981..c7b69ed 100644
--- a/apps/dashboard/src/routes/_protected.tsx
+++ b/apps/dashboard/src/routes/_protected.tsx
@@ -1,4 +1,5 @@
-import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
+import { createFileRoute, redirect } from "@tanstack/react-router";
+import { DashboardLayout } from "#/components/layouts/dashboard-layout";
import { getSession } from "#/lib/auth.functions";
export const Route = createFileRoute("/_protected")({
@@ -12,5 +13,5 @@ export const Route = createFileRoute("/_protected")({
}
return { user: session.user, session: session.session };
},
- component: () => ,
+ component: DashboardLayout,
});
diff --git a/apps/dashboard/src/routes/_protected/dashboard.tsx b/apps/dashboard/src/routes/_protected/dashboard.tsx
deleted file mode 100644
index 03159a8..0000000
--- a/apps/dashboard/src/routes/_protected/dashboard.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-import {
- Avatar,
- AvatarFallback,
- AvatarImage,
-} from "@quickhub/ui/components/avatar";
-import { Badge } from "@quickhub/ui/components/badge";
-import { Button } from "@quickhub/ui/components/button";
-import {
- Card,
- CardDescription,
- CardHeader,
- CardTitle,
-} from "@quickhub/ui/components/card";
-import { Logo } from "@quickhub/ui/components/logo";
-import { createFileRoute } from "@tanstack/react-router";
-import { signOut } from "#/lib/auth.client";
-
-export const Route = createFileRoute("/_protected/dashboard")({
- component: DashboardPage,
-});
-
-function DashboardPage() {
- const { user } = Route.useRouteContext();
- const displayName = user.name ?? user.email ?? "QuickHub user";
- const initials = displayName
- .split(" ")
- .map((part) => part[0])
- .join("")
- .slice(0, 2)
- .toUpperCase();
-
- return (
-
-
-
-
-
-
- QuickHub
-
-
Workspace
-
-
-
-
-
-
-
-
- {initials}
-
-
-
-
- Welcome, {displayName}
-
- Connected
-
-
- The dashboard now pulls from the shared Circle-derived
- component library in @quickhub/ui.
-
-
-
-
- signOut().then(() => {
- window.location.href = "/";
- })
- }
- >
- Sign out
-
-
-
-
-
-
-
- Theme
-
- Circle tokens now define the workspace palette and surface
- language.
-
-
-
-
-
- Primitives
-
- Shared buttons, cards, badges, dialogs, forms, and more now live
- in the UI package.
-
-
-
-
-
- Next step
-
- Build QuickHub-specific layouts on top of these imported
- foundation pieces.
-
-
-
-
-
-
- );
-}
diff --git a/apps/dashboard/src/routes/_protected/index.tsx b/apps/dashboard/src/routes/_protected/index.tsx
new file mode 100644
index 0000000..b56024d
--- /dev/null
+++ b/apps/dashboard/src/routes/_protected/index.tsx
@@ -0,0 +1,9 @@
+import { createFileRoute } from "@tanstack/react-router";
+
+export const Route = createFileRoute("/_protected/")({
+ component: OverviewPage,
+});
+
+function OverviewPage() {
+ return
;
+}
diff --git a/apps/dashboard/src/routes/index.tsx b/apps/dashboard/src/routes/index.tsx
deleted file mode 100644
index 559d987..0000000
--- a/apps/dashboard/src/routes/index.tsx
+++ /dev/null
@@ -1,167 +0,0 @@
-import { Badge } from "@quickhub/ui/components/badge";
-import { Button } from "@quickhub/ui/components/button";
-import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
-} from "@quickhub/ui/components/card";
-import { Logo } from "@quickhub/ui/components/logo";
-import { createFileRoute, Link } from "@tanstack/react-router";
-import { getSession } from "#/lib/auth.functions";
-import { getUserRepos } from "#/lib/github.functions";
-
-export const Route = createFileRoute("/")({
- beforeLoad: async () => {
- const session = await getSession();
- return { session };
- },
- loader: async ({ context }) => {
- if (!context.session) return { repos: [] };
- const repos = await getUserRepos();
- return { repos };
- },
- component: Home,
-});
-
-function Home() {
- const { session } = Route.useRouteContext();
- const { repos } = Route.useLoaderData();
- const ctaCopy = session ? "Open dashboard" : "Continue with GitHub";
- const ctaLink = session ? "/dashboard" : "/login";
-
- return (
-
-
-
-
-
-
-
-
-
-
- QuickHub
-
-
- Placeholder logo
-
-
-
-
- Shared UI baseline
-
-
-
-
- QuickHub, now on a shared UI foundation.
-
-
- Circle's tokens and primitives are now the baseline for
- QuickHub, so the app can grow from a consistent design system
- instead of ad hoc styles.
-
-
-
-
-
- {ctaCopy}
-
-
- Shared theme tokens live in @quickhub/ui and can
- now drive future screens.
-
-
-
-
-
-
- Base kit
-
- Imported primitives ready to extend.
-
-
-
-
- Theme tokens
- active
-
-
- 32 UI primitives
- shared
-
-
- Dashboard wired
- validated
-
-
-
-
-
- {repos.length > 0 && (
-
-
-
- Recent repositories
-
-
- Current data rendered with the shared card, badge, and button
- language.
-
-
-
- {repos.map((repo) => (
-
-
-
-
-
-
- {repo.name}
-
-
-
- {repo.description ??
- "A focused repository surfaced from your GitHub account."}
-
-
- {repo.isPrivate ? (
-
Private
- ) : (
-
Public
- )}
-
-
-
-
- {repo.language ? {repo.language} : null}
- {repo.stars ? {repo.stars} stars : null}
-
-
-
- View repo
-
-
-
-
- ))}
-
-
- )}
-
-
- );
-}
diff --git a/apps/dashboard/src/routes/login.tsx b/apps/dashboard/src/routes/login.tsx
index fca9a33..fed8861 100644
--- a/apps/dashboard/src/routes/login.tsx
+++ b/apps/dashboard/src/routes/login.tsx
@@ -14,7 +14,7 @@ import { getSession } from "#/lib/auth.functions";
export const Route = createFileRoute("/login")({
beforeLoad: async () => {
const session = await getSession();
- if (session) throw redirect({ to: "/dashboard" });
+ if (session) throw redirect({ to: "/" });
},
component: LoginPage,
});
diff --git a/biome.jsonc b/biome.jsonc
index 7bd5617..81df3ef 100644
--- a/biome.jsonc
+++ b/biome.jsonc
@@ -1,4 +1,16 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.5/schema.json",
- "extends": ["ultracite/biome/core"]
+ "extends": ["ultracite/biome/core"],
+ "overrides": [
+ {
+ "includes": ["packages/icons/**"],
+ "linter": {
+ "rules": {
+ "performance": {
+ "noBarrelFile": "off"
+ }
+ }
+ }
+ }
+ ]
}
diff --git a/packages/icons/package.json b/packages/icons/package.json
new file mode 100644
index 0000000..0699250
--- /dev/null
+++ b/packages/icons/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "@quickhub/icons",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "scripts": {
+ "check-types": "tsc --noEmit",
+ "lint": "biome lint",
+ "check": "biome check",
+ "format": "biome format"
+ },
+ "dependencies": {
+ "@hugeicons/react": "^0.3.0"
+ },
+ "devDependencies": {
+ "@biomejs/biome": "2.4.5",
+ "@quickhub/typescript-config": "workspace:*",
+ "@types/react": "^19.2.0",
+ "typescript": "^5.7.2"
+ },
+ "peerDependencies": {
+ "react": "^19.2.0"
+ }
+}
diff --git a/packages/icons/src/index.ts b/packages/icons/src/index.ts
new file mode 100644
index 0000000..4725aeb
--- /dev/null
+++ b/packages/icons/src/index.ts
@@ -0,0 +1,21 @@
+// Re-export icons with stable app-friendly names.
+// If we switch from hugeicons to another library, only this file changes.
+
+export {
+ AddCircleHalfDotIcon as IssuesIcon,
+ Bug01Icon as BugIcon,
+ CheckListIcon as ReviewsIcon,
+ CodeIcon,
+ ComputerIcon as SystemIcon,
+ DashboardSquare01Icon as DashboardIcon,
+ GitBranchIcon,
+ GitPullRequestIcon,
+ Home01Icon as HomeIcon,
+ InboxIcon,
+ Moon01Icon as MoonIcon,
+ MoreHorizontalIcon,
+ Notification01Icon as NotificationIcon,
+ Search01Icon as SearchIcon,
+ Settings01Icon as SettingsIcon,
+ Sun01Icon as SunIcon,
+} from "@hugeicons/react";
diff --git a/packages/icons/tsconfig.json b/packages/icons/tsconfig.json
new file mode 100644
index 0000000..fd89060
--- /dev/null
+++ b/packages/icons/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@quickhub/typescript-config/react-library.json",
+ "include": ["src"]
+}
diff --git a/packages/ui/src/components/button.tsx b/packages/ui/src/components/button.tsx
index 8122c7c..719fb6b 100644
--- a/packages/ui/src/components/button.tsx
+++ b/packages/ui/src/components/button.tsx
@@ -5,7 +5,7 @@ import type * as React from "react";
import { cn } from "../lib/utils";
const buttonVariants = cva(
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-[13px] font-medium transition-[color,background-color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
diff --git a/packages/ui/src/components/dropdown-menu.tsx b/packages/ui/src/components/dropdown-menu.tsx
index bd0d9e9..7f4690d 100644
--- a/packages/ui/src/components/dropdown-menu.tsx
+++ b/packages/ui/src/components/dropdown-menu.tsx
@@ -74,7 +74,7 @@ function DropdownMenuItem({
data-inset={inset}
data-variant={variant}
className={cn(
- "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-foreground data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/40 data-[variant=destructive]:focus:text-destructive-foreground data-[variant=destructive]:*:[svg]:!text-destructive-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-foreground data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/40 data-[variant=destructive]:focus:text-destructive-foreground data-[variant=destructive]:*:[svg]:!text-destructive-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 font-medium outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}
@@ -92,7 +92,7 @@ function DropdownMenuCheckboxItem({
);
@@ -178,17 +175,30 @@ function DropdownMenuSeparator({
function DropdownMenuShortcut({
className,
+ keys,
+ children,
...props
-}: React.ComponentProps<"span">) {
+}: React.ComponentProps<"span"> & {
+ keys?: string[];
+}) {
return (
+ >
+ {keys
+ ? keys.map((key, i) => (
+
+ {i > 0 && then }
+ {key}
+
+ ))
+ : children}
+
);
}
@@ -211,7 +221,7 @@ function DropdownMenuSubTrigger({
data-slot="dropdown-menu-sub-trigger"
data-inset={inset}
className={cn(
- "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8",
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8",
className,
)}
{...props}
diff --git a/packages/ui/src/components/select.tsx b/packages/ui/src/components/select.tsx
index e6cf795..244d352 100644
--- a/packages/ui/src/components/select.tsx
+++ b/packages/ui/src/components/select.tsx
@@ -103,7 +103,7 @@ function SelectItem({
{children}
@@ -311,7 +311,7 @@ function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
=16.0.0'
+
'@img/colour@1.1.0':
resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
engines: {node: '>=18'}
@@ -4998,6 +5031,10 @@ snapshots:
'@fontsource/geist-mono@5.2.7': {}
+ '@hugeicons/react@0.3.4(react@19.2.4)':
+ dependencies:
+ react: 19.2.4
+
'@img/colour@1.1.0': {}
'@img/sharp-darwin-arm64@0.34.5':