Add new colors and wip use them all instead of tailwind ones

Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
Émile Ré
2025-04-05 18:38:30 +04:00
parent 5406e2ef2d
commit e8dacef374
92 changed files with 833 additions and 819 deletions

View File

@@ -12,6 +12,8 @@
},
"dependencies": {
"@lexical/react": "^0.27.0",
"@probo/react-lazy": "^0.1.0",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-avatar": "^1.1.3",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-collapsible": "^1.1.3",
@@ -44,8 +46,7 @@
"react-router": "^7.1.5",
"relay-runtime": "^18.2.0",
"tailwind-merge": "^3.0.2",
"tailwindcss-animate": "^1.0.7",
"@probo/react-lazy": "^0.1.0"
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@babel/core": "^7.26.7",

View File

@@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
@@ -42,7 +42,7 @@
<link rel="stylesheet" href="/App.css" />
</head>
<body class="bg-gray-50 text-gray-900 font-sans">
<body class="font-sans">
<div id="root"></div>
<script type="module" src="/App.js" defer></script>
</body>

View File

@@ -1,5 +1,18 @@
@import "tailwindcss";
@import "./styles/colors.css";
@import "@radix-ui/colors/blue.css";
@import "@radix-ui/colors/blue-dark.css";
@import "@radix-ui/colors/olive.css";
@import "@radix-ui/colors/olive-alpha.css";
@import "@radix-ui/colors/olive-dark.css";
@import "@radix-ui/colors/olive-dark-alpha.css";
@import "@radix-ui/colors/lime.css";
@import "@radix-ui/colors/lime-dark.css";
@import "@radix-ui/colors/red.css";
@import "@radix-ui/colors/red-dark.css";
@import "@radix-ui/colors/red-dark-alpha.css";
@import "@radix-ui/colors/orange.css";
@import "@radix-ui/colors/orange-dark.css";
@import "./styles/policy-content.css";
@plugin 'tailwindcss-animate';
@@ -8,41 +21,107 @@
@custom-variant dark (&:is(.dark *));
@theme {
--color-border: hsl(var(--border));
--color-input: hsl(var(--input));
--color-ring: hsl(var(--ring));
--color-background: hsl(var(--background));
--color-foreground: hsl(var(--foreground));
/* Legacy */
/* --color-border: hsl(var(--border)); -> solid-b
--color-input: hsl(var(--input)); -> solid-b
--color-ring: hsl(var(--ring)); -> active-b
--color-background: hsl(var(--background)); -> level-0
--color-foreground: hsl(var(--foreground)); -> primary
--color-primary: hsl(var(--primary));
--color-primary-foreground: hsl(var(--primary-foreground));
--color-primary: hsl(var(--primary)); -> primary
--color-primary-foreground: hsl(var(--primary-foreground)); -> invert
--color-secondary: hsl(var(--secondary));
--color-secondary-foreground: hsl(var(--secondary-foreground));
--color-secondary: hsl(var(--secondary)); -> invert
--color-secondary-foreground: hsl(var(--secondary-foreground)); -> secondary
--color-destructive: hsl(var(--destructive));
--color-destructive-foreground: hsl(var(--destructive-foreground));
--color-destructive: hsl(var(--destructive)); -> danger-bg
--color-destructive-foreground: hsl(var(--destructive-foreground)); -> danger
--color-muted: hsl(var(--muted));
--color-muted-foreground: hsl(var(--muted-foreground));
--color-muted: hsl(var(--muted)); -> invert-bg
--color-muted-foreground: hsl(var(--muted-foreground)); -> tertiary
--color-accent: hsl(var(--accent));
--color-accent-foreground: hsl(var(--accent-foreground));
--color-accent: hsl(var(--accent)); -> accent-bg
--color-accent-foreground: hsl(var(--accent-foreground)); -> accent
--color-popover: hsl(var(--popover));
--color-popover-foreground: hsl(var(--popover-foreground));
--color-popover: hsl(var(--popover)); -> level-0
--color-popover-foreground: hsl(var(--popover-foreground)); -> primary
--color-card: hsl(var(--card));
--color-card-foreground: hsl(var(--card-foreground));
--color-card: hsl(var(--card)); -> level-0
--color-card-foreground: hsl(var(--card-foreground)); -> primary
--color-sidebar: hsl(var(--sidebar-background));
--color-sidebar-foreground: hsl(var(--sidebar-foreground));
--color-sidebar-primary: hsl(var(--sidebar-primary));
--color-sidebar: hsl(var(--sidebar-background)); -> level-0
--color-sidebar-foreground: hsl(var(--sidebar-foreground)); -> secondary
--color-sidebar-primary: hsl(var(--sidebar-primary)); -> not used
--color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground));
--color-sidebar-accent: hsl(var(--sidebar-accent));
--color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground));
--color-sidebar-border: hsl(var(--sidebar-border));
--color-sidebar-ring: hsl(var(--sidebar-ring));
--color-sidebar-border: hsl(var(--sidebar-border)); -> solid-b
--color-sidebar-ring: hsl(var(--sidebar-ring)); -> active-b */
/* New */
/* Surfaces */
--color-level-0: var(--level-0);
--color-level-1: var(--level-1);
--color-level-2: var(--level-2);
--color-level-3: var(--level-3);
/* Text colors */
--color-primary: var(--primary);
--color-invert: var(--invert);
--color-secondary: var(--secondary);
--color-tertiary: var(--tertiary);
--color-quaternary: var(--quaternary);
--color-disabled: var(--disabled);
--color-accent: var(--accent);
--color-danger: var(--danger);
--color-success: var(--success);
--color-info: var(--info);
--color-warning: var(--warning);
/* Background colors */
--color-primary-bg: var(--primary-bg);
--color-invert-bg: var(--invert-bg);
--color-secondary-bg: var(--secondary-bg);
--color-tertiary-bg: var(--tertiary-bg);
--color-subtle-bg: var(--subtle-bg);
--color-highlight-bg: var(--highlight-bg);
--color-accent-bg: var(--accent-bg);
--color-active-bg: var(--active-bg);
--color-danger-bg: var(--danger-bg);
--color-danger-plain-bg: var(--danger-plain-bg);
--color-success-bg: var(--success-bg);
--color-info-bg: var(--info-bg);
--color-warning-bg: var(--warning-bg);
/* Hover */
--color-h-primary-bg: var(--h-primary-bg);
--color-h-invert-bg: var(--h-invert-bg);
--color-h-secondary-bg: var(--h-secondary-bg);
--color-h-tertiary-bg: var(--h-tertiary-bg);
--color-h-subtle-bg: var(--h-subtle-bg);
--color-h-highlight-bg: var(--h-highlight-bg);
--color-h-accent-bg: var(--h-accent-bg);
--color-h-active-bg: var(--h-active-bg);
/* Pressed */
--color-p-primary-bg: var(--p-primary-bg);
--color-p-invert-bg: var(--p-invert-bg);
--color-p-secondary-bg: var(--p-secondary-bg);
--color-p-tertiary-bg: var(--p-tertiary-bg);
--color-p-subtle-bg: var(--p-subtle-bg);
--color-p-highlight-bg: var(--p-highlight-bg);
--color-p-accent-bg: var(--p-accent-bg);
--color-p-active-bg: var(--p-active-bg);
/* Borders */
--color-solid-b: var(--solid-b);
--color-low-b: var(--low-b);
--color-mid-b: var(--mid-b);
--color-strong-b: var(--strong-b);
--color-active-b: var(--active-b);
--color-accent-b: var(--accent-b);
--color-danger-b: var(--danger-b);
--color-success-b: var(--success-b);
--color-warning-b: var(--warning-b);
--color-info-b: var(--info-b);
}
/*
@@ -59,12 +138,13 @@
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
border-color: var(--color-mid-b, currentColor);
}
}
@layer base {
:root {
/* Legacy */
/* :root {
--background: 0 0% 100%;
--foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
@@ -122,14 +202,122 @@
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;
--sidebar-ring: 217.2 91.2% 59.8%;
} */
/* New */
:root {
/* Surfaces */
--level-0: #FAFAF5;
--level-1: #FFFFFF;
--level-2: #FFFFFF;
--level-3: var(--olive-12);
/* Text colors */
--primary: var(--olive-12);
--invert: var(--olive-1);
--secondary: var(--olive-11);
--tertiary: var(--olive-10);
--quaternary: var(--olive-8);
--disabled: var(--olive-7);
--accent: var(--lime-10);
--danger: var(--red-11);
--success: var(--lime-11);
--info: var(--blue-11);
--warning: var(--orange-11);
/* Background colors */
--primary-bg: var(--olive-12);
--invert-bg: #ffffff;
--secondary-bg: var(--olive-1);
--tertiary-bg: transparent;
--subtle-bg: var(--olive-a2);
--highlight-bg: var(--olive-a3);
--accent-bg: var(--olive-12);
--active-bg: var(--lime-4);
--danger-bg: var(--red-3);
--danger-plain-bg: var(--red-10);
--success-bg: var(--lime-3);
--info-bg: var(--blue-3);
--warning-bg: var(--orange-3);
/* Hover */
--h-primary-bg: #273025;
--h-invert-bg: var(--olive-2);
--h-secondary-bg: var(--olive-2);
--h-tertiary-bg: var(--olive-a2);
--h-subtle-bg: var(--olive-a3);
--h-highlight-bg: var(--olive-a4);
--h-accent-bg: #1E2C1C;
--h-active-bg: var(--lime-5);
/* Pressed */
--p-primary-bg: #30392E;
--p-invert-bg: var(--olive-3);
--p-secondary-bg: var(--olive-3);
--p-tertiary-bg: var(--olive-a3);
--p-subtle-bg: var(--olive-a4);
--p-highlight-bg: var(--olive-a5);
--p-accent-bg: #293A25;
--p-active-bg: var(--lime-6);
/* Borders */
--solid-b: var(--olive-4);
--low-b: var(--olive-a4);
--mid-b: var(--olive-a7);
--strong-b: var(--olive-a8);
--active-b: var(--olive-12);
--accent-b: var(--lime-11);
--danger-b: var(--red-10);
--success-b: var(--lime-10);
--warning-b: var(--orange-10);
--info-b: var(--blue-10);
}
.dark {
/* Surfaces */
--level-0: var(--olive-1);
--level-1: var(--olive-2);
--level-2: var(--olive-3);
--level-3: var(--olive-7);
/* Text colors */
--success: var(--lime-a11);
/* Background colors */
--primary-bg: var(--lime-10);
--invert-bg: var(--olive-1);
--secondary-bg: var(--olive-a3);
--active-bg: var(--olive-a4);
--accent-bg: var(--lime-10);
--danger-bg: var(--red-a3);
--danger-plain-bg: var(--red-a10);
--success-bg: var(--lime-a3);
--info-bg: var(--blue-a3);
--warning-bg: var(--orange-a3);
/* Hover */
--h-primary-bg: #C4F042E1;
--h-secondary-bg: var(--olive-a3);
--h-highlight-bg: var(--olive-a5);
--h-accent-bg: var(--lime-a9);
--h-active-bg: var(--olive-a5);
/* Pressed */
--p-primary-bg: #C4F042D7;
--p-secondary-bg: var(--olive-a4);
--p-highlight-bg: var(--olive-a6);
--p-accent-bg: var(--lime-a10);
--p-active-bg: var(--olive-a6);
/* Borders */
--solid-b: var(--olive-5);
--mid-b: var(--olive-a5);
--active-b: var(--olive-a12);
--warning-b: var(--orange-a10);
}
}
@layer base {
* {
@apply border-border;
@apply border-solid-b;
}
body {
@apply font-sans antialiased bg-background text-foreground;
@apply font-sans antialiased bg-level-0 text-primary;
}
}

View File

@@ -30,7 +30,7 @@ export function EditableField({
</Label>
{helpText && (
<div className="relative flex items-center">
<HelpCircle className="h-4 w-4 text-muted-foreground" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<span className="sr-only">{helpText}</span>
</div>
)}

View File

@@ -15,7 +15,6 @@ import {
} from "@/components/ui/collapsible";
import {
SidebarGroup,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuAction,
SidebarMenuButton,
@@ -63,9 +62,6 @@ export function NavMain() {
return (
<SidebarGroup>
<SidebarGroupLabel className="text-gray-500 pl-3">
Compliance
</SidebarGroupLabel>
<SidebarMenu>
{items.map((item) => {
const active = isItemActive(item) || item.isActive;

View File

@@ -13,7 +13,7 @@ export function NavMainSkeleton() {
<SidebarGroup>
<SidebarGroupLabel className="pl-3">
<div className="py-0.5">
<div className="h-3 w-24 rounded-sm bg-gray-300 animate-pulse" />
<div className="h-3 w-24 rounded-sm bg-subtle-bg animate-pulse" />
</div>
</SidebarGroupLabel>
<SidebarMenu className="space-y-1.5">
@@ -21,7 +21,7 @@ export function NavMainSkeleton() {
<SidebarMenuButton className="animate-pulse">
<div className="h-4 w-4 rounded-md bg-lime-5" />
<div className="py-[3px]">
<div className="h-3.5 w-32 rounded-md bg-gray-300" />
<div className="h-3.5 w-32 rounded-md bg-subtle-bg" />
</div>
</SidebarMenuButton>
</SidebarMenuItem>
@@ -29,7 +29,7 @@ export function NavMainSkeleton() {
<SidebarMenuButton className="animate-pulse">
<div className="h-4 w-4 rounded-md bg-lime-6" />
<div className="py-[3px]">
<div className="h-3.5 w-32 rounded-md bg-gray-300" />
<div className="h-3.5 w-32 rounded-md bg-subtle-bg" />
</div>
</SidebarMenuButton>
</SidebarMenuItem>
@@ -37,7 +37,7 @@ export function NavMainSkeleton() {
<SidebarMenuButton className="animate-pulse">
<div className="h-4 w-4 rounded-md bg-lime-6" />
<div className="py-[3px]">
<div className="h-3.5 w-32 rounded-md bg-gray-300" />
<div className="h-3.5 w-32 rounded-md bg-subtle-bg" />
</div>
</SidebarMenuButton>
</SidebarMenuItem>
@@ -45,7 +45,7 @@ export function NavMainSkeleton() {
<SidebarMenuButton className="animate-pulse">
<div className="h-4 w-4 rounded-md bg-lime-6" />
<div className="py-[3px]">
<div className="h-3.5 w-32 rounded-md bg-gray-300" />
<div className="h-3.5 w-32 rounded-md bg-subtle-bg" />
</div>
</SidebarMenuButton>
</SidebarMenuItem>

View File

@@ -49,13 +49,9 @@ export function NavUser({ viewer }: { viewer: NavUser_viewer$key }) {
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuButton
isActive
size="lg"
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
>
<SidebarMenuButton size="lg" variant="outline">
<Avatar className="h-9 w-9">
<AvatarFallback className="bg-slate-400 text-gray-100">
<AvatarFallback className="bg-highlight-bg">
{currentUser.fullName.substring(0, 2).toUpperCase()}
</AvatarFallback>
</Avatar>
@@ -63,7 +59,7 @@ export function NavUser({ viewer }: { viewer: NavUser_viewer$key }) {
<span className="truncate font-semibold">
{currentUser.fullName}
</span>
<span className="truncate text-xs text-sidebar-foreground/70">
<span className="truncate text-xs text-secondary/70">
{currentUser.email}
</span>
</div>
@@ -78,7 +74,7 @@ export function NavUser({ viewer }: { viewer: NavUser_viewer$key }) {
>
<DropdownMenuLabel className="p-0 font-normal">
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
<Avatar className="h-8 w-8">
<Avatar className="h-8 w-8 bg-highlight-bg">
<AvatarFallback>
{currentUser.fullName.substring(0, 2).toUpperCase()}
</AvatarFallback>

View File

@@ -14,14 +14,14 @@ export function NavUserSkeleton() {
isActive
disabled
size="lg"
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground animate-pulse"
className="data-[state=open]:bg-accent data-[state=open]:text-accent animate-pulse"
>
<div className="bg-gray-400 size-9 rounded-full animate-pulse" />
<div className="bg-subtle-bg size-9 rounded-full animate-pulse" />
<div className="flex-1 space-y-[3px] animate-pulse">
<div className="h-3.5 w-20 rounded-sm bg-gray-400" />
<div className="h-3.5 w-30 rounded-sm bg-gray-400" />
<div className="h-3.5 w-20 rounded-sm bg-subtle-bg" />
<div className="h-3.5 w-30 rounded-sm bg-subtle-bg" />
</div>
<div className="ml-auto size-4 rounded-lg bg-gray-400" />
<div className="ml-auto size-4 rounded-lg bg-subtle-bg" />
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>

View File

@@ -101,27 +101,28 @@ export function OrganizationSwitcher({
<DropdownMenuTrigger asChild>
<SidebarMenuButton
size="lg"
variant="ghost"
className={cn(
"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground gap-2.5",
!currentOrganization && "border border-dashed border-gray-300"
"gap-2.5",
!currentOrganization && "border border-dashed"
)}
>
<div className="flex aspect-square size-8 items-center justify-center rounded-sm bg-slate-400 text-gray-100">
<div className="flex aspect-square size-8 items-center justify-center rounded-sm bg-highlight-bg">
{currentOrganization ? (
<LogoComponent org={currentOrganization} className="size-8" />
) : (
<div className="size-8 bg-slate-400 rounded-sm" />
<div className="size-8 bg-highlight-bg rounded-sm" />
)}
</div>
<div className="grid text-left leading-tight">
<div className="grid text-left leading-tight text-primary">
{currentOrganization ? (
<>
<span className="truncate font-medium text-lg leading-5 text-gray-900">
<span className="truncate font-medium text-lg leading-5">
{currentOrganization.name}
</span>
</>
) : (
<span className="truncate text-gray-500 font-medium">
<span className="truncate text-secondary font-medium">
Select Organization
</span>
)}
@@ -135,7 +136,7 @@ export function OrganizationSwitcher({
side={isMobile ? "bottom" : "right"}
sideOffset={4}
>
<DropdownMenuLabel className="text-xs text-muted-foreground">
<DropdownMenuLabel className="text-xs text-tertiary">
Organizations
</DropdownMenuLabel>
{hasOrganizations &&
@@ -144,10 +145,10 @@ export function OrganizationSwitcher({
key={edge.node.id}
onClick={() => handleOrganizationSwitch(edge.node)}
className={`gap-2 p-2 ${
edge.node.id === organizationId ? "bg-muted" : ""
edge.node.id === organizationId ? "bg-subtle-bg" : ""
}`}
>
<div className="flex size-6 items-center justify-center rounded-sm">
<div className="flex size-6 items-center justify-center rounded-sm bg-highlight-bg">
<LogoComponent
org={edge.node}
className="size-4 shrink-0"
@@ -163,10 +164,10 @@ export function OrganizationSwitcher({
to="/organizations/new"
className="gap-2 p-2 cursor-pointer"
>
<div className="flex size-6 items-center justify-center rounded-md border bg-background">
<div className="flex size-6 items-center justify-center rounded-md border bg-secondary-bg">
<Plus className="size-4" />
</div>
<div className="font-medium text-muted-foreground">
<div className="font-medium text-tertiary">
Add organization
</div>
</Link>

View File

@@ -12,18 +12,18 @@ export function OrganizationSwitcherSkeleton() {
<SidebarMenuItem>
<SidebarMenuButton
size="lg"
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground gap-2.5"
className="data-[state=open]:bg-accent-bg data-[state=open]:text-accent gap-2.5"
>
<div className="size-8 items-center justify-center rounded-md bg-gray-300 animate-pulse" />
<div className="size-8 items-center justify-center rounded-md bg-subtle-bg animate-pulse" />
<div className="flex flex-col items-start">
<div className="py-[1px]">
<div className="h-4.5 animate-pulse w-16 rounded-sm bg-gray-300" />
<div className="h-4.5 animate-pulse w-16 rounded-sm bg-subtle-bg" />
</div>
<div className="py-0.5">
<div className="h-3 animate-pulse w-8 rounded-sm bg-gray-300" />
<div className="h-3 animate-pulse w-8 rounded-sm bg-subtle-bg" />
</div>
</div>
<div className="ml-auto size-4 rounded-lg bg-gray-300 animate-pulse" />
<div className="ml-auto size-4 rounded-lg bg-subtle-bg animate-pulse" />
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>

View File

@@ -57,7 +57,7 @@ export function PageHeading({
const PageHeadingSkeleton: FC = () => {
return (
<div className="py-[3px] w-2/5">
<div className="bg-muted animate rounded-lg h-7.5" />
<div className="bg-subtle-bg animate rounded-lg h-7.5" />
</div>
);
};
@@ -70,12 +70,7 @@ export function PageDescription({
children: ReactNode;
}) {
return (
<div
className={cn(
"text-md text-muted-foreground whitespace-pre-wrap",
className
)}
>
<div className={cn("text-md text-tertiary text-left", className)}>
{children}
</div>
);
@@ -84,7 +79,7 @@ export function PageDescription({
export function PageDescriptionSkeleton() {
return (
<div className="py-[5px]">
<div className="bg-muted animate rounded-md w-100 h-4.5" />
<div className="bg-subtle-bg animate rounded-md w-100 h-4.5" />
</div>
);
}

View File

@@ -4,13 +4,13 @@
line-height: 1.5;
font-weight: 400;
margin-top: 0.5rem;
border: 1px solid hsl(var(--border));
border: 1px solid var(--solid-b);
display: block;
width: 100%;
}
.policy-editor {
background: #fff;
background: var(--bg-invert-bg);
position: relative;
border-radius: 0.5rem;
display: flex;
@@ -63,8 +63,8 @@
display: flex;
flex-wrap: wrap;
padding: 8px;
border-bottom: 1px solid hsl(var(--border));
background-color: hsl(var(--muted));
border-bottom: 1px solid hsl(var(--solid-b));
background-color: hsl(var(--invert-bg));
border-radius: 0.5rem 0.5rem 0 0;
}
@@ -90,7 +90,7 @@
.policy-editor .toolbar .divider {
width: 1px;
background-color: hsl(var(--border));
background-color: hsl(var(--solid-b));
margin: 0 8px;
height: 24px;
}
@@ -130,8 +130,8 @@
margin: 0;
margin-left: 20px;
padding-left: 16px;
border-left: 4px solid hsl(var(--border));
color: hsl(var(--muted-foreground));
border-left: 4px solid hsl(var(--solid-b));
color: hsl(var(--tertiary));
}
.editor-list-ol {
@@ -174,7 +174,7 @@
}
.editor-text-code {
background-color: hsl(var(--muted));
background-color: hsl(var(--invert-bg));
padding: 1px 4px;
border-radius: 4px;
font-family: monospace;
@@ -186,7 +186,7 @@
}
.editor-code {
background-color: hsl(var(--muted));
background-color: hsl(var(--invert-bg));
font-family: monospace;
display: block;
padding: 8px 16px;
@@ -227,4 +227,4 @@
.editor-tokenFunction {
color: #dd4a68;
}
}

View File

@@ -37,7 +37,7 @@ const AvatarFallback = React.forwardRef<
<AvatarPrimitive.Fallback
ref={ref}
className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted",
"flex h-full w-full items-center justify-center rounded-full bg-subtle-bg",
className
)}
{...props}

View File

@@ -4,23 +4,23 @@ import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const badgeVariants = cva(
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2",
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-active-b focus:ring-offset-2",
{
variants: {
variant: {
default:
"border-transparent bg-primary text-primary-foreground shadow-sm hover:bg-primary/80",
secondary:
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive:
"border-transparent bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/80",
outline: "text-foreground",
default: "bg-primary-bg text-invert",
secondary: "bg-secondary-bg border border-low-b",
info: "bg-info-bg text-info border-info-b",
success: "bg-success-bg text-success border-success-b",
warning: "bg-warning-bg text-warning border-warning-b",
destructive: "bg-danger-bg text-danger border-danger-b",
outline: "",
},
},
defaultVariants: {
variant: "default",
},
},
}
);
export interface BadgeProps

View File

@@ -19,7 +19,7 @@ const BreadcrumbList = React.forwardRef<
<ol
ref={ref}
className={cn(
"flex flex-wrap items-center gap-3 break-words text-sm text-gray-500 sm:gap-2.5",
"flex flex-wrap items-center gap-3 break-words text-sm text-secondary sm:gap-2.5",
className
)}
{...props}
@@ -66,7 +66,7 @@ const BreadcrumbPage = React.forwardRef<
role="link"
aria-disabled="true"
aria-current="page"
className={cn("font-normal text-gray-700", className)}
className={cn("font-normal text-primary", className)}
{...props}
/>
));
@@ -80,7 +80,7 @@ const BreadcrumbSeparator = ({
<li
role="presentation"
aria-hidden="true"
className={cn("[&>svg]:w-3.5 [&>svg]:h-3.5 text-gray-300", className)}
className={cn("[&>svg]:w-3.5 [&>svg]:h-3.5 text-quaternary", className)}
{...props}
>
{children ?? "/"}

View File

@@ -5,25 +5,25 @@ import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"cursor-pointer inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
"rounded-full cursor-pointer inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-active-b disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90",
default: "bg-primary-bg text-invert shadow-sm hover:bg-h-primary-bg",
destructive:
"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90",
"bg-danger-plain-bg text-invert shadow-xs hover:bg-danger-plain-bg/90",
outline:
"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
"border border-low-b hover:bg-h-tertiary-bg active:bg-p-tertiary-bg focus:bg-tertiary-bg shadow-xs",
secondary:
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
"bg-secondary-bg border border-low-b shadow-sm hover:bg-h-secondary-bg",
ghost:
"hover:bg-h-tertiary-bg active:bg-p-tertiary-bg focus:bg-tertiary-bg",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
sm: "h-8 px-3 text-xs",
lg: "h-10 px-8",
icon: "h-9 w-9",
},
},

View File

@@ -8,10 +8,7 @@ const Card = React.forwardRef<
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-xl border bg-card text-card-foreground shadow-sm",
className,
)}
className={cn("rounded-xl border bg-level-1", className)}
{...props}
/>
));
@@ -47,7 +44,7 @@ const CardDescription = React.forwardRef<
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
className={cn("text-sm text-tertiary", className)}
{...props}
/>
));

View File

@@ -11,8 +11,8 @@ const Checkbox = React.forwardRef<
<CheckboxPrimitive.Root
ref={ref}
className={cn(
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
className,
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-level-0 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-active-b focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-invert",
className
)}
{...props}
>

View File

@@ -18,7 +18,7 @@ const Command = React.forwardRef<
<CommandPrimitive
ref={ref}
className={cn(
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
"flex h-full w-full flex-col overflow-hidden rounded-md bg-level-0 text-primary",
className
)}
{...props}
@@ -30,7 +30,7 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
return (
<Dialog {...props}>
<DialogContent className="overflow-hidden p-0 shadow-lg">
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-tertiary [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
{children}
</Command>
</DialogContent>
@@ -47,7 +47,7 @@ const CommandInput = React.forwardRef<
<CommandPrimitive.Input
ref={ref}
className={cn(
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-tertiary disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
@@ -90,7 +90,7 @@ const CommandGroup = React.forwardRef<
<CommandPrimitive.Group
ref={ref}
className={cn(
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
"overflow-hidden p-1 text-primary [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-tertiary",
className
)}
{...props}
@@ -105,7 +105,7 @@ const CommandSeparator = React.forwardRef<
>(({ className, ...props }, ref) => (
<CommandPrimitive.Separator
ref={ref}
className={cn("-mx-1 h-px bg-border", className)}
className={cn("-mx-1 h-px bg-solid-b", className)}
{...props}
/>
));
@@ -118,7 +118,7 @@ const CommandItem = React.forwardRef<
<CommandPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 hover:bg-gray-100 transition-colors",
"relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent-bg aria-selected:text-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50 hover:bg-secondary-bg transition-colors",
className
)}
{...props}
@@ -133,10 +133,7 @@ const CommandShortcut = ({
}: React.HTMLAttributes<HTMLSpanElement>) => {
return (
<span
className={cn(
"ml-auto text-xs tracking-widest text-muted-foreground",
className
)}
className={cn("ml-auto text-xs tracking-widest text-tertiary", className)}
{...props}
/>
);

View File

@@ -19,7 +19,7 @@ const DialogOverlay = React.forwardRef<
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-black/50 backdrop-blur-xs data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className,
className
)}
{...props}
/>
@@ -35,13 +35,13 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-gray-200 bg-white p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className,
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-mid-b bg-white p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className
)}
{...props}
>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-gray-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-gray-100 data-[state=open]:text-gray-500">
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-active focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary-bg data-[state=open]:text-secondary">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
@@ -57,7 +57,7 @@ const DialogHeader = ({
<div
className={cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
className,
className
)}
{...props}
/>
@@ -71,7 +71,7 @@ const DialogFooter = ({
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className,
className
)}
{...props}
/>
@@ -86,7 +86,7 @@ const DialogTitle = React.forwardRef<
ref={ref}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className,
className
)}
{...props}
/>
@@ -99,7 +99,7 @@ const DialogDescription = React.forwardRef<
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-sm text-gray-500", className)}
className={cn("text-sm text-secondary", className)}
{...props}
/>
));

View File

@@ -27,9 +27,9 @@ const DropdownMenuSubTrigger = React.forwardRef<
<DropdownMenuPrimitive.SubTrigger
ref={ref}
className={cn(
"flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-hidden focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
"flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-hidden focus:bg-accent-bg data-[state=open]:bg-accent-bg [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
inset && "pl-8",
className,
className
)}
{...props}
>
@@ -47,8 +47,8 @@ const DropdownMenuSubContent = React.forwardRef<
<DropdownMenuPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-level-1 p-1 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
@@ -65,9 +65,9 @@ const DropdownMenuContent = React.forwardRef<
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-level-1 p-1 shadow-md",
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
className
)}
{...props}
/>
@@ -84,9 +84,9 @@ const DropdownMenuItem = React.forwardRef<
<DropdownMenuPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden transition-colors focus:bg-active-bg focus:text-active data-disabled:pointer-events-none data-disabled:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
inset && "pl-8",
className,
className
)}
{...props}
/>
@@ -100,8 +100,8 @@ const DropdownMenuCheckboxItem = React.forwardRef<
<DropdownMenuPrimitive.CheckboxItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
className,
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden transition-colors focus:bg-accent-bg focus:text-accent data-disabled:pointer-events-none data-disabled:opacity-50",
className
)}
checked={checked}
{...props}
@@ -124,8 +124,8 @@ const DropdownMenuRadioItem = React.forwardRef<
<DropdownMenuPrimitive.RadioItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden transition-colors focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
className,
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden transition-colors focus:bg-accent-bg focus:text-accent data-disabled:pointer-events-none data-disabled:opacity-50",
className
)}
{...props}
>
@@ -150,7 +150,7 @@ const DropdownMenuLabel = React.forwardRef<
className={cn(
"px-2 py-1.5 text-sm font-semibold",
inset && "pl-8",
className,
className
)}
{...props}
/>
@@ -163,7 +163,7 @@ const DropdownMenuSeparator = React.forwardRef<
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
className={cn("-mx-1 my-1 h-px bg-subtle-bg", className)}
{...props}
/>
));

View File

@@ -8,14 +8,14 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
<input
type={type}
className={cn(
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className,
"flex h-9 w-full rounded-md border border-solid-b bg-invert-bg px-3 py-1 text-base shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-primary placeholder:text-tertiary focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-active-b disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className
)}
ref={ref}
{...props}
/>
);
},
}
);
Input.displayName = "Input";

View File

@@ -17,7 +17,7 @@ const PopoverContent = React.forwardRef<
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
"z-50 w-72 rounded-md border bg-level-0 p-4 text-primary shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}

View File

@@ -26,8 +26,8 @@ const RadioGroupItem = React.forwardRef<
<RadioGroupPrimitive.Item
ref={ref}
className={cn(
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className,
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-level-0 focus:outline-hidden focus-visible:ring-2 focus-visible:ring-active-b focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
>

View File

@@ -17,8 +17,8 @@ const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className,
"flex h-10 w-full items-center justify-between rounded-md border border-solid-b bg-invert-bg px-3 py-2 text-sm ring-offset-level-0 placeholder:text-tertiary focus:outline-hidden focus:ring focus:ring-active-b disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
>
@@ -36,10 +36,10 @@ const SelectContent = React.forwardRef<
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-invert-bg text-primary shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className,
className
)}
position={position}
{...props}
@@ -48,7 +48,7 @@ const SelectContent = React.forwardRef<
className={cn(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]",
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
)}
>
{children}
@@ -65,8 +65,8 @@ const SelectItem = React.forwardRef<
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
className,
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-active-bg focus:text-active data-disabled:pointer-events-none data-disabled:opacity-50",
className
)}
{...props}
>

View File

@@ -9,20 +9,20 @@ const Separator = React.forwardRef<
>(
(
{ className, orientation = "horizontal", decorative = true, ...props },
ref,
ref
) => (
<SeparatorPrimitive.Root
ref={ref}
decorative={decorative}
orientation={orientation}
className={cn(
"shrink-0 bg-border",
"shrink-0 bg-solid-b",
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
className,
className
)}
{...props}
/>
),
)
);
Separator.displayName = SeparatorPrimitive.Root.displayName;

View File

@@ -22,7 +22,7 @@ const SheetOverlay = React.forwardRef<
<SheetPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className,
className
)}
{...props}
ref={ref}
@@ -31,7 +31,7 @@ const SheetOverlay = React.forwardRef<
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
const sheetVariants = cva(
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out",
"fixed z-50 gap-4 bg-level-0 p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out",
{
variants: {
side: {
@@ -46,7 +46,7 @@ const sheetVariants = cva(
defaultVariants: {
side: "right",
},
},
}
);
interface SheetContentProps
@@ -64,7 +64,7 @@ const SheetContent = React.forwardRef<
className={cn(sheetVariants({ side }), className)}
{...props}
>
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-level-0 transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-active-b focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-invert">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
@@ -81,7 +81,7 @@ const SheetHeader = ({
<div
className={cn(
"flex flex-col space-y-2 text-center sm:text-left",
className,
className
)}
{...props}
/>
@@ -95,7 +95,7 @@ const SheetFooter = ({
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className,
className
)}
{...props}
/>
@@ -108,7 +108,7 @@ const SheetTitle = React.forwardRef<
>(({ className, ...props }, ref) => (
<SheetPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold text-foreground", className)}
className={cn("text-lg font-semibold text-primary", className)}
{...props}
/>
));
@@ -120,7 +120,7 @@ const SheetDescription = React.forwardRef<
>(({ className, ...props }, ref) => (
<SheetPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
className={cn("text-sm text-tertiary", className)}
{...props}
/>
));

View File

@@ -139,7 +139,7 @@ const SidebarProvider = React.forwardRef<
} as React.CSSProperties
}
className={cn(
"group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar",
"group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-level-0",
className
)}
ref={ref}
@@ -179,7 +179,7 @@ const Sidebar = React.forwardRef<
return (
<div
className={cn(
"flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground",
"flex h-full w-(--sidebar-width) flex-col bg-level-0 text-secondary",
className
)}
ref={ref}
@@ -196,7 +196,7 @@ const Sidebar = React.forwardRef<
<SheetContent
data-sidebar="sidebar"
data-mobile="true"
className="w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
className="w-(--sidebar-width) bg-level-0 p-0 text-secondary [&>button]:hidden"
style={
{
"--sidebar-width": SIDEBAR_WIDTH_MOBILE,
@@ -213,7 +213,7 @@ const Sidebar = React.forwardRef<
return (
<div
ref={ref}
className="group peer hidden text-sidebar-foreground md:block"
className="group peer hidden text-secondary md:block"
data-state={state}
data-collapsible={state === "collapsed" ? collapsible : ""}
data-variant={variant}
@@ -246,7 +246,7 @@ const Sidebar = React.forwardRef<
>
<div
data-sidebar="sidebar"
className="flex gap-2 h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow-sm"
className="flex gap-2 h-full w-full flex-col bg-level-0 group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-solid-b group-data-[variant=floating]:shadow-sm"
>
{children}
</div>
@@ -298,10 +298,10 @@ const SidebarRail = React.forwardRef<
onClick={toggleSidebar}
title="Toggle Sidebar"
className={cn(
"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex",
"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-solid-b group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex",
"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
"group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar",
"group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-level-0",
"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
className
@@ -320,7 +320,7 @@ const SidebarInset = React.forwardRef<
<main
ref={ref}
className={cn(
"relative flex min-h-svh flex-1 flex-col bg-background",
"relative flex min-h-svh flex-1 flex-col bg-level-0",
"peer-data-[variant=inset]:min-h-[calc(100svh-(--spacing(4)))] md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm",
className
)}
@@ -339,7 +339,7 @@ const SidebarInput = React.forwardRef<
ref={ref}
data-sidebar="input"
className={cn(
"h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring",
"h-8 w-full bg-level-0 shadow-none focus-visible:ring-2 focus-visible:ring-active-b",
className
)}
{...props}
@@ -386,7 +386,7 @@ const SidebarSeparator = React.forwardRef<
<Separator
ref={ref}
data-sidebar="separator"
className={cn("mx-2 w-auto bg-sidebar-border", className)}
className={cn("mx-2 w-auto bg-solid-b", className)}
{...props}
/>
);
@@ -437,7 +437,7 @@ const SidebarGroupLabel = React.forwardRef<
ref={ref}
data-sidebar="group-label"
className={cn(
"flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-hidden ring-sidebar-ring transition-[margin,opa] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
"flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-secondary/70 outline-hidden ring-active-b transition-[margin,opa] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
className
)}
@@ -458,7 +458,7 @@ const SidebarGroupAction = React.forwardRef<
ref={ref}
data-sidebar="group-action"
className={cn(
"absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
"absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-secondary outline-hidden ring-active-b transition-transform hover:bg-accent-bg hover:text-accent focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
// Increases the hit area of the button on mobile.
"after:absolute after:-inset-2 md:after:hidden",
"group-data-[collapsible=icon]:hidden",
@@ -510,13 +510,16 @@ const SidebarMenuItem = React.forwardRef<
SidebarMenuItem.displayName = "SidebarMenuItem";
const sidebarMenuButtonVariants = cva(
"text-gray-600 peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-primary focus-visible:ring-2 active:bg-sidebar-accent active:text-primary disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-primary data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-primary group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 hover:cursor-pointer",
"rounded-full text-tertiary active:text-primary data-[active=true]:text-primary peer/menu-button flex w-full items-center gap-2 overflow-hidden p-2 text-left text-sm outline-hidden ring-active-b transition-[width,height,padding] focus-visible:ring disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:font-medium group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 hover:cursor-pointer",
{
variants: {
variant: {
default: "hover:bg-sidebar-accent hover:text-primary",
default:
"hover:bg-h-active-bg data-[state=open]:bg-active-bg data-[state=open]:hover:bg-h-active-bg active:bg-active-bg data-[active=true]:bg-active-bg",
outline:
"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-primary hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
"border border-low-b shadow-[0_0_0_1px_hsl(var(--solid-b))] hover:bg-h-tertiary-bg data-[state=open]:hover:bg-h-tertiary-bg hover:shadow-[0_0_0_1px_hsl(var(--accent))] active:bg-tertiary-bg ata-[active=true]:bg-h-tertiary-bg",
ghost:
"shadow-[0_0_0_1px_hsl(var(--solid-b))] hover:bg-h-tertiary-bg data-[state=open]:hover:bg-h-tertiary-bg hover:shadow-[0_0_0_1px_hsl(var(--accent))] active:bg-tertiary-bg ata-[active=true]:bg-h-tertiary-bg",
},
size: {
default: "h-10 py-2 px-3 gap-3",
@@ -604,7 +607,7 @@ const SidebarMenuAction = React.forwardRef<
ref={ref}
data-sidebar="menu-action"
className={cn(
"absolute right-1 top-1.5 flex aspect-square w-6 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0 hover:cursor-pointer",
"absolute right-1 top-1.5 flex aspect-square w-6 items-center justify-center rounded-md p-0 text-secondary outline-hidden ring-active-b transition-transform hover:bg-accent-bg hover:text-accent focus-visible:ring-2 peer-hover/menu-button:text-accent [&>svg]:size-4 [&>svg]:shrink-0 hover:cursor-pointer",
// Increases the hit area of the button on mobile.
"after:absolute after:-inset-2 md:after:hidden",
"peer-data-[size=sm]/menu-button:top-1",
@@ -612,7 +615,7 @@ const SidebarMenuAction = React.forwardRef<
"peer-data-[size=lg]/menu-button:top-2.5",
"group-data-[collapsible=icon]:hidden",
showOnHover &&
"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0",
"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-accent md:opacity-0",
className
)}
{...props}
@@ -629,8 +632,8 @@ const SidebarMenuBadge = React.forwardRef<
ref={ref}
data-sidebar="menu-badge"
className={cn(
"pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground",
"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
"pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-secondary",
"peer-hover/menu-button:text-accent peer-data-[active=true]/menu-button:text-accent",
"peer-data-[size=sm]/menu-button:top-1",
"peer-data-[size=default]/menu-button:top-1.5",
"peer-data-[size=lg]/menu-button:top-2.5",
@@ -688,7 +691,7 @@ const SidebarMenuSub = React.forwardRef<
ref={ref}
data-sidebar="menu-sub"
className={cn(
"ml-5 flex min-w-0 flex-col gap-1 border-l border-sidebar-border px-2.5 py-1",
"ml-5 flex min-w-0 flex-col gap-1 border-l border-solid-b px-2.5 py-1",
"group-data-[collapsible=icon]:hidden",
className
)}
@@ -720,8 +723,8 @@ const SidebarMenuSubButton = React.forwardRef<
data-size={size}
data-active={isActive}
className={cn(
"text-gray-600 flex h-7 min-w-0 items-center gap-2 overflow-hidden rounded-md px-4 outline-hidden ring-sidebar-ring hover:bg-sidebar-accent hover:text-primary focus-visible:ring-2 active:bg-sidebar-accent active:text-primary disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
"data-[active=true]:bg-sidebar-accent data-[active=true]:text-primary",
"text-secondary flex h-7 min-w-0 items-center gap-2 overflow-hidden rounded-md px-4 outline-hidden ring-active-b hover:bg-accent-bg hover:text-primary focus-visible:ring-2 active:bg-accent-bg active:text-primary disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
"data-[active=true]:bg-accent-bg data-[active=true]:text-primary",
size === "sm" && "text-xs",
size === "md" && "text-sm",
"group-data-[collapsible=icon]:hidden",

View File

@@ -42,7 +42,7 @@ const TableFooter = React.forwardRef<
>(({ className, ...props }, ref) => (
<tfoot
ref={ref}
className={cn("bg-primary font-medium text-primary-foreground", className)}
className={cn("bg-primary font-medium text-invert", className)}
{...props}
/>
));
@@ -55,7 +55,7 @@ const TableRow = React.forwardRef<
<tr
ref={ref}
className={cn(
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
"border-b transition-colors hover:bg-h-subtle-bg data-[state=selected]:bg-subtle-bg",
className
)}
{...props}
@@ -70,7 +70,7 @@ const TableHead = React.forwardRef<
<th
ref={ref}
className={cn(
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
"h-12 px-4 text-left align-middle font-medium text-tertiary [&:has([role=checkbox])]:pr-0",
className
)}
{...props}
@@ -96,7 +96,7 @@ const TableCaption = React.forwardRef<
>(({ className, ...props }, ref) => (
<caption
ref={ref}
className={cn("mt-4 text-sm text-muted-foreground", className)}
className={cn("mt-4 text-sm text-tertiary", className)}
{...props}
/>
));

View File

@@ -11,7 +11,7 @@ const TabsList = React.forwardRef<
<TabsPrimitive.List
ref={ref}
className={cn(
"inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
"inline-flex h-10 items-center rounded-md p-1 text-tertiary",
className
)}
{...props}
@@ -26,7 +26,7 @@ const TabsTrigger = React.forwardRef<
<TabsPrimitive.Trigger
ref={ref}
className={cn(
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
"border-b-2 border-transparent cursor-pointer inline-flex items-center justify-center whitespace-nowrap px-3 py-1.5 text-sm font-medium ring-offset-level-0 transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-active-b focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-active data-[state=active]:border-primary",
className
)}
{...props}
@@ -41,7 +41,7 @@ const TabsContent = React.forwardRef<
<TabsPrimitive.Content
ref={ref}
className={cn(
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"mt-2 ring-offset-level-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-active-b focus-visible:ring-offset-2",
className
)}
{...props}

View File

@@ -11,8 +11,8 @@ const Textarea = React.forwardRef<
return (
<textarea
className={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className,
"flex min-h-[80px] w-full rounded-md border border-solid-b bg-invert-bg px-3 py-2 text-sm ring-offset-level-0 placeholder:text-tertiary focus-visible:outline-hidden focus-visible:ring focus-visible:ring-active-b disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}

View File

@@ -15,7 +15,7 @@ const ToastViewport = React.forwardRef<
ref={ref}
className={cn(
"fixed top-0 z-100 flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
className,
className
)}
{...props}
/>
@@ -27,15 +27,15 @@ const toastVariants = cva(
{
variants: {
variant: {
default: "border bg-background text-foreground",
default: "border bg-level-0 text-primary",
destructive:
"destructive group border-destructive bg-destructive text-destructive-foreground",
"destructive group border-danger-b bg-danger-bg text-danger",
},
},
defaultVariants: {
variant: "default",
},
},
}
);
const Toast = React.forwardRef<
@@ -60,8 +60,8 @@ const ToastAction = React.forwardRef<
<ToastPrimitives.Action
ref={ref}
className={cn(
"inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-hidden focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 hover:group-[.destructive]:border-destructive/30 hover:group-[.destructive]:bg-destructive hover:group-[.destructive]:text-destructive-foreground focus:group-[.destructive]:ring-destructive",
className,
"inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-invert focus:outline-hidden focus:ring-1 focus:ring-active-b disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-solid-b/40 hover:group-[.destructive]:border-danger-b/30 hover:group-[.destructive]:bg-danger-bg hover:group-[.destructive]:text-danger focus:group-[.destructive]:ring-danger-b",
className
)}
{...props}
/>
@@ -75,8 +75,8 @@ const ToastClose = React.forwardRef<
<ToastPrimitives.Close
ref={ref}
className={cn(
"absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-hidden focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 hover:group-[.destructive]:text-red-50 focus:group-[.destructive]:ring-red-400 focus:group-[.destructive]:ring-offset-red-600",
className,
"absolute right-1 top-1 rounded-md p-1 text-primary/50 opacity-0 transition-opacity hover:text-primary focus:opacity-100 focus:outline-hidden focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 hover:group-[.destructive]:text-red-50 focus:group-[.destructive]:ring-red-400 focus:group-[.destructive]:ring-offset-red-600",
className
)}
toast-close=""
{...props}

View File

@@ -18,8 +18,8 @@ const TooltipContent = React.forwardRef<
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
"z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-invert animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>

View File

@@ -5,7 +5,7 @@ export default function AuthLayout({ children }: { children: ReactNode }) {
return (
<div className="flex min-h-screen flex-col">
<div className="flex flex-1">
<div className="flex flex-1 flex-col bg-muted/40">
<div className="flex flex-1 flex-col bg-subtle-bg/40">
<div className="flex flex-1 items-center justify-center">
<main className="w-full max-w-md p-6">{children}</main>
</div>
@@ -25,7 +25,7 @@ export default function AuthLayout({ children }: { children: ReactNode }) {
Navigate compliance with
<br />
confidence thanks to{" "}
<span className="text-lime-400">probo</span>
<span className="text-accent">probo</span>
</h1>
</div>
</div>

View File

@@ -14,19 +14,19 @@ export function ErrorPage({
}: ErrorPageProps) {
return (
<div className="flex h-full flex-1 flex-col items-center justify-center p-8 text-center">
<div className="mb-4 rounded-full bg-destructive/10 p-3 text-destructive">
<div className="mb-4 rounded-full bg-danger-bg/10 p-3 text-danger">
<AlertCircle className="size-6" />
</div>
<h1 className="mb-2 text-2xl font-semibold">{title}</h1>
<p className="mb-6 max-w-md text-muted-foreground">{description}</p>
<p className="mb-6 max-w-md text-tertiary">{description}</p>
{error?.message && (
<pre className="mb-8 max-w-2xl overflow-auto rounded-lg bg-muted/50 p-4 text-sm">
<pre className="mb-8 max-w-2xl overflow-auto rounded-lg bg-danger-bg/50 p-4 text-sm">
{error.message}
</pre>
)}
<Link
to="/"
className="inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
className="inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-invert transition-colors hover:bg-primary/90 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-active-b disabled:pointer-events-none disabled:opacity-50"
>
Return Home
</Link>

View File

@@ -140,7 +140,7 @@ export default function ConfirmEmailPage() {
disabled={isLoading}
required
/>
<p className="text-xs text-gray-500 dark:text-gray-400">
<p className="text-xs text-secondary dark:text-tertiary">
The token has been automatically filled from the URL if
available
</p>
@@ -157,7 +157,7 @@ export default function ConfirmEmailPage() {
{!isConfirmed && (
<Link
to="/login"
className="text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
className="text-sm text-secondary hover:text-primary dark:text-tertiary dark:hover:text-quaternary"
>
Back to Login
</Link>

View File

@@ -151,7 +151,7 @@ export default function ConfirmInvitationPage() {
required
autoComplete="off"
/>
<p className="text-xs text-gray-500 dark:text-gray-400">
<p className="text-xs text-secondary dark:text-tertiary">
The token has been automatically filled from the URL if
available
</p>
@@ -196,7 +196,7 @@ export default function ConfirmInvitationPage() {
{!isConfirmed && (
<Link
to="/login"
className="text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
className="text-sm text-secondary hover:text-primary dark:text-tertiary dark:hover:text-quaternary"
>
Back to Login
</Link>

View File

@@ -113,7 +113,7 @@ export default function ForgotPasswordPage() {
<CardFooter className="flex justify-center">
<Link
to="/login"
className="text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
className="text-sm text-secondary hover:text-primary dark:text-tertiary dark:hover:text-quaternary"
>
Back to Login
</Link>

View File

@@ -63,7 +63,7 @@ export default function LoginPage() {
<h1 className="text-2xl font-semibold tracking-tight">
Login to your account
</h1>
<p className="text-sm text-muted-foreground">
<p className="text-sm text-tertiary">
Enter your email below to login to your account
</p>
</div>

View File

@@ -74,7 +74,7 @@ export default function RegisterPage() {
<div className="space-y-6">
<div className="space-y-2 text-center">
<h1 className="text-3xl font-bold">Sign up</h1>
<p className="text-gray-500 dark:text-gray-400">
<p className="text-secondary dark:text-tertiary">
Enter your information to create an account
</p>
</div>
@@ -122,7 +122,7 @@ export default function RegisterPage() {
</form>
<div className="text-center">
<p className="text-sm text-gray-500 dark:text-gray-400">
<p className="text-sm text-secondary dark:text-tertiary">
Already have an account?{" "}
<Link to="/login" className="underline">
Log in here

View File

@@ -150,7 +150,7 @@ export default function ResetPasswordPage() {
required
autoComplete="off"
/>
<p className="text-xs text-gray-500 dark:text-gray-400">
<p className="text-xs text-secondary dark:text-tertiary">
The token has been automatically filled from the URL if
available
</p>
@@ -195,7 +195,7 @@ export default function ResetPasswordPage() {
{!isReset && (
<Link
to="/login"
className="text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
className="text-sm text-secondary hover:text-primary dark:text-tertiary dark:hover:text-quaternary"
>
Back to Login
</Link>

View File

@@ -10,7 +10,7 @@ export function CreateOrganizationViewSkeleton() {
title="Create Organization"
description="Create a new organization to manage your compliance and security needs."
>
<div className="max-w-2xl aspect-square bg-muted rounded-xl animate-pulse" />
<div className="max-w-2xl aspect-square bg-subtle-bg rounded-xl animate-pulse" />
</PageTemplateSkeleton>
);
}

View File

@@ -65,7 +65,7 @@ function EditableField({
return (
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<Label className="text-sm">{label}</Label>
</div>
<div className="space-y-2">
@@ -75,7 +75,7 @@ function EditableField({
onChange={(e) => onChange(e.target.value)}
required={required}
/>
{helpText && <p className="text-sm text-gray-500">{helpText}</p>}
{helpText && <p className="text-sm text-secondary">{helpText}</p>}
</div>
</div>
);

View File

@@ -29,8 +29,8 @@ const BreadCrumbNavLink = ({
{({ isActive }) => (
<BreadcrumbPage
className={cn(
"text-gray-300",
isActive && "text-gray-700",
"text-quaternary",
isActive && "text-primary",
className
)}
>

View File

@@ -57,8 +57,8 @@ const BreadcrumbNavLink = ({
{({ isActive }) => (
<BreadcrumbPage
className={cn(
"text-gray-300",
isActive && "text-gray-700",
"text-quaternary",
isActive && "text-primary",
className
)}
>

View File

@@ -15,7 +15,10 @@ export function SettingsViewSkeleton() {
<div className="space-y-6">
<div className="space-y-2">
{[1, 2].map((i) => (
<div key={i} className="h-64 bg-muted animate-pulse rounded-lg" />
<div
key={i}
className="h-64 bg-subtle-bg animate-pulse rounded-lg"
/>
))}
</div>
</div>

View File

@@ -313,10 +313,10 @@ function SettingsViewContent({
/>
) : (
<div className="flex h-10 w-10 items-center justify-center rounded-lg border">
<Upload className="h-5 w-5 text-muted-foreground" />
<Upload className="h-5 w-5 text-tertiary" />
</div>
)}
<span className="text-muted-foreground">
<span className="text-tertiary">
Upload a logo to be displayed at the top of your trust page
</span>
</div>
@@ -344,8 +344,8 @@ function SettingsViewContent({
<label className="text-sm font-medium">Organization name</label>
<div className="flex items-center justify-between rounded-lg border p-3 shadow-xs">
<div className="flex items-center gap-2">
<Building2 className="h-5 w-5 text-muted-foreground" />
<span className="text-muted-foreground">
<Building2 className="h-5 w-5 text-tertiary" />
<span className="text-tertiary">
Set the name of the organization
</span>
</div>
@@ -389,11 +389,11 @@ function SettingsViewContent({
<div className="space-y-4">
{users.length === 0 ? (
<div className="flex flex-col items-center justify-center p-8 text-center">
<div className="rounded-full bg-muted p-3">
<Building2 className="h-6 w-6 text-muted-foreground" />
<div className="rounded-full bg-subtle-bg p-3">
<Building2 className="h-6 w-6 text-tertiary" />
</div>
<h3 className="mt-4 text-lg font-medium">No members found</h3>
<p className="mt-2 text-sm text-muted-foreground">
<p className="mt-2 text-sm text-tertiary">
You haven&apos;t added any members to your workspace yet.
</p>
</div>
@@ -413,15 +413,13 @@ function SettingsViewContent({
<span className="text-sm font-medium">
{user.fullName}
</span>
<span className="text-sm text-muted-foreground">
<span className="text-sm text-tertiary">
{user.email}
</span>
</div>
</div>
<div className="flex items-center gap-2">
<span className="text-sm text-muted-foreground">
Owner
</span>
<span className="text-sm text-tertiary">Owner</span>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon">

View File

@@ -12,7 +12,7 @@ export function EditFrameworkViewSkeleton() {
title="Update Framework"
description="Update the framework details"
>
<div className="max-w-2xl aspect-square bg-muted rounded-xl animate-pulse" />
<div className="max-w-2xl aspect-square bg-subtle-bg rounded-xl animate-pulse" />
</PageTemplateSkeleton>
);
}

View File

@@ -72,7 +72,7 @@ function EditableField({
</Label>
{helpText && (
<div className="relative flex items-center">
<HelpCircle className="h-4 w-4 text-muted-foreground" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<span className="sr-only">{helpText}</span>
</div>
)}

View File

@@ -12,8 +12,8 @@ export function FrameworkLayoutViewSkeleton() {
<PageTemplateSkeleton
actions={
<div className="flex gap-4 w-1/3">
<div className="bg-muted animate-pulse h-9 w-1/2 rounded-lg" />
<div className="bg-muted animate-pulse h-9 w-1/2 rounded-lg" />
<div className="bg-subtle-bg animate-pulse h-9 w-1/2 rounded-lg" />
<div className="bg-subtle-bg animate-pulse h-9 w-1/2 rounded-lg" />
</div>
}
>
@@ -22,11 +22,11 @@ export function FrameworkLayoutViewSkeleton() {
<Card key={i}>
<CardContent className="p-6">
<div className="relative mb-6">
<div className="bg-muted w-24 h-24 rounded-full animate-pulse mb-4" />
<div className="h-6 w-48 bg-muted animate-pulse rounded mb-2" />
<div className="h-20 w-full bg-muted animate-pulse rounded" />
<div className="bg-subtle-bg w-24 h-24 rounded-full animate-pulse mb-4" />
<div className="h-6 w-48 bg-subtle-bg animate-pulse rounded mb-2" />
<div className="h-20 w-full bg-subtle-bg animate-pulse rounded" />
</div>
<div className="h-4 w-32 bg-muted animate-pulse rounded" />
<div className="h-4 w-32 bg-subtle-bg animate-pulse rounded" />
</CardContent>
</Card>
))}

View File

@@ -133,7 +133,7 @@ function FrameworkLayoutViewContent({
description={framework.description || ""}
actions={
<div className="flex gap-4">
<Button variant="outline" asChild>
<Button variant="secondary" asChild>
<Link
to={`/organizations/${organizationId}/frameworks/${framework.id}/edit`}
>

View File

@@ -22,6 +22,7 @@ export const controlListFragment = graphql`
interface ControlListProps {
fragmentKey: ControlList_List$key;
className?: string;
}
export function ControlList(props: ControlListProps) {
@@ -30,7 +31,7 @@ export function ControlList(props: ControlListProps) {
frameworkId: string;
controlId?: string;
}>();
const { fragmentKey } = props;
const { className, fragmentKey } = props;
const { controls } = useFragment<ControlList_List$key>(
controlListFragment,
fragmentKey
@@ -41,15 +42,20 @@ export function ControlList(props: ControlListProps) {
}
return (
<aside className="shrink-0 w-70 border-r border-gray-100 h-full overflow-x-hidden overflow-y-auto [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-gray-100 [&::-webkit-scrollbar-thumb]:bg-gray-300 [&::-webkit-scrollbar-thumb]:rounded-xs">
<aside
className={cn(
"shrink-0 w-70 border-r h-full overflow-x-hidden overflow-y-auto [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-level-0 [&::-webkit-scrollbar-thumb]:bg-highlight-bg [&::-webkit-scrollbar-thumb]:rounded-xs",
className
)}
>
{controls.edges.map(({ node: control }, i) => (
<NavLink
key={control.id}
to={`/organizations/${organizationId}/frameworks/${frameworkId}/controls/${control.id}`}
className={({ isActive }) =>
cn(
"block pl-8 pr-4 py-4 hover:bg-gray-50 border-b border-gray-100",
(isActive || (i === 0 && !controlId)) && "bg-gray-50"
"block pl-8 pr-4 py-4 border-b hover:bg-h-subtle-bg",
(isActive || (i === 0 && !controlId)) && "bg-subtle-bg"
)
}
>
@@ -58,8 +64,8 @@ export function ControlList(props: ControlListProps) {
<>
<div
className={cn(
"inline-block font-mono text-sm px-1 py-0.25 rounded-sm bg-lime-2 border border-lime-4 text-lime-9 font-semibold",
isActive && "font-bold bg-lime-3 border-lime-6 text-lime-11"
"inline-block font-mono text-sm px-1 py-0.25 rounded-sm bg-highlight-bg border font-semibold",
isActive && "font-bold bg-active-bg border-mid-b"
)}
>
{control.referenceId}

View File

@@ -14,21 +14,21 @@ export function FrameworkListViewSkeleton() {
description="Manage your compliance frameworks"
actions={
<div className="flex gap-4 w-1/3">
<div className="bg-muted animate-pulse h-9 w-1/2 rounded-lg" />
<div className="bg-muted animate-pulse h-9 w-1/2 rounded-lg" />
<div className="bg-subtle-bg animate-pulse h-9 w-1/2 rounded-lg" />
<div className="bg-subtle-bg animate-pulse h-9 w-1/2 rounded-lg" />
</div>
}
>
<div className="grid gap-6 md:grid-cols-2">
{[1, 2].map((i) => (
<Card key={i} className="bg-card/50">
<Card key={i}>
<CardContent className="p-6">
<div className="relative mb-6">
<div className="bg-muted w-24 h-24 rounded-full animate-pulse mb-4" />
<div className="h-6 w-48 bg-muted animate-pulse rounded mb-2" />
<div className="h-20 w-full bg-muted animate-pulse rounded" />
<div className="bg-subtle-bg w-24 h-24 rounded-full animate-pulse mb-4" />
<div className="h-6 w-48 bg-subtle-bg animate-pulse rounded mb-2" />
<div className="h-20 w-full bg-subtle-bg animate-pulse rounded" />
</div>
<div className="h-4 w-32 bg-muted animate-pulse rounded" />
<div className="h-4 w-32 bg-subtle-bg animate-pulse rounded" />
</CardContent>
</Card>
))}

View File

@@ -139,12 +139,12 @@ function FrameworkListViewContent({
className="hidden"
/>
<Button
variant="outline"
variant="secondary"
onClick={handleImportClick}
disabled={isUploading}
>
<Upload className="mr-2 h-4 w-4" />
Import Framework
Import
</Button>
<Button asChild>
<Link to={`/organizations/${organizationId}/frameworks/new`}>
@@ -161,10 +161,10 @@ function FrameworkListViewContent({
<table className="w-full caption-bottom text-sm">
<tbody className="[&_tr:last-child]:border-0">
{frameworks.length === 0 ? (
<tr className="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted">
<tr className="border-b transition-colors hover:bg-h-subte-bg/50 data-[state=selected]:bg-subtle-bg">
<td
colSpan={4}
className="text-center p-4 align-middle text-muted-foreground"
className="text-center p-4 align-middle text-tertiary"
>
No frameworks found. Create or import one to get started.
</td>
@@ -173,7 +173,7 @@ function FrameworkListViewContent({
frameworks.map((framework) => (
<tr
key={framework.id}
className="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted cursor-pointer"
className="border-b transition-colors hover:bg-h-subtle-bg/50 data-[state=selected]:bg-subtle-bg cursor-pointer"
>
<td className="p-4 align-middle">
<Link

View File

@@ -13,11 +13,11 @@ export function FrameworkViewSkeleton() {
<Card key={i}>
<CardContent className="p-6">
<div className="relative mb-6">
<div className="bg-muted w-24 h-24 rounded-full animate-pulse mb-4" />
<div className="h-6 w-48 bg-muted animate-pulse rounded mb-2" />
<div className="h-20 w-full bg-muted animate-pulse rounded" />
<div className="bg-subtle-bg w-24 h-24 rounded-full animate-pulse mb-4" />
<div className="h-6 w-48 bg-subtle-bg animate-pulse rounded mb-2" />
<div className="h-20 w-full bg-subtle-bg animate-pulse rounded" />
</div>
<div className="h-4 w-32 bg-muted animate-pulse rounded" />
<div className="h-4 w-32 bg-subtle-bg animate-pulse rounded" />
</CardContent>
</Card>
))}

View File

@@ -12,7 +12,7 @@ export function NewFrameworkViewSkeleton() {
title="Create Framework"
description="Create a new framework to organize your mitigations"
>
<div className="max-w-2xl aspect-square bg-muted rounded-xl animate-pulse" />
<div className="max-w-2xl aspect-square bg-subtle-bg rounded-xl animate-pulse" />
</PageTemplateSkeleton>
);
}

View File

@@ -56,7 +56,7 @@ function EditableField({
</Label>
{helpText && (
<div className="relative flex items-center">
<HelpCircle className="h-4 w-4 text-muted-foreground" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<span className="sr-only">{helpText}</span>
</div>
)}

View File

@@ -451,42 +451,42 @@ export function Control({
};
const getImportanceColor = (importance: string | undefined): string => {
if (!importance) return "bg-gray-100 text-gray-800";
if (!importance) return "bg-secondary-bg text-secondary";
switch (importance) {
case "LOW":
return "bg-blue-100 text-blue-800";
return "bg-success-bg text-success";
case "MEDIUM":
return "bg-yellow-100 text-yellow-800";
return "bg-info-bg text-info";
case "HIGH":
return "bg-orange-100 text-orange-800";
return "bg-warning-bg text-warning";
case "CRITICAL":
return "bg-red-100 text-red-800";
return "bg-danger-bg text-danger";
default:
return "bg-gray-100 text-gray-800";
return "bg-secondary-bg text-secondary";
}
};
const getStateColor = (state: string | undefined): string => {
if (!state) return "bg-gray-100 text-gray-800";
if (!state) return "bg-secondary-bg text-secondary";
switch (state) {
case "NOT_STARTED":
return "bg-gray-100 text-gray-800";
return "bg-secondary-bg text-secondary";
case "IN_PROGRESS":
return "bg-blue-100 text-blue-800";
return "bg-info-bg text-info";
case "IMPLEMENTED":
return "bg-green-100 text-green-800";
return "bg-success-bg text-success";
case "NOT_APPLICABLE":
return "bg-purple-100 text-purple-800";
return "bg-warning-bg text-warning";
default:
return "bg-gray-100 text-gray-800";
return "bg-secondary-bg text-secondary";
}
};
return (
<div className="w-auto p-5 flex items-start gap-5">
<div className="font-mono text-lg px-1 py-0.25 rounded-sm bg-lime-3 border border-lime-6 text-lime-11 font-bold">
<div className="font-mono text-lg px-1 py-0.25 rounded-sm bg-active-bg border-mid-b border font-bold">
{control.referenceId}
</div>
<div className="flex-1">
@@ -494,7 +494,7 @@ export function Control({
{/* Control Description */}
{control.description && (
<div className="mt-4 text-gray-600">{control.description}</div>
<div className="mt-4 text-tertiary">{control.description}</div>
)}
{/* Security Measures Section */}
@@ -516,7 +516,7 @@ export function Control({
<div className="flex items-center space-x-4 mb-4">
<div className="flex-1">
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-tertiary" />
<Input
placeholder="Search security measures by name or description..."
value={mitigationSearchQuery}
@@ -550,20 +550,20 @@ export function Control({
<div className="flex-1 overflow-hidden">
{isLoadingMitigations ? (
<div className="flex items-center justify-center h-full">
<Loader2 className="w-8 h-8 animate-spin text-blue-500" />
<Loader2 className="w-8 h-8 animate-spin text-info" />
<span className="ml-2">Loading security measures...</span>
</div>
) : (
<div className="max-h-[50vh] overflow-y-auto pr-2">
{filteredMitigations().length === 0 ? (
<div className="text-center py-8 text-gray-500">
<div className="text-center py-8 text-secondary">
No security measures found. Try adjusting your search or
select a different category.
</div>
) : (
<table className="w-full">
<table className="w-full bg-level-1">
<thead className="sticky top-0 bg-white">
<tr className="border-b text-left text-sm text-gray-500 bg-gray-50">
<tr className="border-b text-left text-sm text-secondary bg-invert-bg">
<th className="py-3 px-4 font-medium">Name</th>
<th className="py-3 px-4 font-medium">
Importance
@@ -580,14 +580,14 @@ export function Control({
return (
<tr
key={mitigation.id}
className="border-b hover:bg-gray-50"
className="border-b hover:bg-invert-bg"
>
<td className="py-3 px-4">
<div className="font-medium">
{mitigation.name}
</div>
{mitigation.description && (
<div className="text-xs text-gray-500 line-clamp-1 mt-0.5">
<div className="text-xs text-secondary line-clamp-1 mt-0.5">
{mitigation.description}
</div>
)}
@@ -619,7 +619,7 @@ export function Control({
handleUnlinkMitigation(mitigation.id)
}
disabled={isUnlinkingMitigation}
className="text-xs h-7 text-red-500 border-red-200 hover:bg-red-50"
className="text-xs h-7 text-danger border-danger-b hover:bg-h-danger-bg"
>
{isUnlinkingMitigation ? (
<Loader2 className="w-4 h-4 animate-spin" />
@@ -630,13 +630,13 @@ export function Control({
</Button>
) : (
<Button
variant="outline"
variant="secondary"
size="sm"
onClick={() =>
handleLinkMitigation(mitigation.id)
}
disabled={isLinkingMitigation}
className="text-xs h-7 text-blue-500 border-blue-200 hover:bg-blue-50"
className="text-xs h-7 text-info border-info-b hover:bg-h-info-bg"
>
{isLinkingMitigation ? (
<Loader2 className="w-4 h-4 animate-spin" />
@@ -668,7 +668,7 @@ export function Control({
{/* Linked Mitigations List */}
<div>
<div className="flex justify-between items-center mb-4">
<h3 className="text-xl font-medium text-gray-600">
<h3 className="text-xl font-medium text-secondary">
Security measures
</h3>
<Button
@@ -684,7 +684,7 @@ export function Control({
{isLoadingMitigations ? (
<div className="flex items-center justify-center h-24">
<Loader2 className="w-6 h-6 animate-spin text-blue-500" />
<Loader2 className="w-6 h-6 animate-spin text-info" />
<span className="ml-2">Loading security measures...</span>
</div>
) : linkedMitigationsData?.control?.mitigations?.edges &&
@@ -692,7 +692,7 @@ export function Control({
<div className="overflow-x-auto border rounded-md">
<table className="w-full">
<thead>
<tr className="border-b text-left text-sm text-gray-500 bg-gray-50">
<tr className="border-b text-left text-sm text-secondary bg-invert-bg">
<th className="py-3 px-4 font-medium">Name</th>
<th className="py-3 px-4 font-medium">Importance</th>
<th className="py-3 px-4 font-medium">State</th>
@@ -705,12 +705,12 @@ export function Control({
{getLinkedMitigations().map((mitigation) => (
<tr
key={mitigation.id}
className="border-b hover:bg-gray-50"
className="border-b hover:bg-invert-bg"
>
<td className="py-3 px-4">
<div className="font-medium">{mitigation.name}</div>
{mitigation.description && (
<div className="text-xs text-gray-500 line-clamp-1 mt-0.5">
<div className="text-xs text-secondary line-clamp-1 mt-0.5">
{mitigation.description}
</div>
)}
@@ -754,7 +754,7 @@ export function Control({
handleUnlinkMitigation(mitigation.id)
}
disabled={isUnlinkingMitigation}
className="text-xs h-7 text-red-500 border-red-200 hover:bg-red-50"
className="text-xs h-7 text-danger border-danger-b hover:bg-h-danger-bg"
>
Unlink
</Button>
@@ -766,7 +766,7 @@ export function Control({
</table>
</div>
) : (
<div className="text-center py-8 text-gray-500 border rounded-md">
<div className="text-center py-8 text-secondary border rounded-md">
No security measures linked to this control yet. Click
&quot;Link Security Measures&quot; to connect some.
</div>

View File

@@ -13,11 +13,11 @@ export function ControlViewSkeleton() {
<Card key={i}>
<CardContent className="p-6">
<div className="relative mb-6">
<div className="bg-muted w-24 h-24 rounded-full animate-pulse mb-4" />
<div className="h-6 w-48 bg-muted animate-pulse rounded mb-2" />
<div className="h-20 w-full bg-muted animate-pulse rounded" />
<div className="bg-subtle-bg w-24 h-24 rounded-full animate-pulse mb-4" />
<div className="h-6 w-48 bg-subtle-bg animate-pulse rounded mb-2" />
<div className="h-20 w-full bg-subtle-bg animate-pulse rounded" />
</div>
<div className="h-4 w-32 bg-muted animate-pulse rounded" />
<div className="h-4 w-32 bg-subtle-bg animate-pulse rounded" />
</CardContent>
</Card>
))}

View File

@@ -12,7 +12,7 @@ export function EditMitigationViewSkeleton() {
title="Edit Mitigation"
description="Edit a mitigation. You will be able to link it to control and risks"
>
<div className="max-w-2xl aspect-square bg-muted rounded-xl animate-pulse" />
<div className="max-w-2xl aspect-square bg-subtle-bg rounded-xl animate-pulse" />
</PageTemplateSkeleton>
);
}

View File

@@ -170,8 +170,8 @@ function EditMitigationViewContent({
className={cn(
"rounded-full cursor-pointer px-4 py-1 text-sm transition-colors",
formData.importance === "MANDATORY"
? "bg-red-100 text-red-900 ring-2 ring-red-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
? "bg-danger-bg text-danger ring ring-danger-b"
: "bg-invert-bg hover:bg-h-invert-bg"
)}
>
Mandatory
@@ -182,8 +182,8 @@ function EditMitigationViewContent({
className={cn(
"rounded-full cursor-pointer px-4 py-1 text-sm transition-colors",
formData.importance === "PREFERRED"
? "bg-yellow-100 text-yellow-900 ring-2 ring-yellow-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
? "bg-warning-bg text-warning ring ring-warning-b"
: "bg-invert-bg hover:bg-h-invert-bg"
)}
>
Preferred
@@ -194,8 +194,8 @@ function EditMitigationViewContent({
className={cn(
"rounded-full cursor-pointer px-4 py-1 text-sm transition-colors",
formData.importance === "ADVANCED"
? "bg-blue-100 text-blue-900 ring-2 ring-blue-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
? "bg-info-bg text-info ring ring-info-b"
: "bg-invert-bg hover:bg-h-invert-bg"
)}
>
Advanced

View File

@@ -13,19 +13,17 @@ export function MitigationListViewSkeleton() {
description="Mitigations are actions taken to reduce the risk of a risk."
>
<div className="space-y-6">
<div className="rounded-xl border bg-card p-4 space-y-4">
<div className="h-5 w-32 bg-muted animate-pulse rounded" />
<div className="flex gap-2">
<div className="h-10 flex-1 bg-muted animate-pulse rounded" />
<div className="h-10 w-32 bg-muted animate-pulse rounded" />
</div>
</div>
<div className="h-[72px] bg-subtle-bg animate-pulse rounded-xl" />
<div className="space-y-2">
{[1, 2, 3].map((i) => (
<div
key={i}
className="h-[72px] bg-muted animate-pulse rounded-xl"
/>
<div key={i} className="rounded-xl border bg-level-1 p-4 space-y-4">
<div className="h-5 w-32 bg-subtle-bg animate-pulse rounded" />
<div className="flex gap-2">
<div className="h-10 flex-1 bg-subtle-bg animate-pulse rounded" />
<div className="h-10 w-32 bg-subtle-bg animate-pulse rounded" />
</div>
</div>
))}
</div>
</div>

View File

@@ -267,15 +267,15 @@ function MitigationListContent({
const getStatusIcon = (status: string) => {
switch (status) {
case "complete":
return <CheckCircle2 className="h-5 w-5 text-green-500" />;
return <CheckCircle2 className="h-5 w-5 text-success" />;
case "in-progress":
return <Clock className="h-5 w-5 text-blue-500" />;
return <Clock className="h-5 w-5 text-info" />;
case "not-started":
return <AlertCircle className="h-5 w-5 text-gray-200" />;
return <AlertCircle className="h-5 w-5 text-disabled" />;
case "incomplete":
return <AlertCircle className="h-5 w-5 text-red-500" />;
return <AlertCircle className="h-5 w-5 text-danger" />;
case "not-applicable":
return <X className="h-5 w-5 text-gray-300" />;
return <X className="h-5 w-5 text-quaternary" />;
default:
return null;
}
@@ -332,7 +332,7 @@ function MitigationListContent({
actions={
<div className="flex gap-4">
<Button
variant="outline"
variant="secondary"
onClick={() => fileInputRef.current?.click()}
disabled={isImporting}
>
@@ -359,13 +359,13 @@ function MitigationListContent({
<div className="mb-8">
<div className="flex items-center justify-between mb-1">
<h3 className="text-lg font-medium">Mitigation Implementation</h3>
<span className="text-sm text-muted-foreground">
<span className="text-sm text-tertiary">
{globalProgress}% complete
</span>
</div>
{/* Progress bar container */}
<div className="w-full h-5 rounded-full overflow-hidden bg-muted mb-2">
<div className="w-full h-5 rounded-full overflow-hidden bg-subtle-bg mb-2">
{/* Segmented progress bar */}
<div className="flex h-full">
{/* Complete segment */}
@@ -404,7 +404,7 @@ function MitigationListContent({
{/* Not applicable segment */}
{globalStatusCounts["not-applicable"] > 0 && (
<div
className="bg-gray-600 h-full"
className="bg-primary-bg h-full"
style={{
width: `${
(globalStatusCounts["not-applicable"] / totalMitigations) *
@@ -416,7 +416,7 @@ function MitigationListContent({
{/* Not started segment */}
{globalStatusCounts["not-started"] > 0 && (
<div
className="bg-gray-200 h-full"
className="bg-secondary h-full"
style={{
width: `${
(globalStatusCounts["not-started"] / totalMitigations) * 100
@@ -448,16 +448,16 @@ function MitigationListContent({
</div>
)}
{globalStatusCounts["not-applicable"] > 0 && (
<div className="flex items-center gap-1.5 text-muted-foreground">
<div className="w-3 h-3 rounded-full bg-gray-600"></div>
<div className="flex items-center gap-1.5 text-tertiary">
<div className="w-3 h-3 rounded-full bg-primary"></div>
<span>
Not Applicable ({globalStatusCounts["not-applicable"]})
</span>
</div>
)}
{globalStatusCounts["not-started"] > 0 && (
<div className="flex items-center gap-1.5 text-muted-foreground">
<div className="w-3 h-3 rounded-full bg-gray-200"></div>
<div className="flex items-center gap-1.5 text-tertiary">
<div className="w-3 h-3 rounded-full bg-secondary"></div>
<span>Not Started ({globalStatusCounts["not-started"]})</span>
</div>
)}
@@ -476,14 +476,14 @@ function MitigationListContent({
>
<Card className="border-0 shadow-none">
<CardHeader
className="bg-muted/50 cursor-pointer"
className="bg-subtle-bg/50 cursor-pointer"
onClick={() => toggleCategory(category.id)}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<CardTitle>{category.name}</CardTitle>
</div>
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<div className="flex items-center gap-2 text-sm text-tertiary">
<span>
{category.doneCount} / {category.totalCount}
</span>
@@ -502,7 +502,7 @@ function MitigationListContent({
<div className="w-full">
<table className="w-full">
<thead>
<tr className="bg-muted/30 text-sm font-medium text-muted-foreground">
<tr className="bg-subtle-bg/30 text-sm font-medium text-tertiary">
<th className="w-24 px-4 py-2 text-left">
Importance
</th>
@@ -518,7 +518,7 @@ function MitigationListContent({
{category.mitigations.map((mitigation) => (
<tr
key={mitigation.id || Math.random().toString()}
className="hover:bg-muted/50 cursor-pointer"
className="hover:bg-h-subtle-bg cursor-pointer"
onClick={() => {
if (mitigation?.id) {
// Store this category in the hash
@@ -570,7 +570,7 @@ function MitigationListContent({
</table>
</div>
) : (
<div className="flex items-center justify-center p-6 text-center text-muted-foreground">
<div className="flex items-center justify-center p-6 text-center text-tertiary">
No mitigations in this category
</div>
)}

View File

@@ -12,9 +12,9 @@ export function MitigationViewSkeleton() {
<PageTemplateSkeleton
actions={
<div className="flex items-center gap-2 w-1/3">
<div className="bg-muted animate-pulse h-8 w-1/3 rounded-lg" />
<div className="bg-muted animate-pulse h-8 w-1/3 rounded-lg" />
<div className="bg-muted animate-pulse h-8 w-1/3 rounded-full" />
<div className="bg-subtle-bg animate-pulse h-8 w-1/3 rounded-lg" />
<div className="bg-subtle-bg animate-pulse h-8 w-1/3 rounded-lg" />
<div className="bg-subtle-bg animate-pulse h-8 w-1/3 rounded-full" />
</div>
}
>
@@ -22,8 +22,8 @@ export function MitigationViewSkeleton() {
{[1, 2, 3].map((i) => (
<Card key={i}>
<CardContent className="p-6">
<div className="h-6 w-48 bg-muted animate-pulse rounded mb-2" />
<div className="h-4 w-full bg-muted animate-pulse rounded" />
<div className="h-6 w-48 bg-subtle-bg animate-pulse rounded mb-2" />
<div className="h-4 w-full bg-subtle-bg animate-pulse rounded" />
</CardContent>
</Card>
))}

View File

@@ -631,20 +631,20 @@ function MitigationViewContent({
};
const getStateColor = (state: string | undefined): string => {
if (!state) return "bg-gray-100 text-gray-800";
if (!state) return "bg-secondary-bg text-primary";
const upperState = state.toUpperCase();
if (upperState === "NOT_STARTED") return "bg-gray-100 text-gray-800";
if (upperState === "NOT_STARTED") return "bg-secondary-bg text-primary";
if (upperState === "IN_PROGRESS") return "bg-blue-100 text-blue-800";
if (upperState === "NOT_APPLICABLE") return "bg-purple-100 text-purple-800";
if (upperState === "IMPLEMENTED") return "bg-green-100 text-green-800";
return "bg-gray-100 text-gray-800";
return "bg-secondary-bg text-primary";
};
const getImportanceColor = (importance: string | undefined): string => {
if (!importance) return "bg-gray-100 text-gray-800";
if (!importance) return "bg-secondary-bg text-primary";
const upperImportance = importance.toUpperCase();
@@ -652,7 +652,7 @@ function MitigationViewContent({
if (upperImportance === "PREFERRED") return "bg-orange-100 text-orange-800";
if (upperImportance === "ADVANCED") return "bg-blue-100 text-blue-800";
return "bg-gray-100 text-gray-800";
return "bg-secondary-bg text-primary";
};
const [updateTask] = useMutation<MitigationViewUpdateTaskStateMutationType>(
@@ -1214,7 +1214,7 @@ function MitigationViewContent({
} else if (mimeType.includes("excel") || mimeType.includes("spreadsheet")) {
return <FileText className="w-4 h-4 text-green-600" />;
} else {
return <FileGeneric className="w-4 h-4 text-gray-500" />;
return <FileGeneric className="w-4 h-4 text-secondary" />;
}
};
@@ -1891,18 +1891,16 @@ function MitigationViewContent({
title={data.mitigation.name ?? ""}
actions={
<div className="flex items-center gap-2">
<Button variant="outline" size="sm" onClick={handleEditMitigation}>
Edit Mitigation
</Button>
<Button onClick={handleEditMitigation}>Edit Mitigation</Button>
<Select
defaultValue={data.mitigation.state}
onValueChange={handleMitigationStateChange}
>
<SelectTrigger className="w-[160px] h-8 text-sm">
<SelectTrigger className="w-[160px] h-10 text-sm">
<div
className={`${getStateColor(
data.mitigation.state
)} px-2 py-0.5 rounded-full text-sm w-full text-center`}
)} px-2 py-0.5 rounded-sm text-sm w-full text-center`}
>
{formatState(data.mitigation.state)}
</div>
@@ -1927,7 +1925,7 @@ function MitigationViewContent({
<div className="space-y-4 mb-8">
<Card className="mt-4">
<CardContent className="pt-6">
<div className="prose prose-gray prose-sm md:prose-base text-gray-600 max-w-3xl">
<div className="prose prose-gray prose-sm md:prose-base text-secondary max-w-3xl">
<ReactMarkdown>{data.mitigation.description}</ReactMarkdown>
</div>
</CardContent>
@@ -1939,8 +1937,9 @@ function MitigationViewContent({
defaultValue="tasks"
value={mainContentTab}
onValueChange={setMainContentTab}
className="mb-4"
>
<TabsList className="mb-4">
<TabsList className="border-b w-full p-0 h-auto">
<TabsTrigger value="tasks" className="flex items-center gap-2">
<Check className="w-4 h-4" />
Tasks
@@ -2005,7 +2004,7 @@ function MitigationViewContent({
<div className="flex items-center space-x-4 mb-4">
<div className="flex-1">
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-tertiary" />
<Input
placeholder="Search controls by ID, name, or description..."
value={controlSearchQuery}
@@ -2048,7 +2047,7 @@ function MitigationViewContent({
) : (
<div className="grid grid-cols-1 gap-2 max-h-[50vh] overflow-y-auto pr-2">
{filteredControls().length === 0 ? (
<div className="text-center py-8 text-gray-500">
<div className="text-center py-8 text-secondary">
No controls found. Try adjusting your search or select
a different framework.
</div>
@@ -2084,7 +2083,7 @@ function MitigationViewContent({
{control.name}
</h3>
{control.description && (
<p className="text-sm text-gray-500 mt-1 line-clamp-2">
<p className="text-sm text-secondary mt-1 line-clamp-2">
{control.description}
</p>
)}
@@ -2168,7 +2167,7 @@ function MitigationViewContent({
{getLinkedControls().map((control: ControlNode) => (
<tr
key={control.id}
className="border-b hover:bg-gray-50"
className="border-b hover:bg-invert-bg"
>
<td className="py-3 px-4">
<div className="font-mono text-sm px-1.5 py-0.5 rounded-sm bg-lime-100 border border-lime-200 text-lime-800 font-bold inline-block">
@@ -2195,7 +2194,7 @@ function MitigationViewContent({
</table>
</div>
) : (
<div className="text-center py-8 text-gray-500">
<div className="text-center py-8 text-secondary">
No controls linked to this mitigation yet. Click &quot;Map
to Controls&quot; to link controls.
</div>
@@ -2211,7 +2210,7 @@ function MitigationViewContent({
<div className="flex items-center justify-between mb-6">
<h2 className="text-xl font-semibold">Tasks</h2>
<div className="flex items-center gap-3">
<div className="text-sm text-gray-500 flex items-center bg-gray-50 px-3 py-1.5 rounded-md border border-gray-200">
<div className="text-sm text-secondary flex items-center bg-invert-bg px-3 py-1.5 rounded-md border border-mid-b">
<FileIcon className="w-4 h-4 mr-2 text-blue-500" />
<span>Drag & drop files onto tasks to add evidence</span>
</div>
@@ -2269,7 +2268,7 @@ function MitigationViewContent({
}
placeholder="Days"
/>
<p className="text-xs text-gray-500 mt-1">Days</p>
<p className="text-xs text-secondary mt-1">Days</p>
</div>
<div className="w-full">
<Input
@@ -2282,7 +2281,7 @@ function MitigationViewContent({
}
placeholder="Hours"
/>
<p className="text-xs text-gray-500 mt-1">Hours</p>
<p className="text-xs text-secondary mt-1">Hours</p>
</div>
<div className="w-full">
<Input
@@ -2295,7 +2294,7 @@ function MitigationViewContent({
}
placeholder="Minutes"
/>
<p className="text-xs text-gray-500 mt-1">
<p className="text-xs text-secondary mt-1">
Minutes
</p>
</div>
@@ -2319,10 +2318,10 @@ function MitigationViewContent({
{tasks.map((task) => (
<div
key={task?.id}
className="rounded-md overflow-hidden border border-gray-200"
className="rounded-md overflow-hidden border border-mid-b"
>
<div
className={`flex items-center gap-3 py-4 px-2 hover:bg-gray-50 group relative transition-all duration-200 ${
className={`flex items-center gap-3 py-4 px-2 hover:bg-invert-bg group relative transition-all duration-200 ${
isDraggingFile && draggedOverTaskId !== task?.id
? "border-dashed border-blue-300 bg-blue-50 bg-opacity-30"
: ""
@@ -2365,16 +2364,14 @@ function MitigationViewContent({
<div className="flex flex-col items-center gap-3 text-blue-600">
<Loader2 className="w-10 h-10 animate-spin text-blue-500" />
<p className="font-medium">Adding document...</p>
<p className="text-sm text-gray-500">Please wait</p>
<p className="text-sm text-secondary">Please wait</p>
</div>
</div>
)}
<div
className={`w-5 h-5 rounded border flex items-center justify-center cursor-pointer ${
task?.state === "DONE"
? "border-gray-400 bg-gray-100"
: "border-gray-300"
task?.state === "DONE" && "border-strong-b"
} ${isDraggingFile ? "opacity-50" : ""}`}
onClick={(e) => {
e.stopPropagation(); // Prevent task selection when checkbox is clicked
@@ -2384,7 +2381,7 @@ function MitigationViewContent({
}}
>
{task?.state === "DONE" && (
<CheckCircle2 className="w-4 h-4 text-gray-500" />
<CheckCircle2 className="w-4 h-4 text-secondary" />
)}
</div>
<div
@@ -2395,9 +2392,8 @@ function MitigationViewContent({
<div>
<h3
className={`text-sm ${
task?.state === "DONE"
? "text-gray-500 line-through"
: "text-gray-900"
task?.state === "DONE" &&
"text-secondary line-through"
}`}
>
{task?.name}
@@ -2406,7 +2402,7 @@ function MitigationViewContent({
<p
className={`text-xs mt-1 flex items-center ${
task?.state === "DONE"
? "text-gray-400 line-through"
? "text-tertiary line-through"
: "text-blue-500"
}`}
>
@@ -2417,7 +2413,7 @@ function MitigationViewContent({
</p>
)}
{task?.assignedTo && (
<p className="text-xs mt-1 flex items-center text-gray-600">
<p className="text-xs mt-1 flex items-center text-secondary">
<User className="w-3 h-3 mr-1" />
<span>{task.assignedTo.fullName}</span>
</p>
@@ -2439,7 +2435,7 @@ function MitigationViewContent({
<PopoverTrigger asChild>
<button
type="button"
className="text-gray-400 hover:text-blue-600"
className="text-tertiary hover:text-blue-600"
onClick={(e) => {
e.stopPropagation();
if (task?.id) {
@@ -2461,12 +2457,12 @@ function MitigationViewContent({
{task?.assignedTo ? (
<div className="p-4 space-y-4">
<div className="flex items-center gap-2">
<User className="w-4 h-4 text-gray-500" />
<User className="w-4 h-4 text-secondary" />
<div className="text-sm">
<p className="font-medium">
{task.assignedTo.fullName}
</p>
<p className="text-xs text-gray-500">
<p className="text-xs text-secondary">
{task.assignedTo.primaryEmailAddress}
</p>
</div>
@@ -2505,7 +2501,7 @@ function MitigationViewContent({
}}
/>
</div>
<div className="px-3 py-2 text-xs text-gray-500">
<div className="px-3 py-2 text-xs text-secondary">
Click on a person to assign them to this task
</div>
<div className="py-1">
@@ -2574,7 +2570,7 @@ function MitigationViewContent({
<p className="font-medium">
{edge.node.fullName}
</p>
<p className="text-xs text-gray-500">
<p className="text-xs text-secondary">
{edge.node.primaryEmailAddress}
</p>
</div>
@@ -2591,7 +2587,7 @@ function MitigationViewContent({
<button
type="button"
className="text-gray-400 hover:text-blue-600"
className="text-tertiary hover:text-blue-600"
onClick={(e) => {
e.stopPropagation();
if (task?.id && task?.name) {
@@ -2604,7 +2600,7 @@ function MitigationViewContent({
</button>
<button
type="button"
className="text-gray-400 hover:text-red-600"
className="text-tertiary hover:text-red-600"
onClick={(e) => {
e.stopPropagation();
if (task?.id && task?.name) {
@@ -2623,7 +2619,7 @@ function MitigationViewContent({
task.evidences.edges.length > 0 && (
<>
<div
className="flex items-center justify-between px-4 py-2 border-t border-gray-200 bg-gray-50 cursor-pointer hover:bg-gray-100"
className="flex items-center justify-between px-4 py-2 border-t border-mid-b bg-invert-bg cursor-pointer hover:bg-secondary-bg"
onClick={(e) => {
e.stopPropagation(); // Prevent task selection
if (task.id) toggleEvidenceList(task.id);
@@ -2631,7 +2627,7 @@ function MitigationViewContent({
>
<div className="flex items-center gap-2">
<FileText className="w-4 h-4 text-blue-500" />
<span className="text-xs text-gray-600">
<span className="text-xs text-secondary">
{task.evidences.edges.length}{" "}
{task.evidences.edges.length === 1
? "Evidence"
@@ -2639,14 +2635,14 @@ function MitigationViewContent({
</span>
</div>
{expandedEvidenceTaskId === task.id ? (
<ChevronUp className="w-4 h-4 text-gray-500" />
<ChevronUp className="w-4 h-4 text-secondary" />
) : (
<ChevronDown className="w-4 h-4 text-gray-500" />
<ChevronDown className="w-4 h-4 text-secondary" />
)}
</div>
{expandedEvidenceTaskId === task.id && (
<div className="bg-white border-t border-gray-200 p-3 space-y-2.5">
<div className="bg-white border-t border-mid-b p-3 space-y-2.5">
{task.evidences.edges.map((edge) => {
if (!edge) return null;
const evidence = edge.node;
@@ -2655,17 +2651,17 @@ function MitigationViewContent({
return (
<div
key={evidence.id}
className="flex items-center justify-between p-3 rounded-md border border-gray-200 hover:border-blue-300 hover:shadow-sm transition-all bg-gray-50"
className="flex items-center justify-between p-3 rounded-md border border-mid-b hover:border-blue-300 hover:shadow-sm transition-all bg-invert-bg"
>
<div className="flex items-center gap-3">
<div className="bg-white p-2 rounded-md border border-gray-200">
<div className="bg-white p-2 rounded-md border border-mid-b">
{getFileIcon(
evidence.mimeType,
evidence.type
)}
</div>
<div>
<div className="text-sm font-medium text-gray-800 flex items-center gap-2">
<div className="text-sm font-medium text-primary flex items-center gap-2">
{evidence.filename}
{evidence.state === "REQUESTED" && (
<Badge
@@ -2676,14 +2672,14 @@ function MitigationViewContent({
</Badge>
)}
</div>
<div className="text-xs text-gray-500 flex items-center gap-2 mt-0.5">
<div className="text-xs text-secondary flex items-center gap-2 mt-0.5">
{evidence.state === "REQUESTED" ? (
<span className="italic text-yellow-600">
Waiting for fulfillment
{evidence.description && (
<>
<span className="mx-1">•</span>
<span className="text-gray-600 not-italic">
<span className="text-secondary not-italic">
{evidence.description}
</span>
</>
@@ -2691,7 +2687,7 @@ function MitigationViewContent({
</span>
) : evidence.type === "FILE" ? (
<>
<span className="font-medium text-gray-600">
<span className="font-medium text-secondary">
{formatFileSize(evidence.size)}
</span>
<span>•</span>
@@ -2802,7 +2798,7 @@ function MitigationViewContent({
))}
{tasks.length === 0 && (
<div className="text-center py-12 bg-gray-50 rounded-lg border border-gray-200">
<div className="text-center py-12 bg-invert-bg rounded-lg border border-mid-b">
<p>No tasks yet. Click &quot;Add Task&quot; to create one.</p>
</div>
)}
@@ -2843,7 +2839,7 @@ function MitigationViewContent({
{risksData.mitigation.risks.edges.map(({ node }) => (
<tr
key={node.id}
className="border-b hover:bg-gray-50"
className="border-b hover:bg-invert-bg"
onClick={() =>
navigate(
`/organizations/${organizationId}/risks/${node.id}`
@@ -2883,7 +2879,7 @@ function MitigationViewContent({
</table>
</div>
) : (
<div className="text-center py-8 text-gray-500">
<div className="text-center py-8 text-secondary">
No risks linked to this mitigation yet.
</div>
)}
@@ -2906,7 +2902,7 @@ function MitigationViewContent({
<SheetTitle className="text-xl font-semibold">
{selectedTask.name}
</SheetTitle>
<SheetClose className="rounded-full p-1 hover:bg-gray-100">
<SheetClose className="rounded-full p-1 hover:bg-secondary-bg">
<X className="h-5 w-5" />
</SheetClose>
</div>
@@ -2929,7 +2925,7 @@ function MitigationViewContent({
</div>
{!isEditingDuration ? (
<div
className="text-sm text-gray-500 flex items-center hover:bg-gray-100 px-2 py-1 rounded-md cursor-pointer"
className="text-sm text-secondary flex items-center hover:bg-secondary-bg px-2 py-1 rounded-md cursor-pointer"
onClick={() =>
startEditingDuration(selectedTask.timeEstimate)
}
@@ -2954,7 +2950,7 @@ function MitigationViewContent({
className="w-12 p-1 text-xs border rounded"
placeholder="0"
/>
<span className="text-xs text-gray-500">d</span>
<span className="text-xs text-secondary">d</span>
</div>
<div className="flex items-center gap-1">
<input
@@ -2968,7 +2964,7 @@ function MitigationViewContent({
className="w-12 p-1 text-xs border rounded"
placeholder="0"
/>
<span className="text-xs text-gray-500">h</span>
<span className="text-xs text-secondary">h</span>
</div>
<div className="flex items-center gap-1">
<input
@@ -2982,7 +2978,7 @@ function MitigationViewContent({
className="w-12 p-1 text-xs border rounded"
placeholder="0"
/>
<span className="text-xs text-gray-500">m</span>
<span className="text-xs text-secondary">m</span>
</div>
<button
className="p-1 text-sm text-blue-600 hover:text-blue-800"
@@ -2991,7 +2987,7 @@ function MitigationViewContent({
Save
</button>
<button
className="p-1 text-sm text-gray-500 hover:text-gray-700"
className="p-1 text-sm text-secondary hover:text-primary"
onClick={() => setIsEditingDuration(false)}
>
Cancel
@@ -3004,10 +3000,10 @@ function MitigationViewContent({
{/* Task description */}
{selectedTask.description && (
<div className="space-y-2">
<h3 className="text-sm font-medium text-gray-600">
<h3 className="text-sm font-medium text-secondary">
Description
</h3>
<div className="prose prose-sm max-w-none p-3 bg-gray-50 rounded-md border border-gray-100">
<div className="prose prose-sm max-w-none p-3 bg-invert-bg rounded-md border border-low-b">
<ReactMarkdown>{selectedTask.description}</ReactMarkdown>
</div>
</div>
@@ -3015,11 +3011,11 @@ function MitigationViewContent({
{/* Assigned person */}
<div className="space-y-2">
<h3 className="text-sm font-medium text-gray-600">
<h3 className="text-sm font-medium text-secondary">
Assignment
</h3>
{selectedTask.assignedTo ? (
<div className="flex items-center justify-between p-3 bg-gray-50 rounded-md border border-gray-100">
<div className="flex items-center justify-between p-3 bg-invert-bg rounded-md border border-low-b">
<div className="flex items-center gap-3">
<div className="bg-blue-100 text-blue-700 rounded-full p-2">
<User className="w-5 h-5" />
@@ -3028,7 +3024,7 @@ function MitigationViewContent({
<p className="font-medium">
{selectedTask.assignedTo.fullName}
</p>
<p className="text-xs text-gray-500">
<p className="text-xs text-secondary">
{selectedTask.assignedTo.primaryEmailAddress}
</p>
</div>
@@ -3044,8 +3040,8 @@ function MitigationViewContent({
</Button>
</div>
) : (
<div className="flex items-center justify-between p-3 bg-gray-50 rounded-md border border-gray-100">
<p className="text-gray-500">
<div className="flex items-center justify-between p-3 bg-invert-bg rounded-md border border-low-b">
<p className="text-secondary">
No one is assigned to this task
</p>
<Popover>
@@ -3115,7 +3111,7 @@ function MitigationViewContent({
<p className="font-medium">
{edge.node.fullName}
</p>
<p className="text-xs text-gray-500">
<p className="text-xs text-secondary">
{edge.node.primaryEmailAddress}
</p>
</div>
@@ -3134,7 +3130,7 @@ function MitigationViewContent({
{/* Evidence section */}
<div className="space-y-3">
<div className="flex items-center justify-between">
<h3 className="text-sm font-medium text-gray-600">
<h3 className="text-sm font-medium text-secondary">
Evidence
</h3>
<Button
@@ -3161,14 +3157,14 @@ function MitigationViewContent({
return (
<div
key={evidence.id}
className="flex items-center justify-between p-3 rounded-md border border-gray-200 hover:border-blue-300 hover:shadow-sm transition-all bg-gray-50"
className="flex items-center justify-between p-3 rounded-md border border-mid-b hover:border-blue-300 hover:shadow-sm transition-all bg-invert-bg"
>
<div className="flex items-center gap-3">
<div className="bg-white p-2 rounded-md border border-gray-200">
<div className="bg-white p-2 rounded-md border border-mid-b">
{getFileIcon(evidence.mimeType, evidence.type)}
</div>
<div>
<div className="text-sm font-medium text-gray-800 flex items-center gap-2">
<div className="text-sm font-medium text-primary flex items-center gap-2">
{evidence.filename}
{evidence.state === "REQUESTED" && (
<Badge
@@ -3179,14 +3175,14 @@ function MitigationViewContent({
</Badge>
)}
</div>
<div className="text-xs text-gray-500 flex items-center gap-2 mt-0.5">
<div className="text-xs text-secondary flex items-center gap-2 mt-0.5">
{evidence.state === "REQUESTED" ? (
<span className="italic text-yellow-600">
Waiting for fulfillment
{evidence.description && (
<>
<span className="mx-1">•</span>
<span className="text-gray-600 not-italic">
<span className="text-secondary not-italic">
{evidence.description}
</span>
</>
@@ -3194,7 +3190,7 @@ function MitigationViewContent({
</span>
) : evidence.type === "FILE" ? (
<>
<span className="font-medium text-gray-600">
<span className="font-medium text-secondary">
{formatFileSize(evidence.size)}
</span>
<span>•</span>
@@ -3296,12 +3292,12 @@ function MitigationViewContent({
);
})
) : (
<div className="text-center py-6 bg-gray-50 rounded-md border border-dashed border-gray-200">
<FileIcon className="w-8 h-8 text-gray-400 mx-auto mb-2" />
<p className="text-sm text-gray-500">
<div className="text-center py-6 bg-invert-bg rounded-md border border-dashed border-mid-b">
<FileIcon className="w-8 h-8 text-tertiary mx-auto mb-2" />
<p className="text-sm text-secondary">
No evidence attached yet
</p>
<p className="text-xs text-gray-400 mt-1">
<p className="text-xs text-tertiary mt-1">
Upload files or add links to provide evidence
</p>
</div>
@@ -3492,7 +3488,7 @@ function MitigationViewContent({
<span>{previewEvidence?.filename}</span>
<button
onClick={() => setIsPreviewModalOpen(false)}
className="rounded-full p-1 hover:bg-gray-100"
className="rounded-full p-1 hover:bg-secondary-bg"
>
<X className="w-5 h-5" />
</button>
@@ -3502,11 +3498,11 @@ function MitigationViewContent({
from here.
</DialogDescription>
</DialogHeader>
<div className="flex flex-col items-center justify-center min-h-[300px] bg-gray-50 rounded-md p-4">
<div className="flex flex-col items-center justify-center min-h-[300px] bg-invert-bg rounded-md p-4">
{isLoadingFileUrl ? (
<div className="flex flex-col items-center gap-2">
<Loader2 className="w-8 h-8 animate-spin text-blue-500" />
<p className="text-gray-500">Loading preview...</p>
<p className="text-secondary">Loading preview...</p>
</div>
) : previewEvidence?.fileUrl ? (
previewEvidence.mimeType.startsWith("image/") ? (
@@ -3523,8 +3519,8 @@ function MitigationViewContent({
/>
) : (
<div className="flex flex-col items-center gap-4">
<FileGeneric className="w-16 h-16 text-gray-400" />
<p className="text-gray-600">
<FileGeneric className="w-16 h-16 text-tertiary" />
<p className="text-secondary">
Preview not available for this file type
</p>
<Button
@@ -3540,8 +3536,8 @@ function MitigationViewContent({
)
) : (
<div className="flex flex-col items-center gap-2">
<FileGeneric className="w-12 h-12 text-gray-400" />
<p className="text-gray-500">Failed to load preview</p>
<FileGeneric className="w-12 h-12 text-tertiary" />
<p className="text-secondary">Failed to load preview</p>
</div>
)}
</div>

View File

@@ -12,7 +12,7 @@ export function NewMitigationViewSkeleton() {
title="New Mitigation"
description="Add a new mitigation. You will be able to link it to control and risks"
>
<div className="max-w-2xl aspect-square bg-muted rounded-xl animate-pulse" />
<div className="max-w-2xl aspect-square bg-subtle-bg rounded-xl animate-pulse" />
</PageTemplateSkeleton>
);
}

View File

@@ -152,7 +152,7 @@ export default function NewMitigationView() {
"rounded-full cursor-pointer px-4 py-1 text-sm transition-colors",
formData.importance === "MANDATORY"
? "bg-red-100 text-red-900 ring-2 ring-red-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
: "bg-secondary-bg text-primary hover:bg-h-secondary-bg"
)}
>
Mandatory
@@ -164,7 +164,7 @@ export default function NewMitigationView() {
"rounded-full cursor-pointer px-4 py-1 text-sm transition-colors",
formData.importance === "PREFERRED"
? "bg-yellow-100 text-yellow-900 ring-2 ring-yellow-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
: "bg-secondary-bg text-primary hover:bg-h-secondary-bg"
)}
>
Preferred
@@ -176,7 +176,7 @@ export default function NewMitigationView() {
"rounded-full cursor-pointer px-4 py-1 text-sm transition-colors",
formData.importance === "ADVANCED"
? "bg-blue-100 text-blue-900 ring-2 ring-blue-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
: "bg-secondary-bg text-primary hover:bg-h-secondary-bg"
)}
>
Advanced

View File

@@ -12,7 +12,7 @@ export function NewPeopleViewSkeleton() {
title="New Person"
description="Add a new person interacting with organization"
>
<div className="max-w-2xl aspect-square bg-muted rounded-xl animate-pulse" />
<div className="max-w-2xl aspect-square bg-subtle-bg rounded-xl animate-pulse" />
</PageTemplateSkeleton>
);
}

View File

@@ -49,7 +49,7 @@ function EditableField({
return (
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<Label className="text-sm">{label}</Label>
</div>
<div className="space-y-2">
@@ -59,7 +59,7 @@ function EditableField({
onChange={(e) => onChange(e.target.value)}
required={required}
/>
{helpText && <p className="text-sm text-gray-500">{helpText}</p>}
{helpText && <p className="text-sm text-secondary">{helpText}</p>}
</div>
</div>
);
@@ -175,7 +175,7 @@ function NewPeopleViewContent() {
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<Label className="text-sm">Additional Email Addresses</Label>
</div>
<div className="space-y-2">
@@ -224,7 +224,7 @@ function NewPeopleViewContent() {
<div className="space-y-4">
<div className="space-y-2">
<h2 className="text-lg font-medium">Additional Information</h2>
<p className="text-sm text-gray-500">
<p className="text-sm text-secondary">
Additional details about the person
</p>
</div>
@@ -232,7 +232,7 @@ function NewPeopleViewContent() {
<div className="space-y-4">
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<Label className="text-sm">Kind</Label>
</div>
<div className="flex gap-2">
@@ -243,7 +243,7 @@ function NewPeopleViewContent() {
"rounded-full px-4 py-1 text-sm transition-colors",
formData.kind === "EMPLOYEE"
? "bg-blue-100 text-blue-900 ring-2 ring-blue-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
: "bg-secondary-bg text-primary hover:bg-h-secondary-bg"
)}
>
Employee
@@ -255,7 +255,7 @@ function NewPeopleViewContent() {
"rounded-full px-4 py-1 text-sm transition-colors",
formData.kind === "CONTRACTOR"
? "bg-purple-100 text-purple-900 ring-2 ring-purple-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
: "bg-secondary-bg text-primary hover:bg-h-secondary-bg"
)}
>
Contractor
@@ -269,7 +269,7 @@ function NewPeopleViewContent() {
"rounded-full px-4 py-1 text-sm transition-colors",
formData.kind === "SERVICE_ACCOUNT"
? "bg-green-100 text-green-900 ring-2 ring-green-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
: "bg-secondary-bg text-primary hover:bg-h-secondary-bg"
)}
>
Service Account
@@ -286,7 +286,7 @@ function NewPeopleViewContent() {
</Button>
<Button
type="submit"
className="bg-primary text-primary-foreground hover:bg-primary/90"
className="bg-primary text-invert hover:bg-primary/90"
>
Create Person
</Button>

View File

@@ -11,18 +11,20 @@ export function PeopleListViewSkeleton() {
<PageTemplateSkeleton
title="People"
description="Keep track of your company's workforce and their progress towards completing tasks assigned to them."
actions={<div className="bg-muted animate-pulse h-9 w-1/6 rounded-lg" />}
actions={
<div className="bg-subtle-bg animate-pulse h-9 w-1/6 rounded-lg" />
}
>
<div className="space-y-6">
<div className="rounded-xl border bg-card p-4 space-y-2">
<div className="h-5 w-32 bg-muted animate-pulse rounded" />
<div className="h-10 w-full bg-muted animate-pulse rounded" />
<div className="rounded-xl border bg-level-1 p-4 space-y-2">
<div className="h-5 w-32 bg-subtle-bg animate-pulse rounded" />
<div className="h-10 w-full bg-subtle-bg animate-pulse rounded" />
</div>
<div className="space-y-2">
{[1, 2, 3].map((i) => (
<div
key={i}
className="h-[72px] bg-muted animate-pulse rounded-xl"
className="h-[72px] bg-subtle-bg animate-pulse rounded-xl"
/>
))}
</div>

View File

@@ -179,12 +179,7 @@ function PeopleListContent({
description="Keep track of your company's workforce and their progress
towards completing tasks assigned to them."
actions={
<Button
asChild
variant="outline"
style={{ borderRadius: "0.5rem" }}
className="gap-2"
>
<Button asChild variant="secondary" className="gap-2">
<Link to={`/organizations/${organizationId}/people/new`}>
<UserPlus className="h-4 w-4" />
Add a person
@@ -200,7 +195,7 @@ function PeopleListContent({
to={`/organizations/${organizationId}/people/${person?.id}`}
className="block"
>
<div className="flex items-center justify-between p-4 rounded-xl border bg-card hover:bg-accent/5 transition-colors">
<div className="flex items-center justify-between p-4 rounded-xl border bg-level-1 hover:bg-accent-bg/5 transition-colors">
<div className="flex items-center gap-3">
<Avatar className="h-8 w-8">
<AvatarFallback>{person?.fullName?.[0]}</AvatarFallback>
@@ -209,8 +204,8 @@ function PeopleListContent({
<p className="font-medium">{person?.fullName}</p>
{person?.primaryEmailAddress && (
<>
<span className="text-muted-foreground">•</span>
<p className="text-sm text-muted-foreground">
<span className="text-tertiary">•</span>
<p className="text-sm text-tertiary">
{person.primaryEmailAddress}
</p>
</>
@@ -218,10 +213,7 @@ function PeopleListContent({
</div>
</div>
<div className="flex items-center gap-2">
<Badge
variant="secondary"
className="bg-lime-9 text-white rounded-full px-3 py-0.5 text-xs font-medium"
>
<Badge className="px-3 py-0.5 text-xs font-medium">
{person?.kind === "EMPLOYEE"
? "Employee"
: person?.kind === "CONTRACTOR"
@@ -233,7 +225,7 @@ function PeopleListContent({
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-muted-foreground hover:bg-transparent hover:[&>svg]:text-destructive"
className="h-8 w-8 text-tertiary hover:bg-transparent hover:[&>svg]:text-danger"
onClick={(e) => {
e.preventDefault();
if (
@@ -254,7 +246,7 @@ function PeopleListContent({
>
<Trash2 className="h-4 w-4 transition-colors" />
</Button>
<ChevronRight className="h-4 w-4 text-muted-foreground" />
<ChevronRight className="h-4 w-4 text-tertiary" />
</div>
</div>
</Link>

View File

@@ -11,12 +11,15 @@ export function PeopleViewSkeleton() {
<PageTemplateSkeleton>
<div className="space-y-6">
<div className="space-y-1">
<div className="h-8 w-48 bg-muted animate-pulse rounded" />
<div className="h-4 w-96 bg-muted animate-pulse rounded" />
<div className="h-8 w-48 bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-96 bg-subtle-bg animate-pulse rounded" />
</div>
<div className="space-y-2">
{[1, 2].map((i) => (
<div key={i} className="h-20 bg-muted animate-pulse rounded-lg" />
<div
key={i}
className="h-20 bg-subtle-bg animate-pulse rounded-lg"
/>
))}
</div>
</div>

View File

@@ -73,7 +73,7 @@ function EditableField({
return (
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<Label className="text-sm">{label}</Label>
</div>
<div className="space-y-2">
@@ -82,7 +82,7 @@ function EditableField({
value={value}
onChange={(e) => onChange(e.target.value)}
/>
{helpText && <p className="text-sm text-gray-500">{helpText}</p>}
{helpText && <p className="text-sm text-secondary">{helpText}</p>}
</div>
</div>
);
@@ -164,7 +164,7 @@ function PeopleViewContent({
return (
<PageTemplate title={formData.fullName}>
<div className="space-y-6">
<div className="mx-auto max-w-4xl space-y-6">
<div className="max-w-4xl space-y-6">
<EditableField
label="Full Name"
value={formData.fullName}
@@ -182,7 +182,7 @@ function PeopleViewContent({
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<Label className="text-sm">Additional Email Addresses</Label>
</div>
<div className="space-y-2">
@@ -229,7 +229,7 @@ function PeopleViewContent({
<div className="space-y-4">
<div className="space-y-2">
<h2 className="text-lg font-medium">Additional Information</h2>
<p className="text-sm text-gray-500">
<p className="text-sm text-secondary">
Additional details about the person
</p>
</div>
@@ -237,7 +237,7 @@ function PeopleViewContent({
<div className="space-y-4">
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<Label className="text-sm">Kind</Label>
</div>
<Select
@@ -266,7 +266,7 @@ function PeopleViewContent({
</Button>
<Button
onClick={handleSave}
className="bg-primary text-primary-foreground hover:bg-primary/90"
className="bg-primary text-invert hover:bg-primary/90"
disabled={!hasChanges}
>
Save Changes

View File

@@ -12,7 +12,7 @@ export function EditPolicyViewSkeleton() {
title="Edit Policy"
description="Edit an existing policy"
>
<div className="bg-muted animate-pulse rounded-lg h-[600px]" />
<div className="bg-subtle-bg animate-pulse rounded-lg h-[600px]" />
</PageTemplateSkeleton>
);
}

View File

@@ -12,7 +12,7 @@ export function NewPolicyViewSkeleton() {
title="New Policy"
description="Add a new policy for your organization"
>
<div className="bg-muted animate-pulse rounded-lg h-[600px]" />
<div className="bg-subtle-bg animate-pulse rounded-lg h-[600px]" />
</PageTemplateSkeleton>
);
}

View File

@@ -12,43 +12,45 @@ export function PolicyListViewSkeleton() {
<PageTemplateSkeleton
title="Policies"
description="Manage your organization's policies"
actions={<div className="bg-muted animate-pulse h-9 w-1/6 rounded-lg" />}
actions={
<div className="bg-subtle-bg animate-pulse h-9 w-1/6 rounded-lg" />
}
>
{/* Search and filter mitigations skeleton */}
<div className="flex flex-col md:flex-row gap-4 mb-6">
<div className="flex-1 h-10 bg-muted animate-pulse rounded" />
<div className="flex-1 h-10 bg-subtle-bg animate-pulse rounded" />
<div className="flex gap-2">
<div className="h-10 w-[180px] bg-muted animate-pulse rounded" />
<div className="h-10 w-24 bg-muted animate-pulse rounded" />
<div className="h-10 w-[180px] bg-subtle-bg animate-pulse rounded" />
<div className="h-10 w-24 bg-subtle-bg animate-pulse rounded" />
</div>
</div>
{/* Results summary skeleton */}
<div className="mb-4 h-4 w-48 bg-muted animate-pulse rounded" />
<div className="mb-4 h-4 w-48 bg-subtle-bg animate-pulse rounded" />
{/* Policy grid skeleton */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
{[1, 2, 3, 4, 5, 6].map((i) => (
<Card key={i} className="bg-card/50 h-full flex flex-col">
<Card key={i} className="bg-level-1/50 h-full flex flex-col">
<CardContent className="p-6 flex-grow">
<div className="flex justify-between items-start mb-3">
<div className="h-7 w-48 bg-muted animate-pulse rounded" />
<div className="h-6 w-20 bg-muted animate-pulse rounded-full" />
<div className="h-7 w-48 bg-subtle-bg animate-pulse rounded" />
<div className="h-6 w-20 bg-subtle-bg animate-pulse rounded-full" />
</div>
<div className="space-y-2 mb-4">
<div className="h-4 w-full bg-muted animate-pulse rounded" />
<div className="h-4 w-full bg-muted animate-pulse rounded" />
<div className="h-4 w-2/3 bg-muted animate-pulse rounded" />
<div className="h-4 w-full bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-full bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-2/3 bg-subtle-bg animate-pulse rounded" />
</div>
<div className="mt-auto space-y-2">
<div className="h-4 w-40 bg-muted animate-pulse rounded" />
<div className="h-4 w-40 bg-muted animate-pulse rounded" />
<div className="h-4 w-40 bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-40 bg-subtle-bg animate-pulse rounded" />
</div>
</CardContent>
<CardFooter className="p-0 border-t">
<div className="w-full grid grid-cols-2">
<div className="h-12 border-r bg-muted/20 animate-pulse" />
<div className="h-12 bg-muted/20 animate-pulse" />
<div className="h-12 border-r bg-subtle-bg/20 animate-pulse" />
<div className="h-12 bg-subtle-bg/20 animate-pulse" />
</div>
</CardFooter>
</Card>

View File

@@ -92,20 +92,20 @@ function PolicyCard({
: "No description available";
return (
<Card className="relative overflow-hidden border bg-card transition-all hover:shadow-md h-full flex flex-col">
<Card className="relative overflow-hidden border transition-all hover:shadow-md h-full flex flex-col">
<CardContent className="p-6 flex-grow">
<div className="flex flex-col h-full">
<div className="flex justify-between items-start mb-3">
<h3 className="font-semibold text-xl">{title}</h3>
{status && (
<Badge
className={`${
variant={
status === "ACTIVE"
? "bg-green-100 text-green-700 hover:bg-green-200"
? "success"
: status === "DRAFT"
? "bg-yellow-100 text-yellow-700 hover:bg-yellow-200"
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
}`}
? "warning"
: "secondary"
}
>
{status === "ACTIVE"
? "Security"
@@ -116,11 +116,11 @@ function PolicyCard({
)}
</div>
<p className="text-muted-foreground text-sm line-clamp-3 mb-4">
<p className="text-tertiary text-sm line-clamp-3 mb-4">
{description}
</p>
<div className="flex items-center gap-2 text-sm text-muted-foreground mt-auto">
<div className="flex items-center gap-2 text-sm text-tertiary mt-auto">
<Clock className="h-4 w-4" />
<span>
Last updated: {format(formattedUpdatedAt, "yyyy-MM-dd")}
@@ -235,7 +235,7 @@ function PolicyListViewContent({
{/* Search and filter mitigations */}
<div className="flex flex-col md:flex-row gap-4 mb-6">
<div className="relative flex-1">
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-tertiary" />
<Input
placeholder="Search policies..."
className="pl-10"
@@ -261,7 +261,7 @@ function PolicyListViewContent({
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="flex items-center gap-2">
<Button variant="secondary" className="flex items-center gap-2">
<ArrowUpDown className="h-4 w-4" />
Sort
</Button>
@@ -291,7 +291,7 @@ function PolicyListViewContent({
</div>
{/* Results summary */}
<div className="mb-4 text-sm text-muted-foreground">
<div className="mb-4 text-sm text-tertiary">
Showing {filteredPolicies.length} of {policies.length} policies
</div>
@@ -315,10 +315,10 @@ function PolicyListViewContent({
))}
</div>
) : (
<div className="text-center py-12 border rounded-lg bg-muted/20">
<FileText className="mx-auto h-8 w-8 text-muted-foreground mb-3" />
<div className="text-center py-12 border rounded-lg bg-subtle-bg/20">
<FileText className="mx-auto h-8 w-8 text-tertiary mb-3" />
<h3 className="text-lg font-medium">No policies found</h3>
<p className="text-muted-foreground mb-4">
<p className="text-tertiary mb-4">
{searchQuery || statusFilter !== "ALL"
? "Try adjusting your search or filters"
: "Create your first policy to get started"}

View File

@@ -13,8 +13,8 @@ export function PolicyViewSkeleton() {
withDescription
actions={
<div className="flex gap-2 w-1/3">
<div className="bg-muted animate-pulse h-8 w-1/2 rounded-lg" />
<div className="bg-muted animate-pulse h-8 w-1/2 rounded-lg" />
<div className="bg-subtle-bg animate-pulse h-8 w-1/2 rounded-lg" />
<div className="bg-subtle-bg animate-pulse h-8 w-1/2 rounded-lg" />
</div>
}
>
@@ -25,35 +25,35 @@ export function PolicyViewSkeleton() {
<div className="flex items-center gap-3 mb-4">
<div className="p-2 rounded-md bg-slate-100/50 h-10 w-10 animate-pulse" />
<div className="flex gap-2">
<div className="h-6 w-16 bg-muted animate-pulse rounded-md" />
<div className="h-6 w-20 bg-muted animate-pulse rounded-md" />
<div className="h-6 w-16 bg-muted animate-pulse rounded-md" />
<div className="h-6 w-16 bg-subtle-bg animate-pulse rounded-md" />
<div className="h-6 w-20 bg-subtle-bg animate-pulse rounded-md" />
<div className="h-6 w-16 bg-subtle-bg animate-pulse rounded-md" />
</div>
<div className="ml-auto">
<div className="h-9 w-9 bg-muted animate-pulse rounded-full" />
<div className="h-9 w-9 bg-subtle-bg animate-pulse rounded-full" />
</div>
</div>
<div className="h-8 w-3/4 bg-muted animate-pulse rounded mb-3" />
<div className="h-8 w-3/4 bg-subtle-bg animate-pulse rounded mb-3" />
<div className="space-y-2 mb-6">
<div className="h-4 w-full bg-muted animate-pulse rounded" />
<div className="h-4 w-full bg-muted animate-pulse rounded" />
<div className="h-4 w-2/3 bg-muted animate-pulse rounded" />
<div className="h-4 w-full bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-full bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-2/3 bg-subtle-bg animate-pulse rounded" />
</div>
<div className="flex border-b mb-6">
<div className="px-4 py-2 h-8 w-28 bg-muted animate-pulse rounded" />
<div className="px-4 py-2 h-8 w-28 bg-muted animate-pulse rounded opacity-50" />
<div className="px-4 py-2 h-8 w-28 bg-muted animate-pulse rounded opacity-50" />
<div className="px-4 py-2 h-8 w-28 bg-subtle-bg animate-pulse rounded" />
<div className="px-4 py-2 h-8 w-28 bg-subtle-bg animate-pulse rounded opacity-50" />
<div className="px-4 py-2 h-8 w-28 bg-subtle-bg animate-pulse rounded opacity-50" />
</div>
<div className="space-y-4">
<div className="h-4 w-full bg-muted animate-pulse rounded" />
<div className="h-4 w-full bg-muted animate-pulse rounded" />
<div className="h-4 w-full bg-muted animate-pulse rounded" />
<div className="h-4 w-full bg-muted animate-pulse rounded" />
<div className="h-4 w-3/4 bg-muted animate-pulse rounded" />
<div className="h-4 w-full bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-full bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-full bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-full bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-3/4 bg-subtle-bg animate-pulse rounded" />
</div>
</CardContent>
</Card>
@@ -62,44 +62,44 @@ export function PolicyViewSkeleton() {
<div className="lg:col-span-1">
<Card className="border shadow-sm mb-6">
<CardContent className="p-6">
<div className="h-6 w-32 bg-muted animate-pulse rounded mb-6" />
<div className="h-6 w-32 bg-subtle-bg animate-pulse rounded mb-6" />
<div className="space-y-6">
<div>
<div className="h-4 w-28 bg-muted animate-pulse rounded mb-1" />
<div className="h-5 w-24 bg-muted animate-pulse rounded" />
<div className="h-4 w-28 bg-subtle-bg animate-pulse rounded mb-1" />
<div className="h-5 w-24 bg-subtle-bg animate-pulse rounded" />
</div>
<div>
<div className="h-4 w-28 bg-muted animate-pulse rounded mb-1" />
<div className="h-5 w-24 bg-muted animate-pulse rounded" />
<div className="h-4 w-28 bg-subtle-bg animate-pulse rounded mb-1" />
<div className="h-5 w-24 bg-subtle-bg animate-pulse rounded" />
</div>
<div>
<div className="h-4 w-28 bg-muted animate-pulse rounded mb-1" />
<div className="h-5 w-36 bg-muted animate-pulse rounded" />
<div className="h-4 w-28 bg-subtle-bg animate-pulse rounded mb-1" />
<div className="h-5 w-36 bg-subtle-bg animate-pulse rounded" />
</div>
<hr className="my-4" />
<div>
<div className="h-5 w-32 bg-muted animate-pulse rounded mb-3" />
<div className="h-5 w-32 bg-subtle-bg animate-pulse rounded mb-3" />
<div className="space-y-2">
<div className="h-4 w-48 bg-muted animate-pulse rounded" />
<div className="h-4 w-48 bg-muted animate-pulse rounded" />
<div className="h-4 w-48 bg-subtle-bg animate-pulse rounded" />
<div className="h-4 w-48 bg-subtle-bg animate-pulse rounded" />
</div>
</div>
</div>
</CardContent>
</Card>
<div className="h-10 w-full bg-muted animate-pulse rounded mb-6" />
<div className="h-10 w-full bg-subtle-bg animate-pulse rounded mb-6" />
<Card className="border shadow-sm bg-red-50/30">
<CardContent className="p-6">
<div className="h-5 w-28 bg-muted animate-pulse rounded mb-3" />
<div className="h-16 w-full bg-muted animate-pulse rounded mb-4" />
<div className="h-10 w-full bg-muted animate-pulse rounded" />
<div className="h-5 w-28 bg-subtle-bg animate-pulse rounded mb-3" />
<div className="h-16 w-full bg-subtle-bg animate-pulse rounded mb-4" />
<div className="h-10 w-full bg-subtle-bg animate-pulse rounded" />
</CardContent>
</Card>
</div>

View File

@@ -151,7 +151,7 @@ function PolicyViewContent({
<PageTemplate
title={policy.name ?? ""}
description={
<div className="flex items-center gap-2 text-muted-foreground">
<div className="flex items-center gap-2 text-tertiary">
<Badge variant={policy.status === "ACTIVE" ? "default" : "outline"}>
{policy.status === "ACTIVE" ? "Active" : "Draft"}
</Badge>
@@ -176,7 +176,7 @@ function PolicyViewContent({
}
actions={
<div className="flex gap-2">
<Button variant="outline" size="sm" asChild>
<Button variant="secondary" asChild>
<Link
to={`/organizations/${organizationId}/policies/${policy.id}/edit`}
>
@@ -185,8 +185,6 @@ function PolicyViewContent({
</Link>
</Button>
<Button
variant="outline"
size="sm"
onClick={() => {
// Logic to download policy content as PDF or text
const element = document.createElement("a");
@@ -219,10 +217,10 @@ function PolicyViewContent({
<Badge
className={`px-3 py-1 rounded-md font-medium ${
policy.status === "ACTIVE"
? "bg-green-100 text-green-700 hover:bg-green-200"
? "bg-success-bg text-success hover:bg-h-success-bg"
: policy.status === "DRAFT"
? "bg-yellow-100 text-yellow-700 hover:bg-yellow-200"
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
? "bg-warning-bg text-warning hover:bg-h-warning-bg"
: "bg-secondary-bg text-secondary hover:bg-h-secondary-bg"
}`}
>
{policy.status === "ACTIVE"
@@ -237,7 +235,7 @@ function PolicyViewContent({
<h1 className="text-3xl font-bold mb-3">{policy.name}</h1>
<p className="text-muted-foreground mb-6">
<p className="text-tertiary mb-6">
{getDescription(policy.content)}
</p>
@@ -247,33 +245,33 @@ function PolicyViewContent({
onValueChange={setActiveTab}
className="mb-6"
>
<TabsList className="border-b w-full rounded-none bg-transparent p-0 h-auto">
<TabsList className="border-b w-full rounded-none p-0 h-auto">
<TabsTrigger
value="content"
className={`rounded-none border-b-2 border-transparent px-4 py-2 font-medium ${
className={`px-4 py-2 font-medium ${
activeTab === "content"
? "border-primary text-primary"
: "text-muted-foreground"
: "text-tertiary"
}`}
>
Policy Content
</TabsTrigger>
<TabsTrigger
value="history"
className={`rounded-none border-b-2 border-transparent px-4 py-2 font-medium ${
className={`px-4 py-2 font-medium ${
activeTab === "history"
? "border-primary text-primary"
: "text-muted-foreground"
: "text-tertiary"
}`}
>
Version History
</TabsTrigger>
<TabsTrigger
value="approvals"
className={`rounded-none border-b-2 border-transparent px-4 py-2 font-medium ${
className={`px-4 py-2 font-medium ${
activeTab === "approvals"
? "border-primary text-primary"
: "text-muted-foreground"
: "text-tertiary"
}`}
>
Approvals
@@ -293,7 +291,7 @@ function PolicyViewContent({
<TabsContent value="history" className="pt-6">
<div className="text-center py-12">
<p className="text-muted-foreground">
<p className="text-tertiary">
Version history will be available soon.
</p>
</div>
@@ -301,7 +299,7 @@ function PolicyViewContent({
<TabsContent value="approvals" className="pt-6">
<div className="text-center py-12">
<p className="text-muted-foreground">
<p className="text-tertiary">
Approval workflow will be available soon.
</p>
</div>
@@ -318,7 +316,7 @@ function PolicyViewContent({
<div className="space-y-6">
<div>
<div className="flex items-center gap-2 text-muted-foreground mb-1">
<div className="flex items-center gap-2 text-tertiary mb-1">
<FileText className="h-4 w-4" />
<span className="text-sm">Last Updated</span>
</div>
@@ -326,7 +324,7 @@ function PolicyViewContent({
</div>
<div>
<div className="flex items-center gap-2 text-muted-foreground mb-1">
<div className="flex items-center gap-2 text-tertiary mb-1">
<FileText className="h-4 w-4" />
<span className="text-sm">Review Due</span>
</div>
@@ -338,7 +336,7 @@ function PolicyViewContent({
</div>
<div>
<div className="flex items-center gap-2 text-muted-foreground mb-1">
<div className="flex items-center gap-2 text-tertiary mb-1">
<User className="h-4 w-4" />
<span className="text-sm">Owner</span>
</div>
@@ -364,10 +362,10 @@ function PolicyViewContent({
</Link>
</Button>
<Card className="border shadow-sm mt-6 bg-red-50">
<Card className="border shadow-sm mt-6 bg-danger-bg">
<CardContent className="p-6">
<h3 className="text-red-500 font-semibold mb-3">Danger Zone</h3>
<p className="text-sm text-muted-foreground mb-4">
<h3 className="text-danger font-semibold mb-3">Danger Zone</h3>
<p className="text-sm text-tertiary mb-4">
Permanently delete this policy and all of its data. This action
cannot be undone.
</p>

View File

@@ -10,7 +10,7 @@ export function NewRiskViewSkeleton() {
return (
<PageTemplateSkeleton>
<div className="space-y-2">
<div className="h-96 bg-muted animate-pulse rounded-lg" />
<div className="h-96 bg-subtle-bg animate-pulse rounded-lg" />
</div>
</PageTemplateSkeleton>
);

View File

@@ -277,7 +277,7 @@ export default function NewRiskView() {
))}
</SelectContent>
</Select>
<p className="text-sm text-muted-foreground">
<p className="text-sm text-tertiary">
Select a template to prefill the form or create a custom risk.
</p>
</div>

View File

@@ -11,7 +11,10 @@ export function RiskViewSkeleton() {
<PageTemplateSkeleton>
<div className="space-y-2">
{[1, 2].map((i) => (
<div key={i} className="h-20 bg-muted animate-pulse rounded-lg" />
<div key={i} className="h-20 bg-level-1 rounded-xl">
<div className="h10 animate-pulse rounded-lg" />
<div className="h10 animate-pulse rounded-lg" />
</div>
))}
</div>
</PageTemplateSkeleton>

View File

@@ -287,27 +287,27 @@ function RiskListViewContent({
<div className="w-full overflow-auto">
<table className="w-full caption-bottom text-sm">
<thead className="[&_tr]:border-b">
<tr className="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted">
<th className="h-12 px-4 text-left align-middle font-medium text-muted-foreground w-1/2">
<tr className="border-b transition-colors hover:bg-h-subtle-bg data-[state=selected]:bg-subtle-bg">
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/2">
Name
</th>
<th className="h-12 px-4 text-left align-middle font-medium text-muted-foreground w-1/4">
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/4">
Probability
</th>
<th className="h-12 px-4 text-left align-middle font-medium text-muted-foreground w-1/4">
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-1/4">
Impact
</th>
<th className="h-12 px-4 text-left align-middle font-medium text-muted-foreground w-[80px]">
<th className="h-12 px-4 text-left align-middle font-medium text-tertiary w-[80px]">
Action
</th>
</tr>
</thead>
<tbody className="[&_tr:last-child]:border-0">
{risks.length === 0 ? (
<tr className="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted">
<tr className="border-b transition-colors hover:bg-h-subtle-bg data-[state=selected]:bg-subtle-bg">
<td
colSpan={4}
className="text-center p-4 align-middle text-muted-foreground"
className="text-center p-4 align-middle text-tertiary"
>
No risks found. Create a new risk to get started.
</td>
@@ -316,7 +316,7 @@ function RiskListViewContent({
risks.map((risk) => (
<tr
key={risk.id}
className="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted cursor-pointer"
className="border-b transition-colors hover:bg-h-subtle-bg data-[state=selected]:bg-subtle-bg cursor-pointer"
>
<td className="p-0 align-middle font-medium w-1/2">
<Link
@@ -350,7 +350,7 @@ function RiskListViewContent({
setRiskToDelete({ id: risk.id, name: risk.name });
}}
>
<Trash2 className="h-4 w-4 text-destructive" />
<Trash2 className="h-4 w-4 text-danger" />
</Button>
</td>
</tr>

View File

@@ -10,7 +10,7 @@ export function ShowRiskViewSkeleton() {
return (
<PageTemplateSkeleton>
<div className="space-y-2">
<div className="h-96 bg-muted animate-pulse rounded-lg" />
<div className="h-96 subtle-bg animate-pulse rounded-lg" />
</div>
</PageTemplateSkeleton>
);

View File

@@ -415,7 +415,7 @@ function ShowRiskViewContent({
<CardContent>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
<div>
<h3 className="text-sm font-medium text-gray-500">
<h3 className="text-sm font-medium text-secondary">
Probability
</h3>
<p className="mt-1 text-lg">
@@ -423,19 +423,19 @@ function ShowRiskViewContent({
</p>
</div>
<div>
<h3 className="text-sm font-medium text-gray-500">Impact</h3>
<h3 className="text-sm font-medium text-secondary">Impact</h3>
<p className="mt-1 text-lg">
{(risk.impact! * 100).toFixed(0)}%
</p>
</div>
<div>
<h3 className="text-sm font-medium text-gray-500">Severity</h3>
<h3 className="text-sm font-medium text-secondary">Severity</h3>
<p className="mt-1">
<Badge className={severity.class}>{severity.level}</Badge>
</p>
</div>
<div>
<h3 className="text-sm font-medium text-gray-500">Created</h3>
<h3 className="text-sm font-medium text-secondary">Created</h3>
<p className="mt-1 text-sm">{formatDate(risk.createdAt!)}</p>
</div>
</div>
@@ -490,7 +490,7 @@ function ShowRiskViewContent({
disabled={isUnlinkingMitigation}
title="Unlink mitigation"
>
<Trash2 className="h-4 w-4 text-destructive" />
<Trash2 className="h-4 w-4 text-danger" />
</Button>
</TableCell>
</TableRow>
@@ -499,7 +499,7 @@ function ShowRiskViewContent({
</Table>
</div>
) : (
<div className="text-center py-10 text-gray-500">
<div className="text-center py-10 text-secondary">
<p>No mitigations associated with this risk.</p>
</div>
)}
@@ -510,13 +510,13 @@ function ShowRiskViewContent({
<CardContent className="pt-6">
<div className="space-y-4">
<div>
<h3 className="text-sm font-medium text-gray-500">
<h3 className="text-sm font-medium text-secondary">
Full Description
</h3>
<p className="mt-1">{risk.description}</p>
</div>
<div>
<h3 className="text-sm font-medium text-gray-500">
<h3 className="text-sm font-medium text-secondary">
Last Updated
</h3>
<p className="mt-1">{formatDate(risk.updatedAt!)}</p>
@@ -578,7 +578,7 @@ function ShowRiskViewContent({
<div className="flex flex-row space-x-2">
<div className="flex-1">
<div className="relative">
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
<Search className="absolute left-2 top-2.5 h-4 w-4 text-tertiary" />
<Input
placeholder="Search mitigations..."
className="pl-8"
@@ -629,7 +629,7 @@ function ShowRiskViewContent({
return (
<div
key={mitigation.id}
className="p-4 hover:bg-gray-50"
className="p-4 hover:bg-invert-bg"
>
<div className="flex justify-between">
<div>

View File

@@ -14,18 +14,18 @@ export function VendorListViewSkeleton() {
keep track of their risk and compliance status."
>
<div className="space-y-6">
<div className="rounded-xl border bg-card p-4 space-y-4">
<div className="h-5 w-32 bg-muted animate-pulse rounded" />
<div className="rounded-xl border bg-level-1 p-4 space-y-4">
<div className="h-5 w-32 subtle-bg animate-pulse rounded" />
<div className="flex gap-2">
<div className="h-10 flex-1 bg-muted animate-pulse rounded" />
<div className="h-10 w-32 bg-muted animate-pulse rounded" />
<div className="h-10 flex-1 subtle-bg animate-pulse rounded" />
<div className="h-10 w-32 subtle-bg animate-pulse rounded" />
</div>
</div>
<div className="space-y-2">
{[1, 2, 3].map((i) => (
<div
key={i}
className="h-[72px] bg-muted animate-pulse rounded-xl"
className="h-[72px] subtle-bg animate-pulse rounded-xl"
/>
))}
</div>

View File

@@ -246,7 +246,7 @@ function VendorListContent({
keep track of their risk and compliance status."
>
<div className="space-y-6">
<div className="rounded-xl border bg-card p-4">
<div className="rounded-xl border bg-level-1 p-4">
<div className="flex items-center gap-2 mb-4">
<Store className="h-5 w-5" />
<h3 className="font-medium">Add a vendor</h3>
@@ -276,12 +276,12 @@ function VendorListContent({
{filteredVendors.length > 0 ? (
<div
style={{ borderRadius: "0.3rem" }}
className="absolute top-full left-0 mt-1 w-[calc(100%-100px)] max-h-48 overflow-y-auto border bg-popover shadow-md z-10"
className="absolute top-full left-0 mt-1 w-[calc(100%-100px)] max-h-48 overflow-y-auto border bg-invert-bg shadow-md z-10"
>
{filteredVendors.map((vendor: VendorItem) => (
<button
key={vendor.id}
className="w-full px-3 py-2 text-left hover:bg-accent"
className="w-full px-3 py-2 text-left bg-invert-bg hover:bg-h-subtle-bg"
onClick={() => {
createVendor({
variables: {
@@ -314,10 +314,10 @@ function VendorListContent({
) : (
<div
style={{ borderRadius: "0.3rem" }}
className="absolute top-full left-0 mt-1 w-[calc(100%-100px)] border bg-popover shadow-md z-10"
className="absolute top-full left-0 mt-1 w-[calc(100%-100px)] border bg-level-0 shadow-md z-10"
>
<button
className="w-full px-3 py-2 text-left hover:bg-accent flex items-center gap-2"
className="w-full px-3 py-2 text-left hover:bg-accent-bg flex items-center gap-2"
onClick={() => {
createVendor({
variables: {
@@ -360,7 +360,7 @@ function VendorListContent({
to={`/organizations/${organizationId}/vendors/${vendor?.id}`}
className="block"
>
<div className="flex items-center justify-between p-4 rounded-xl border bg-card hover:bg-accent/5 transition-colors">
<div className="flex items-center justify-between p-4 rounded-xl border bg-level-1 hover:bg-accent-bg/5 transition-colors">
<div className="flex items-center gap-3">
<Avatar className="h-8 w-8">
<AvatarFallback>{vendor?.name?.[0]}</AvatarFallback>
@@ -369,8 +369,8 @@ function VendorListContent({
<p className="font-medium">{vendor?.name}</p>
{vendor?.description && (
<>
<span className="text-muted-foreground">•</span>
<p className="text-sm text-muted-foreground">
<span className="text-tertiary">•</span>
<p className="text-sm text-tertiary">
{vendor.description}
</p>
</>
@@ -382,10 +382,10 @@ function VendorListContent({
variant="secondary"
className={
vendor.riskTier === "CRITICAL"
? "bg-red-100 text-red-900 rounded-full px-3 py-0.5 text-xs font-medium"
? "bg-danger-bg text-danger rounded-full px-3 py-0.5 text-xs font-medium"
: vendor?.riskTier === "SIGNIFICANT"
? "bg-yellow-100 text-yellow-900 rounded-full px-3 py-0.5 text-xs font-medium"
: "bg-green-100 text-green-900 rounded-full px-3 py-0.5 text-xs font-medium"
? "bg-warning-bg text-warning rounded-full px-3 py-0.5 text-xs font-medium"
: "bg-success-bg text-success rounded-full px-3 py-0.5 text-xs font-medium"
}
>
{vendor.riskTier}
@@ -393,7 +393,7 @@ function VendorListContent({
<Button
variant="ghost"
size="icon"
className="h-8 w-8 text-muted-foreground hover:bg-transparent hover:[&>svg]:text-destructive"
className="h-8 w-8 text-tertiary hover:bg-transparent hover:[&>svg]:text-danger"
onClick={(e) => {
e.preventDefault(); // Prevent navigation
if (
@@ -421,7 +421,7 @@ function VendorListContent({
>
<Trash2 className="h-4 w-4 transition-colors" />
</Button>
<ChevronRight className="h-4 w-4 text-muted-foreground" />
<ChevronRight className="h-4 w-4 text-tertiary" />
</div>
</div>
</Link>

View File

@@ -11,7 +11,7 @@ export function VendorViewSkeleton() {
<PageTemplateSkeleton>
<div className="space-y-2">
{[1, 2].map((i) => (
<div key={i} className="h-20 bg-muted animate-pulse rounded-lg" />
<div key={i} className="h-20 subtle-bg animate-pulse rounded-lg" />
))}
</div>
</PageTemplateSkeleton>

View File

@@ -77,7 +77,7 @@ function EditableField({
return (
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<Label className="text-sm">{label}</Label>
</div>
<div className="space-y-2">
@@ -86,7 +86,7 @@ function EditableField({
value={value}
onChange={(e) => onChange(e.target.value)}
/>
{helpText && <p className="text-sm text-gray-500">{helpText}</p>}
{helpText && <p className="text-sm text-secondary">{helpText}</p>}
</div>
</div>
);
@@ -218,7 +218,7 @@ function VendorViewContent({
<div className="space-y-4">
<div className="space-y-2">
<h2 className="text-lg font-medium">Service Information</h2>
<p className="text-sm text-gray-500">
<p className="text-sm text-secondary">
Basic information about the vendor service
</p>
</div>
@@ -242,7 +242,7 @@ function VendorViewContent({
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<Label className="text-sm">Service Criticality</Label>
</div>
<div className="flex gap-2">
@@ -253,8 +253,8 @@ function VendorViewContent({
className={cn(
"rounded-full px-4 py-1 text-sm transition-colors",
formData.serviceCriticality === "LOW"
? "bg-green-100 text-green-900 ring-2 ring-green-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
? "bg-success-bg text-success ring ring-success-b"
: "bg-invert-bg"
)}
>
Low
@@ -266,8 +266,8 @@ function VendorViewContent({
className={cn(
"rounded-full px-4 py-1 text-sm transition-colors",
formData.serviceCriticality === "MEDIUM"
? "bg-yellow-100 text-yellow-900 ring-2 ring-yellow-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
? "bg-warning-bg text-warning ring ring-warning-b"
: "bg-invert-bg"
)}
>
Medium
@@ -279,14 +279,14 @@ function VendorViewContent({
className={cn(
"rounded-full px-4 py-1 text-sm transition-colors",
formData.serviceCriticality === "HIGH"
? "bg-red-100 text-red-900 ring-2 ring-red-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
? "bg-danger-bg text-danger ring ring-danger-b"
: "bg-invert-bg"
)}
>
High
</button>
</div>
<p className="text-sm text-gray-500">
<p className="text-sm text-secondary">
{formData.serviceCriticality === "HIGH" &&
"Critical service - downtime severely impacts end-users"}
{formData.serviceCriticality === "MEDIUM" &&
@@ -298,7 +298,7 @@ function VendorViewContent({
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<HelpCircle className="h-4 w-4 text-tertiary" />
<Label className="text-sm">Risk Tier</Label>
</div>
<div className="flex gap-2">
@@ -307,8 +307,8 @@ function VendorViewContent({
className={cn(
"rounded-full px-4 py-1 text-sm transition-colors",
formData.riskTier === "CRITICAL"
? "bg-red-100 text-red-900 ring-2 ring-red-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
? "bg-danger-bg text-danger ring ring-danger-b"
: "bg-invert-bg"
)}
>
Critical
@@ -318,8 +318,8 @@ function VendorViewContent({
className={cn(
"rounded-full px-4 py-1 text-sm transition-colors",
formData.riskTier === "SIGNIFICANT"
? "bg-yellow-100 text-yellow-900 ring-2 ring-yellow-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
? "bg-warning-bg text-warning ring ring-warning-b"
: "bg-invert-bg"
)}
>
Significant
@@ -329,14 +329,14 @@ function VendorViewContent({
className={cn(
"rounded-full px-4 py-1 text-sm transition-colors",
formData.riskTier === "GENERAL"
? "bg-green-100 text-green-900 ring-2 ring-green-600 ring-offset-2"
: "bg-gray-100 text-gray-900 hover:bg-gray-200"
? "bg-info-bg text-info ring ring-info-b"
: "bg-invert-bg"
)}
>
General
</button>
</div>
<p className="text-sm text-gray-500">
<p className="text-sm text-secondary">
{formData.riskTier === "CRITICAL" &&
"Handles sensitive data, critical for platform operation"}
{formData.riskTier === "SIGNIFICANT" &&
@@ -376,7 +376,7 @@ function VendorViewContent({
</Button>
<Button
onClick={handleSave}
className="bg-primary text-primary-foreground hover:bg-primary/90"
className="bg-primary text-invert hover:bg-primary/90"
disabled={!hasChanges}
>
Save Changes

View File

@@ -1,168 +0,0 @@
@theme {
--color-lime-1: var(--lime-1);
--color-lime-2: var(--lime-2);
--color-lime-3: var(--lime-3);
--color-lime-4: var(--lime-4);
--color-lime-5: var(--lime-5);
--color-lime-6: var(--lime-6);
--color-lime-7: var(--lime-7);
--color-lime-8: var(--lime-8);
--color-lime-9: var(--lime-9);
--color-lime-10: var(--lime-10);
--color-lime-11: var(--lime-11);
--color-lime-12: var(--lime-12);
--color-lime-a1: var(--lime-a1);
--color-lime-a2: var(--lime-a2);
--color-lime-a3: var(--lime-a3);
--color-lime-a4: var(--lime-a4);
--color-lime-a5: var(--lime-a5);
--color-lime-a6: var(--lime-a6);
--color-lime-a7: var(--lime-a7);
--color-lime-a8: var(--lime-a8);
--color-lime-a9: var(--lime-a9);
--color-lime-a10: var(--lime-a10);
--color-lime-a11: var(--lime-a11);
--color-lime-a12: var(--lime-a12);
--color-lime-contrast: var(--lime-contrast);
--color-lime-surface: var(--lime-surface);
--color-lime-indicator: var(--lime-indicator);
--color-lime-track: var(--lime-track);
}
@layer base {
:root {
--lime-1: #fcfdfa;
--lime-2: #f7faf4;
--lime-3: #e9f7de;
--lime-4: #dbf1c9;
--lime-5: #cce8b5;
--lime-6: #bbdba0;
--lime-7: #a6ca87;
--lime-8: #8ab562;
--lime-9: #8bb663;
--lime-10: #80aa58;
--lime-11: #597b38;
--lime-12: #314023;
--lime-a1: #66990005;
--lime-a2: #468c000b;
--lime-a3: #55c20021;
--lime-a4: #55bd0036;
--lime-a5: #50b0014a;
--lime-a6: #499f005f;
--lime-a7: #428f0078;
--lime-a8: #4187009d;
--lime-a9: #4288009c;
--lime-a10: #3d7d00a7;
--lime-a11: #2a5600c7;
--lime-a12: #102200dc;
--lime-contrast: #fff;
--lime-surface: #f5f9f1cc;
--lime-indicator: #8bb663;
--lime-track: #8bb663;
@supports (color: color(display-p3 1 1 1)) {
@media (color-gamut: p3) {
--lime-1: oklch(99.3% 0.0039 131.3);
--lime-2: oklch(98.2% 0.0087 131.3);
--lime-3: oklch(96% 0.0366 131.3);
--lime-4: oklch(93.2% 0.0583 131.3);
--lime-5: oklch(89.8% 0.0744 131.3);
--lime-6: oklch(85.4% 0.0862 131.3);
--lime-7: oklch(79.5% 0.0979 131.3);
--lime-8: oklch(72.3% 0.121 131.3);
--lime-9: oklch(72.6% 0.121 131.3);
--lime-10: oklch(68.9% 0.121 131.3);
--lime-11: oklch(54.2% 0.1026 131.3);
--lime-12: oklch(35% 0.0511 131.3);
--lime-a1: color(display-p3 0.4118 0.6078 0.0196 / 0.02);
--lime-a2: color(display-p3 0.3765 0.5569 0.0196 / 0.044);
--lime-a3: color(display-p3 0.3922 0.7451 0.0039 / 0.122);
--lime-a4: color(display-p3 0.3647 0.702 0.0078 / 0.197);
--lime-a5: color(display-p3 0.3373 0.6549 0.0039 / 0.271);
--lime-a6: color(display-p3 0.3059 0.5843 0.0039 / 0.35);
--lime-a7: color(display-p3 0.2745 0.5255 0.0039 / 0.444);
--lime-a8: color(display-p3 0.2667 0.4902 0 / 0.577);
--lime-a9: color(display-p3 0.2667 0.4941 0 / 0.573);
--lime-a10: color(display-p3 0.251 0.4549 0 / 0.616);
--lime-a11: color(display-p3 0.1686 0.302 0 / 0.75);
--lime-a12: color(display-p3 0.0667 0.1216 0 / 0.851);
--lime-contrast: #fff;
--lime-surface: color(display-p3 0.9647 0.9765 0.9529 / 0.8);
--lime-indicator: oklch(72.6% 0.121 131.3);
--lime-track: oklch(72.6% 0.121 131.3);
}
}
}
.dark {
--lime-1: #0f120d;
--lime-2: #161914;
--lime-3: #21281b;
--lime-4: #2b371f;
--lime-5: #354527;
--lime-6: #405330;
--lime-7: #4c6238;
--lime-8: #597441;
--lime-9: #8bb663;
--lime-10: #80aa58;
--lime-11: #9cc775;
--lime-12: #d2ebbf;
--lime-a1: #00910002;
--lime-a2: #9ff46709;
--lime-a3: #b5fc7719;
--lime-a4: #b3fe6929;
--lime-a5: #b5fe7638;
--lime-a6: #baff8147;
--lime-a7: #beff8457;
--lime-a8: #bdfd846b;
--lime-a9: #c1ff88b1;
--lime-a10: #beff80a4;
--lime-a11: #c7ff94c3;
--lime-a12: #e4ffcfea;
--lime-contrast: #fff;
--lime-surface: #1b211780;
--lime-indicator: #8bb663;
--lime-track: #8bb663;
@supports (color: color(display-p3 1 1 1)) {
@media (color-gamut: p3) {
--lime-1: oklch(17.8% 0.0117 131.3);
--lime-2: oklch(20.9% 0.0117 131.3);
--lime-3: oklch(26.6% 0.025 131.3);
--lime-4: oklch(31.9% 0.0435 131.3);
--lime-5: oklch(36.7% 0.0515 131.3);
--lime-6: oklch(41.6% 0.06 131.3);
--lime-7: oklch(46.8% 0.0695 131.3);
--lime-8: oklch(52.4% 0.081 131.3);
--lime-9: oklch(72.6% 0.121 131.3);
--lime-10: oklch(68.9% 0.121 131.3);
--lime-11: oklch(78% 0.1182 131.3);
--lime-12: oklch(91.1% 0.0649 131.3);
--lime-a1: color(display-p3 0 0.8549 0 / 0.005);
--lime-a2: color(display-p3 0.7608 0.9922 0.4157 / 0.034);
--lime-a3: color(display-p3 0.7569 1 0.5137 / 0.097);
--lime-a4: color(display-p3 0.7529 1 0.4863 / 0.16);
--lime-a5: color(display-p3 0.7686 1 0.5176 / 0.219);
--lime-a6: color(display-p3 0.8 1 0.5686 / 0.274);
--lime-a7: color(display-p3 0.8 1 0.5804 / 0.337);
--lime-a8: color(display-p3 0.8 1 0.5843 / 0.412);
--lime-a9: color(display-p3 0.8118 1 0.5922 / 0.69);
--lime-a10: color(display-p3 0.8039 1 0.5647 / 0.639);
--lime-a11: color(display-p3 0.8314 1 0.6275 / 0.761);
--lime-a12: color(display-p3 0.9216 1 0.8353 / 0.912);
--lime-contrast: #fff;
--lime-surface: color(display-p3 0.1098 0.1255 0.0863 / 0.5);
--lime-indicator: oklch(72.6% 0.121 131.3);
--lime-track: oklch(72.6% 0.121 131.3);
}
}
}
}

View File

@@ -39,7 +39,7 @@
margin-bottom: 1rem;
}
.policy-content ul,
.policy-content ul,
.policy-content ol {
margin-left: 1.5rem;
margin-bottom: 1rem;
@@ -67,24 +67,24 @@
}
.policy-content blockquote {
border-left: 4px solid hsl(var(--border));
border-left: 4px solid hsl(var(--solid-b));
padding-left: 1rem;
margin-left: 0;
margin-right: 0;
font-style: italic;
color: hsl(var(--muted-foreground));
color: hsl(var(--tertiary));
}
.policy-content code {
font-family: monospace;
background-color: hsl(var(--muted));
background-color: hsl(var(--invert-bg));
padding: 0.2rem 0.4rem;
border-radius: 0.25rem;
font-size: 0.875em;
}
.policy-content pre {
background-color: hsl(var(--muted));
background-color: hsl(var(--invert-bg));
padding: 1rem;
border-radius: 0.5rem;
overflow-x: auto;
@@ -105,12 +105,12 @@
.policy-content th,
.policy-content td {
border: 1px solid hsl(var(--border));
border: 1px solid hsl(var(--solid-b));
padding: 0.5rem;
}
.policy-content th {
background-color: hsl(var(--muted));
background-color: hsl(var(--invert-bg));
font-weight: 600;
}
@@ -122,6 +122,6 @@
.policy-content hr {
border: 0;
border-top: 1px solid hsl(var(--border));
border-top: 1px solid hsl(var(--solid-b));
margin: 1.5rem 0;
}
}

7
package-lock.json generated
View File

@@ -20,6 +20,7 @@
"dependencies": {
"@lexical/react": "^0.27.0",
"@probo/react-lazy": "^0.1.0",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-avatar": "^1.1.3",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-collapsible": "^1.1.3",
@@ -2816,6 +2817,12 @@
"resolved": "packages/tsconfig",
"link": true
},
"node_modules/@radix-ui/colors": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-3.0.0.tgz",
"integrity": "sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==",
"license": "MIT"
},
"node_modules/@radix-ui/number": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz",