bug: shadcn ui merge

This commit is contained in:
null 2026-05-20 01:41:15 -05:00
parent d45fd42c7f
commit ad5ca38a86
73 changed files with 831 additions and 830 deletions

View File

@ -242,7 +242,7 @@ const eventLabel = (eventType: FeedEventType): string => {
const eventPillClass = (eventType: FeedEventType): string => { const eventPillClass = (eventType: FeedEventType): string => {
if (eventType === "task.comment") { if (eventType === "task.comment") {
return "border-blue-200 bg-blue-50 text-blue-700"; return "border-primary/30 bg-primary/10 text-primary";
} }
if (eventType === "task.created") { if (eventType === "task.created") {
return "border-emerald-200 bg-emerald-50 text-emerald-700"; return "border-emerald-200 bg-emerald-50 text-emerald-700";
@ -263,7 +263,7 @@ const eventPillClass = (eventType: FeedEventType): string => {
return "border-lime-200 bg-lime-50 text-lime-700"; return "border-lime-200 bg-lime-50 text-lime-700";
} }
if (eventType === "agent.offline") { if (eventType === "agent.offline") {
return "border-slate-300 bg-slate-100 text-slate-700"; return "border-input bg-accent text-muted-foreground";
} }
if (eventType === "agent.updated") { if (eventType === "agent.updated") {
return "border-indigo-200 bg-indigo-50 text-indigo-700"; return "border-indigo-200 bg-indigo-50 text-indigo-700";
@ -280,7 +280,7 @@ const eventPillClass = (eventType: FeedEventType): string => {
if (eventType === "approval.rejected") { if (eventType === "approval.rejected") {
return "border-rose-200 bg-rose-50 text-rose-700"; return "border-rose-200 bg-rose-50 text-rose-700";
} }
return "border-slate-200 bg-slate-100 text-slate-700"; return "border-border bg-accent text-muted-foreground";
}; };
const FeedCard = memo(function FeedCard({ const FeedCard = memo(function FeedCard({
@ -297,14 +297,14 @@ const FeedCard = memo(function FeedCard({
<div <div
id={feedItemElementId(item.id)} id={feedItemElementId(item.id)}
className={cn( className={cn(
"scroll-mt-28 rounded-xl border bg-white p-4 transition", "scroll-mt-28 rounded-xl border bg-card p-4 transition",
isHighlighted isHighlighted
? "border-blue-300 ring-2 ring-blue-200" ? "border-primary/40 ring-2 ring-primary/20"
: "border-slate-200 hover:border-slate-300", : "border-border hover:border-input",
)} )}
> >
<div className="flex items-start gap-3"> <div className="flex items-start gap-3">
<div className="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full bg-slate-100 text-xs font-semibold text-slate-700"> <div className="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full bg-accent text-xs font-semibold text-muted-foreground">
{authorAvatar} {authorAvatar}
</div> </div>
<div className="min-w-0 flex-1"> <div className="min-w-0 flex-1">
@ -312,7 +312,7 @@ const FeedCard = memo(function FeedCard({
{item.context_href ? ( {item.context_href ? (
<Link <Link
href={item.context_href} href={item.context_href}
className="block text-sm font-semibold leading-snug text-slate-900 transition hover:text-slate-950 hover:underline" className="block text-sm font-semibold leading-snug text-foreground transition hover:text-foreground hover:underline"
title={item.title} title={item.title}
style={{ style={{
display: "-webkit-box", display: "-webkit-box",
@ -324,11 +324,11 @@ const FeedCard = memo(function FeedCard({
{item.title} {item.title}
</Link> </Link>
) : ( ) : (
<p className="text-sm font-semibold leading-snug text-slate-900"> <p className="text-sm font-semibold leading-snug text-foreground">
{item.title} {item.title}
</p> </p>
)} )}
<div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-[11px] text-slate-500"> <div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-[11px] text-muted-foreground">
<span <span
className={cn( className={cn(
"rounded-full border px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide", "rounded-full border px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide",
@ -340,29 +340,29 @@ const FeedCard = memo(function FeedCard({
{item.board_href && item.board_name ? ( {item.board_href && item.board_name ? (
<Link <Link
href={item.board_href} href={item.board_href}
className="font-semibold text-slate-700 hover:text-slate-900 hover:underline" className="font-semibold text-muted-foreground hover:text-foreground hover:underline"
> >
{item.board_name} {item.board_name}
</Link> </Link>
) : item.board_name ? ( ) : item.board_name ? (
<span className="font-semibold text-slate-700"> <span className="font-semibold text-muted-foreground">
{item.board_name} {item.board_name}
</span> </span>
) : null} ) : null}
{item.board_name ? ( {item.board_name ? (
<span className="text-slate-300">·</span> <span className="text-muted-foreground/50">·</span>
) : null} ) : null}
<span className="font-medium text-slate-700"> <span className="font-medium text-muted-foreground">
{item.actor_name} {item.actor_name}
</span> </span>
{item.actor_role ? ( {item.actor_role ? (
<> <>
<span className="text-slate-300">·</span> <span className="text-muted-foreground/50">·</span>
<span className="text-slate-500">{item.actor_role}</span> <span className="text-muted-foreground">{item.actor_role}</span>
</> </>
) : null} ) : null}
<span className="text-slate-300">·</span> <span className="text-muted-foreground/50">·</span>
<span className="text-slate-400"> <span className="text-muted-foreground/70">
{formatShortTimestamp(item.created_at)} {formatShortTimestamp(item.created_at)}
</span> </span>
</div> </div>
@ -370,11 +370,11 @@ const FeedCard = memo(function FeedCard({
</div> </div>
</div> </div>
{message ? ( {message ? (
<div className="mt-3 select-text cursor-text text-sm leading-relaxed text-slate-900 break-words"> <div className="mt-3 select-text cursor-text text-sm leading-relaxed text-foreground break-words">
<Markdown content={message} variant="basic" /> <Markdown content={message} variant="basic" />
</div> </div>
) : ( ) : (
<p className="mt-3 text-sm text-slate-500"></p> <p className="mt-3 text-sm text-muted-foreground"></p>
)} )}
</div> </div>
); );
@ -1506,18 +1506,18 @@ export default function ActivityPage() {
</SignedOut> </SignedOut>
<SignedIn> <SignedIn>
<DashboardSidebar /> <DashboardSidebar />
<main className="flex-1 overflow-y-auto bg-slate-50"> <main className="flex-1 overflow-y-auto bg-muted">
<div className="sticky top-0 z-30 border-b border-slate-200 bg-white"> <div className="sticky top-0 z-30 border-b border-border bg-card">
<div className="px-4 py-4 md:px-8 md:py-6"> <div className="px-4 py-4 md:px-8 md:py-6">
<div className="flex flex-wrap items-center justify-between gap-4"> <div className="flex flex-wrap items-center justify-between gap-4">
<div> <div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<ActivityIcon className="h-5 w-5 text-slate-600" /> <ActivityIcon className="h-5 w-5 text-muted-foreground" />
<h1 className="text-2xl font-semibold tracking-tight text-slate-900"> <h1 className="text-2xl font-semibold tracking-tight text-foreground">
Live feed Live feed
</h1> </h1>
</div> </div>
<p className="mt-1 text-sm text-slate-500"> <p className="mt-1 text-sm text-muted-foreground">
Realtime task, approval, agent, and board-chat activity Realtime task, approval, agent, and board-chat activity
across all boards. across all boards.
</p> </p>

View File

@ -258,16 +258,16 @@ export default function EditAgentPage() {
> >
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="rounded-xl border border-slate-200 bg-white p-6 shadow-sm space-y-6" className="rounded-xl border border-border bg-card p-6 shadow-sm space-y-6"
> >
<div> <div>
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Basic configuration Basic configuration
</p> </p>
<div className="mt-4 space-y-6"> <div className="mt-4 space-y-6">
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Agent name <span className="text-red-500">*</span> Agent name <span className="text-red-500">*</span>
</label> </label>
<Input <Input
@ -278,7 +278,7 @@ export default function EditAgentPage() {
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Role Role
</label> </label>
<Input <Input
@ -297,10 +297,10 @@ export default function EditAgentPage() {
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Board Board
{resolvedIsGatewayMain ? ( {resolvedIsGatewayMain ? (
<span className="ml-2 text-xs font-normal text-slate-500"> <span className="ml-2 text-xs font-normal text-muted-foreground">
optional optional
</span> </span>
) : ( ) : (
@ -310,7 +310,7 @@ export default function EditAgentPage() {
{resolvedBoardId ? ( {resolvedBoardId ? (
<button <button
type="button" type="button"
className="text-xs font-medium text-slate-600 hover:text-slate-900" className="text-xs font-medium text-muted-foreground hover:text-foreground"
onClick={() => { onClick={() => {
setBoardId(""); setBoardId("");
}} }}
@ -338,19 +338,19 @@ export default function EditAgentPage() {
disabled={boards.length === 0} disabled={boards.length === 0}
/> />
{resolvedIsGatewayMain ? ( {resolvedIsGatewayMain ? (
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Main agents are not attached to a board. If a board is Main agents are not attached to a board. If a board is
selected, it is only used to resolve the gateway main selected, it is only used to resolve the gateway main
session key and will be cleared on save. session key and will be cleared on save.
</p> </p>
) : boards.length === 0 ? ( ) : boards.length === 0 ? (
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Create a board before assigning agents. Create a board before assigning agents.
</p> </p>
) : null} ) : null}
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Emoji Emoji
</label> </label>
<Select <Select
@ -377,20 +377,20 @@ export default function EditAgentPage() {
</div> </div>
</div> </div>
</div> </div>
<div className="mt-6 rounded-xl border border-slate-200 bg-slate-50 p-4"> <div className="mt-6 rounded-xl border border-border bg-muted p-4">
<label className="flex items-start gap-3 text-sm text-slate-700"> <label className="flex items-start gap-3 text-sm text-muted-foreground">
<input <input
type="checkbox" type="checkbox"
className="mt-1 h-4 w-4 rounded border-slate-300 text-blue-600 focus:ring-blue-200" className="mt-1 h-4 w-4 rounded border-input text-primary focus:ring-ring/30"
checked={resolvedIsGatewayMain} checked={resolvedIsGatewayMain}
onChange={(event) => setIsGatewayMain(event.target.checked)} onChange={(event) => setIsGatewayMain(event.target.checked)}
disabled={isLoading} disabled={isLoading}
/> />
<span> <span>
<span className="block font-medium text-slate-900"> <span className="block font-medium text-foreground">
Gateway main agent Gateway main agent
</span> </span>
<span className="block text-xs text-slate-500"> <span className="block text-xs text-muted-foreground">
Uses the gateway main session key and is not tied to a single Uses the gateway main session key and is not tied to a single
board. board.
</span> </span>
@ -400,12 +400,12 @@ export default function EditAgentPage() {
</div> </div>
<div> <div>
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Personality & behavior Personality & behavior
</p> </p>
<div className="mt-4"> <div className="mt-4">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Communication style Communication style
</label> </label>
<Input <Input
@ -423,12 +423,12 @@ export default function EditAgentPage() {
</div> </div>
<div> <div>
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Schedule & notifications Schedule & notifications
</p> </p>
<div className="mt-4"> <div className="mt-4">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Interval Interval
</label> </label>
<Input <Input
@ -437,7 +437,7 @@ export default function EditAgentPage() {
placeholder="e.g. 10m" placeholder="e.g. 10m"
disabled={isLoading} disabled={isLoading}
/> />
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Set how often this agent runs HEARTBEAT.md. Set how often this agent runs HEARTBEAT.md.
</p> </p>
</div> </div>
@ -445,7 +445,7 @@ export default function EditAgentPage() {
</div> </div>
{errorMessage ? ( {errorMessage ? (
<div className="rounded-lg border border-slate-200 bg-white p-3 text-sm text-slate-600 shadow-sm"> <div className="rounded-lg border border-border bg-card p-3 text-sm text-muted-foreground shadow-sm">
{errorMessage} {errorMessage}
</div> </div>
) : null} ) : null}

View File

@ -142,16 +142,16 @@ export default function NewAgentPage() {
> >
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="rounded-xl border border-slate-200 bg-white p-6 shadow-sm space-y-6" className="rounded-xl border border-border bg-card p-6 shadow-sm space-y-6"
> >
<div> <div>
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Basic configuration Basic configuration
</p> </p>
<div className="mt-4 space-y-6"> <div className="mt-4 space-y-6">
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Agent name <span className="text-red-500">*</span> Agent name <span className="text-red-500">*</span>
</label> </label>
<Input <Input
@ -162,7 +162,7 @@ export default function NewAgentPage() {
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Role Role
</label> </label>
<Input <Input
@ -180,7 +180,7 @@ export default function NewAgentPage() {
</div> </div>
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Board <span className="text-red-500">*</span> Board <span className="text-red-500">*</span>
</label> </label>
<SearchableSelect <SearchableSelect
@ -197,13 +197,13 @@ export default function NewAgentPage() {
disabled={boards.length === 0} disabled={boards.length === 0}
/> />
{boards.length === 0 ? ( {boards.length === 0 ? (
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Create a board before adding agents. Create a board before adding agents.
</p> </p>
) : null} ) : null}
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Emoji Emoji
</label> </label>
<Select <Select
@ -233,12 +233,12 @@ export default function NewAgentPage() {
</div> </div>
<div> <div>
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Personality & behavior Personality & behavior
</p> </p>
<div className="mt-4"> <div className="mt-4">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Communication style Communication style
</label> </label>
<Input <Input
@ -256,12 +256,12 @@ export default function NewAgentPage() {
</div> </div>
<div> <div>
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Schedule & notifications Schedule & notifications
</p> </p>
<div className="mt-4"> <div className="mt-4">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Interval Interval
</label> </label>
<Input <Input
@ -270,7 +270,7 @@ export default function NewAgentPage() {
placeholder="e.g. 10m" placeholder="e.g. 10m"
disabled={isLoading} disabled={isLoading}
/> />
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
How often this agent runs HEARTBEAT.md (10m, 30m, 2h). How often this agent runs HEARTBEAT.md (10m, 30m, 2h).
</p> </p>
</div> </div>
@ -278,7 +278,7 @@ export default function NewAgentPage() {
</div> </div>
{errorMessage ? ( {errorMessage ? (
<div className="rounded-lg border border-slate-200 bg-white p-3 text-sm text-slate-600 shadow-sm"> <div className="rounded-lg border border-border bg-card p-3 text-sm text-muted-foreground shadow-sm">
{errorMessage} {errorMessage}
</div> </div>
) : null} ) : null}

View File

@ -142,7 +142,7 @@ export default function AgentsPage() {
adminOnlyMessage="Only organization owners and admins can access agents." adminOnlyMessage="Only organization owners and admins can access agents."
stickyHeader stickyHeader
> >
<div className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm"> <div className="overflow-hidden rounded-xl border border-border bg-card shadow-sm">
<AgentsTable <AgentsTable
agents={agents} agents={agents}
boards={boards} boards={boards}

View File

@ -166,7 +166,7 @@ function GlobalApprovalsInner() {
}, [errorText, warnings]); }, [errorText, warnings]);
return ( return (
<main className="flex-1 overflow-y-auto bg-gradient-to-br from-slate-50 to-slate-100"> <main className="flex-1 overflow-y-auto bg-background">
<div className="p-4 md:p-6"> <div className="p-4 md:p-6">
<div className="h-[calc(100vh-160px)] min-h-[300px] sm:min-h-[520px]"> <div className="h-[calc(100vh-160px)] min-h-[300px] sm:min-h-[520px]">
<BoardApprovalsPanel <BoardApprovalsPanel

View File

@ -288,7 +288,7 @@ export default function EditBoardGroupPage() {
> >
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="space-y-6 rounded-xl border border-slate-200 bg-white p-6 shadow-sm" className="space-y-6 rounded-xl border border-border bg-card p-6 shadow-sm"
> >
{assignFailedCount && Number.isFinite(assignFailedCount) ? ( {assignFailedCount && Number.isFinite(assignFailedCount) ? (
<div className="rounded-xl border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900 shadow-sm"> <div className="rounded-xl border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900 shadow-sm">
@ -298,7 +298,7 @@ export default function EditBoardGroupPage() {
) : null} ) : null}
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Group name <span className="text-red-500">*</span> Group name <span className="text-red-500">*</span>
</label> </label>
<Input <Input
@ -311,7 +311,7 @@ export default function EditBoardGroupPage() {
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Description Description
</label> </label>
<Textarea <Textarea
@ -323,16 +323,16 @@ export default function EditBoardGroupPage() {
/> />
</div> </div>
<div className="space-y-2 border-t border-slate-100 pt-6"> <div className="space-y-2 border-t border-border pt-6">
<div className="flex flex-wrap items-center justify-between gap-2"> <div className="flex flex-wrap items-center justify-between gap-2">
<div> <div>
<p className="text-sm font-medium text-slate-900">Boards</p> <p className="text-sm font-medium text-foreground">Boards</p>
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-muted-foreground">
Assign boards to this group to share context across related Assign boards to this group to share context across related
work. work.
</p> </p>
</div> </div>
<span className="text-xs text-slate-500"> <span className="text-xs text-muted-foreground">
{selectedBoardIds.size} selected {selectedBoardIds.size} selected
</span> </span>
</div> </div>
@ -344,9 +344,9 @@ export default function EditBoardGroupPage() {
disabled={isLoading || !baseGroup} disabled={isLoading || !baseGroup}
/> />
<div className="max-h-64 overflow-auto rounded-xl border border-slate-200 bg-slate-50/40"> <div className="max-h-64 overflow-auto rounded-xl border border-border bg-muted/40">
{boardsLoading && boards.length === 0 ? ( {boardsLoading && boards.length === 0 ? (
<div className="px-4 py-6 text-sm text-slate-500"> <div className="px-4 py-6 text-sm text-muted-foreground">
Loading boards Loading boards
</div> </div>
) : boardsError ? ( ) : boardsError ? (
@ -354,7 +354,7 @@ export default function EditBoardGroupPage() {
{boardsError.message} {boardsError.message}
</div> </div>
) : boards.length === 0 ? ( ) : boards.length === 0 ? (
<div className="px-4 py-6 text-sm text-slate-500"> <div className="px-4 py-6 text-sm text-muted-foreground">
No boards found. No boards found.
</div> </div>
) : ( ) : (
@ -378,7 +378,7 @@ export default function EditBoardGroupPage() {
<label className="flex cursor-pointer items-start gap-3"> <label className="flex cursor-pointer items-start gap-3">
<input <input
type="checkbox" type="checkbox"
className="mt-1 h-4 w-4 rounded border-slate-300 text-blue-600" className="mt-1 h-4 w-4 rounded border-input text-primary"
checked={checked} checked={checked}
onChange={() => { onChange={() => {
setSelectedBoardIds((prev) => { setSelectedBoardIds((prev) => {
@ -394,11 +394,11 @@ export default function EditBoardGroupPage() {
disabled={isLoading || !baseGroup} disabled={isLoading || !baseGroup}
/> />
<div className="min-w-0"> <div className="min-w-0">
<p className="truncate text-sm font-medium text-slate-900"> <p className="truncate text-sm font-medium text-foreground">
{board.name} {board.name}
</p> </p>
<div className="mt-1 flex flex-wrap items-center gap-2 text-xs text-slate-500"> <div className="mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
<span className="font-mono text-[11px] text-slate-400"> <span className="font-mono text-[11px] text-muted-foreground/70">
{board.id} {board.id}
</span> </span>
{isAlreadyGrouped ? ( {isAlreadyGrouped ? (
@ -420,7 +420,7 @@ export default function EditBoardGroupPage() {
<p className="text-sm text-rose-700">{assignmentsError}</p> <p className="text-sm text-rose-700">{assignmentsError}</p>
) : null} ) : null}
{assignmentsResult ? ( {assignmentsResult ? (
<p className="text-sm text-slate-700"> <p className="text-sm text-muted-foreground">
Updated {assignmentsResult.updated} board Updated {assignmentsResult.updated} board
{assignmentsResult.updated === 1 ? "" : "s"}, failed{" "} {assignmentsResult.updated === 1 ? "" : "s"}, failed{" "}
{assignmentsResult.failed}. {assignmentsResult.failed}.

View File

@ -78,9 +78,9 @@ const statusTone = (value?: string | null) => {
case "review": case "review":
return "bg-amber-50 text-amber-800 border-amber-200"; return "bg-amber-50 text-amber-800 border-amber-200";
case "done": case "done":
return "bg-slate-50 text-slate-600 border-slate-200"; return "bg-muted text-muted-foreground border-border";
default: default:
return "bg-blue-50 text-blue-700 border-blue-200"; return "bg-primary/10 text-primary border-primary/30";
} }
}; };
@ -89,7 +89,7 @@ const priorityTone = (value?: string | null) => {
case "high": case "high":
return "bg-rose-50 text-rose-700 border-rose-200"; return "bg-rose-50 text-rose-700 border-rose-200";
case "low": case "low":
return "bg-slate-50 text-slate-600 border-slate-200"; return "bg-muted text-muted-foreground border-border";
default: default:
return "bg-indigo-50 text-indigo-700 border-indigo-200"; return "bg-indigo-50 text-indigo-700 border-indigo-200";
} }
@ -112,24 +112,24 @@ const canWriteGroupBoards = (
function GroupChatMessageCard({ message }: { message: BoardGroupMemoryRead }) { function GroupChatMessageCard({ message }: { message: BoardGroupMemoryRead }) {
return ( return (
<div className="rounded-2xl border border-slate-200 bg-slate-50/60 p-4"> <div className="rounded-2xl border border-border bg-muted/60 p-4">
<div className="flex flex-wrap items-center justify-between gap-2"> <div className="flex flex-wrap items-center justify-between gap-2">
<p className="text-sm font-semibold text-slate-900"> <p className="text-sm font-semibold text-foreground">
{message.source ?? "User"} {message.source ?? "User"}
</p> </p>
<span className="text-xs text-slate-400"> <span className="text-xs text-muted-foreground/70">
{formatTimestamp(message.created_at)} {formatTimestamp(message.created_at)}
</span> </span>
</div> </div>
<div className="mt-2 select-text cursor-text text-sm leading-relaxed text-slate-900 break-words"> <div className="mt-2 select-text cursor-text text-sm leading-relaxed text-foreground break-words">
<Markdown content={message.content} variant="basic" /> <Markdown content={message.content} variant="basic" />
</div> </div>
{message.tags?.length ? ( {message.tags?.length ? (
<div className="mt-3 flex flex-wrap gap-2 text-[11px] text-slate-600"> <div className="mt-3 flex flex-wrap gap-2 text-[11px] text-muted-foreground">
{message.tags.map((tag) => ( {message.tags.map((tag) => (
<span <span
key={tag} key={tag}
className="rounded-full border border-slate-200 bg-white px-2 py-0.5" className="rounded-full border border-border bg-card px-2 py-0.5"
> >
{tag} {tag}
</span> </span>
@ -749,23 +749,23 @@ export default function BoardGroupDetailPage() {
</SignedOut> </SignedOut>
<SignedIn> <SignedIn>
<DashboardSidebar /> <DashboardSidebar />
<main className="flex-1 overflow-y-auto bg-slate-50"> <main className="flex-1 overflow-y-auto bg-muted">
<div className="sticky top-0 z-30 border-b border-slate-200 bg-white shadow-sm"> <div className="sticky top-0 z-30 border-b border-border bg-card shadow-sm">
<div className="px-4 py-4 md:px-8 md:py-6"> <div className="px-4 py-4 md:px-8 md:py-6">
<div className="flex flex-wrap items-start justify-between gap-4"> <div className="flex flex-wrap items-start justify-between gap-4">
<div className="min-w-0"> <div className="min-w-0">
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Board group Board group
</p> </p>
<h1 className="mt-2 text-2xl font-semibold tracking-tight text-slate-900"> <h1 className="mt-2 text-2xl font-semibold tracking-tight text-foreground">
{group?.name ?? "Group"} {group?.name ?? "Group"}
</h1> </h1>
{group?.description ? ( {group?.description ? (
<p className="mt-2 max-w-2xl text-sm text-slate-600"> <p className="mt-2 max-w-2xl text-sm text-muted-foreground">
{group.description} {group.description}
</p> </p>
) : ( ) : (
<p className="mt-2 text-sm text-slate-400"> <p className="mt-2 text-sm text-muted-foreground/70">
No description No description
</p> </p>
)} )}
@ -824,18 +824,18 @@ export default function BoardGroupDetailPage() {
</div> </div>
<div className="mt-5 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center"> <div className="mt-5 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center">
<label className="inline-flex items-center gap-2 text-sm text-slate-700"> <label className="inline-flex items-center gap-2 text-sm text-muted-foreground">
<input <input
type="checkbox" type="checkbox"
className="h-4 w-4 rounded border-slate-300 text-blue-600" className="h-4 w-4 rounded border-input text-primary"
checked={includeDone} checked={includeDone}
onChange={(event) => setIncludeDone(event.target.checked)} onChange={(event) => setIncludeDone(event.target.checked)}
/> />
Include done Include done
</label> </label>
<div className="flex items-center gap-2 text-sm text-slate-700"> <div className="flex items-center gap-2 text-sm text-muted-foreground">
<span className="text-slate-500">Top tasks per board</span> <span className="text-muted-foreground">Top tasks per board</span>
<div className="flex items-center gap-1 rounded-lg border border-slate-200 bg-white p-1"> <div className="flex items-center gap-1 rounded-lg border border-border bg-card p-1">
{[0, 3, 5, 10].map((value) => ( {[0, 3, 5, 10].map((value) => (
<button <button
key={value} key={value}
@ -843,8 +843,8 @@ export default function BoardGroupDetailPage() {
className={cn( className={cn(
"rounded-md px-2.5 py-1 text-xs font-semibold transition-colors", "rounded-md px-2.5 py-1 text-xs font-semibold transition-colors",
perBoardLimit === value perBoardLimit === value
? "bg-slate-900 text-white" ? "bg-foreground text-background"
: "text-slate-600 hover:bg-slate-100 hover:text-slate-900", : "text-muted-foreground hover:bg-accent hover:text-foreground",
)} )}
onClick={() => setPerBoardLimit(value)} onClick={() => setPerBoardLimit(value)}
> >
@ -854,9 +854,9 @@ export default function BoardGroupDetailPage() {
</div> </div>
</div> </div>
<div className="flex flex-wrap items-center gap-2 text-sm text-slate-700"> <div className="flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
<span className="text-slate-500">Agent pace</span> <span className="text-muted-foreground">Agent pace</span>
<div className="flex flex-wrap items-center gap-1 rounded-lg border border-slate-200 bg-white p-1"> <div className="flex flex-wrap items-center gap-1 rounded-lg border border-border bg-card p-1">
{HEARTBEAT_PRESETS.map((preset) => { {HEARTBEAT_PRESETS.map((preset) => {
const value = `${preset.amount}${preset.unit}`; const value = `${preset.amount}${preset.unit}`;
return ( return (
@ -866,8 +866,8 @@ export default function BoardGroupDetailPage() {
className={cn( className={cn(
"rounded-md px-2.5 py-1 text-xs font-semibold transition-colors", "rounded-md px-2.5 py-1 text-xs font-semibold transition-colors",
heartbeatEvery === value heartbeatEvery === value
? "bg-slate-900 text-white" ? "bg-foreground text-background"
: "text-slate-600 hover:bg-slate-100 hover:text-slate-900", : "text-muted-foreground hover:bg-accent hover:text-foreground",
!canManageHeartbeat && !canManageHeartbeat &&
"opacity-50 cursor-not-allowed", "opacity-50 cursor-not-allowed",
)} )}
@ -886,9 +886,9 @@ export default function BoardGroupDetailPage() {
value={heartbeatAmount} value={heartbeatAmount}
onChange={(event) => setHeartbeatAmount(event.target.value)} onChange={(event) => setHeartbeatAmount(event.target.value)}
className={cn( className={cn(
"h-8 w-20 rounded-md border bg-white px-2 text-xs text-slate-900 shadow-sm", "h-8 w-20 rounded-md border bg-card px-2 text-xs text-foreground shadow-sm",
heartbeatEvery heartbeatEvery
? "border-slate-200" ? "border-border"
: "border-rose-300 focus:border-rose-400 focus:ring-2 focus:ring-rose-100", : "border-rose-300 focus:border-rose-400 focus:ring-2 focus:ring-rose-100",
!canManageHeartbeat && "opacity-60 cursor-not-allowed", !canManageHeartbeat && "opacity-60 cursor-not-allowed",
)} )}
@ -921,10 +921,10 @@ export default function BoardGroupDetailPage() {
<SelectItem value="d">day</SelectItem> <SelectItem value="d">day</SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>
<label className="inline-flex items-center gap-2 text-xs text-slate-700"> <label className="inline-flex items-center gap-2 text-xs text-muted-foreground">
<input <input
type="checkbox" type="checkbox"
className="h-4 w-4 rounded border-slate-300 text-blue-600" className="h-4 w-4 rounded border-input text-primary"
checked={includeBoardLeads} checked={includeBoardLeads}
onChange={(event) => onChange={(event) =>
setIncludeBoardLeads(event.target.checked) setIncludeBoardLeads(event.target.checked)
@ -952,7 +952,7 @@ export default function BoardGroupDetailPage() {
</Button> </Button>
</div> </div>
{!canManageHeartbeat ? ( {!canManageHeartbeat ? (
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Read-only access. You cannot change agent pace for this Read-only access. You cannot change agent pace for this
group. group.
</p> </p>
@ -969,11 +969,11 @@ export default function BoardGroupDetailPage() {
</div> </div>
) : null} ) : null}
{heartbeatApplyResult ? ( {heartbeatApplyResult ? (
<div className="rounded-xl border border-slate-200 bg-white p-4 text-sm text-slate-700 shadow-sm"> <div className="rounded-xl border border-border bg-card p-4 text-sm text-muted-foreground shadow-sm">
<p className="font-semibold text-slate-900"> <p className="font-semibold text-foreground">
Heartbeat applied Heartbeat applied
</p> </p>
<p className="mt-1 text-slate-600"> <p className="mt-1 text-muted-foreground">
Updated {heartbeatApplyResult.updated_agent_ids.length}{" "} Updated {heartbeatApplyResult.updated_agent_ids.length}{" "}
agents, failed{" "} agents, failed{" "}
{heartbeatApplyResult.failed_agent_ids.length}. {heartbeatApplyResult.failed_agent_ids.length}.
@ -982,7 +982,7 @@ export default function BoardGroupDetailPage() {
) : null} ) : null}
{snapshotQuery.isLoading ? ( {snapshotQuery.isLoading ? (
<div className="rounded-xl border border-slate-200 bg-white p-6 text-sm text-slate-600 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 text-sm text-muted-foreground shadow-sm">
Loading group snapshot Loading group snapshot
</div> </div>
) : snapshotQuery.error ? ( ) : snapshotQuery.error ? (
@ -990,7 +990,7 @@ export default function BoardGroupDetailPage() {
{snapshotQuery.error.message} {snapshotQuery.error.message}
</div> </div>
) : boards.length === 0 ? ( ) : boards.length === 0 ? (
<div className="rounded-xl border border-slate-200 bg-white p-6 text-sm text-slate-600 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 text-sm text-muted-foreground shadow-sm">
No boards in this group yet. Assign boards from the board No boards in this group yet. Assign boards from the board
settings page. settings page.
</div> </div>
@ -999,9 +999,9 @@ export default function BoardGroupDetailPage() {
{boards.map((item) => ( {boards.map((item) => (
<div <div
key={item.board.id} key={item.board.id}
className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm" className="overflow-hidden rounded-xl border border-border bg-card shadow-sm"
> >
<div className="border-b border-slate-200 px-6 py-4"> <div className="border-b border-border px-6 py-4">
<div className="flex items-start justify-between gap-4"> <div className="flex items-start justify-between gap-4">
<div className="min-w-0"> <div className="min-w-0">
<Link <Link
@ -1009,17 +1009,17 @@ export default function BoardGroupDetailPage() {
className="group inline-flex items-center gap-2" className="group inline-flex items-center gap-2"
title="Open board" title="Open board"
> >
<p className="truncate text-sm font-semibold text-slate-900 group-hover:text-blue-600"> <p className="truncate text-sm font-semibold text-foreground group-hover:text-primary">
{item.board.name} {item.board.name}
</p> </p>
<ArrowUpRight className="h-4 w-4 text-slate-400 group-hover:text-blue-600" /> <ArrowUpRight className="h-4 w-4 text-muted-foreground/70 group-hover:text-primary" />
</Link> </Link>
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-muted-foreground">
Updated {formatTimestamp(item.board.updated_at)} Updated {formatTimestamp(item.board.updated_at)}
</p> </p>
</div> </div>
<div className="flex flex-wrap items-center justify-end gap-2 text-xs"> <div className="flex flex-wrap items-center justify-end gap-2 text-xs">
<span className="rounded-full border border-slate-200 bg-slate-50 px-2 py-0.5 text-slate-700"> <span className="rounded-full border border-border bg-muted px-2 py-0.5 text-muted-foreground">
Inbox {safeCount(item, "inbox")} Inbox {safeCount(item, "inbox")}
</span> </span>
<span className="rounded-full border border-emerald-200 bg-emerald-50 px-2 py-0.5 text-emerald-800"> <span className="rounded-full border border-emerald-200 bg-emerald-50 px-2 py-0.5 text-emerald-800">
@ -1042,7 +1042,7 @@ export default function BoardGroupDetailPage() {
pathname: `/boards/${item.board.id}`, pathname: `/boards/${item.board.id}`,
query: { taskId: task.id }, query: { taskId: task.id },
}} }}
className="block rounded-lg border border-slate-200 bg-slate-50/40 p-3 transition hover:border-blue-200 hover:bg-blue-50/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2" className="block rounded-lg border border-border bg-muted/40 p-3 transition hover:border-primary/30 hover:bg-primary/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
title="Open task on board" title="Open task on board"
> >
<div className="flex flex-wrap items-center justify-between gap-2"> <div className="flex flex-wrap items-center justify-between gap-2">
@ -1063,22 +1063,22 @@ export default function BoardGroupDetailPage() {
> >
{task.priority} {task.priority}
</span> </span>
<p className="truncate text-sm font-medium text-slate-900"> <p className="truncate text-sm font-medium text-foreground">
{task.title} {task.title}
</p> </p>
</div> </div>
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
{formatTimestamp(task.updated_at)} {formatTimestamp(task.updated_at)}
</p> </p>
</div> </div>
<div className="mt-2 flex flex-wrap items-center justify-between gap-2 text-xs text-slate-600"> <div className="mt-2 flex flex-wrap items-center justify-between gap-2 text-xs text-muted-foreground">
<p className="truncate"> <p className="truncate">
Assignee:{" "} Assignee:{" "}
<span className="font-medium text-slate-900"> <span className="font-medium text-foreground">
{task.assignee ?? "Unassigned"} {task.assignee ?? "Unassigned"}
</span> </span>
</p> </p>
<p className="font-mono text-[11px] text-slate-400"> <p className="font-mono text-[11px] text-muted-foreground/70">
{task.id} {task.id}
</p> </p>
</div> </div>
@ -1087,7 +1087,7 @@ export default function BoardGroupDetailPage() {
))} ))}
</ul> </ul>
) : ( ) : (
<p className="text-sm text-slate-500"> <p className="text-sm text-muted-foreground">
No tasks in this snapshot. No tasks in this snapshot.
</p> </p>
)} )}
@ -1102,7 +1102,7 @@ export default function BoardGroupDetailPage() {
</SignedIn> </SignedIn>
{isChatOpen || isNotesOpen ? ( {isChatOpen || isNotesOpen ? (
<div <div
className="fixed inset-0 z-40 bg-slate-900/20" className="fixed inset-0 z-40 bg-foreground/20"
onClick={() => { onClick={() => {
setIsChatOpen(false); setIsChatOpen(false);
setChatError(null); setChatError(null);
@ -1113,17 +1113,17 @@ export default function BoardGroupDetailPage() {
) : null} ) : null}
<aside <aside
className={cn( className={cn(
"fixed right-0 top-0 z-50 h-full w-[560px] max-w-[96vw] transform border-l border-slate-200 bg-white shadow-2xl transition-transform", "fixed right-0 top-0 z-50 h-full w-[560px] max-w-[96vw] transform border-l border-border bg-card shadow-2xl transition-transform",
isChatOpen ? "transform-none" : "translate-x-full", isChatOpen ? "transform-none" : "translate-x-full",
)} )}
> >
<div className="flex h-full flex-col"> <div className="flex h-full flex-col">
<div className="flex items-center justify-between border-b border-slate-200 px-6 py-4"> <div className="flex items-center justify-between border-b border-border px-6 py-4">
<div className="min-w-0"> <div className="min-w-0">
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Group chat Group chat
</p> </p>
<p className="mt-1 truncate text-sm font-medium text-slate-900"> <p className="mt-1 truncate text-sm font-medium text-foreground">
Shared across linked boards. Tag @lead, @name, or @all. Shared across linked boards. Tag @lead, @name, or @all.
</p> </p>
</div> </div>
@ -1133,7 +1133,7 @@ export default function BoardGroupDetailPage() {
setIsChatOpen(false); setIsChatOpen(false);
setChatError(null); setChatError(null);
}} }}
className="rounded-lg border border-slate-200 p-2 text-slate-500 transition hover:bg-slate-50" className="rounded-lg border border-border p-2 text-muted-foreground transition hover:bg-muted"
aria-label="Close group chat" aria-label="Close group chat"
> >
<X className="h-4 w-4" /> <X className="h-4 w-4" />
@ -1141,24 +1141,24 @@ export default function BoardGroupDetailPage() {
</div> </div>
<div className="flex flex-1 flex-col overflow-hidden px-6 py-4"> <div className="flex flex-1 flex-col overflow-hidden px-6 py-4">
<div className="flex flex-wrap items-center justify-between gap-3 pb-3"> <div className="flex flex-wrap items-center justify-between gap-3 pb-3">
<label className="inline-flex items-center gap-2 text-sm text-slate-700"> <label className="inline-flex items-center gap-2 text-sm text-muted-foreground">
<input <input
type="checkbox" type="checkbox"
className="h-4 w-4 rounded border-slate-300 text-blue-600" className="h-4 w-4 rounded border-input text-primary"
checked={chatBroadcast} checked={chatBroadcast}
onChange={(event) => setChatBroadcast(event.target.checked)} onChange={(event) => setChatBroadcast(event.target.checked)}
disabled={!canWriteGroup} disabled={!canWriteGroup}
/> />
Broadcast Broadcast
</label> </label>
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
{chatBroadcast {chatBroadcast
? "Notifies every agent in the group." ? "Notifies every agent in the group."
: "Notifies leads + mentions."} : "Notifies leads + mentions."}
</p> </p>
</div> </div>
<div className="flex-1 space-y-4 overflow-y-auto rounded-2xl border border-slate-200 bg-white p-4"> <div className="flex-1 space-y-4 overflow-y-auto rounded-2xl border border-border bg-card p-4">
{chatHistoryQuery.error ? ( {chatHistoryQuery.error ? (
<div className="rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700"> <div className="rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
{chatHistoryQuery.error.message} {chatHistoryQuery.error.message}
@ -1170,9 +1170,9 @@ export default function BoardGroupDetailPage() {
</div> </div>
) : null} ) : null}
{chatHistoryQuery.isLoading && chatMessages.length === 0 ? ( {chatHistoryQuery.isLoading && chatMessages.length === 0 ? (
<p className="text-sm text-slate-500">Loading</p> <p className="text-sm text-muted-foreground">Loading</p>
) : chatMessages.length === 0 ? ( ) : chatMessages.length === 0 ? (
<p className="text-sm text-slate-500"> <p className="text-sm text-muted-foreground">
No messages yet. Start the conversation with a broadcast or a No messages yet. Start the conversation with a broadcast or a
mention. mention.
</p> </p>
@ -1200,17 +1200,17 @@ export default function BoardGroupDetailPage() {
</aside> </aside>
<aside <aside
className={cn( className={cn(
"fixed right-0 top-0 z-50 h-full w-[560px] max-w-[96vw] transform border-l border-slate-200 bg-white shadow-2xl transition-transform", "fixed right-0 top-0 z-50 h-full w-[560px] max-w-[96vw] transform border-l border-border bg-card shadow-2xl transition-transform",
isNotesOpen ? "transform-none" : "translate-x-full", isNotesOpen ? "transform-none" : "translate-x-full",
)} )}
> >
<div className="flex h-full flex-col"> <div className="flex h-full flex-col">
<div className="flex items-center justify-between border-b border-slate-200 px-6 py-4"> <div className="flex items-center justify-between border-b border-border px-6 py-4">
<div className="min-w-0"> <div className="min-w-0">
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Group notes Group notes
</p> </p>
<p className="mt-1 truncate text-sm font-medium text-slate-900"> <p className="mt-1 truncate text-sm font-medium text-foreground">
Shared across linked boards. Tag @lead, @name, or @all. Shared across linked boards. Tag @lead, @name, or @all.
</p> </p>
</div> </div>
@ -1220,7 +1220,7 @@ export default function BoardGroupDetailPage() {
setIsNotesOpen(false); setIsNotesOpen(false);
setNoteSendError(null); setNoteSendError(null);
}} }}
className="rounded-lg border border-slate-200 p-2 text-slate-500 transition hover:bg-slate-50" className="rounded-lg border border-border p-2 text-muted-foreground transition hover:bg-muted"
aria-label="Close group notes" aria-label="Close group notes"
> >
<X className="h-4 w-4" /> <X className="h-4 w-4" />
@ -1228,24 +1228,24 @@ export default function BoardGroupDetailPage() {
</div> </div>
<div className="flex flex-1 flex-col overflow-hidden px-6 py-4"> <div className="flex flex-1 flex-col overflow-hidden px-6 py-4">
<div className="flex flex-wrap items-center justify-between gap-3 pb-3"> <div className="flex flex-wrap items-center justify-between gap-3 pb-3">
<label className="inline-flex items-center gap-2 text-sm text-slate-700"> <label className="inline-flex items-center gap-2 text-sm text-muted-foreground">
<input <input
type="checkbox" type="checkbox"
className="h-4 w-4 rounded border-slate-300 text-blue-600" className="h-4 w-4 rounded border-input text-primary"
checked={notesBroadcast} checked={notesBroadcast}
onChange={(event) => setNotesBroadcast(event.target.checked)} onChange={(event) => setNotesBroadcast(event.target.checked)}
disabled={!canWriteGroup} disabled={!canWriteGroup}
/> />
Broadcast Broadcast
</label> </label>
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
{notesBroadcast {notesBroadcast
? "Notifies every agent in the group." ? "Notifies every agent in the group."
: "Notifies leads + mentions."} : "Notifies leads + mentions."}
</p> </p>
</div> </div>
<div className="flex-1 space-y-4 overflow-y-auto rounded-2xl border border-slate-200 bg-white p-4"> <div className="flex-1 space-y-4 overflow-y-auto rounded-2xl border border-border bg-card p-4">
{notesHistoryQuery.error ? ( {notesHistoryQuery.error ? (
<div className="rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700"> <div className="rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
{notesHistoryQuery.error.message} {notesHistoryQuery.error.message}
@ -1257,9 +1257,9 @@ export default function BoardGroupDetailPage() {
</div> </div>
) : null} ) : null}
{notesHistoryQuery.isLoading && notesMessages.length === 0 ? ( {notesHistoryQuery.isLoading && notesMessages.length === 0 ? (
<p className="text-sm text-slate-500">Loading</p> <p className="text-sm text-muted-foreground">Loading</p>
) : notesMessages.length === 0 ? ( ) : notesMessages.length === 0 ? (
<p className="text-sm text-slate-500"> <p className="text-sm text-muted-foreground">
No notes yet. Post a note or a broadcast to share context No notes yet. Post a note or a broadcast to share context
across boards. across boards.
</p> </p>

View File

@ -133,11 +133,11 @@ export default function NewBoardGroupPage() {
> >
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="space-y-6 rounded-xl border border-slate-200 bg-white p-6 shadow-sm" className="space-y-6 rounded-xl border border-border bg-card p-6 shadow-sm"
> >
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Group name <span className="text-red-500">*</span> Group name <span className="text-red-500">*</span>
</label> </label>
<Input <Input
@ -150,7 +150,7 @@ export default function NewBoardGroupPage() {
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Description Description
</label> </label>
<Textarea <Textarea
@ -164,8 +164,8 @@ export default function NewBoardGroupPage() {
<div className="space-y-2"> <div className="space-y-2">
<div className="flex flex-wrap items-center justify-between gap-2"> <div className="flex flex-wrap items-center justify-between gap-2">
<label className="text-sm font-medium text-slate-900">Boards</label> <label className="text-sm font-medium text-foreground">Boards</label>
<span className="text-xs text-slate-500"> <span className="text-xs text-muted-foreground">
{selectedBoardIds.size} selected {selectedBoardIds.size} selected
</span> </span>
</div> </div>
@ -175,9 +175,9 @@ export default function NewBoardGroupPage() {
placeholder="Search boards..." placeholder="Search boards..."
disabled={isCreating} disabled={isCreating}
/> />
<div className="max-h-64 overflow-auto rounded-xl border border-slate-200 bg-slate-50/40"> <div className="max-h-64 overflow-auto rounded-xl border border-border bg-muted/40">
{boardsQuery.isLoading ? ( {boardsQuery.isLoading ? (
<div className="px-4 py-6 text-sm text-slate-500"> <div className="px-4 py-6 text-sm text-muted-foreground">
Loading boards Loading boards
</div> </div>
) : boardsQuery.error ? ( ) : boardsQuery.error ? (
@ -185,7 +185,7 @@ export default function NewBoardGroupPage() {
{boardsQuery.error.message} {boardsQuery.error.message}
</div> </div>
) : boards.length === 0 ? ( ) : boards.length === 0 ? (
<div className="px-4 py-6 text-sm text-slate-500"> <div className="px-4 py-6 text-sm text-muted-foreground">
No boards found. No boards found.
</div> </div>
) : ( ) : (
@ -207,7 +207,7 @@ export default function NewBoardGroupPage() {
<label className="flex cursor-pointer items-start gap-3"> <label className="flex cursor-pointer items-start gap-3">
<input <input
type="checkbox" type="checkbox"
className="mt-1 h-4 w-4 rounded border-slate-300 text-blue-600" className="mt-1 h-4 w-4 rounded border-input text-primary"
checked={checked} checked={checked}
onChange={() => { onChange={() => {
setSelectedBoardIds((prev) => { setSelectedBoardIds((prev) => {
@ -223,11 +223,11 @@ export default function NewBoardGroupPage() {
disabled={isCreating} disabled={isCreating}
/> />
<div className="min-w-0"> <div className="min-w-0">
<p className="truncate text-sm font-medium text-slate-900"> <p className="truncate text-sm font-medium text-foreground">
{board.name} {board.name}
</p> </p>
<div className="mt-1 flex flex-wrap items-center gap-2 text-xs text-slate-500"> <div className="mt-1 flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
<span className="font-mono text-[11px] text-slate-400"> <span className="font-mono text-[11px] text-muted-foreground/70">
{board.id} {board.id}
</span> </span>
{isAlreadyGrouped ? ( {isAlreadyGrouped ? (
@ -244,7 +244,7 @@ export default function NewBoardGroupPage() {
</ul> </ul>
)} )}
</div> </div>
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Optional. Selected boards will be assigned to this group after Optional. Selected boards will be assigned to this group after
creation. You can change membership later in group edit or board creation. You can change membership later in group edit or board
settings. settings.
@ -267,11 +267,11 @@ export default function NewBoardGroupPage() {
</Button> </Button>
</div> </div>
<div className="border-t border-slate-100 pt-4 text-xs text-slate-500"> <div className="border-t border-border pt-4 text-xs text-muted-foreground">
Want to assign boards later? Update each board in{" "} Want to assign boards later? Update each board in{" "}
<Link <Link
href="/boards" href="/boards"
className="font-medium text-blue-600 hover:text-blue-700" className="font-medium text-primary hover:text-primary"
> >
Boards Boards
</Link>{" "} </Link>{" "}

View File

@ -102,7 +102,7 @@ export default function BoardGroupsPage() {
} }
stickyHeader stickyHeader
> >
<div className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm"> <div className="overflow-hidden rounded-xl border border-border bg-card shadow-sm">
<BoardGroupsTable <BoardGroupsTable
groups={groups} groups={groups}
isLoading={groupsQuery.isLoading} isLoading={groupsQuery.isLoading}

View File

@ -38,9 +38,9 @@ export function TaskCustomFieldsEditor({
emptyMessage = "No custom fields configured for this board.", emptyMessage = "No custom fields configured for this board.",
}: TaskCustomFieldsEditorProps) { }: TaskCustomFieldsEditorProps) {
if (isLoading) if (isLoading)
return <p className="text-xs text-slate-500">{loadingMessage}</p>; return <p className="text-xs text-muted-foreground">{loadingMessage}</p>;
if (definitions.length === 0) { if (definitions.length === 0) {
return <p className="text-xs text-slate-500">{emptyMessage}</p>; return <p className="text-xs text-muted-foreground">{emptyMessage}</p>;
} }
return ( return (
@ -51,7 +51,7 @@ export function TaskCustomFieldsEditor({
return ( return (
<div key={definition.id} className="space-y-1"> <div key={definition.id} className="space-y-1">
<label className="text-[11px] font-semibold uppercase tracking-wide text-slate-500"> <label className="text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">
{definition.label || definition.field_key} {definition.label || definition.field_key}
{definition.required === true ? ( {definition.required === true ? (
<span className="ml-1 text-rose-600">*</span> <span className="ml-1 text-rose-600">*</span>
@ -145,7 +145,7 @@ export function TaskCustomFieldsEditor({
)} )}
{definition.description ? ( {definition.description ? (
<p className="text-xs text-slate-500">{definition.description}</p> <p className="text-xs text-muted-foreground">{definition.description}</p>
) : null} ) : null}
</div> </div>
); );

View File

@ -32,7 +32,7 @@ export default function BoardApprovalsPage() {
</SignedOut> </SignedOut>
<SignedIn> <SignedIn>
<DashboardSidebar /> <DashboardSidebar />
<main className="flex-1 overflow-y-auto bg-gradient-to-br from-slate-50 to-slate-100"> <main className="flex-1 overflow-y-auto bg-background">
<div className="p-4 md:p-6"> <div className="p-4 md:p-6">
{boardId ? ( {boardId ? (
<div className="h-[calc(100vh-160px)] min-h-[300px] sm:min-h-[520px]"> <div className="h-[calc(100vh-160px)] min-h-[300px] sm:min-h-[520px]">

View File

@ -142,7 +142,7 @@ export const formatCustomFieldDetailValue = (
href={parsedUrl.toString()} href={parsedUrl.toString()}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
className="inline-flex items-center gap-1 text-blue-700 underline decoration-blue-300 underline-offset-2 hover:text-blue-800" className="inline-flex items-center gap-1 text-primary underline decoration-primary/40 underline-offset-2 hover:text-primary"
> >
<span className="break-all">{parsedUrl.toString()}</span> <span className="break-all">{parsedUrl.toString()}</span>
<ArrowUpRight className="h-3.5 w-3.5 flex-shrink-0" /> <ArrowUpRight className="h-3.5 w-3.5 flex-shrink-0" />
@ -157,7 +157,7 @@ export const formatCustomFieldDetailValue = (
try { try {
const normalized = typeof value === "string" ? JSON.parse(value) : value; const normalized = typeof value === "string" ? JSON.parse(value) : value;
return ( return (
<pre className="whitespace-pre-wrap break-words rounded border border-slate-200 bg-white px-2 py-1 font-mono text-xs leading-relaxed text-slate-800"> <pre className="whitespace-pre-wrap break-words rounded border border-border bg-card px-2 py-1 font-mono text-xs leading-relaxed text-foreground">
{JSON.stringify(normalized, null, 2)} {JSON.stringify(normalized, null, 2)}
</pre> </pre>
); );

View File

@ -137,10 +137,10 @@ function WebhookCard({
return ( return (
<div <div
key={webhook.id} key={webhook.id}
className="space-y-3 rounded-lg border border-slate-200 px-4 py-4" className="space-y-3 rounded-lg border border-border px-4 py-4"
> >
<div className="flex flex-wrap items-center justify-between gap-2"> <div className="flex flex-wrap items-center justify-between gap-2">
<span className="text-sm font-semibold text-slate-900"> <span className="text-sm font-semibold text-foreground">
Webhook {webhook.id.slice(0, 8)} Webhook {webhook.id.slice(0, 8)}
</span> </span>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@ -218,7 +218,7 @@ function WebhookCard({
disabled={isBusy} disabled={isBusy}
/> />
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900">Agent</label> <label className="text-sm font-medium text-foreground">Agent</label>
<Select <Select
value={draftAgentValue} value={draftAgentValue}
onValueChange={setDraftAgentValue} onValueChange={setDraftAgentValue}
@ -243,19 +243,19 @@ function WebhookCard({
</> </>
) : ( ) : (
<> <>
<div className="text-sm text-slate-700"> <div className="text-sm text-muted-foreground">
<Markdown <Markdown
content={webhook.description || ""} content={webhook.description || ""}
variant="description" variant="description"
/> />
</div> </div>
<p className="text-xs text-slate-600"> <p className="text-xs text-muted-foreground">
Recipient: {mappedAgent?.name ?? "Lead agent"} Recipient: {mappedAgent?.name ?? "Lead agent"}
</p> </p>
</> </>
)} )}
<div className="rounded-md bg-slate-50 px-3 py-2"> <div className="rounded-md bg-muted px-3 py-2">
<code className="break-all text-xs text-slate-700"> <code className="break-all text-xs text-muted-foreground">
{webhook.endpoint_url ?? webhook.endpoint_path} {webhook.endpoint_url ?? webhook.endpoint_path}
</code> </code>
</div> </div>
@ -770,7 +770,7 @@ export default function EditBoardPage() {
<div className="space-y-6"> <div className="space-y-6">
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="space-y-6 rounded-xl border border-slate-200 bg-white p-6 shadow-sm" className="space-y-6 rounded-xl border border-border bg-card p-6 shadow-sm"
> >
{resolvedBoardType !== "general" && {resolvedBoardType !== "general" &&
baseBoard && baseBoard &&
@ -796,7 +796,7 @@ export default function EditBoardPage() {
) : null} ) : null}
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Board name <span className="text-red-500">*</span> Board name <span className="text-red-500">*</span>
</label> </label>
<Input <Input
@ -807,7 +807,7 @@ export default function EditBoardPage() {
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Gateway <span className="text-red-500">*</span> Gateway <span className="text-red-500">*</span>
</label> </label>
<SearchableSelect <SearchableSelect
@ -827,7 +827,7 @@ export default function EditBoardPage() {
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Board type Board type
</label> </label>
<Select value={resolvedBoardType} onValueChange={setBoardType}> <Select value={resolvedBoardType} onValueChange={setBoardType}>
@ -840,7 +840,7 @@ export default function EditBoardPage() {
</SelectContent> </SelectContent>
</Select> </Select>
<div className="space-y-2 pt-1"> <div className="space-y-2 pt-1">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Max worker agents Max worker agents
</label> </label>
<Input <Input
@ -861,7 +861,7 @@ export default function EditBoardPage() {
</div> </div>
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Board group Board group
</label> </label>
<SearchableSelect <SearchableSelect
@ -877,14 +877,14 @@ export default function EditBoardPage() {
itemClassName="px-4 py-3" itemClassName="px-4 py-3"
disabled={isLoading} disabled={isLoading}
/> />
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Boards in the same group can share cross-board context for Boards in the same group can share cross-board context for
agents. agents.
</p> </p>
</div> </div>
{resolvedBoardType !== "general" ? ( {resolvedBoardType !== "general" ? (
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Target date Target date
</label> </label>
<Input <Input
@ -898,7 +898,7 @@ export default function EditBoardPage() {
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Description <span className="text-red-500">*</span> Description <span className="text-red-500">*</span>
</label> </label>
<Textarea <Textarea
@ -913,7 +913,7 @@ export default function EditBoardPage() {
{resolvedBoardType !== "general" ? ( {resolvedBoardType !== "general" ? (
<> <>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Objective Objective
{isGoalFieldsRequired && ( {isGoalFieldsRequired && (
<span className="text-red-500"> *</span> <span className="text-red-500"> *</span>
@ -929,7 +929,7 @@ export default function EditBoardPage() {
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Success metrics (JSON) Success metrics (JSON)
{isGoalFieldsRequired && ( {isGoalFieldsRequired && (
<span className="text-red-500"> *</span> <span className="text-red-500"> *</span>
@ -942,7 +942,7 @@ export default function EditBoardPage() {
className="min-h-[140px] font-mono text-xs" className="min-h-[140px] font-mono text-xs"
disabled={isLoading} disabled={isLoading}
/> />
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Add key outcomes so the lead agent can measure progress. Add key outcomes so the lead agent can measure progress.
</p> </p>
{metricsError ? ( {metricsError ? (
@ -952,16 +952,16 @@ export default function EditBoardPage() {
</> </>
) : null} ) : null}
<section className="space-y-3 border-t border-slate-200 pt-4"> <section className="space-y-3 border-t border-border pt-4">
<div> <div>
<h2 className="text-base font-semibold text-slate-900"> <h2 className="text-base font-semibold text-foreground">
Rules Rules
</h2> </h2>
<p className="text-xs text-slate-600"> <p className="text-xs text-muted-foreground">
Configure board-level workflow enforcement. Configure board-level workflow enforcement.
</p> </p>
</div> </div>
<div className="flex items-start gap-3 rounded-lg border border-slate-200 px-3 py-3"> <div className="flex items-start gap-3 rounded-lg border border-border px-3 py-3">
<button <button
type="button" type="button"
role="switch" role="switch"
@ -974,11 +974,11 @@ export default function EditBoardPage() {
className={`mt-0.5 inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${ className={`mt-0.5 inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${
resolvedRequireApprovalForDone resolvedRequireApprovalForDone
? "border-emerald-600 bg-emerald-600" ? "border-emerald-600 bg-emerald-600"
: "border-slate-300 bg-slate-200" : "border-input bg-border"
} ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`} } ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`}
> >
<span <span
className={`inline-block h-5 w-5 rounded-full bg-white shadow-sm transition ${ className={`inline-block h-5 w-5 rounded-full bg-card shadow-sm transition ${
resolvedRequireApprovalForDone resolvedRequireApprovalForDone
? "translate-x-5" ? "translate-x-5"
: "translate-x-0.5" : "translate-x-0.5"
@ -986,17 +986,17 @@ export default function EditBoardPage() {
/> />
</button> </button>
<span className="space-y-1"> <span className="space-y-1">
<span className="block text-sm font-medium text-slate-900"> <span className="block text-sm font-medium text-foreground">
Require approval Require approval
</span> </span>
<span className="block text-xs text-slate-600"> <span className="block text-xs text-muted-foreground">
Require at least one linked approval in{" "} Require at least one linked approval in{" "}
<code>approved</code> state before a task can be marked{" "} <code>approved</code> state before a task can be marked{" "}
<code>done</code>. <code>done</code>.
</span> </span>
</span> </span>
</div> </div>
<div className="flex items-start gap-3 rounded-lg border border-slate-200 px-3 py-3"> <div className="flex items-start gap-3 rounded-lg border border-border px-3 py-3">
<button <button
type="button" type="button"
role="switch" role="switch"
@ -1009,11 +1009,11 @@ export default function EditBoardPage() {
className={`mt-0.5 inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${ className={`mt-0.5 inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${
resolvedRequireReviewBeforeDone resolvedRequireReviewBeforeDone
? "border-emerald-600 bg-emerald-600" ? "border-emerald-600 bg-emerald-600"
: "border-slate-300 bg-slate-200" : "border-input bg-border"
} ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`} } ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`}
> >
<span <span
className={`inline-block h-5 w-5 rounded-full bg-white shadow-sm transition ${ className={`inline-block h-5 w-5 rounded-full bg-card shadow-sm transition ${
resolvedRequireReviewBeforeDone resolvedRequireReviewBeforeDone
? "translate-x-5" ? "translate-x-5"
: "translate-x-0.5" : "translate-x-0.5"
@ -1021,16 +1021,16 @@ export default function EditBoardPage() {
/> />
</button> </button>
<span className="space-y-1"> <span className="space-y-1">
<span className="block text-sm font-medium text-slate-900"> <span className="block text-sm font-medium text-foreground">
Require review before done Require review before done
</span> </span>
<span className="block text-xs text-slate-600"> <span className="block text-xs text-muted-foreground">
Tasks must move to <code>review</code> before they can be Tasks must move to <code>review</code> before they can be
marked <code>done</code>. marked <code>done</code>.
</span> </span>
</span> </span>
</div> </div>
<div className="flex items-start gap-3 rounded-lg border border-slate-200 px-3 py-3"> <div className="flex items-start gap-3 rounded-lg border border-border px-3 py-3">
<button <button
type="button" type="button"
role="switch" role="switch"
@ -1045,11 +1045,11 @@ export default function EditBoardPage() {
className={`mt-0.5 inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${ className={`mt-0.5 inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${
resolvedCommentRequiredForReview resolvedCommentRequiredForReview
? "border-emerald-600 bg-emerald-600" ? "border-emerald-600 bg-emerald-600"
: "border-slate-300 bg-slate-200" : "border-input bg-border"
} ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`} } ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`}
> >
<span <span
className={`inline-block h-5 w-5 rounded-full bg-white shadow-sm transition ${ className={`inline-block h-5 w-5 rounded-full bg-card shadow-sm transition ${
resolvedCommentRequiredForReview resolvedCommentRequiredForReview
? "translate-x-5" ? "translate-x-5"
: "translate-x-0.5" : "translate-x-0.5"
@ -1057,16 +1057,16 @@ export default function EditBoardPage() {
/> />
</button> </button>
<span className="space-y-1"> <span className="space-y-1">
<span className="block text-sm font-medium text-slate-900"> <span className="block text-sm font-medium text-foreground">
Require comment for review Require comment for review
</span> </span>
<span className="block text-xs text-slate-600"> <span className="block text-xs text-muted-foreground">
Require a task comment when moving status to{" "} Require a task comment when moving status to{" "}
<code>review</code>. <code>review</code>.
</span> </span>
</span> </span>
</div> </div>
<div className="flex items-start gap-3 rounded-lg border border-slate-200 px-3 py-3"> <div className="flex items-start gap-3 rounded-lg border border-border px-3 py-3">
<button <button
type="button" type="button"
role="switch" role="switch"
@ -1081,11 +1081,11 @@ export default function EditBoardPage() {
className={`mt-0.5 inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${ className={`mt-0.5 inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${
resolvedBlockStatusChangesWithPendingApproval resolvedBlockStatusChangesWithPendingApproval
? "border-emerald-600 bg-emerald-600" ? "border-emerald-600 bg-emerald-600"
: "border-slate-300 bg-slate-200" : "border-input bg-border"
} ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`} } ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`}
> >
<span <span
className={`inline-block h-5 w-5 rounded-full bg-white shadow-sm transition ${ className={`inline-block h-5 w-5 rounded-full bg-card shadow-sm transition ${
resolvedBlockStatusChangesWithPendingApproval resolvedBlockStatusChangesWithPendingApproval
? "translate-x-5" ? "translate-x-5"
: "translate-x-0.5" : "translate-x-0.5"
@ -1093,16 +1093,16 @@ export default function EditBoardPage() {
/> />
</button> </button>
<span className="space-y-1"> <span className="space-y-1">
<span className="block text-sm font-medium text-slate-900"> <span className="block text-sm font-medium text-foreground">
Block status changes with pending approval Block status changes with pending approval
</span> </span>
<span className="block text-xs text-slate-600"> <span className="block text-xs text-muted-foreground">
Prevent status transitions while any linked approval is in{" "} Prevent status transitions while any linked approval is in{" "}
<code>pending</code> state. <code>pending</code> state.
</span> </span>
</span> </span>
</div> </div>
<div className="flex items-start gap-3 rounded-lg border border-slate-200 px-3 py-3"> <div className="flex items-start gap-3 rounded-lg border border-border px-3 py-3">
<button <button
type="button" type="button"
role="switch" role="switch"
@ -1115,11 +1115,11 @@ export default function EditBoardPage() {
className={`mt-0.5 inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${ className={`mt-0.5 inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${
resolvedOnlyLeadCanChangeStatus resolvedOnlyLeadCanChangeStatus
? "border-emerald-600 bg-emerald-600" ? "border-emerald-600 bg-emerald-600"
: "border-slate-300 bg-slate-200" : "border-input bg-border"
} ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`} } ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`}
> >
<span <span
className={`inline-block h-5 w-5 rounded-full bg-white shadow-sm transition ${ className={`inline-block h-5 w-5 rounded-full bg-card shadow-sm transition ${
resolvedOnlyLeadCanChangeStatus resolvedOnlyLeadCanChangeStatus
? "translate-x-5" ? "translate-x-5"
: "translate-x-0.5" : "translate-x-0.5"
@ -1127,10 +1127,10 @@ export default function EditBoardPage() {
/> />
</button> </button>
<span className="space-y-1"> <span className="space-y-1">
<span className="block text-sm font-medium text-slate-900"> <span className="block text-sm font-medium text-foreground">
Only lead can change status Only lead can change status
</span> </span>
<span className="block text-xs text-slate-600"> <span className="block text-xs text-muted-foreground">
Restrict status changes to the board lead. Restrict status changes to the board lead.
</span> </span>
</span> </span>
@ -1138,7 +1138,7 @@ export default function EditBoardPage() {
</section> </section>
{gateways.length === 0 ? ( {gateways.length === 0 ? (
<div className="rounded-lg border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-600"> <div className="rounded-lg border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
<p> <p>
No gateways available. Create one in Gateways to continue. No gateways available. Create one in Gateways to continue.
</p> </p>
@ -1166,18 +1166,18 @@ export default function EditBoardPage() {
</Button> </Button>
</div> </div>
<section className="space-y-4 border-t border-slate-200 pt-4"> <section className="space-y-4 border-t border-border pt-4">
<div> <div>
<h2 className="text-base font-semibold text-slate-900"> <h2 className="text-base font-semibold text-foreground">
Webhooks Webhooks
</h2> </h2>
<p className="text-xs text-slate-600"> <p className="text-xs text-muted-foreground">
Add inbound webhook endpoints so the lead agent can react to Add inbound webhook endpoints so the lead agent can react to
external events. external events.
</p> </p>
</div> </div>
<div className="space-y-3 rounded-lg border border-slate-200 px-4 py-4"> <div className="space-y-3 rounded-lg border border-border px-4 py-4">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Lead agent instruction Lead agent instruction
</label> </label>
<Textarea <Textarea
@ -1190,7 +1190,7 @@ export default function EditBoardPage() {
disabled={isLoading || isWebhookBusy} disabled={isLoading || isWebhookBusy}
/> />
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Agent Agent
</label> </label>
<Select <Select
@ -1237,11 +1237,11 @@ export default function EditBoardPage() {
) : null} ) : null}
{webhooksQuery.isLoading ? ( {webhooksQuery.isLoading ? (
<p className="text-sm text-slate-500">Loading webhooks</p> <p className="text-sm text-muted-foreground">Loading webhooks</p>
) : null} ) : null}
{!webhooksQuery.isLoading && webhooks.length === 0 ? ( {!webhooksQuery.isLoading && webhooks.length === 0 ? (
<p className="rounded-lg border border-dashed border-slate-300 px-4 py-3 text-sm text-slate-600"> <p className="rounded-lg border border-dashed border-input px-4 py-3 text-sm text-muted-foreground">
No webhooks configured yet. No webhooks configured yet.
</p> </p>
) : null} ) : null}
@ -1282,7 +1282,7 @@ export default function EditBoardPage() {
<DialogClose asChild> <DialogClose asChild>
<button <button
type="button" type="button"
className="sticky top-4 z-10 ml-auto rounded-lg border border-slate-200 bg-[color:var(--surface)] p-2 text-slate-500 transition hover:bg-slate-50" className="sticky top-4 z-10 ml-auto rounded-lg border border-border bg-[color:var(--surface)] p-2 text-muted-foreground transition hover:bg-muted"
aria-label="Close onboarding" aria-label="Close onboarding"
> >
<X className="h-4 w-4" /> <X className="h-4 w-4" />
@ -1295,7 +1295,7 @@ export default function EditBoardPage() {
onConfirmed={handleOnboardingConfirmed} onConfirmed={handleOnboardingConfirmed}
/> />
) : ( ) : (
<div className="rounded-lg border border-slate-200 bg-slate-50 p-3 text-sm text-slate-600"> <div className="rounded-lg border border-border bg-muted p-3 text-sm text-muted-foreground">
Unable to start onboarding. Unable to start onboarding.
</div> </div>
)} )}

File diff suppressed because it is too large Load Diff

View File

@ -111,13 +111,13 @@ export default function WebhookPayloadsPage() {
isAdmin={isAdmin} isAdmin={isAdmin}
adminOnlyMessage="Only organization owners and admins can view webhook payloads." adminOnlyMessage="Only organization owners and admins can view webhook payloads."
> >
<div className="space-y-4 rounded-xl border border-slate-200 bg-white p-6 shadow-sm"> <div className="space-y-4 rounded-xl border border-border bg-card p-6 shadow-sm">
<div className="flex flex-wrap items-start justify-between gap-3"> <div className="flex flex-wrap items-start justify-between gap-3">
<div className="space-y-1"> <div className="space-y-1">
<h2 className="text-base font-semibold text-slate-900"> <h2 className="text-base font-semibold text-foreground">
{payloadTitle} {payloadTitle}
</h2> </h2>
<p className="text-sm text-slate-600"> <p className="text-sm text-muted-foreground">
{webhook?.description ?? "Loading webhook details..."} {webhook?.description ?? "Loading webhook details..."}
</p> </p>
</div> </div>
@ -131,15 +131,15 @@ export default function WebhookPayloadsPage() {
</div> </div>
{webhook ? ( {webhook ? (
<div className="rounded-md bg-slate-50 px-3 py-2"> <div className="rounded-md bg-muted px-3 py-2">
<code className="break-all text-xs text-slate-700"> <code className="break-all text-xs text-muted-foreground">
{webhook.endpoint_url ?? webhook.endpoint_path} {webhook.endpoint_url ?? webhook.endpoint_path}
</code> </code>
</div> </div>
) : null} ) : null}
<div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border border-slate-200 px-3 py-2"> <div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border px-3 py-2">
<p className="text-sm text-slate-700"> <p className="text-sm text-muted-foreground">
{total} payload{total === 1 ? "" : "s"} total {total} payload{total === 1 ? "" : "s"} total
</p> </p>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@ -153,7 +153,7 @@ export default function WebhookPayloadsPage() {
> >
Previous Previous
</Button> </Button>
<span className="text-xs text-slate-600"> <span className="text-xs text-muted-foreground">
Page {currentPage} of {pageCount} Page {currentPage} of {pageCount}
</span> </span>
<Button <Button
@ -172,11 +172,11 @@ export default function WebhookPayloadsPage() {
) : null} ) : null}
{isLoading ? ( {isLoading ? (
<p className="text-sm text-slate-500">Loading payloads...</p> <p className="text-sm text-muted-foreground">Loading payloads...</p>
) : null} ) : null}
{!isLoading && payloads.length === 0 ? ( {!isLoading && payloads.length === 0 ? (
<p className="rounded-lg border border-dashed border-slate-300 px-4 py-3 text-sm text-slate-600"> <p className="rounded-lg border border-dashed border-input px-4 py-3 text-sm text-muted-foreground">
No payloads received for this webhook yet. No payloads received for this webhook yet.
</p> </p>
) : null} ) : null}
@ -185,17 +185,17 @@ export default function WebhookPayloadsPage() {
{payloads.map((payload: BoardWebhookPayloadRead) => ( {payloads.map((payload: BoardWebhookPayloadRead) => (
<div <div
key={payload.id} key={payload.id}
className="space-y-3 rounded-lg border border-slate-200 px-4 py-4" className="space-y-3 rounded-lg border border-border px-4 py-4"
> >
<div className="flex flex-wrap items-center justify-between gap-2"> <div className="flex flex-wrap items-center justify-between gap-2">
<span className="text-sm font-semibold text-slate-900"> <span className="text-sm font-semibold text-foreground">
Payload {payload.id.slice(0, 8)} Payload {payload.id.slice(0, 8)}
</span> </span>
<span className="text-xs text-slate-500"> <span className="text-xs text-muted-foreground">
{new Date(payload.received_at).toLocaleString()} {new Date(payload.received_at).toLocaleString()}
</span> </span>
</div> </div>
<div className="grid gap-2 text-xs text-slate-600 md:grid-cols-2"> <div className="grid gap-2 text-xs text-muted-foreground md:grid-cols-2">
<p> <p>
Content type:{" "} Content type:{" "}
<code>{payload.content_type ?? "not provided"}</code> <code>{payload.content_type ?? "not provided"}</code>
@ -204,7 +204,7 @@ export default function WebhookPayloadsPage() {
Source IP: <code>{payload.source_ip ?? "not provided"}</code> Source IP: <code>{payload.source_ip ?? "not provided"}</code>
</p> </p>
</div> </div>
<pre className="max-h-96 overflow-auto rounded-md bg-slate-900/95 p-3 text-xs text-slate-100"> <pre className="max-h-96 overflow-auto rounded-md bg-foreground/95 p-3 text-xs text-background">
{stringifyPayload(payload.payload)} {stringifyPayload(payload.payload)}
</pre> </pre>
</div> </div>

View File

@ -161,12 +161,12 @@ export default function NewBoardPage() {
> >
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="space-y-6 rounded-xl border border-slate-200 bg-white p-6 shadow-sm" className="space-y-6 rounded-xl border border-border bg-card p-6 shadow-sm"
> >
<div className="space-y-4"> <div className="space-y-4">
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Board name <span className="text-red-500">*</span> Board name <span className="text-red-500">*</span>
</label> </label>
<Input <Input
@ -177,7 +177,7 @@ export default function NewBoardPage() {
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Gateway <span className="text-red-500">*</span> Gateway <span className="text-red-500">*</span>
</label> </label>
<SearchableSelect <SearchableSelect
@ -197,7 +197,7 @@ export default function NewBoardPage() {
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Board group Board group
</label> </label>
<SearchableSelect <SearchableSelect
@ -213,14 +213,14 @@ export default function NewBoardPage() {
itemClassName="px-4 py-3" itemClassName="px-4 py-3"
disabled={isLoading} disabled={isLoading}
/> />
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Optional. Groups increase cross-board visibility. Optional. Groups increase cross-board visibility.
</p> </p>
</div> </div>
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Description <span className="text-red-500">*</span> Description <span className="text-red-500">*</span>
</label> </label>
<Textarea <Textarea
@ -234,12 +234,12 @@ export default function NewBoardPage() {
</div> </div>
{gateways.length === 0 ? ( {gateways.length === 0 ? (
<div className="rounded-lg border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-600"> <div className="rounded-lg border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
<p> <p>
No gateways available. Create one in{" "} No gateways available. Create one in{" "}
<Link <Link
href="/gateways" href="/gateways"
className="font-medium text-blue-600 hover:text-blue-700" className="font-medium text-primary hover:text-primary"
> >
Gateways Gateways
</Link>{" "} </Link>{" "}

View File

@ -134,7 +134,7 @@ export default function BoardsPage() {
} }
stickyHeader stickyHeader
> >
<div className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm"> <div className="overflow-hidden rounded-xl border border-border bg-card shadow-sm">
<BoardsTable <BoardsTable
boards={boards} boards={boards}
boardGroups={groups} boardGroups={groups}

View File

@ -129,7 +129,7 @@ export default function EditCustomFieldPage() {
stickyHeader stickyHeader
> >
{customFieldsQuery.isLoading ? ( {customFieldsQuery.isLoading ? (
<div className="max-w-3xl rounded-xl border border-slate-200 bg-white p-6 text-sm text-slate-500 shadow-sm"> <div className="max-w-3xl rounded-xl border border-border bg-card p-6 text-sm text-muted-foreground shadow-sm">
Loading custom field Loading custom field
</div> </div>
) : null} ) : null}

View File

@ -101,7 +101,7 @@ export default function CustomFieldsPage() {
adminOnlyMessage="Only organization owners and admins can manage custom fields." adminOnlyMessage="Only organization owners and admins can manage custom fields."
stickyHeader stickyHeader
> >
<div className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm"> <div className="overflow-hidden rounded-xl border border-border bg-card shadow-sm">
<CustomFieldsTable <CustomFieldsTable
fields={customFields} fields={customFields}
isLoading={customFieldsQuery.isLoading} isLoading={customFieldsQuery.isLoading}

View File

@ -185,7 +185,7 @@ export default function GatewayDetailPage() {
adminOnlyMessage="Only organization owners and admins can access gateways." adminOnlyMessage="Only organization owners and admins can access gateways."
> >
{gatewayQuery.isLoading ? ( {gatewayQuery.isLoading ? (
<div className="rounded-xl border border-slate-200 bg-white p-6 text-sm text-slate-500 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 text-sm text-muted-foreground shadow-sm">
Loading gateway Loading gateway
</div> </div>
) : gatewayQuery.error ? ( ) : gatewayQuery.error ? (
@ -195,16 +195,16 @@ export default function GatewayDetailPage() {
) : gateway ? ( ) : gateway ? (
<div className="space-y-6"> <div className="space-y-6">
<div className="grid gap-6 lg:grid-cols-2"> <div className="grid gap-6 lg:grid-cols-2">
<div className="rounded-xl border border-slate-200 bg-white p-6 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 shadow-sm">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<p className="text-xs font-semibold uppercase tracking-wide text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
Connection Connection
</p> </p>
<div className="flex items-center gap-2 text-xs text-slate-500"> <div className="flex items-center gap-2 text-xs text-muted-foreground">
<span <span
className={`h-2 w-2 rounded-full ${ className={`h-2 w-2 rounded-full ${
statusQuery.isLoading statusQuery.isLoading
? "bg-slate-300" ? "bg-muted-foreground/40"
: isConnected : isConnected
? "bg-emerald-500" ? "bg-emerald-500"
: "bg-rose-500" : "bg-rose-500"
@ -219,59 +219,59 @@ export default function GatewayDetailPage() {
</span> </span>
</div> </div>
</div> </div>
<div className="mt-4 space-y-3 text-sm text-slate-700"> <div className="mt-4 space-y-3 text-sm text-muted-foreground">
<div> <div>
<p className="text-xs uppercase text-slate-400"> <p className="text-xs uppercase text-muted-foreground/70">
Gateway URL Gateway URL
</p> </p>
<p className="mt-1 text-sm font-medium text-slate-900"> <p className="mt-1 text-sm font-medium text-foreground">
{gateway.url} {gateway.url}
</p> </p>
</div> </div>
<div> <div>
<p className="text-xs uppercase text-slate-400">Token</p> <p className="text-xs uppercase text-muted-foreground/70">Token</p>
<p className="mt-1 text-sm font-medium text-slate-900"> <p className="mt-1 text-sm font-medium text-foreground">
{maskToken(gateway.token)} {maskToken(gateway.token)}
</p> </p>
</div> </div>
<div> <div>
<p className="text-xs uppercase text-slate-400"> <p className="text-xs uppercase text-muted-foreground/70">
Device pairing Device pairing
</p> </p>
<p className="mt-1 text-sm font-medium text-slate-900"> <p className="mt-1 text-sm font-medium text-foreground">
{gateway.disable_device_pairing ? "Disabled" : "Required"} {gateway.disable_device_pairing ? "Disabled" : "Required"}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div className="rounded-xl border border-slate-200 bg-white p-6 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 shadow-sm">
<p className="text-xs font-semibold uppercase tracking-wide text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
Runtime Runtime
</p> </p>
<div className="mt-4 space-y-3 text-sm text-slate-700"> <div className="mt-4 space-y-3 text-sm text-muted-foreground">
<div> <div>
<p className="text-xs uppercase text-slate-400"> <p className="text-xs uppercase text-muted-foreground/70">
Workspace root Workspace root
</p> </p>
<p className="mt-1 text-sm font-medium text-slate-900"> <p className="mt-1 text-sm font-medium text-foreground">
{gateway.workspace_root} {gateway.workspace_root}
</p> </p>
</div> </div>
<div className="grid gap-3 sm:grid-cols-2"> <div className="grid gap-3 sm:grid-cols-2">
<div> <div>
<p className="text-xs uppercase text-slate-400"> <p className="text-xs uppercase text-muted-foreground/70">
Created Created
</p> </p>
<p className="mt-1 text-sm font-medium text-slate-900"> <p className="mt-1 text-sm font-medium text-foreground">
{formatTimestamp(gateway.created_at)} {formatTimestamp(gateway.created_at)}
</p> </p>
</div> </div>
<div> <div>
<p className="text-xs uppercase text-slate-400"> <p className="text-xs uppercase text-muted-foreground/70">
Updated Updated
</p> </p>
<p className="mt-1 text-sm font-medium text-slate-900"> <p className="mt-1 text-sm font-medium text-foreground">
{formatTimestamp(gateway.updated_at)} {formatTimestamp(gateway.updated_at)}
</p> </p>
</div> </div>
@ -280,15 +280,15 @@ export default function GatewayDetailPage() {
</div> </div>
</div> </div>
<div className="rounded-xl border border-slate-200 bg-white p-6 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 shadow-sm">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<p className="text-xs font-semibold uppercase tracking-wide text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
Agents Agents
</p> </p>
{agentsQuery.isLoading ? ( {agentsQuery.isLoading ? (
<span className="text-xs text-slate-500">Loading</span> <span className="text-xs text-muted-foreground">Loading</span>
) : ( ) : (
<span className="text-xs text-slate-500"> <span className="text-xs text-muted-foreground">
{agents.length} total {agents.length} total
</span> </span>
)} )}

View File

@ -113,7 +113,7 @@ export default function GatewaysPage() {
adminOnlyMessage="Only organization owners and admins can access gateways." adminOnlyMessage="Only organization owners and admins can access gateways."
stickyHeader stickyHeader
> >
<div className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm"> <div className="overflow-hidden rounded-xl border border-border bg-card shadow-sm">
<GatewaysTable <GatewaysTable
gateways={gateways} gateways={gateways}
isLoading={gatewaysQuery.isLoading} isLoading={gatewaysQuery.isLoading}

View File

@ -170,7 +170,7 @@ export default function ForgejoConnectionsEditPage({
errorMessage={deleteError} errorMessage={deleteError}
confirmLabel="Delete Connection" confirmLabel="Delete Connection"
confirmingLabel="Deleting…" confirmingLabel="Deleting…"
confirmClassName="bg-[color:var(--danger)] text-white hover:bg-[color:var(--danger)]/90" confirmClassName="bg-destructive text-destructive-foreground hover:bg-destructive/90"
cancelLabel="Keep Connection" cancelLabel="Keep Connection"
/> />
</DashboardPageLayout> </DashboardPageLayout>

View File

@ -175,7 +175,7 @@ export default function ForgejoConnectionsPage() {
errorMessage={deleteError} errorMessage={deleteError}
confirmLabel="Delete Connection" confirmLabel="Delete Connection"
confirmingLabel="Deleting…" confirmingLabel="Deleting…"
confirmClassName="bg-[color:var(--danger)] text-white hover:bg-[color:var(--danger)]/90" confirmClassName="bg-destructive text-destructive-foreground hover:bg-destructive/90"
cancelLabel="Keep Connection" cancelLabel="Keep Connection"
/> />
</> </>

View File

@ -177,7 +177,7 @@ export default function ForgejoRepositoriesEditPage({
errorMessage={deleteError} errorMessage={deleteError}
confirmLabel="Delete Repository" confirmLabel="Delete Repository"
confirmingLabel="Deleting…" confirmingLabel="Deleting…"
confirmClassName="bg-[color:var(--danger)] text-white hover:bg-[color:var(--danger)]/90" confirmClassName="bg-destructive text-destructive-foreground hover:bg-destructive/90"
cancelLabel="Keep Repository" cancelLabel="Keep Repository"
/> />
</DashboardPageLayout> </DashboardPageLayout>

View File

@ -201,7 +201,7 @@ export default function ForgejoRepositoriesPage() {
errorMessage={deleteError} errorMessage={deleteError}
confirmLabel="Delete Repository" confirmLabel="Delete Repository"
confirmingLabel="Deleting…" confirmingLabel="Deleting…"
confirmClassName="bg-[color:var(--danger)] text-white hover:bg-[color:var(--danger)]/90" confirmClassName="bg-destructive text-destructive-foreground hover:bg-destructive/90"
cancelLabel="Keep Repository" cancelLabel="Keep Repository"
/> />
</> </>

View File

@ -152,7 +152,7 @@ export default function InvitePage() {
<Suspense <Suspense
fallback={ fallback={
<div className="min-h-screen bg-app text-strong"> <div className="min-h-screen bg-app text-strong">
<header className="border-b border-[color:var(--border)] bg-white"> <header className="border-b border-[color:var(--border)] bg-card">
<div className="mx-auto flex max-w-5xl items-center justify-between px-6 py-4"> <div className="mx-auto flex max-w-5xl items-center justify-between px-6 py-4">
<BrandMark /> <BrandMark />
</div> </div>

View File

@ -5,8 +5,8 @@ export default function Loading() {
className="flex min-h-screen items-center justify-center bg-app px-6" className="flex min-h-screen items-center justify-center bg-app px-6"
> >
<div className="flex flex-col items-center gap-3"> <div className="flex flex-col items-center gap-3">
<div className="h-10 w-10 animate-spin rounded-full border-2 border-slate-200 border-t-[var(--accent)]" /> <div className="h-10 w-10 animate-spin rounded-full border-2 border-border border-t-[var(--accent)]" />
<p className="text-sm text-slate-500">Loading pipeline...</p> <p className="text-sm text-muted-foreground">Loading pipeline...</p>
</div> </div>
</div> </div>
); );

View File

@ -115,12 +115,12 @@ export default function OnboardingPage() {
<DashboardShell> <DashboardShell>
<SignedOut> <SignedOut>
<div className="lg:col-span-2 flex min-h-[70vh] items-center justify-center"> <div className="lg:col-span-2 flex min-h-[70vh] items-center justify-center">
<div className="w-full max-w-2xl rounded-xl border border-slate-200 bg-white shadow-sm"> <div className="w-full max-w-2xl rounded-xl border border-border bg-card shadow-sm">
<div className="border-b border-slate-100 px-6 py-5"> <div className="border-b border-border px-6 py-5">
<h1 className="text-2xl font-semibold tracking-tight text-slate-900"> <h1 className="text-2xl font-semibold tracking-tight text-foreground">
Pipeline profile Pipeline profile
</h1> </h1>
<p className="mt-1 text-sm text-slate-600"> <p className="mt-1 text-sm text-muted-foreground">
Sign in to configure your profile and timezone. Sign in to configure your profile and timezone.
</p> </p>
</div> </div>
@ -138,12 +138,12 @@ export default function OnboardingPage() {
</SignedOut> </SignedOut>
<SignedIn> <SignedIn>
<div className="lg:col-span-2 flex min-h-[70vh] items-center justify-center"> <div className="lg:col-span-2 flex min-h-[70vh] items-center justify-center">
<section className="w-full max-w-2xl rounded-xl border border-slate-200 bg-white shadow-sm"> <section className="w-full max-w-2xl rounded-xl border border-border bg-card shadow-sm">
<div className="border-b border-slate-100 px-6 py-5"> <div className="border-b border-border px-6 py-5">
<h1 className="text-2xl font-semibold tracking-tight text-slate-900"> <h1 className="text-2xl font-semibold tracking-tight text-foreground">
Pipeline profile Pipeline profile
</h1> </h1>
<p className="mt-1 text-sm text-slate-600"> <p className="mt-1 text-sm text-muted-foreground">
Configure your Pipeline settings and preferences. Configure your Pipeline settings and preferences.
</p> </p>
</div> </div>
@ -151,8 +151,8 @@ export default function OnboardingPage() {
<form onSubmit={handleSubmit} className="space-y-6"> <form onSubmit={handleSubmit} className="space-y-6">
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-700 flex items-center gap-2"> <label className="text-sm font-medium text-muted-foreground flex items-center gap-2">
<User className="h-4 w-4 text-slate-500" /> <User className="h-4 w-4 text-muted-foreground" />
Name Name
<span className="text-red-500">*</span> <span className="text-red-500">*</span>
</label> </label>
@ -161,12 +161,12 @@ export default function OnboardingPage() {
onChange={(event) => setName(event.target.value)} onChange={(event) => setName(event.target.value)}
placeholder="Enter your name" placeholder="Enter your name"
disabled={isLoading} disabled={isLoading}
className="border-slate-300 text-slate-900 focus-visible:ring-blue-500" className="border-input text-foreground focus-visible:ring-ring"
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-700 flex items-center gap-2"> <label className="text-sm font-medium text-muted-foreground flex items-center gap-2">
<Globe className="h-4 w-4 text-slate-500" /> <Globe className="h-4 w-4 text-muted-foreground" />
Timezone Timezone
<span className="text-red-500">*</span> <span className="text-red-500">*</span>
</label> </label>
@ -185,8 +185,8 @@ export default function OnboardingPage() {
</div> </div>
</div> </div>
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4 text-sm text-blue-800 flex items-start gap-3"> <div className="flex items-start gap-3 rounded-lg border border-border bg-muted p-4 text-sm text-muted-foreground">
<Info className="mt-0.5 h-4 w-4 text-blue-600" /> <Info className="mt-0.5 h-4 w-4 text-primary" />
<p> <p>
<strong>Note:</strong> Your timezone is used to display all <strong>Note:</strong> Your timezone is used to display all
timestamps and schedule mission-critical events accurately. timestamps and schedule mission-critical events accurately.
@ -194,7 +194,7 @@ export default function OnboardingPage() {
</div> </div>
{errorMessage ? ( {errorMessage ? (
<div className="rounded-lg border border-slate-200 bg-slate-50 p-3 text-xs text-slate-600"> <div className="rounded-lg border border-border bg-muted p-3 text-xs text-muted-foreground">
{errorMessage} {errorMessage}
</div> </div>
) : null} ) : null}
@ -202,26 +202,27 @@ export default function OnboardingPage() {
<div className="flex flex-wrap gap-3 pt-2"> <div className="flex flex-wrap gap-3 pt-2">
<Button <Button
type="submit" type="submit"
className="flex-1 bg-blue-600 text-white hover:bg-blue-700 py-2.5" className="flex-1 py-2.5"
disabled={isLoading || requiredMissing} disabled={isLoading || requiredMissing}
> >
<Save className="h-4 w-4" /> <Save className="h-4 w-4" />
{isLoading ? "Saving…" : "Save Profile"} {isLoading ? "Saving…" : "Save Profile"}
</Button> </Button>
<button <Button
type="button" type="button"
variant="outline"
onClick={() => { onClick={() => {
setName(""); setName("");
setTimezone(""); setTimezone("");
setError(null); setError(null);
}} }}
className="flex-1 rounded-md border border-slate-300 px-4 py-2.5 text-sm font-medium text-slate-700 transition-colors hover:bg-slate-50" className="flex-1 py-2.5"
> >
<span className="inline-flex items-center gap-2"> <span className="inline-flex items-center gap-2">
<RotateCcw className="h-4 w-4" /> <RotateCcw className="h-4 w-4" />
Reset Reset
</span> </span>
</button> </Button>
</div> </div>
</form> </form>
</div> </div>

View File

@ -157,17 +157,17 @@ function BoardAccessEditor({
return ( return (
<div className="space-y-3"> <div className="space-y-3">
<div> <div>
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Board access Board access
</p> </p>
<div className="mt-3 inline-flex rounded-xl border border-slate-200 bg-slate-100 p-1"> <div className="mt-3 inline-flex rounded-xl border border-border bg-accent p-1">
<button <button
type="button" type="button"
className={cn( className={cn(
"rounded-md px-3 py-1.5 text-xs font-semibold transition", "rounded-md px-3 py-1.5 text-xs font-semibold transition",
scope === "all" scope === "all"
? "bg-white text-slate-900 shadow-sm" ? "bg-card text-foreground shadow-sm"
: "text-slate-500 hover:text-slate-700", : "text-muted-foreground hover:text-muted-foreground",
)} )}
onClick={() => onScopeChange("all")} onClick={() => onScopeChange("all")}
disabled={disabled} disabled={disabled}
@ -179,8 +179,8 @@ function BoardAccessEditor({
className={cn( className={cn(
"rounded-md px-3 py-1.5 text-xs font-semibold transition", "rounded-md px-3 py-1.5 text-xs font-semibold transition",
scope === "custom" scope === "custom"
? "bg-white text-slate-900 shadow-sm" ? "bg-card text-foreground shadow-sm"
: "text-slate-500 hover:text-slate-700", : "text-muted-foreground hover:text-muted-foreground",
)} )}
onClick={() => onScopeChange("custom")} onClick={() => onScopeChange("custom")}
disabled={disabled} disabled={disabled}
@ -191,8 +191,8 @@ function BoardAccessEditor({
</div> </div>
{scope === "all" ? ( {scope === "all" ? (
<div className="flex flex-wrap items-center gap-6 rounded-xl border border-slate-200 bg-white px-4 py-2.5 text-sm"> <div className="flex flex-wrap items-center gap-6 rounded-xl border border-border bg-card px-4 py-2.5 text-sm">
<label className="flex items-center gap-2 text-slate-600"> <label className="flex items-center gap-2 text-muted-foreground">
<input <input
type="checkbox" type="checkbox"
className="h-4 w-4" className="h-4 w-4"
@ -202,7 +202,7 @@ function BoardAccessEditor({
/> />
Read Read
</label> </label>
<label className="flex items-center gap-2 text-slate-600"> <label className="flex items-center gap-2 text-muted-foreground">
<input <input
type="checkbox" type="checkbox"
className="h-4 w-4" className="h-4 w-4"
@ -212,18 +212,18 @@ function BoardAccessEditor({
/> />
Write Write
</label> </label>
<span className="text-xs text-slate-500"> <span className="text-xs text-muted-foreground">
Write access implies read permissions. Write access implies read permissions.
</span> </span>
</div> </div>
) : ( ) : (
<div> <div>
{boards.length === 0 ? ( {boards.length === 0 ? (
<div className="rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-500"> <div className="rounded-xl border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
{emptyMessage ?? "No boards available yet."} {emptyMessage ?? "No boards available yet."}
</div> </div>
) : ( ) : (
<div className="overflow-hidden rounded-xl border border-slate-200"> <div className="overflow-hidden rounded-xl border border-border">
<BoardAccessTable <BoardAccessTable
boards={boards} boards={boards}
access={access} access={access}
@ -702,13 +702,13 @@ export default function OrganizationPage() {
</SignedOut> </SignedOut>
<SignedIn> <SignedIn>
<DashboardSidebar /> <DashboardSidebar />
<main className="flex-1 overflow-y-auto bg-slate-50"> <main className="flex-1 overflow-y-auto bg-muted">
<div className="sticky top-0 z-30 border-b border-slate-200 bg-white"> <div className="sticky top-0 z-30 border-b border-border bg-card">
<div className="px-4 py-4 md:px-8 md:py-6"> <div className="px-4 py-4 md:px-8 md:py-6">
<div className="flex flex-wrap items-center justify-between gap-6"> <div className="flex flex-wrap items-center justify-between gap-6">
<div> <div>
<div className="flex flex-wrap items-center gap-3"> <div className="flex flex-wrap items-center gap-3">
<h1 className="text-2xl font-semibold tracking-tight text-slate-900"> <h1 className="text-2xl font-semibold tracking-tight text-foreground">
Organization Organization
</h1> </h1>
<Badge <Badge
@ -719,24 +719,24 @@ export default function OrganizationPage() {
{orgName} {orgName}
</Badge> </Badge>
</div> </div>
<p className="mt-1 text-sm text-slate-500"> <p className="mt-1 text-sm text-muted-foreground">
Manage members and board access across your workspace. Manage members and board access across your workspace.
</p> </p>
<div className="mt-3 flex flex-wrap items-center gap-4 text-xs text-slate-500"> <div className="mt-3 flex flex-wrap items-center gap-4 text-xs text-muted-foreground">
<span> <span>
<strong className="text-slate-900"> <strong className="text-foreground">
{members.length} {members.length}
</strong>{" "} </strong>{" "}
members members
</span> </span>
<span> <span>
<strong className="text-slate-900"> <strong className="text-foreground">
{boards.length} {boards.length}
</strong>{" "} </strong>{" "}
boards boards
</span> </span>
<span> <span>
<strong className="text-slate-900"> <strong className="text-foreground">
{invites.length} {invites.length}
</strong>{" "} </strong>{" "}
pending pending
@ -776,17 +776,17 @@ export default function OrganizationPage() {
</div> </div>
<div className="px-4 py-4 md:px-8 md:py-8"> <div className="px-4 py-4 md:px-8 md:py-8">
<div className="overflow-hidden rounded-2xl border border-slate-200 bg-white"> <div className="overflow-hidden rounded-2xl border border-border bg-card">
<div className="flex flex-wrap items-center justify-between gap-3 border-b border-slate-200 px-5 py-4"> <div className="flex flex-wrap items-center justify-between gap-3 border-b border-border px-5 py-4">
<div> <div>
<h2 className="text-sm font-semibold text-slate-900"> <h2 className="text-sm font-semibold text-foreground">
Members & invites Members & invites
</h2> </h2>
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Invite teammates and tune their board permissions. Invite teammates and tune their board permissions.
</p> </p>
</div> </div>
<div className="flex items-center gap-2 text-xs text-slate-500"> <div className="flex items-center gap-2 text-xs text-muted-foreground">
<Users className="h-4 w-4" /> <Users className="h-4 w-4" />
{members.length + invites.length} total {members.length + invites.length} total
</div> </div>
@ -829,7 +829,7 @@ export default function OrganizationPage() {
<form className="space-y-5" onSubmit={handleInviteSubmit}> <form className="space-y-5" onSubmit={handleInviteSubmit}>
<div className="grid gap-4 sm:grid-cols-[1fr_200px]"> <div className="grid gap-4 sm:grid-cols-[1fr_200px]">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Email address Email address
</label> </label>
<Input <Input
@ -841,7 +841,7 @@ export default function OrganizationPage() {
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Role Role
</label> </label>
<Select value={inviteRole} onValueChange={setInviteRole}> <Select value={inviteRole} onValueChange={setInviteRole}>
@ -893,7 +893,7 @@ export default function OrganizationPage() {
</DialogFooter> </DialogFooter>
</form> </form>
) : ( ) : (
<div className="rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-500"> <div className="rounded-xl border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
Only organization admins can invite new members. Only organization admins can invite new members.
</div> </div>
)} )}
@ -910,26 +910,26 @@ export default function OrganizationPage() {
</DialogHeader> </DialogHeader>
{memberDetailsQuery.isLoading ? ( {memberDetailsQuery.isLoading ? (
<div className="rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-500"> <div className="rounded-xl border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
Loading member access... Loading member access...
</div> </div>
) : memberDetailsQuery.data?.status === 200 ? ( ) : memberDetailsQuery.data?.status === 200 ? (
<div className="space-y-6"> <div className="space-y-6">
<div className="rounded-xl border border-slate-200 bg-white px-5 py-4"> <div className="rounded-xl border border-border bg-card px-5 py-4">
<p className="text-sm font-semibold text-slate-900"> <p className="text-sm font-semibold text-foreground">
{memberDetailsQuery.data.data.user?.name || {memberDetailsQuery.data.data.user?.name ||
memberDetailsQuery.data.data.user?.preferred_name || memberDetailsQuery.data.data.user?.preferred_name ||
memberDetailsQuery.data.data.user?.email || memberDetailsQuery.data.data.user?.email ||
memberDetailsQuery.data.data.user_id} memberDetailsQuery.data.data.user_id}
</p> </p>
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-muted-foreground">
{memberDetailsQuery.data.data.user?.email ?? {memberDetailsQuery.data.data.user?.email ??
"No email on file"} "No email on file"}
</p> </p>
</div> </div>
<div className="space-y-3"> <div className="space-y-3">
<label className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Role Role
</label> </label>
<Select <Select
@ -967,7 +967,7 @@ export default function OrganizationPage() {
) : null} ) : null}
</div> </div>
) : ( ) : (
<div className="rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-500"> <div className="rounded-xl border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
Unable to load member access. Unable to load member access.
</div> </div>
)} )}

View File

@ -683,7 +683,7 @@ export default function GitProjectSettingsPage() {
errorMessage={deleteError} errorMessage={deleteError}
confirmLabel="Delete" confirmLabel="Delete"
confirmingLabel="Deleting…" confirmingLabel="Deleting…"
confirmClassName="bg-[color:var(--danger)] text-white hover:bg-[color:var(--danger)]/90" confirmClassName="bg-destructive text-destructive-foreground hover:bg-destructive/90"
cancelLabel="Keep" cancelLabel="Keep"
/> />
</> </>

View File

@ -161,17 +161,17 @@ export default function SettingsPage() {
description="Update your profile and account preferences." description="Update your profile and account preferences."
> >
<div className="space-y-6"> <div className="space-y-6">
<section className="rounded-xl border border-slate-200 bg-white p-6 shadow-sm"> <section className="rounded-xl border border-border bg-card p-6 shadow-sm">
<h2 className="text-base font-semibold text-slate-900">Profile</h2> <h2 className="text-base font-semibold text-foreground">Profile</h2>
<p className="mt-1 text-sm text-slate-500"> <p className="mt-1 text-sm text-muted-foreground">
Keep your identity and timezone up to date. Keep your identity and timezone up to date.
</p> </p>
<form onSubmit={handleSave} className="mt-6 space-y-5"> <form onSubmit={handleSave} className="mt-6 space-y-5">
<div className="grid gap-5 md:grid-cols-2"> <div className="grid gap-5 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="flex items-center gap-2 text-sm font-medium text-slate-700"> <label className="flex items-center gap-2 text-sm font-medium text-muted-foreground">
<User className="h-4 w-4 text-slate-500" /> <User className="h-4 w-4 text-muted-foreground" />
Name Name
</label> </label>
<Input <Input
@ -182,12 +182,12 @@ export default function SettingsPage() {
}} }}
placeholder="Your name" placeholder="Your name"
disabled={isSaving} disabled={isSaving}
className="border-slate-300 [--input-bg:#fff] [--input-text:#0f172a] placeholder:text-slate-500 focus-visible:ring-blue-500" className="border-input [--input-bg:var(--card)] [--input-text:var(--card-foreground)] placeholder:text-muted-foreground focus-visible:ring-ring"
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="flex items-center gap-2 text-sm font-medium text-slate-700"> <label className="flex items-center gap-2 text-sm font-medium text-muted-foreground">
<Globe className="h-4 w-4 text-slate-500" /> <Globe className="h-4 w-4 text-muted-foreground" />
Timezone Timezone
</label> </label>
<SearchableSelect <SearchableSelect
@ -210,15 +210,15 @@ export default function SettingsPage() {
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="flex items-center gap-2 text-sm font-medium text-slate-700"> <label className="flex items-center gap-2 text-sm font-medium text-muted-foreground">
<Mail className="h-4 w-4 text-slate-500" /> <Mail className="h-4 w-4 text-muted-foreground" />
Email Email
</label> </label>
<Input <Input
value={displayEmail} value={displayEmail}
readOnly readOnly
disabled disabled
className="border-slate-200 [--input-bg:#f8fafc] [--input-text:#475569]" className="border-border [--input-bg:var(--muted)] [--input-text:var(--muted-foreground)]"
/> />
</div> </div>
@ -251,14 +251,14 @@ export default function SettingsPage() {
</form> </form>
</section> </section>
<section className="rounded-xl border border-slate-200 bg-white p-6 shadow-sm"> <section className="rounded-xl border border-border bg-card p-6 shadow-sm">
<div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between"> <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
<div className="min-w-0"> <div className="min-w-0">
<h2 className="flex items-center gap-2 text-base font-semibold text-slate-900"> <h2 className="flex items-center gap-2 text-base font-semibold text-foreground">
<GitBranch className="h-4 w-4 text-slate-500" /> <GitBranch className="h-4 w-4 text-muted-foreground" />
Git Projects Git Projects
</h2> </h2>
<p className="mt-1 text-sm text-slate-500"> <p className="mt-1 text-sm text-muted-foreground">
Manage Forgejo connections, tracked repositories, and issue Manage Forgejo connections, tracked repositories, and issue
sync. sync.
</p> </p>
@ -283,7 +283,7 @@ export default function SettingsPage() {
<div className="mt-4"> <div className="mt-4">
<Button <Button
type="button" type="button"
className="bg-rose-600 text-white hover:bg-rose-700" className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
onClick={() => { onClick={() => {
setDeleteError(null); setDeleteError(null);
setDeleteDialogOpen(true); setDeleteDialogOpen(true);

View File

@ -21,7 +21,7 @@ export default function SignInPage() {
// Dedicated sign-in route for Cypress E2E. // Dedicated sign-in route for Cypress E2E.
// Avoids modal/iframe auth flows and gives Cypress a stable top-level page. // Avoids modal/iframe auth flows and gives Cypress a stable top-level page.
return ( return (
<main className="flex min-h-screen items-center justify-center bg-slate-50 p-6"> <main className="flex min-h-screen items-center justify-center bg-muted p-6">
<SignIn <SignIn
routing="path" routing="path"
path="/sign-in" path="/sign-in"

View File

@ -788,8 +788,8 @@ export default function SkillsMarketplacePage() {
> >
<div className="space-y-6"> <div className="space-y-6">
{gateways.length === 0 ? ( {gateways.length === 0 ? (
<div className="rounded-xl border border-slate-200 bg-white p-6 text-sm text-slate-600 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 text-sm text-muted-foreground shadow-sm">
<p className="font-medium text-slate-900"> <p className="font-medium text-foreground">
No gateways available yet. No gateways available yet.
</p> </p>
<p className="mt-2"> <p className="mt-2">
@ -804,12 +804,12 @@ export default function SkillsMarketplacePage() {
</div> </div>
) : ( ) : (
<> <>
<div className="mb-5 rounded-xl border border-slate-200 bg-white p-4 shadow-sm"> <div className="mb-5 rounded-xl border border-border bg-card p-4 shadow-sm">
<div className="grid gap-4 md:grid-cols-[1fr_240px_240px]"> <div className="grid gap-4 md:grid-cols-[1fr_240px_240px]">
<div> <div>
<label <label
htmlFor="marketplace-search" htmlFor="marketplace-search"
className="mb-1 block text-sm font-medium text-slate-700" className="mb-1 block text-sm font-medium text-muted-foreground"
> >
Search Search
</label> </label>
@ -824,7 +824,7 @@ export default function SkillsMarketplacePage() {
<div> <div>
<label <label
htmlFor="marketplace-category-filter" htmlFor="marketplace-category-filter"
className="mb-1 block text-sm font-medium text-slate-700" className="mb-1 block text-sm font-medium text-muted-foreground"
> >
Category Category
</label> </label>
@ -854,7 +854,7 @@ export default function SkillsMarketplacePage() {
<div> <div>
<label <label
htmlFor="marketplace-risk-filter" htmlFor="marketplace-risk-filter"
className="mb-1 block text-sm font-medium text-slate-700" className="mb-1 block text-sm font-medium text-muted-foreground"
> >
Risk Risk
</label> </label>
@ -880,7 +880,7 @@ export default function SkillsMarketplacePage() {
</div> </div>
</div> </div>
</div> </div>
<div className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm"> <div className="overflow-hidden rounded-xl border border-border bg-card shadow-sm">
<MarketplaceSkillsTable <MarketplaceSkillsTable
skills={filteredSkills} skills={filteredSkills}
installedGatewayNamesBySkillId={ installedGatewayNamesBySkillId={
@ -901,13 +901,13 @@ export default function SkillsMarketplacePage() {
}} }}
/> />
</div> </div>
<div className="flex items-center justify-between rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm text-slate-600 shadow-sm"> <div className="flex items-center justify-between rounded-xl border border-border bg-card px-4 py-3 text-sm text-muted-foreground shadow-sm">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<p> <p>
Showing {rangeStart}-{rangeEnd} of {totalSkills} Showing {rangeStart}-{rangeEnd} of {totalSkills}
</p> </p>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<span className="text-xs font-medium uppercase tracking-wide text-slate-500"> <span className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
Rows Rows
</span> </span>
<Select <Select
@ -951,7 +951,7 @@ export default function SkillsMarketplacePage() {
> >
Previous Previous
</Button> </Button>
<span className="text-xs font-medium uppercase tracking-wide text-slate-500"> <span className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
{totalCountInfo.hasKnownTotal {totalCountInfo.hasKnownTotal
? `Page ${currentPage} of ${totalPages}` ? `Page ${currentPage} of ${totalPages}`
: `Page ${currentPage}`} : `Page ${currentPage}`}

View File

@ -54,7 +54,7 @@ export default function EditSkillPackPage() {
stickyHeader stickyHeader
> >
{packQuery.isLoading ? ( {packQuery.isLoading ? (
<div className="rounded-xl border border-slate-200 bg-white p-6 text-sm text-slate-500 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 text-sm text-muted-foreground shadow-sm">
Loading pack... Loading pack...
</div> </div>
) : packQuery.error ? ( ) : packQuery.error ? (
@ -62,7 +62,7 @@ export default function EditSkillPackPage() {
{packQuery.error.message} {packQuery.error.message}
</div> </div>
) : !pack ? ( ) : !pack ? (
<div className="rounded-xl border border-slate-200 bg-white p-6 text-sm text-slate-500 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 text-sm text-muted-foreground shadow-sm">
Pack not found. Pack not found.
</div> </div>
) : ( ) : (

View File

@ -231,7 +231,7 @@ export default function SkillsPacksPage() {
stickyHeader stickyHeader
> >
<div className="space-y-6"> <div className="space-y-6">
<div className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm"> <div className="overflow-hidden rounded-xl border border-border bg-card shadow-sm">
<SkillPacksTable <SkillPacksTable
packs={packs} packs={packs}
isLoading={packsQuery.isLoading} isLoading={packsQuery.isLoading}

View File

@ -60,7 +60,7 @@ export default function EditTagPage() {
adminOnlyMessage="Only organization owners and admins can manage tags." adminOnlyMessage="Only organization owners and admins can manage tags."
> >
{tagQuery.isLoading ? ( {tagQuery.isLoading ? (
<div className="rounded-xl border border-slate-200 bg-white p-6 text-sm text-slate-500 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 text-sm text-muted-foreground shadow-sm">
Loading tag Loading tag
</div> </div>
) : tagQuery.error ? ( ) : tagQuery.error ? (
@ -68,7 +68,7 @@ export default function EditTagPage() {
{tagQuery.error.message} {tagQuery.error.message}
</div> </div>
) : !tag ? ( ) : !tag ? (
<div className="rounded-xl border border-slate-200 bg-white p-6 text-sm text-slate-500 shadow-sm"> <div className="rounded-xl border border-border bg-card p-6 text-sm text-muted-foreground shadow-sm">
Tag not found. Tag not found.
</div> </div>
) : ( ) : (

View File

@ -100,7 +100,7 @@ export default function TagsPage() {
adminOnlyMessage="Only organization owners and admins can manage tags." adminOnlyMessage="Only organization owners and admins can manage tags."
stickyHeader stickyHeader
> >
<div className="overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm"> <div className="overflow-hidden rounded-xl border border-border bg-card shadow-sm">
<TagsTable <TagsTable
tags={tags} tags={tags}
isLoading={tagsQuery.isLoading} isLoading={tagsQuery.isLoading}

View File

@ -134,14 +134,14 @@ const formatRubricTooltipValue = (
return ( return (
<div className="flex w-full items-center justify-between gap-3"> <div className="flex w-full items-center justify-between gap-3">
<span className="flex items-center gap-2 text-slate-600"> <span className="flex items-center gap-2 text-muted-foreground">
<span <span
className="h-2.5 w-2.5 rounded-[2px]" className="h-2.5 w-2.5 rounded-[2px]"
style={{ backgroundColor: indicatorColor }} style={{ backgroundColor: indicatorColor }}
/> />
<span>{label}</span> <span>{label}</span>
</span> </span>
<span className="font-mono font-medium tabular-nums text-slate-900"> <span className="font-mono font-medium tabular-nums text-foreground">
{displayValue} {displayValue}
</span> </span>
</div> </div>
@ -554,11 +554,11 @@ export function BoardApprovalsPanel({
</div> </div>
) : null} ) : null}
{loadingState ? ( {loadingState ? (
<p className="text-sm text-slate-500">Loading approvals</p> <p className="text-sm text-muted-foreground">Loading approvals</p>
) : pendingCount === 0 && resolvedCount === 0 ? ( ) : pendingCount === 0 && resolvedCount === 0 ? (
<div <div
className={cn( className={cn(
"rounded-xl border border-dashed border-slate-200 bg-white px-6 py-10 text-center", "rounded-xl border border-dashed border-border bg-card px-6 py-10 text-center",
scrollable && "flex h-full items-center justify-center", scrollable && "flex h-full items-center justify-center",
)} )}
> >
@ -566,10 +566,10 @@ export function BoardApprovalsPanel({
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-emerald-50 text-emerald-600"> <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-emerald-50 text-emerald-600">
<CheckCircle2 className="h-6 w-6" /> <CheckCircle2 className="h-6 w-6" />
</div> </div>
<p className="mt-4 text-sm font-semibold text-slate-900"> <p className="mt-4 text-sm font-semibold text-foreground">
All clear All clear
</p> </p>
<p className="mt-2 text-sm text-slate-500"> <p className="mt-2 text-sm text-muted-foreground">
No approvals to review right now. New approvals will show up here No approvals to review right now. New approvals will show up here
as soon as they arrive. as soon as they arrive.
</p> </p>
@ -584,15 +584,15 @@ export function BoardApprovalsPanel({
> >
<div <div
className={cn( className={cn(
"overflow-hidden rounded-xl border border-slate-200 bg-white", "overflow-hidden rounded-xl border border-border bg-card",
scrollable && "flex min-h-0 flex-col", scrollable && "flex min-h-0 flex-col",
)} )}
> >
<div className="border-b border-slate-200 bg-slate-50 px-4 py-3"> <div className="border-b border-border bg-muted px-4 py-3">
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500"> <p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">
Unapproved tasks Unapproved tasks
</p> </p>
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-muted-foreground">
{pendingCount} pending · {resolvedCount} resolved {pendingCount} pending · {resolvedCount} resolved
</p> </p>
</div> </div>
@ -632,13 +632,13 @@ export function BoardApprovalsPanel({
type="button" type="button"
onClick={() => setSelectedId(approval.id)} onClick={() => setSelectedId(approval.id)}
className={cn( className={cn(
"w-full px-4 py-4 text-left transition hover:bg-slate-50", "w-full px-4 py-4 text-left transition hover:bg-muted",
isSelected && "bg-amber-50 border-l-2 border-amber-500", isSelected && "bg-amber-50 border-l-2 border-amber-500",
!isPending && "opacity-60", !isPending && "opacity-60",
)} )}
> >
<div className="flex items-start justify-between gap-3"> <div className="flex items-start justify-between gap-3">
<span className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500"> <span className="text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground">
{humanizeAction(approval.action_type)} {humanizeAction(approval.action_type)}
</span> </span>
<span <span
@ -650,16 +650,16 @@ export function BoardApprovalsPanel({
{formatStatusLabel(approval.status)} {formatStatusLabel(approval.status)}
</span> </span>
</div> </div>
<p className="mt-2 text-sm font-semibold text-slate-900"> <p className="mt-2 text-sm font-semibold text-foreground">
{primaryLabel} {primaryLabel}
</p> </p>
{boardText ? ( {boardText ? (
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-muted-foreground">
Board · {boardText} Board · {boardText}
</p> </p>
) : null} ) : null}
<div className="mt-2 flex items-center gap-2 text-xs text-slate-500"> <div className="mt-2 flex items-center gap-2 text-xs text-muted-foreground">
<span className="rounded bg-slate-100 px-1.5 py-0.5 font-semibold text-slate-700"> <span className="rounded bg-accent px-1.5 py-0.5 font-semibold text-muted-foreground">
{approval.confidence}% score {approval.confidence}% score
</span> </span>
<Clock className="h-3.5 w-3.5 opacity-60" /> <Clock className="h-3.5 w-3.5 opacity-60" />
@ -673,19 +673,19 @@ export function BoardApprovalsPanel({
<div <div
className={cn( className={cn(
"overflow-hidden rounded-xl border border-slate-200 bg-white", "overflow-hidden rounded-xl border border-border bg-card",
scrollable && "flex min-h-0 flex-col", scrollable && "flex min-h-0 flex-col",
)} )}
> >
<div className="border-b border-slate-200 bg-slate-50 px-4 py-3"> <div className="border-b border-border bg-muted px-4 py-3">
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500"> <p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">
{selectedApproval?.status === "pending" {selectedApproval?.status === "pending"
? "Latest unapproved task" ? "Latest unapproved task"
: "Approval detail"} : "Approval detail"}
</p> </p>
</div> </div>
{!selectedApproval ? ( {!selectedApproval ? (
<div className="flex h-full items-center justify-center px-6 py-10 text-sm text-slate-500"> <div className="flex h-full items-center justify-center px-6 py-10 text-sm text-muted-foreground">
Select an approval to review details. Select an approval to review details.
</div> </div>
) : ( ) : (
@ -755,10 +755,10 @@ export function BoardApprovalsPanel({
<div className="flex h-full flex-col gap-6 px-6 py-6"> <div className="flex h-full flex-col gap-6 px-6 py-6">
<div className="flex flex-wrap items-start justify-between gap-3"> <div className="flex flex-wrap items-start justify-between gap-3">
<div> <div>
<p className="text-lg font-semibold text-slate-900"> <p className="text-lg font-semibold text-foreground">
{humanizeAction(selectedApproval.action_type)} {humanizeAction(selectedApproval.action_type)}
</p> </p>
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-muted-foreground">
Requested{" "} Requested{" "}
{formatTimestamp(selectedApproval.created_at)} {formatTimestamp(selectedApproval.created_at)}
</p> </p>
@ -781,7 +781,7 @@ export function BoardApprovalsPanel({
handleDecision(selectedApproval.id, "approved") handleDecision(selectedApproval.id, "approved")
} }
disabled={updatingId === selectedApproval.id} disabled={updatingId === selectedApproval.id}
className="bg-slate-900 text-white hover:bg-slate-800" className="bg-foreground text-background hover:bg-foreground/90"
> >
Approve Approve
</Button> </Button>
@ -792,7 +792,7 @@ export function BoardApprovalsPanel({
handleDecision(selectedApproval.id, "rejected") handleDecision(selectedApproval.id, "rejected")
} }
disabled={updatingId === selectedApproval.id} disabled={updatingId === selectedApproval.id}
className="border-slate-300 text-slate-700 hover:bg-slate-100" className="border-input text-muted-foreground hover:bg-accent"
> >
Reject Reject
</Button> </Button>
@ -801,17 +801,17 @@ export function BoardApprovalsPanel({
</div> </div>
</div> </div>
<div className="flex items-center gap-3 rounded-lg border border-slate-200 bg-slate-50 px-4 py-3"> <div className="flex items-center gap-3 rounded-lg border border-border bg-muted px-4 py-3">
<StatusDot <StatusDot
status={selectedApproval.status} status={selectedApproval.status}
variant="approval" variant="approval"
className={cn("h-2 w-2 rounded-full")} className={cn("h-2 w-2 rounded-full")}
/> />
<div> <div>
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500"> <p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">
Status Status
</p> </p>
<p className="text-sm font-medium text-slate-700"> <p className="text-sm font-medium text-muted-foreground">
{formatStatusLabel(selectedApproval.status)} ·{" "} {formatStatusLabel(selectedApproval.status)} ·{" "}
{selectedApproval.status === "pending" {selectedApproval.status === "pending"
? "Awaiting your decision" ? "Awaiting your decision"
@ -822,10 +822,10 @@ export function BoardApprovalsPanel({
{titleText ? ( {titleText ? (
<div className="space-y-2"> <div className="space-y-2">
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500"> <p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">
Title Title
</p> </p>
<div className="text-sm font-medium text-slate-900"> <div className="text-sm font-medium text-foreground">
{titleText} {titleText}
</div> </div>
</div> </div>
@ -833,10 +833,10 @@ export function BoardApprovalsPanel({
{descriptionText ? ( {descriptionText ? (
<div className="space-y-2"> <div className="space-y-2">
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500"> <p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">
Description Description
</p> </p>
<div className="rounded-lg border border-slate-200 bg-white px-4 py-3 text-sm text-slate-700"> <div className="rounded-lg border border-border bg-card px-4 py-3 text-sm text-muted-foreground">
{descriptionText} {descriptionText}
</div> </div>
</div> </div>
@ -844,10 +844,10 @@ export function BoardApprovalsPanel({
{reasoningText ? ( {reasoningText ? (
<div className="space-y-2"> <div className="space-y-2">
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500"> <p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">
Lead reasoning Lead reasoning
</p> </p>
<div className="rounded-lg border border-slate-200 bg-white px-4 py-3 text-sm text-slate-600"> <div className="rounded-lg border border-border bg-card px-4 py-3 text-sm text-muted-foreground">
<p>{reasoningText}</p> <p>{reasoningText}</p>
</div> </div>
</div> </div>
@ -855,7 +855,7 @@ export function BoardApprovalsPanel({
{relatedTasks.length > 0 ? ( {relatedTasks.length > 0 ? (
<div className="space-y-2"> <div className="space-y-2">
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500"> <p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">
Related tasks Related tasks
</p> </p>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
@ -866,7 +866,7 @@ export function BoardApprovalsPanel({
selectedApproval.board_id, selectedApproval.board_id,
task.id, task.id,
)} )}
className="rounded-md border border-slate-200 bg-white px-2 py-1 text-xs text-slate-700 underline-offset-2 transition hover:border-slate-300 hover:bg-slate-50 hover:text-slate-900 hover:underline" className="rounded-md border border-border bg-card px-2 py-1 text-xs text-muted-foreground underline-offset-2 transition hover:border-input hover:bg-muted hover:text-foreground hover:underline"
> >
{task.title} {task.title}
</Link> </Link>
@ -877,19 +877,19 @@ export function BoardApprovalsPanel({
{extraRows.length > 0 ? ( {extraRows.length > 0 ? (
<div className="space-y-2"> <div className="space-y-2">
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500"> <p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">
Details Details
</p> </p>
<div className="grid gap-3 sm:grid-cols-2"> <div className="grid gap-3 sm:grid-cols-2">
{extraRows.map((row) => ( {extraRows.map((row) => (
<div <div
key={`${selectedApproval.id}-${row.label}`} key={`${selectedApproval.id}-${row.label}`}
className="rounded-lg border border-slate-200 bg-white px-3 py-2" className="rounded-lg border border-border bg-card px-3 py-2"
> >
<p className="text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500"> <p className="text-[10px] font-semibold uppercase tracking-[0.18em] text-muted-foreground">
{row.label} {row.label}
</p> </p>
<p className="mt-1 text-sm font-medium text-slate-900"> <p className="mt-1 text-sm font-medium text-foreground">
{row.value} {row.value}
</p> </p>
</div> </div>
@ -900,7 +900,7 @@ export function BoardApprovalsPanel({
{hasRubric ? ( {hasRubric ? (
<div className="space-y-4"> <div className="space-y-4">
<p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500"> <p className="text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">
Rubric scores Rubric scores
</p> </p>
<div className="flex flex-col gap-4 sm:flex-row sm:items-center"> <div className="flex flex-col gap-4 sm:flex-row sm:items-center">
@ -915,11 +915,11 @@ export function BoardApprovalsPanel({
className="h-2.5 w-2.5 rounded-full" className="h-2.5 w-2.5 rounded-full"
style={{ backgroundColor: entry.fill }} style={{ backgroundColor: entry.fill }}
/> />
<span className="text-slate-700"> <span className="text-muted-foreground">
{entry.name} {entry.name}
</span> </span>
</div> </div>
<span className="font-medium tabular-nums text-slate-900"> <span className="font-medium tabular-nums text-foreground">
{entry.percentLabel} {entry.percentLabel}
</span> </span>
</div> </div>

View File

@ -227,7 +227,7 @@ function BoardChatComposerImpl({
disabled={isSending || disabled} disabled={isSending || disabled}
/> />
{mentionTarget && filteredMentionOptions.length > 0 ? ( {mentionTarget && filteredMentionOptions.length > 0 ? (
<div className="absolute bottom-full left-0 z-20 mb-2 w-full overflow-hidden rounded-xl border border-slate-200 bg-white shadow-lg"> <div className="absolute bottom-full left-0 z-20 mb-2 w-full overflow-hidden rounded-xl border border-border bg-card shadow-lg">
<div className="max-h-52 overflow-y-auto py-1"> <div className="max-h-52 overflow-y-auto py-1">
{filteredMentionOptions.map((option, index) => ( {filteredMentionOptions.map((option, index) => (
<button <button
@ -239,12 +239,12 @@ function BoardChatComposerImpl({
}} }}
className={`flex w-full items-center justify-between px-3 py-2 text-left text-sm transition ${ className={`flex w-full items-center justify-between px-3 py-2 text-left text-sm transition ${
index === activeIndex index === activeIndex
? "bg-slate-100 text-slate-900" ? "bg-accent text-foreground"
: "text-slate-700 hover:bg-slate-50" : "text-muted-foreground hover:bg-muted"
}`} }`}
> >
<span className="font-mono">@{option}</span> <span className="font-mono">@{option}</span>
<span className="text-xs text-slate-400">mention</span> <span className="text-xs text-muted-foreground/70">mention</span>
</button> </button>
))} ))}
</div> </div>

View File

@ -392,13 +392,13 @@ export function BoardOnboardingChat({
{draft ? ( {draft ? (
<div className="space-y-3"> <div className="space-y-3">
<p className="text-sm text-slate-600"> <p className="text-sm text-muted-foreground">
Review the lead agent draft and confirm. Review the lead agent draft and confirm.
</p> </p>
{isAwaitingAgent ? ( {isAwaitingAgent ? (
<div className="rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-700"> <div className="rounded-xl border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
<div className="flex items-center gap-2 font-medium text-slate-900"> <div className="flex items-center gap-2 font-medium text-foreground">
<RefreshCcw className="h-4 w-4 animate-spin text-slate-500" /> <RefreshCcw className="h-4 w-4 animate-spin text-muted-foreground" />
<span> <span>
{awaitingKind === "extra_context" {awaitingKind === "extra_context"
? "Updating the draft…" ? "Updating the draft…"
@ -406,80 +406,80 @@ export function BoardOnboardingChat({
</span> </span>
</div> </div>
{lastSubmittedAnswer ? ( {lastSubmittedAnswer ? (
<p className="mt-2 text-xs text-slate-600"> <p className="mt-2 text-xs text-muted-foreground">
Sent:{" "} Sent:{" "}
<span className="font-medium text-slate-900"> <span className="font-medium text-foreground">
{lastSubmittedAnswer} {lastSubmittedAnswer}
</span> </span>
</p> </p>
) : null} ) : null}
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-muted-foreground">
This usually takes a few seconds. This usually takes a few seconds.
</p> </p>
</div> </div>
) : null} ) : null}
<div className="rounded-lg border border-slate-200 bg-slate-50 p-3 text-sm"> <div className="rounded-lg border border-border bg-muted p-3 text-sm">
<p className="font-semibold text-slate-900">Objective</p> <p className="font-semibold text-foreground">Objective</p>
<p className="text-slate-700">{draft.objective || "—"}</p> <p className="text-muted-foreground">{draft.objective || "—"}</p>
<p className="mt-3 font-semibold text-slate-900">Success metrics</p> <p className="mt-3 font-semibold text-foreground">Success metrics</p>
<pre className="mt-1 whitespace-pre-wrap text-xs text-slate-600"> <pre className="mt-1 whitespace-pre-wrap text-xs text-muted-foreground">
{JSON.stringify(draft.success_metrics ?? {}, null, 2)} {JSON.stringify(draft.success_metrics ?? {}, null, 2)}
</pre> </pre>
<p className="mt-3 font-semibold text-slate-900">Target date</p> <p className="mt-3 font-semibold text-foreground">Target date</p>
<p className="text-slate-700">{draft.target_date || "—"}</p> <p className="text-muted-foreground">{draft.target_date || "—"}</p>
<p className="mt-3 font-semibold text-slate-900">Board type</p> <p className="mt-3 font-semibold text-foreground">Board type</p>
<p className="text-slate-700">{draft.board_type || "goal"}</p> <p className="text-muted-foreground">{draft.board_type || "goal"}</p>
{draft.user_profile ? ( {draft.user_profile ? (
<> <>
<p className="mt-4 font-semibold text-slate-900"> <p className="mt-4 font-semibold text-foreground">
User profile User profile
</p> </p>
<p className="text-slate-700"> <p className="text-muted-foreground">
<span className="font-medium text-slate-900"> <span className="font-medium text-foreground">
Preferred name: Preferred name:
</span>{" "} </span>{" "}
{draft.user_profile.preferred_name || "—"} {draft.user_profile.preferred_name || "—"}
</p> </p>
<p className="text-slate-700"> <p className="text-muted-foreground">
<span className="font-medium text-slate-900">Pronouns:</span>{" "} <span className="font-medium text-foreground">Pronouns:</span>{" "}
{draft.user_profile.pronouns || "—"} {draft.user_profile.pronouns || "—"}
</p> </p>
<p className="text-slate-700"> <p className="text-muted-foreground">
<span className="font-medium text-slate-900">Timezone:</span>{" "} <span className="font-medium text-foreground">Timezone:</span>{" "}
{draft.user_profile.timezone || "—"} {draft.user_profile.timezone || "—"}
</p> </p>
</> </>
) : null} ) : null}
{draft.lead_agent ? ( {draft.lead_agent ? (
<> <>
<p className="mt-4 font-semibold text-slate-900"> <p className="mt-4 font-semibold text-foreground">
Lead agent preferences Lead agent preferences
</p> </p>
<p className="text-slate-700"> <p className="text-muted-foreground">
<span className="font-medium text-slate-900">Name:</span>{" "} <span className="font-medium text-foreground">Name:</span>{" "}
{draft.lead_agent.name || "—"} {draft.lead_agent.name || "—"}
</p> </p>
<p className="text-slate-700"> <p className="text-muted-foreground">
<span className="font-medium text-slate-900">Role:</span>{" "} <span className="font-medium text-foreground">Role:</span>{" "}
{draft.lead_agent.identity_profile?.role || "—"} {draft.lead_agent.identity_profile?.role || "—"}
</p> </p>
<p className="text-slate-700"> <p className="text-muted-foreground">
<span className="font-medium text-slate-900"> <span className="font-medium text-foreground">
Communication: Communication:
</span>{" "} </span>{" "}
{draft.lead_agent.identity_profile?.communication_style || {draft.lead_agent.identity_profile?.communication_style ||
"—"} "—"}
</p> </p>
<p className="text-slate-700"> <p className="text-muted-foreground">
<span className="font-medium text-slate-900">Emoji:</span>{" "} <span className="font-medium text-foreground">Emoji:</span>{" "}
{draft.lead_agent.identity_profile?.emoji || "—"} {draft.lead_agent.identity_profile?.emoji || "—"}
</p> </p>
</> </>
) : null} ) : null}
</div> </div>
<div className="rounded-lg border border-slate-200 bg-white p-3"> <div className="rounded-lg border border-border bg-card p-3">
<div className="flex items-center justify-between gap-2"> <div className="flex items-center justify-between gap-2">
<p className="text-sm font-semibold text-slate-900"> <p className="text-sm font-semibold text-foreground">
Extra context (optional) Extra context (optional)
</p> </p>
<Button <Button
@ -527,12 +527,12 @@ export function BoardOnboardingChat({
: "Send context"} : "Send context"}
</Button> </Button>
</div> </div>
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Tip: press Enter to send. Shift+Enter for a newline. Tip: press Enter to send. Shift+Enter for a newline.
</p> </p>
</div> </div>
) : ( ) : (
<p className="mt-2 text-xs text-slate-600"> <p className="mt-2 text-xs text-muted-foreground">
Add anything that wasn&apos;t covered in the agent&apos;s Add anything that wasn&apos;t covered in the agent&apos;s
questions. questions.
</p> </p>
@ -550,13 +550,13 @@ export function BoardOnboardingChat({
</div> </div>
) : question ? ( ) : question ? (
<div className="space-y-3"> <div className="space-y-3">
<p className="text-sm font-medium text-slate-900"> <p className="text-sm font-medium text-foreground">
{question.question} {question.question}
</p> </p>
{isAwaitingAgent ? ( {isAwaitingAgent ? (
<div className="rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-700"> <div className="rounded-xl border border-border bg-muted px-4 py-3 text-sm text-muted-foreground">
<div className="flex items-center gap-2 font-medium text-slate-900"> <div className="flex items-center gap-2 font-medium text-foreground">
<RefreshCcw className="h-4 w-4 animate-spin text-slate-500" /> <RefreshCcw className="h-4 w-4 animate-spin text-muted-foreground" />
<span> <span>
{awaitingKind === "extra_context" {awaitingKind === "extra_context"
? "Updating the draft…" ? "Updating the draft…"
@ -564,14 +564,14 @@ export function BoardOnboardingChat({
</span> </span>
</div> </div>
{lastSubmittedAnswer ? ( {lastSubmittedAnswer ? (
<p className="mt-2 text-xs text-slate-600"> <p className="mt-2 text-xs text-muted-foreground">
Sent:{" "} Sent:{" "}
<span className="font-medium text-slate-900"> <span className="font-medium text-foreground">
{lastSubmittedAnswer} {lastSubmittedAnswer}
</span> </span>
</p> </p>
) : null} ) : null}
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-muted-foreground">
This usually takes a few seconds. This usually takes a few seconds.
</p> </p>
</div> </div>
@ -611,7 +611,7 @@ export function BoardOnboardingChat({
}} }}
disabled={loading || isAwaitingAgent} disabled={loading || isAwaitingAgent}
/> />
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Tip: press Enter to send. Shift+Enter for a newline. Tip: press Enter to send. Shift+Enter for a newline.
</p> </p>
</div> </div>
@ -631,16 +631,16 @@ export function BoardOnboardingChat({
{loading ? "Sending..." : isAwaitingAgent ? "Waiting..." : "Next"} {loading ? "Sending..." : isAwaitingAgent ? "Waiting..." : "Next"}
</Button> </Button>
{loading ? ( {loading ? (
<p className="text-xs text-slate-500">Sending your answer</p> <p className="text-xs text-muted-foreground">Sending your answer</p>
) : isAwaitingAgent ? ( ) : isAwaitingAgent ? (
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Waiting for the agent to respond Waiting for the agent to respond
</p> </p>
) : null} ) : null}
</div> </div>
</div> </div>
) : ( ) : (
<div className="rounded-lg border border-slate-200 bg-slate-50 p-3 text-sm text-slate-600"> <div className="rounded-lg border border-border bg-muted p-3 text-sm text-muted-foreground">
{loading {loading
? "Waiting for the lead agent..." ? "Waiting for the lead agent..."
: "Preparing onboarding..."} : "Preparing onboarding..."}

View File

@ -18,13 +18,13 @@ export function ActivityFeed<TItem extends FeedItem>({
renderItem, renderItem,
}: ActivityFeedProps<TItem>) { }: ActivityFeedProps<TItem>) {
if (isLoading && items.length === 0) { if (isLoading && items.length === 0) {
return <p className="text-sm text-slate-500">Loading feed</p>; return <p className="text-sm text-muted-foreground">Loading feed</p>;
} }
const hasError = errorMessage !== null && errorMessage !== undefined; const hasError = errorMessage !== null && errorMessage !== undefined;
if (hasError) { if (hasError) {
return ( return (
<div className="rounded-lg border border-slate-200 bg-white p-4 text-sm text-slate-700 shadow-sm"> <div className="rounded-lg border border-border bg-card p-4 text-sm text-muted-foreground shadow-sm">
{errorMessage || "Unable to load feed."} {errorMessage || "Unable to load feed."}
</div> </div>
); );
@ -32,11 +32,11 @@ export function ActivityFeed<TItem extends FeedItem>({
if (items.length === 0) { if (items.length === 0) {
return ( return (
<div className="rounded-xl border border-slate-200 bg-white p-10 text-center shadow-sm"> <div className="rounded-xl border border-border bg-card p-10 text-center shadow-sm">
<p className="text-sm font-medium text-slate-900"> <p className="text-sm font-medium text-foreground">
Waiting for new activity Waiting for new activity
</p> </p>
<p className="mt-1 text-sm text-slate-500"> <p className="mt-1 text-sm text-muted-foreground">
When updates happen, they will show up here. When updates happen, they will show up here.
</p> </p>
</div> </div>

View File

@ -46,7 +46,7 @@ type AgentsTableProps = {
const DEFAULT_EMPTY_ICON = ( const DEFAULT_EMPTY_ICON = (
<svg <svg
className="h-16 w-16 text-slate-300" className="h-16 w-16 text-muted-foreground/50"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
@ -120,7 +120,7 @@ export function AgentsTable({
accessorKey: "openclaw_session_id", accessorKey: "openclaw_session_id",
header: "Session", header: "Session",
cell: ({ row }) => ( cell: ({ row }) => (
<span className="text-sm text-slate-700"> <span className="text-sm text-muted-foreground">
{truncate(row.original.openclaw_session_id)} {truncate(row.original.openclaw_session_id)}
</span> </span>
), ),
@ -131,7 +131,7 @@ export function AgentsTable({
cell: ({ row }) => { cell: ({ row }) => {
const boardId = row.original.board_id; const boardId = row.original.board_id;
if (!boardId) { if (!boardId) {
return <span className="text-sm text-slate-700"></span>; return <span className="text-sm text-muted-foreground"></span>;
} }
const boardName = boardNameById.get(boardId) ?? boardId; const boardName = boardNameById.get(boardId) ?? boardId;
return linkifyCell({ return linkifyCell({
@ -186,7 +186,7 @@ export function AgentsTable({
} }
: undefined : undefined
} }
rowClassName="hover:bg-slate-50" rowClassName="hover:bg-muted"
cellClassName="px-6 py-4" cellClassName="px-6 py-4"
emptyState={ emptyState={
emptyState emptyState

View File

@ -108,7 +108,7 @@ const MARKDOWN_CODE_COMPONENTS: Components = {
pre: ({ node: _node, className, ...props }) => ( pre: ({ node: _node, className, ...props }) => (
<pre <pre
className={cn( className={cn(
"my-3 overflow-x-auto rounded-lg bg-slate-950 p-3 text-xs leading-relaxed text-slate-100", "my-3 overflow-x-auto rounded-lg bg-foreground p-3 text-xs leading-relaxed text-background",
className, className,
)} )}
{...props} {...props}
@ -134,7 +134,7 @@ const MARKDOWN_CODE_COMPONENTS: Components = {
return ( return (
<code <code
className={cn( className={cn(
"rounded bg-slate-100 px-1 py-0.5 font-mono text-[0.85em] text-slate-900", "rounded bg-accent px-1 py-0.5 font-mono text-[0.85em] text-foreground",
className, className,
)} )}
{...props} {...props}
@ -160,7 +160,7 @@ const MARKDOWN_TABLE_COMPONENTS: Components = {
</div> </div>
), ),
thead: ({ node: _node, className, ...props }) => ( thead: ({ node: _node, className, ...props }) => (
<thead className={cn("bg-slate-50", className)} {...props} /> <thead className={cn("bg-muted", className)} {...props} />
), ),
tbody: ({ node: _node, className, ...props }) => ( tbody: ({ node: _node, className, ...props }) => (
<tbody className={cn("divide-y divide-slate-100", className)} {...props} /> <tbody className={cn("divide-y divide-slate-100", className)} {...props} />
@ -171,7 +171,7 @@ const MARKDOWN_TABLE_COMPONENTS: Components = {
th: ({ node: _node, className, children, ...props }) => ( th: ({ node: _node, className, children, ...props }) => (
<th <th
className={cn( className={cn(
"border border-slate-200 px-3 py-2 text-left text-xs font-semibold", "border border-border px-3 py-2 text-left text-xs font-semibold",
className, className,
)} )}
{...props} {...props}
@ -181,7 +181,7 @@ const MARKDOWN_TABLE_COMPONENTS: Components = {
), ),
td: ({ node: _node, className, children, ...props }) => ( td: ({ node: _node, className, children, ...props }) => (
<td <td
className={cn("border border-slate-200 px-3 py-2 align-top", className)} className={cn("border border-border px-3 py-2 align-top", className)}
{...props} {...props}
> >
{renderMentions(children)} {renderMentions(children)}

View File

@ -9,7 +9,7 @@ export function PipelineIcon({ className }: PipelineIconProps) {
<div <div
className={ className={
className ?? className ??
"grid h-10 w-10 place-items-center rounded-lg bg-[color:var(--accent)] text-white shadow-sm" "grid h-10 w-10 place-items-center rounded-lg bg-primary text-primary-foreground shadow-sm"
} }
aria-hidden="true" aria-hidden="true"
> >

View File

@ -8,7 +8,7 @@ const AGENT_STATUS_DOT_CLASS_BY_STATUS: Record<string, string> = {
provisioning: "bg-amber-500", provisioning: "bg-amber-500",
updating: "bg-sky-500", updating: "bg-sky-500",
deleting: "bg-rose-500", deleting: "bg-rose-500",
offline: "bg-slate-400", offline: "bg-muted-foreground",
}; };
const APPROVAL_STATUS_DOT_CLASS_BY_STATUS: Record<string, string> = { const APPROVAL_STATUS_DOT_CLASS_BY_STATUS: Record<string, string> = {
@ -18,7 +18,7 @@ const APPROVAL_STATUS_DOT_CLASS_BY_STATUS: Record<string, string> = {
}; };
const TASK_STATUS_DOT_CLASS_BY_STATUS: Record<string, string> = { const TASK_STATUS_DOT_CLASS_BY_STATUS: Record<string, string> = {
inbox: "bg-slate-400", inbox: "bg-muted-foreground",
in_progress: "bg-purple-500", in_progress: "bg-purple-500",
review: "bg-indigo-500", review: "bg-indigo-500",
done: "bg-emerald-500", done: "bg-emerald-500",
@ -34,9 +34,9 @@ const STATUS_DOT_CLASS_BY_VARIANT: Record<
}; };
const DEFAULT_STATUS_DOT_CLASS: Record<StatusDotVariant, string> = { const DEFAULT_STATUS_DOT_CLASS: Record<StatusDotVariant, string> = {
agent: "bg-slate-300", agent: "bg-muted-foreground/40",
approval: "bg-amber-500", approval: "bg-amber-500",
task: "bg-slate-300", task: "bg-muted-foreground/40",
}; };
export const statusDotClass = ( export const statusDotClass = (

View File

@ -4,7 +4,7 @@ type AdminOnlyNoticeProps = {
export function AdminOnlyNotice({ message }: AdminOnlyNoticeProps) { export function AdminOnlyNotice({ message }: AdminOnlyNoticeProps) {
return ( return (
<div className="rounded-xl border border-slate-200 bg-white px-6 py-5 text-sm text-slate-600 shadow-sm"> <div className="rounded-xl border border-border bg-card px-6 py-5 text-sm text-muted-foreground shadow-sm">
{message} {message}
</div> </div>
); );

View File

@ -20,9 +20,9 @@ export function SignedOutPanel({
buttonTestId, buttonTestId,
}: SignedOutPanelProps) { }: SignedOutPanelProps) {
return ( return (
<div className="col-span-1 md:col-span-2 flex min-h-[calc(100vh-64px)] items-center justify-center bg-slate-50 p-10 text-center"> <div className="col-span-1 md:col-span-2 flex min-h-[calc(100vh-64px)] items-center justify-center bg-muted p-10 text-center">
<div className="rounded-xl border border-slate-200 bg-white px-4 py-4 md:px-8 md:py-6 shadow-sm"> <div className="rounded-xl border border-border bg-card px-4 py-4 md:px-8 md:py-6 shadow-sm">
<p className="text-sm text-slate-600">{message}</p> <p className="text-sm text-muted-foreground">{message}</p>
<SignInButton <SignInButton
mode={mode} mode={mode}
forceRedirectUrl={forceRedirectUrl} forceRedirectUrl={forceRedirectUrl}

View File

@ -37,7 +37,7 @@ type BoardGroupsTableProps = {
const DEFAULT_EMPTY_ICON = ( const DEFAULT_EMPTY_ICON = (
<svg <svg
className="h-16 w-16 text-slate-300" className="h-16 w-16 text-muted-foreground/50"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
@ -94,8 +94,8 @@ export function BoardGroupsTable({
label: row.original.name, label: row.original.name,
subtitle: row.original.description ?? "No description", subtitle: row.original.description ?? "No description",
subtitleClassName: row.original.description subtitleClassName: row.original.description
? "mt-1 line-clamp-2 text-xs text-slate-500" ? "mt-1 line-clamp-2 text-xs text-muted-foreground"
: "mt-1 text-xs text-slate-400", : "mt-1 text-xs text-muted-foreground/70",
}), }),
}, },
{ {
@ -129,7 +129,7 @@ export function BoardGroupsTable({
isLoading={isLoading} isLoading={isLoading}
stickyHeader={stickyHeader} stickyHeader={stickyHeader}
emptyMessage={emptyMessage} emptyMessage={emptyMessage}
rowClassName="transition hover:bg-slate-50" rowClassName="transition hover:bg-muted"
cellClassName="px-3 py-3 md:px-6 md:py-4 align-top" cellClassName="px-3 py-3 md:px-6 md:py-4 align-top"
rowActions={ rowActions={
showActions showActions

View File

@ -38,7 +38,7 @@ type BoardsTableProps = {
const DEFAULT_EMPTY_ICON = ( const DEFAULT_EMPTY_ICON = (
<svg <svg
className="h-16 w-16 text-slate-300" className="h-16 w-16 text-muted-foreground/50"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
@ -117,7 +117,7 @@ export function BoardsTable({
cell: ({ row }) => { cell: ({ row }) => {
const groupId = row.original.board_group_id; const groupId = row.original.board_group_id;
if (!groupId) { if (!groupId) {
return <span className="text-sm text-slate-400"></span>; return <span className="text-sm text-muted-foreground/70"></span>;
} }
const group = groupById.get(groupId); const group = groupById.get(groupId);
const label = group?.name ?? compactId(groupId); const label = group?.name ?? compactId(groupId);
@ -161,7 +161,7 @@ export function BoardsTable({
isLoading={isLoading} isLoading={isLoading}
stickyHeader={stickyHeader} stickyHeader={stickyHeader}
emptyMessage={emptyMessage} emptyMessage={emptyMessage}
rowClassName="transition hover:bg-slate-50" rowClassName="transition hover:bg-muted"
cellClassName="px-3 py-3 md:px-6 md:py-4 align-top" cellClassName="px-3 py-3 md:px-6 md:py-4 align-top"
rowActions={ rowActions={
showActions showActions

View File

@ -314,10 +314,10 @@ function ChartTooltipCard({
<ChartTooltipContent <ChartTooltipContent
{...props} {...props}
className={cn( className={cn(
"border border-gray-200 bg-white px-3 py-2 text-sm shadow-lg", "border border-border bg-popover px-3 py-2 text-sm text-popover-foreground shadow-lg",
className, className,
)} )}
labelClassName={cn("text-sm font-semibold text-gray-900", labelClassName)} labelClassName={cn("text-sm font-semibold text-foreground", labelClassName)}
/> />
); );
} }
@ -439,7 +439,7 @@ function ChartLegendItem({
aria-pressed={!isHidden} aria-pressed={!isHidden}
onClick={handleClick} onClick={handleClick}
className={cn( className={cn(
"flex items-center gap-2 text-gray-600 transition-opacity [&>svg]:h-3 [&>svg]:w-3 cursor-pointer disabled:cursor-not-allowed disabled:opacity-60", "flex items-center gap-2 text-muted-foreground transition-opacity [&>svg]:h-3 [&>svg]:w-3 cursor-pointer disabled:cursor-not-allowed disabled:opacity-60",
isHidden && "opacity-50", isHidden && "opacity-50",
className, className,
)} )}
@ -453,7 +453,7 @@ function ChartLegendItem({
style={{ backgroundColor: resolvedColor }} style={{ backgroundColor: resolvedColor }}
/> />
)} )}
<span className={cn(isHidden && "line-through text-gray-400")}> <span className={cn(isHidden && "line-through text-muted-foreground/70")}>
{resolvedLabel} {resolvedLabel}
</span> </span>
</button> </button>

View File

@ -65,7 +65,7 @@ const SparklineTooltip = ({
: "Day"; : "Day";
const prefix = resolvedLabel ?? (dayIndex ? `${label} ${dayIndex}` : ""); const prefix = resolvedLabel ?? (dayIndex ? `${label} ${dayIndex}` : "");
return ( return (
<div className="rounded-md border border-gray-200 bg-white px-2 py-1 text-xs font-medium text-gray-700 shadow-sm"> <div className="rounded-md border border-border bg-popover px-2 py-1 text-xs font-medium text-popover-foreground shadow-sm">
{prefix ? `${prefix}: ` : ""} {prefix ? `${prefix}: ` : ""}
{formatSparkValue(rawValue)} {formatSparkValue(rawValue)}
</div> </div>
@ -85,8 +85,8 @@ export default function MetricSparkline({
} }
const data = buildSparkData(values); const data = buildSparkData(values);
const strokeColor = "#60a5fa"; const strokeColor = "var(--accent)";
const fillColor = "#bfdbfe"; const fillColor = "var(--accent-soft)";
return ( return (
<div className={cn("h-8 w-full", className)}> <div className={cn("h-8 w-full", className)}>

View File

@ -93,15 +93,15 @@ export function CustomFieldForm({
return ( return (
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="max-w-3xl rounded-xl border border-slate-200 bg-white p-6 shadow-sm space-y-6" className="max-w-3xl rounded-xl border border-border bg-card p-6 shadow-sm space-y-6"
> >
<div> <div>
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Basic configuration Basic configuration
</p> </p>
<div className="mt-4 grid gap-6 md:grid-cols-2"> <div className="mt-4 grid gap-6 md:grid-cols-2">
<label className="space-y-1"> <label className="space-y-1">
<span className="text-sm font-semibold text-slate-900"> <span className="text-sm font-semibold text-foreground">
Field key Field key
</span> </span>
<Input <Input
@ -118,14 +118,14 @@ export function CustomFieldForm({
required={mode === "create"} required={mode === "create"}
/> />
{mode === "edit" ? ( {mode === "edit" ? (
<span className="text-xs text-slate-500"> <span className="text-xs text-muted-foreground">
Field key cannot be changed after creation. Field key cannot be changed after creation.
</span> </span>
) : null} ) : null}
</label> </label>
<label className="space-y-1"> <label className="space-y-1">
<span className="text-sm font-semibold text-slate-900">Label</span> <span className="text-sm font-semibold text-foreground">Label</span>
<Input <Input
value={formState.label} value={formState.label}
onChange={(event) => onChange={(event) =>
@ -138,7 +138,7 @@ export function CustomFieldForm({
</label> </label>
<label className="space-y-1"> <label className="space-y-1">
<span className="text-sm font-semibold text-slate-900"> <span className="text-sm font-semibold text-foreground">
Field type Field type
</span> </span>
<Select <Select
@ -165,7 +165,7 @@ export function CustomFieldForm({
</label> </label>
<label className="space-y-1"> <label className="space-y-1">
<span className="text-sm font-semibold text-slate-900"> <span className="text-sm font-semibold text-foreground">
UI visible UI visible
</span> </span>
<Select <Select
@ -192,7 +192,7 @@ export function CustomFieldForm({
</label> </label>
</div> </div>
<label className="mt-4 flex items-center gap-2 text-sm text-slate-700"> <label className="mt-4 flex items-center gap-2 text-sm text-muted-foreground">
<input <input
type="checkbox" type="checkbox"
checked={formState.required} checked={formState.required}
@ -209,12 +209,12 @@ export function CustomFieldForm({
</div> </div>
<div> <div>
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Validation and defaults Validation and defaults
</p> </p>
<div className="mt-4 space-y-4"> <div className="mt-4 space-y-4">
<label className="space-y-1"> <label className="space-y-1">
<span className="text-sm font-semibold text-slate-900"> <span className="text-sm font-semibold text-foreground">
Validation regex Validation regex
</span> </span>
<Input <Input
@ -231,13 +231,13 @@ export function CustomFieldForm({
!STRING_VALIDATION_FIELD_TYPES.has(formState.fieldType) !STRING_VALIDATION_FIELD_TYPES.has(formState.fieldType)
} }
/> />
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Supported for text/date/date-time/url fields. Supported for text/date/date-time/url fields.
</p> </p>
</label> </label>
<label className="space-y-1"> <label className="space-y-1">
<span className="text-sm font-semibold text-slate-900"> <span className="text-sm font-semibold text-foreground">
Default value Default value
</span> </span>
<Textarea <Textarea
@ -255,7 +255,7 @@ export function CustomFieldForm({
</label> </label>
<label className="space-y-1"> <label className="space-y-1">
<span className="text-sm font-semibold text-slate-900"> <span className="text-sm font-semibold text-foreground">
Description Description
</span> </span>
<Textarea <Textarea
@ -276,10 +276,10 @@ export function CustomFieldForm({
<div> <div>
<div className="flex flex-wrap items-center justify-between gap-2"> <div className="flex flex-wrap items-center justify-between gap-2">
<p className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Board bindings Board bindings
</p> </p>
<span className="text-xs text-slate-500"> <span className="text-xs text-muted-foreground">
{selectedBoardIds.size} selected {selectedBoardIds.size} selected
</span> </span>
</div> </div>
@ -290,9 +290,9 @@ export function CustomFieldForm({
placeholder="Search boards..." placeholder="Search boards..."
disabled={isSubmitting} disabled={isSubmitting}
/> />
<div className="max-h-64 overflow-auto rounded-xl border border-slate-200 bg-slate-50/40"> <div className="max-h-64 overflow-auto rounded-xl border border-border bg-muted/40">
{boardsLoading ? ( {boardsLoading ? (
<div className="px-4 py-6 text-sm text-slate-500"> <div className="px-4 py-6 text-sm text-muted-foreground">
Loading boards Loading boards
</div> </div>
) : boardsError ? ( ) : boardsError ? (
@ -300,7 +300,7 @@ export function CustomFieldForm({
{boardsError} {boardsError}
</div> </div>
) : filteredBoards.length === 0 ? ( ) : filteredBoards.length === 0 ? (
<div className="px-4 py-6 text-sm text-slate-500"> <div className="px-4 py-6 text-sm text-muted-foreground">
No boards found. No boards found.
</div> </div>
) : ( ) : (
@ -312,7 +312,7 @@ export function CustomFieldForm({
<label className="flex cursor-pointer items-start gap-3"> <label className="flex cursor-pointer items-start gap-3">
<input <input
type="checkbox" type="checkbox"
className="mt-1 h-4 w-4 rounded border-slate-300 text-blue-600" className="mt-1 h-4 w-4 rounded border-input text-primary"
checked={checked} checked={checked}
onChange={() => { onChange={() => {
setSelectedBoardIds((prev) => { setSelectedBoardIds((prev) => {
@ -328,10 +328,10 @@ export function CustomFieldForm({
disabled={isSubmitting} disabled={isSubmitting}
/> />
<div className="min-w-0"> <div className="min-w-0">
<p className="truncate text-sm font-medium text-slate-900"> <p className="truncate text-sm font-medium text-foreground">
{board.name} {board.name}
</p> </p>
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-muted-foreground">
{board.slug} {board.slug}
</p> </p>
</div> </div>
@ -342,7 +342,7 @@ export function CustomFieldForm({
</ul> </ul>
)} )}
</div> </div>
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
Required. The custom field appears on tasks in selected boards. Required. The custom field appears on tasks in selected boards.
</p> </p>
</div> </div>

View File

@ -33,7 +33,7 @@ type CustomFieldsTableProps = {
const DEFAULT_EMPTY_ICON = ( const DEFAULT_EMPTY_ICON = (
<svg <svg
className="h-16 w-16 text-slate-300" className="h-16 w-16 text-muted-foreground/50"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
@ -77,13 +77,13 @@ export function CustomFieldsTable({
header: "Field", header: "Field",
cell: ({ row }) => ( cell: ({ row }) => (
<div> <div>
<p className="text-sm font-semibold text-slate-900"> <p className="text-sm font-semibold text-foreground">
{row.original.label || row.original.field_key} {row.original.label || row.original.field_key}
</p> </p>
<p className="mt-1 font-mono text-xs text-slate-500"> <p className="mt-1 font-mono text-xs text-muted-foreground">
key: {row.original.field_key} key: {row.original.field_key}
</p> </p>
<p className="mt-1 text-xs text-slate-500"> <p className="mt-1 text-xs text-muted-foreground">
{row.original.description || "No description"} {row.original.description || "No description"}
</p> </p>
</div> </div>
@ -93,7 +93,7 @@ export function CustomFieldsTable({
accessorKey: "required", accessorKey: "required",
header: "Required", header: "Required",
cell: ({ row }) => ( cell: ({ row }) => (
<span className="text-sm text-slate-700"> <span className="text-sm text-muted-foreground">
{row.original.required === true ? "Required" : "Optional"} {row.original.required === true ? "Required" : "Optional"}
</span> </span>
), ),
@ -102,7 +102,7 @@ export function CustomFieldsTable({
accessorKey: "field_type", accessorKey: "field_type",
header: "Type", header: "Type",
cell: ({ row }) => ( cell: ({ row }) => (
<span className="text-sm text-slate-700"> <span className="text-sm text-muted-foreground">
{row.original.field_type} {row.original.field_type}
</span> </span>
), ),
@ -111,7 +111,7 @@ export function CustomFieldsTable({
accessorKey: "ui_visibility", accessorKey: "ui_visibility",
header: "UI visible", header: "UI visible",
cell: ({ row }) => ( cell: ({ row }) => (
<span className="text-sm text-slate-700"> <span className="text-sm text-muted-foreground">
{row.original.ui_visibility} {row.original.ui_visibility}
</span> </span>
), ),
@ -121,7 +121,7 @@ export function CustomFieldsTable({
header: "Default value", header: "Default value",
enableSorting: false, enableSorting: false,
cell: ({ row }) => ( cell: ({ row }) => (
<p className="font-mono text-xs break-all text-slate-700"> <p className="font-mono text-xs break-all text-muted-foreground">
{formatCustomFieldDefaultValue(row.original.default_value) || "—"} {formatCustomFieldDefaultValue(row.original.default_value) || "—"}
</p> </p>
), ),
@ -152,7 +152,7 @@ export function CustomFieldsTable({
table={table} table={table}
isLoading={isLoading} isLoading={isLoading}
stickyHeader={stickyHeader} stickyHeader={stickyHeader}
rowClassName="transition hover:bg-slate-50" rowClassName="transition hover:bg-muted"
cellClassName="px-6 py-4 align-top" cellClassName="px-6 py-4 align-top"
rowActions={ rowActions={
editHref || onDelete editHref || onDelete

View File

@ -60,10 +60,10 @@ export function GatewayForm({
return ( return (
<form <form
onSubmit={onSubmit} onSubmit={onSubmit}
className="space-y-6 rounded-xl border border-slate-200 bg-white p-6 shadow-sm" className="space-y-6 rounded-xl border border-border bg-card p-6 shadow-sm"
> >
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Gateway name <span className="text-red-500">*</span> Gateway name <span className="text-red-500">*</span>
</label> </label>
<Input <Input
@ -76,7 +76,7 @@ export function GatewayForm({
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Gateway URL <span className="text-red-500">*</span> Gateway URL <span className="text-red-500">*</span>
</label> </label>
<div className="relative"> <div className="relative">
@ -95,7 +95,7 @@ export function GatewayForm({
) : null} ) : null}
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Gateway token Gateway token
</label> </label>
<Input <Input
@ -109,7 +109,7 @@ export function GatewayForm({
<div className="grid gap-6 md:grid-cols-2"> <div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Workspace root <span className="text-red-500">*</span> Workspace root <span className="text-red-500">*</span>
</label> </label>
<Input <Input
@ -121,10 +121,10 @@ export function GatewayForm({
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Disable device pairing Disable device pairing
</label> </label>
<label className="flex h-10 items-center gap-3 px-1 text-sm text-slate-900"> <label className="flex h-10 items-center gap-3 px-1 text-sm text-foreground">
<button <button
type="button" type="button"
role="switch" role="switch"
@ -137,11 +137,11 @@ export function GatewayForm({
className={`inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${ className={`inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${
disableDevicePairing disableDevicePairing
? "border-emerald-600 bg-emerald-600" ? "border-emerald-600 bg-emerald-600"
: "border-slate-300 bg-slate-200" : "border-input bg-border"
} ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`} } ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`}
> >
<span <span
className={`inline-block h-5 w-5 rounded-full bg-white shadow-sm transition ${ className={`inline-block h-5 w-5 rounded-full bg-card shadow-sm transition ${
disableDevicePairing ? "translate-x-5" : "translate-x-0.5" disableDevicePairing ? "translate-x-5" : "translate-x-0.5"
}`} }`}
/> />
@ -151,10 +151,10 @@ export function GatewayForm({
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-sm font-medium text-slate-900"> <label className="text-sm font-medium text-foreground">
Allow self-signed TLS certificates Allow self-signed TLS certificates
</label> </label>
<label className="flex h-10 items-center gap-3 px-1 text-sm text-slate-900"> <label className="flex h-10 items-center gap-3 px-1 text-sm text-foreground">
<button <button
type="button" type="button"
role="switch" role="switch"
@ -165,11 +165,11 @@ export function GatewayForm({
className={`inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${ className={`inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition ${
allowInsecureTls allowInsecureTls
? "border-emerald-600 bg-emerald-600" ? "border-emerald-600 bg-emerald-600"
: "border-slate-300 bg-slate-200" : "border-input bg-border"
} ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`} } ${isLoading ? "cursor-not-allowed opacity-60" : "cursor-pointer"}`}
> >
<span <span
className={`inline-block h-5 w-5 rounded-full bg-white shadow-sm transition ${ className={`inline-block h-5 w-5 rounded-full bg-card shadow-sm transition ${
allowInsecureTls ? "translate-x-5" : "translate-x-0.5" allowInsecureTls ? "translate-x-5" : "translate-x-0.5"
}`} }`}
/> />

View File

@ -38,7 +38,7 @@ type GatewaysTableProps = {
const DEFAULT_EMPTY_ICON = ( const DEFAULT_EMPTY_ICON = (
<svg <svg
className="h-16 w-16 text-slate-300" className="h-16 w-16 text-muted-foreground/50"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
@ -100,7 +100,7 @@ export function GatewaysTable({
accessorKey: "workspace_root", accessorKey: "workspace_root",
header: "Workspace root", header: "Workspace root",
cell: ({ row }) => ( cell: ({ row }) => (
<span className="text-sm text-slate-700"> <span className="text-sm text-muted-foreground">
{truncate(row.original.workspace_root, 28)} {truncate(row.original.workspace_root, 28)}
</span> </span>
), ),

View File

@ -385,7 +385,7 @@ export function BoardForgejoRepositoryLinks({
errorMessage={unlinkError} errorMessage={unlinkError}
confirmLabel="Unlink Repository" confirmLabel="Unlink Repository"
confirmingLabel="Unlinking..." confirmingLabel="Unlinking..."
confirmClassName="bg-[color:var(--danger)] text-white hover:bg-[color:var(--danger)]/90" confirmClassName="bg-destructive text-destructive-foreground hover:bg-destructive/90"
cancelLabel="Keep Linked" cancelLabel="Keep Linked"
/> />
</> </>

View File

@ -24,7 +24,7 @@ type DependencyBannerVariant = "blocked" | "resolved";
const toneClassByVariant: Record<DependencyBannerVariant, string> = { const toneClassByVariant: Record<DependencyBannerVariant, string> = {
blocked: "border-rose-200 bg-rose-50 text-rose-700", blocked: "border-rose-200 bg-rose-50 text-rose-700",
resolved: "border-blue-200 bg-blue-50 text-blue-700", resolved: "border-primary/30 bg-primary/10 text-primary",
}; };
export function DependencyBanner({ export function DependencyBanner({
@ -52,12 +52,12 @@ export function DependencyBanner({
? "border-rose-200 bg-rose-50 hover:bg-rose-100/40" ? "border-rose-200 bg-rose-50 hover:bg-rose-100/40"
: isDone : isDone
? "border-emerald-200 bg-emerald-50 hover:bg-emerald-100/40" ? "border-emerald-200 bg-emerald-50 hover:bg-emerald-100/40"
: "border-slate-200 bg-white hover:bg-slate-50", : "border-border bg-card hover:bg-muted",
dependency.disabled && "cursor-not-allowed opacity-60", dependency.disabled && "cursor-not-allowed opacity-60",
)} )}
> >
<div className="flex items-center justify-between gap-3"> <div className="flex items-center justify-between gap-3">
<p className="truncate text-sm font-medium text-slate-900"> <p className="truncate text-sm font-medium text-foreground">
{dependency.title} {dependency.title}
</p> </p>
<span <span
@ -67,7 +67,7 @@ export function DependencyBanner({
? "text-rose-700" ? "text-rose-700"
: isDone : isDone
? "text-emerald-700" ? "text-emerald-700"
: "text-slate-500", : "text-muted-foreground",
)} )}
> >
{dependency.statusLabel} {dependency.statusLabel}
@ -77,7 +77,7 @@ export function DependencyBanner({
); );
}) })
) : ( ) : (
<p className="text-sm text-slate-500">{emptyMessage}</p> <p className="text-sm text-muted-foreground">{emptyMessage}</p>
)} )}
{children ? ( {children ? (
<div <div

View File

@ -61,7 +61,7 @@ export function TaskCard({
if (normalized === "low") { if (normalized === "low") {
return "bg-emerald-100 text-emerald-700"; return "bg-emerald-100 text-emerald-700";
} }
return "bg-slate-100 text-slate-600"; return "bg-accent text-muted-foreground";
}; };
const priorityLabel = priority ? priority.toUpperCase() : "MEDIUM"; const priorityLabel = priority ? priority.toUpperCase() : "MEDIUM";
@ -70,7 +70,7 @@ export function TaskCard({
return ( return (
<div <div
className={cn( className={cn(
"group relative cursor-pointer rounded-lg border border-slate-200 bg-white p-4 shadow-sm transition-all hover:-translate-y-0.5 hover:border-slate-300 hover:shadow-md", "group relative cursor-pointer rounded-lg border border-border bg-card p-4 shadow-sm transition-all hover:-translate-y-0.5 hover:border-input hover:shadow-md",
isDragging && "opacity-60 shadow-none", isDragging && "opacity-60 shadow-none",
hasPendingApproval && "border-amber-200 bg-amber-50/40", hasPendingApproval && "border-amber-200 bg-amber-50/40",
isBlocked && "border-rose-200 bg-rose-50/50", isBlocked && "border-rose-200 bg-rose-50/50",
@ -99,7 +99,7 @@ export function TaskCard({
) : null} ) : null}
<div className="flex items-start justify-between gap-3"> <div className="flex items-start justify-between gap-3">
<div className="min-w-0 space-y-2"> <div className="min-w-0 space-y-2">
<p className="text-sm font-medium text-slate-900 line-clamp-2 break-words"> <p className="text-sm font-medium text-foreground line-clamp-2 break-words">
{title} {title}
</p> </p>
{isBlocked ? ( {isBlocked ? (
@ -125,7 +125,7 @@ export function TaskCard({
{visibleTags.map((tag) => ( {visibleTags.map((tag) => (
<span <span
key={tag.id} key={tag.id}
className="inline-flex items-center gap-1 rounded-full border border-slate-200 bg-white px-2 py-0.5 text-[10px] font-semibold text-slate-700" className="inline-flex items-center gap-1 rounded-full border border-border bg-card px-2 py-0.5 text-[10px] font-semibold text-muted-foreground"
> >
<span <span
className="h-1.5 w-1.5 rounded-full" className="h-1.5 w-1.5 rounded-full"
@ -135,7 +135,7 @@ export function TaskCard({
</span> </span>
))} ))}
{tags.length > visibleTags.length ? ( {tags.length > visibleTags.length ? (
<span className="text-[10px] font-semibold text-slate-500"> <span className="text-[10px] font-semibold text-muted-foreground">
+{tags.length - visibleTags.length} +{tags.length - visibleTags.length}
</span> </span>
) : null} ) : null}
@ -146,16 +146,16 @@ export function TaskCard({
<span <span
className={cn( className={cn(
"inline-flex items-center rounded-full px-2 py-1 text-[10px] font-semibold uppercase tracking-wide", "inline-flex items-center rounded-full px-2 py-1 text-[10px] font-semibold uppercase tracking-wide",
priorityBadge(priority) ?? "bg-slate-100 text-slate-600", priorityBadge(priority) ?? "bg-accent text-muted-foreground",
)} )}
> >
{priorityLabel} {priorityLabel}
</span> </span>
</div> </div>
</div> </div>
<div className="mt-3 flex items-center justify-between text-xs text-slate-500"> <div className="mt-3 flex items-center justify-between text-xs text-muted-foreground">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<UserCircle className="h-4 w-4 text-slate-400" /> <UserCircle className="h-4 w-4 text-muted-foreground/70" />
<span>{assignee ?? "Unassigned"}</span> <span>{assignee ?? "Unassigned"}</span>
</div> </div>
{due ? ( {due ? (
@ -168,7 +168,7 @@ export function TaskCard({
<CalendarClock <CalendarClock
className={cn( className={cn(
"h-4 w-4", "h-4 w-4",
isOverdue ? "text-rose-500" : "text-slate-400", isOverdue ? "text-rose-500" : "text-muted-foreground/70",
)} )}
/> />
<span>{due}</span> <span>{due}</span>

View File

@ -51,17 +51,17 @@ const columns: Array<{
{ {
title: "Inbox", title: "Inbox",
status: "inbox", status: "inbox",
dot: "bg-slate-400", dot: "bg-muted-foreground",
accent: "hover:border-slate-400 hover:bg-slate-50", accent: "hover:border-muted-foreground hover:bg-muted",
text: "group-hover:text-slate-700 text-slate-500", text: "group-hover:text-muted-foreground text-muted-foreground",
badge: "bg-slate-100 text-slate-600", badge: "bg-accent text-muted-foreground",
}, },
{ {
title: "In Progress", title: "In Progress",
status: "in_progress", status: "in_progress",
dot: "bg-purple-500", dot: "bg-purple-500",
accent: "hover:border-purple-400 hover:bg-purple-50", accent: "hover:border-purple-400 hover:bg-purple-50",
text: "group-hover:text-purple-600 text-slate-500", text: "group-hover:text-purple-600 text-muted-foreground",
badge: "bg-purple-100 text-purple-700", badge: "bg-purple-100 text-purple-700",
}, },
{ {
@ -69,7 +69,7 @@ const columns: Array<{
status: "review", status: "review",
dot: "bg-indigo-500", dot: "bg-indigo-500",
accent: "hover:border-indigo-400 hover:bg-indigo-50", accent: "hover:border-indigo-400 hover:bg-indigo-50",
text: "group-hover:text-indigo-600 text-slate-500", text: "group-hover:text-indigo-600 text-muted-foreground",
badge: "bg-indigo-100 text-indigo-700", badge: "bg-indigo-100 text-indigo-700",
}, },
{ {
@ -77,7 +77,7 @@ const columns: Array<{
status: "done", status: "done",
dot: "bg-green-500", dot: "bg-green-500",
accent: "hover:border-green-400 hover:bg-green-50", accent: "hover:border-green-400 hover:bg-green-50",
text: "group-hover:text-green-600 text-slate-500", text: "group-hover:text-green-600 text-muted-foreground",
badge: "bg-emerald-100 text-emerald-700", badge: "bg-emerald-100 text-emerald-700",
}, },
]; ];
@ -424,17 +424,17 @@ export const TaskBoard = memo(function TaskBoard({
"sm:min-h-[calc(100vh-260px)]", "sm:min-h-[calc(100vh-260px)]",
activeColumn === column.status && activeColumn === column.status &&
!readOnly && !readOnly &&
"ring-2 ring-slate-200", "ring-2 ring-border",
)} )}
onDrop={readOnly ? undefined : handleDrop(column.status)} onDrop={readOnly ? undefined : handleDrop(column.status)}
onDragOver={readOnly ? undefined : handleDragOver(column.status)} onDragOver={readOnly ? undefined : handleDragOver(column.status)}
onDragLeave={readOnly ? undefined : handleDragLeave(column.status)} onDragLeave={readOnly ? undefined : handleDragLeave(column.status)}
> >
<div className="column-header z-10 rounded-t-xl border border-b-0 border-slate-200 bg-white px-4 py-3 sm:sticky sm:top-0 sm:bg-white/80 sm:backdrop-blur"> <div className="column-header z-10 rounded-t-xl border border-b-0 border-border bg-card px-4 py-3 sm:sticky sm:top-0 sm:bg-card/80 sm:backdrop-blur">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<span className={cn("h-2 w-2 rounded-full", column.dot)} /> <span className={cn("h-2 w-2 rounded-full", column.dot)} />
<h3 className="text-sm font-semibold text-slate-900"> <h3 className="text-sm font-semibold text-foreground">
{column.title} {column.title}
</h3> </h3>
</div> </div>
@ -448,7 +448,7 @@ export const TaskBoard = memo(function TaskBoard({
</span> </span>
</div> </div>
{column.status === "review" && reviewCounts ? ( {column.status === "review" && reviewCounts ? (
<div className="mt-2 flex flex-wrap items-center gap-2 text-[10px] font-semibold uppercase tracking-wide text-slate-500"> <div className="mt-2 flex flex-wrap items-center gap-2 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground">
{( {(
[ [
{ key: "all", label: "All", count: reviewCounts.all }, { key: "all", label: "All", count: reviewCounts.all },
@ -476,8 +476,8 @@ export const TaskBoard = memo(function TaskBoard({
className={cn( className={cn(
"rounded-full border px-2.5 py-1 transition", "rounded-full border px-2.5 py-1 transition",
reviewBucket === option.key reviewBucket === option.key
? "border-slate-900 bg-slate-900 text-white" ? "border-foreground bg-foreground text-background"
: "border-slate-200 bg-white text-slate-600 hover:border-slate-300 hover:bg-slate-50", : "border-border bg-card text-muted-foreground hover:border-input hover:bg-muted",
)} )}
aria-pressed={reviewBucket === option.key} aria-pressed={reviewBucket === option.key}
> >
@ -487,7 +487,7 @@ export const TaskBoard = memo(function TaskBoard({
</div> </div>
) : null} ) : null}
</div> </div>
<div className="rounded-b-xl border border-t-0 border-slate-200 bg-white p-3"> <div className="rounded-b-xl border border-t-0 border-border bg-card p-3">
<div className="space-y-3"> <div className="space-y-3">
{filteredTasks.map((task) => { {filteredTasks.map((task) => {
const dueState = resolveDueState(task); const dueState = resolveDueState(task);

View File

@ -69,7 +69,7 @@ export function UserMenu({
> >
<span <span
className={cn( className={cn(
"relative flex h-9 w-9 items-center justify-center overflow-hidden rounded-[10px] text-xs font-semibold text-white shadow-sm", "relative flex h-9 w-9 items-center justify-center overflow-hidden rounded-[10px] text-xs font-semibold text-primary-foreground shadow-sm",
avatarUrl avatarUrl
? "bg-[color:var(--neutral-200,var(--surface-muted))]" ? "bg-[color:var(--neutral-200,var(--surface-muted))]"
: "bg-gradient-to-br from-[color:var(--primary-navy,var(--accent))] to-[color:var(--secondary-navy,var(--accent-strong))]", : "bg-gradient-to-br from-[color:var(--primary-navy,var(--accent))] to-[color:var(--secondary-navy,var(--accent-strong))]",
@ -99,7 +99,7 @@ export function UserMenu({
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<span <span
className={cn( className={cn(
"flex h-10 w-10 items-center justify-center overflow-hidden rounded-xl text-sm font-semibold text-white", "flex h-10 w-10 items-center justify-center overflow-hidden rounded-xl text-sm font-semibold text-primary-foreground",
avatarUrl avatarUrl
? "bg-[color:var(--neutral-200,var(--surface-muted))]" ? "bg-[color:var(--neutral-200,var(--surface-muted))]"
: "bg-gradient-to-br from-[color:var(--primary-navy,var(--accent))] to-[color:var(--secondary-navy,var(--accent-strong))]", : "bg-gradient-to-br from-[color:var(--primary-navy,var(--accent))] to-[color:var(--secondary-navy,var(--accent-strong))]",
@ -141,7 +141,7 @@ export function UserMenu({
</Link> </Link>
<Link <Link
href="/boards/new" href="/boards/new"
className="flex w-full items-center justify-center gap-2 rounded-xl bg-[color:var(--primary-navy,var(--accent))] px-3 py-2 text-sm font-semibold text-white shadow-[0_2px_8px_rgba(10,22,40,0.15)] transition hover:bg-[color:var(--secondary-navy,var(--accent-strong))] hover:translate-y-[-1px] hover:shadow-[0_4px_12px_rgba(10,22,40,0.20)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--accent-teal,var(--accent))] focus-visible:ring-offset-2" className="flex w-full items-center justify-center gap-2 rounded-xl bg-primary px-3 py-2 text-sm font-semibold text-primary-foreground shadow-[0_2px_8px_rgba(10,22,40,0.15)] transition hover:bg-[color:var(--accent-strong)] hover:translate-y-[-1px] hover:shadow-[0_4px_12px_rgba(10,22,40,0.20)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
onClick={() => setOpen(false)} onClick={() => setOpen(false)}
> >
<Plus className="h-4 w-4 opacity-90" /> <Plus className="h-4 w-4 opacity-90" />

View File

@ -37,7 +37,7 @@ export function BoardAccessTable({
href: `/boards/${row.original.id}`, href: `/boards/${row.original.id}`,
label: row.original.name, label: row.original.name,
subtitle: row.original.slug, subtitle: row.original.slug,
subtitleClassName: "mt-1 text-xs text-slate-500", subtitleClassName: "mt-1 text-xs text-muted-foreground",
}), }),
}, },
{ {
@ -97,8 +97,8 @@ export function BoardAccessTable({
return ( return (
<DataTable <DataTable
table={table} table={table}
rowClassName="border-t border-slate-200 hover:bg-slate-50" rowClassName="border-t border-border hover:bg-muted"
headerClassName="bg-slate-50 text-[11px] uppercase tracking-wide text-slate-500" headerClassName="bg-muted text-[11px] uppercase tracking-wide text-muted-foreground"
headerCellClassName="px-4 py-2 font-medium" headerCellClassName="px-4 py-2 font-medium"
cellClassName="px-4 py-3" cellClassName="px-4 py-3"
/> />

View File

@ -97,14 +97,14 @@ export function MembersInvitesTable({
const display = memberDisplay(row.original.member); const display = memberDisplay(row.original.member);
return ( return (
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-indigo-500 text-xs font-semibold text-white"> <div className="flex h-9 w-9 items-center justify-center rounded-lg bg-primary text-xs font-semibold text-primary-foreground">
{display.initials} {display.initials}
</div> </div>
<div> <div>
<div className="text-sm font-semibold text-slate-900"> <div className="text-sm font-semibold text-foreground">
{display.primary} {display.primary}
</div> </div>
<div className="text-xs text-slate-500"> <div className="text-xs text-muted-foreground">
{display.secondary} {display.secondary}
</div> </div>
</div> </div>
@ -114,14 +114,14 @@ export function MembersInvitesTable({
return ( return (
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="flex h-9 w-9 items-center justify-center rounded-lg bg-slate-200 text-xs font-semibold text-slate-600"> <div className="flex h-9 w-9 items-center justify-center rounded-lg bg-border text-xs font-semibold text-muted-foreground">
{initialsFrom(row.original.invite.invited_email)} {initialsFrom(row.original.invite.invited_email)}
</div> </div>
<div> <div>
<div className="text-sm font-semibold text-slate-900"> <div className="text-sm font-semibold text-foreground">
{row.original.invite.invited_email} {row.original.invite.invited_email}
</div> </div>
<div className="text-xs text-slate-500"> <div className="text-xs text-muted-foreground">
Invited {formatTimestamp(row.original.invite.created_at)} Invited {formatTimestamp(row.original.invite.created_at)}
</div> </div>
</div> </div>
@ -155,7 +155,7 @@ export function MembersInvitesTable({
id: "access", id: "access",
header: "Access", header: "Access",
cell: ({ row }) => ( cell: ({ row }) => (
<span className="text-slate-600"> <span className="text-muted-foreground">
{row.original.kind === "member" {row.original.kind === "member"
? summarizeAccess( ? summarizeAccess(
row.original.member.all_boards_read, row.original.member.all_boards_read,
@ -175,7 +175,7 @@ export function MembersInvitesTable({
if (row.original.kind === "member") { if (row.original.kind === "member") {
const member = row.original.member; const member = row.original.member;
if (!isAdmin) { if (!isAdmin) {
return <span className="text-xs text-slate-400">Admin only</span>; return <span className="text-xs text-muted-foreground/70">Admin only</span>;
} }
return ( return (
<div className="flex justify-end"> <div className="flex justify-end">
@ -241,13 +241,13 @@ export function MembersInvitesTable({
isLoading={isLoading} isLoading={isLoading}
loadingLabel="Loading members..." loadingLabel="Loading members..."
emptyMessage="No members or invites yet." emptyMessage="No members or invites yet."
headerClassName="bg-slate-50 text-[11px] uppercase tracking-wide text-slate-500" headerClassName="bg-muted text-[11px] uppercase tracking-wide text-muted-foreground"
headerCellClassName="px-5 py-3 text-left font-medium" headerCellClassName="px-5 py-3 text-left font-medium"
cellClassName="px-5 py-4" cellClassName="px-5 py-4"
rowClassName={(row) => rowClassName={(row) =>
row.original.kind === "invite" row.original.kind === "invite"
? "border-t border-slate-200 bg-slate-50/60" ? "border-t border-border bg-muted/60"
: "border-t border-slate-200 hover:bg-slate-50" : "border-t border-border hover:bg-muted"
} }
/> />
); );

View File

@ -138,13 +138,13 @@ export function MarketplaceSkillForm({
return ( return (
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="space-y-6 rounded-xl border border-slate-200 bg-white p-6 shadow-sm" className="space-y-6 rounded-xl border border-border bg-card p-6 shadow-sm"
> >
<div className="space-y-5"> <div className="space-y-5">
<div className="space-y-2"> <div className="space-y-2">
<label <label
htmlFor="source-url" htmlFor="source-url"
className="text-xs font-semibold uppercase tracking-wider text-slate-500" className="text-xs font-semibold uppercase tracking-wider text-muted-foreground"
> >
{sourceLabel} {sourceLabel}
</label> </label>
@ -158,7 +158,7 @@ export function MarketplaceSkillForm({
disabled={isSubmitting || sourceUrlReadOnly} disabled={isSubmitting || sourceUrlReadOnly}
/> />
{sourceUrlHelpText ? ( {sourceUrlHelpText ? (
<p className="text-xs text-slate-500">{sourceUrlHelpText}</p> <p className="text-xs text-muted-foreground">{sourceUrlHelpText}</p>
) : null} ) : null}
</div> </div>
@ -166,7 +166,7 @@ export function MarketplaceSkillForm({
<div className="space-y-2"> <div className="space-y-2">
<label <label
htmlFor="skill-branch" htmlFor="skill-branch"
className="text-xs font-semibold uppercase tracking-wider text-slate-500" className="text-xs font-semibold uppercase tracking-wider text-muted-foreground"
> >
{branchLabel} {branchLabel}
</label> </label>
@ -183,7 +183,7 @@ export function MarketplaceSkillForm({
<div className="space-y-2"> <div className="space-y-2">
<label <label
htmlFor="skill-name" htmlFor="skill-name"
className="text-xs font-semibold uppercase tracking-wider text-slate-500" className="text-xs font-semibold uppercase tracking-wider text-muted-foreground"
> >
{nameLabel} {nameLabel}
</label> </label>
@ -199,7 +199,7 @@ export function MarketplaceSkillForm({
<div className="space-y-2"> <div className="space-y-2">
<label <label
htmlFor="skill-description" htmlFor="skill-description"
className="text-xs font-semibold uppercase tracking-wider text-slate-500" className="text-xs font-semibold uppercase tracking-wider text-muted-foreground"
> >
{descriptionLabel} {descriptionLabel}
</label> </label>

View File

@ -68,7 +68,7 @@ function riskPillClassName(risk: string | null | undefined) {
case "critical": case "critical":
return "bg-[color:rgba(244,63,94,0.16)] text-rose-800 border border-rose-200/70"; return "bg-[color:rgba(244,63,94,0.16)] text-rose-800 border border-rose-200/70";
case "unknown": case "unknown":
return "bg-[color:rgba(148,163,184,0.16)] text-slate-700 border border-slate-200/80"; return "bg-[color:rgba(148,163,184,0.16)] text-muted-foreground border border-border/80";
default: default:
return "bg-[color:rgba(99,102,241,0.16)] text-indigo-800 border border-indigo-200/70"; return "bg-[color:rgba(99,102,241,0.16)] text-indigo-800 border border-indigo-200/70";
} }
@ -129,17 +129,17 @@ export function MarketplaceSkillsTable({
<button <button
type="button" type="button"
onClick={() => onSkillClick(row.original)} onClick={() => onSkillClick(row.original)}
className="text-sm font-medium text-blue-700 hover:text-blue-600 hover:underline" className="text-sm font-medium text-primary hover:text-primary hover:underline"
> >
{row.original.name} {row.original.name}
</button> </button>
) : ( ) : (
<p className="text-sm font-medium text-slate-900"> <p className="text-sm font-medium text-foreground">
{row.original.name} {row.original.name}
</p> </p>
)} )}
<p <p
className="mt-1 line-clamp-2 text-xs text-slate-500" className="mt-1 line-clamp-2 text-xs text-muted-foreground"
title={row.original.description || "No description provided."} title={row.original.description || "No description provided."}
> >
{row.original.description || "No description provided."} {row.original.description || "No description provided."}
@ -155,7 +155,7 @@ export function MarketplaceSkillsTable({
return ( return (
<Link <Link
href={packsHrefFromPackUrl(packUrl)} href={packsHrefFromPackUrl(packUrl)}
className="inline-flex items-center gap-1 text-sm font-medium text-slate-700 hover:text-blue-600" className="inline-flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-primary"
> >
{truncate(packLabelFromUrl(packUrl), 40)} {truncate(packLabelFromUrl(packUrl), 40)}
</Link> </Link>
@ -166,7 +166,7 @@ export function MarketplaceSkillsTable({
accessorKey: "category", accessorKey: "category",
header: "Category", header: "Category",
cell: ({ row }) => ( cell: ({ row }) => (
<span className="text-sm text-slate-700"> <span className="text-sm text-muted-foreground">
{row.original.category || "uncategorized"} {row.original.category || "uncategorized"}
</span> </span>
), ),
@ -190,7 +190,7 @@ export function MarketplaceSkillsTable({
const sourceHref = row.original.source || row.original.source_url; const sourceHref = row.original.source || row.original.source_url;
if (!sourceHref) { if (!sourceHref) {
return <span className="text-sm text-slate-400">No source</span>; return <span className="text-sm text-muted-foreground/70">No source</span>;
} }
return ( return (
@ -198,7 +198,7 @@ export function MarketplaceSkillsTable({
href={sourceHref} href={sourceHref}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
className="text-sm font-medium text-slate-700 hover:text-blue-600 hover:underline" className="text-sm font-medium text-muted-foreground hover:text-primary hover:underline"
title={sourceHref} title={sourceHref}
> >
{truncate(sourceHref, 36)} {truncate(sourceHref, 36)}
@ -214,7 +214,7 @@ export function MarketplaceSkillsTable({
const installedOn = const installedOn =
installedGatewayNamesBySkillId?.[row.original.id] ?? []; installedGatewayNamesBySkillId?.[row.original.id] ?? [];
if (installedOn.length === 0) { if (installedOn.length === 0) {
return <span className="text-sm text-slate-500">-</span>; return <span className="text-sm text-muted-foreground">-</span>;
} }
return ( return (
<div className="flex flex-wrap gap-1"> <div className="flex flex-wrap gap-1">
@ -223,12 +223,12 @@ export function MarketplaceSkillsTable({
return ( return (
<span <span
key={`${gateway.id}-${index}`} key={`${gateway.id}-${index}`}
className="inline-flex items-center gap-1 text-sm text-slate-700" className="inline-flex items-center gap-1 text-sm text-muted-foreground"
title={gateway.name} title={gateway.name}
> >
<Link <Link
href={`/gateways/${gateway.id}`} href={`/gateways/${gateway.id}`}
className="text-blue-700 hover:text-blue-600 hover:underline" className="text-primary hover:text-primary hover:underline"
> >
{gateway.name} {gateway.name}
</Link> </Link>
@ -302,7 +302,7 @@ export function MarketplaceSkillsTable({
table={table} table={table}
isLoading={isLoading} isLoading={isLoading}
stickyHeader={stickyHeader} stickyHeader={stickyHeader}
rowClassName="transition hover:bg-slate-50" rowClassName="transition hover:bg-muted"
cellClassName="px-6 py-4 align-top" cellClassName="px-6 py-4 align-top"
emptyState={ emptyState={
emptyState emptyState

View File

@ -58,7 +58,7 @@ export function SkillInstallDialog({
<div className="mt-2 space-y-3.5"> <div className="mt-2 space-y-3.5">
{isGatewayStatusLoading ? ( {isGatewayStatusLoading ? (
<p className="text-sm text-slate-500">Loading gateways...</p> <p className="text-sm text-muted-foreground">Loading gateways...</p>
) : ( ) : (
gateways.map((gateway) => { gateways.map((gateway) => {
const isInstalled = gatewayInstalledById[gateway.id] === true; const isInstalled = gatewayInstalledById[gateway.id] === true;
@ -67,10 +67,10 @@ export function SkillInstallDialog({
return ( return (
<div <div
key={gateway.id} key={gateway.id}
className="flex items-center justify-between rounded-xl border border-slate-200 bg-white p-4" className="flex items-center justify-between rounded-xl border border-border bg-card p-4"
> >
<div> <div>
<p className="text-sm font-medium text-slate-900"> <p className="text-sm font-medium text-foreground">
{gateway.name} {gateway.name}
</p> </p>
</div> </div>
@ -101,7 +101,7 @@ export function SkillInstallDialog({
) : null} ) : null}
</div> </div>
<DialogFooter className="mt-6 border-t border-slate-200 pt-4"> <DialogFooter className="mt-6 border-t border-border pt-4">
<Button <Button
variant="outline" variant="outline"
onClick={() => onOpenChange(false)} onClick={() => onOpenChange(false)}

View File

@ -65,10 +65,10 @@ export function SkillPacksTable({
header: "Pack", header: "Pack",
cell: ({ row }) => ( cell: ({ row }) => (
<div> <div>
<p className="text-sm font-medium text-slate-900"> <p className="text-sm font-medium text-foreground">
{row.original.name} {row.original.name}
</p> </p>
<p className="mt-1 line-clamp-2 text-xs text-slate-500"> <p className="mt-1 line-clamp-2 text-xs text-muted-foreground">
{row.original.description || "No description provided."} {row.original.description || "No description provided."}
</p> </p>
</div> </div>
@ -82,7 +82,7 @@ export function SkillPacksTable({
href={row.original.source_url} href={row.original.source_url}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
className="inline-flex items-center gap-1 text-sm font-medium text-slate-700 hover:text-blue-600" className="inline-flex items-center gap-1 text-sm font-medium text-muted-foreground hover:text-primary"
> >
{truncate(row.original.source_url, 48)} {truncate(row.original.source_url, 48)}
</Link> </Link>
@ -92,7 +92,7 @@ export function SkillPacksTable({
accessorKey: "branch", accessorKey: "branch",
header: "Branch", header: "Branch",
cell: ({ row }) => ( cell: ({ row }) => (
<p className="text-sm text-slate-900"> <p className="text-sm text-foreground">
{row.original.branch || "main"} {row.original.branch || "main"}
</p> </p>
), ),
@ -103,7 +103,7 @@ export function SkillPacksTable({
cell: ({ row }) => ( cell: ({ row }) => (
<Link <Link
href={`/skills/marketplace?packId=${encodeURIComponent(row.original.id)}`} href={`/skills/marketplace?packId=${encodeURIComponent(row.original.id)}`}
className="text-sm font-medium text-blue-700 hover:text-blue-600 hover:underline" className="text-sm font-medium text-primary hover:text-primary hover:underline"
> >
{row.original.skill_count ?? 0} {row.original.skill_count ?? 0}
</Link> </Link>
@ -159,7 +159,7 @@ export function SkillPacksTable({
table={table} table={table}
isLoading={isLoading} isLoading={isLoading}
stickyHeader={stickyHeader} stickyHeader={stickyHeader}
rowClassName="transition hover:bg-slate-50" rowClassName="transition hover:bg-muted"
cellClassName="px-6 py-4 align-top" cellClassName="px-6 py-4 align-top"
rowActions={ rowActions={
getEditHref || onDelete getEditHref || onDelete

View File

@ -10,7 +10,7 @@ import {
export const SKILLS_TABLE_EMPTY_ICON = ( export const SKILLS_TABLE_EMPTY_ICON = (
<svg <svg
className="h-16 w-16 text-slate-300" className="h-16 w-16 text-muted-foreground/50"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"

View File

@ -101,13 +101,13 @@ export function TagForm({
return ( return (
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="space-y-6 rounded-xl border border-slate-200 bg-white p-6 shadow-sm" className="space-y-6 rounded-xl border border-border bg-card p-6 shadow-sm"
> >
<div className="space-y-5"> <div className="space-y-5">
<div className="rounded-xl border border-slate-200 bg-slate-50/40 p-4"> <div className="rounded-xl border border-border bg-muted/40 p-4">
<div className="grid gap-4 md:grid-cols-2"> <div className="grid gap-4 md:grid-cols-2">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Name Name
</label> </label>
<Input <Input
@ -119,13 +119,13 @@ export function TagForm({
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<div className="flex items-center justify-between gap-2"> <div className="flex items-center justify-between gap-2">
<label className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Slug Slug
</label> </label>
<button <button
type="button" type="button"
onClick={() => setSlug(suggestedSlug)} onClick={() => setSlug(suggestedSlug)}
className="text-xs font-medium text-slate-500 underline underline-offset-2 transition hover:text-slate-700 disabled:cursor-not-allowed disabled:opacity-50" className="text-xs font-medium text-muted-foreground underline underline-offset-2 transition hover:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
disabled={!suggestedSlug || isSubmitting} disabled={!suggestedSlug || isSubmitting}
> >
Use from name Use from name
@ -139,18 +139,18 @@ export function TagForm({
/> />
</div> </div>
</div> </div>
<p className="mt-2 text-xs text-slate-500"> <p className="mt-2 text-xs text-muted-foreground">
Leave slug blank to auto-generate from the tag name. Leave slug blank to auto-generate from the tag name.
</p> </p>
</div> </div>
<div className="grid gap-4 md:grid-cols-[1fr_auto]"> <div className="grid gap-4 md:grid-cols-[1fr_auto]">
<div className="space-y-2"> <div className="space-y-2">
<label className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Color Color
</label> </label>
<div className="flex items-center rounded-lg border border-slate-200 bg-white px-3"> <div className="flex items-center rounded-lg border border-border bg-card px-3">
<span className="text-sm font-medium text-slate-400">#</span> <span className="text-sm font-medium text-muted-foreground/70">#</span>
<Input <Input
value={color} value={color}
onChange={(event) => setColor(event.target.value)} onChange={(event) => setColor(event.target.value)}
@ -161,15 +161,15 @@ export function TagForm({
</div> </div>
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Preview Preview
</label> </label>
<div className="inline-flex h-[42px] items-center gap-2 rounded-lg border border-slate-200 bg-white px-3"> <div className="inline-flex h-[42px] items-center gap-2 rounded-lg border border-border bg-card px-3">
<span <span
className="h-4 w-4 rounded border border-slate-300" className="h-4 w-4 rounded border border-input"
style={{ backgroundColor: `#${previewColor}` }} style={{ backgroundColor: `#${previewColor}` }}
/> />
<span className="text-xs font-semibold text-slate-700"> <span className="text-xs font-semibold text-muted-foreground">
#{previewColor.toUpperCase()} #{previewColor.toUpperCase()}
</span> </span>
</div> </div>
@ -177,7 +177,7 @@ export function TagForm({
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<label className="text-xs font-semibold uppercase tracking-wider text-slate-500"> <label className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Description Description
</label> </label>
<Textarea <Textarea

View File

@ -32,7 +32,7 @@ type TagsTableProps = {
const DEFAULT_EMPTY_ICON = ( const DEFAULT_EMPTY_ICON = (
<svg <svg
className="h-16 w-16 text-slate-300" className="h-16 w-16 text-muted-foreground/50"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
@ -81,14 +81,14 @@ export function TagsTable({
const color = normalizeColor(row.original.color); const color = normalizeColor(row.original.color);
return ( return (
<div className="space-y-1"> <div className="space-y-1">
<div className="inline-flex items-center gap-2 rounded-full border border-slate-200 bg-white px-2.5 py-1 text-xs font-semibold text-slate-800"> <div className="inline-flex items-center gap-2 rounded-full border border-border bg-card px-2.5 py-1 text-xs font-semibold text-foreground">
<span <span
className="h-2 w-2 rounded-full" className="h-2 w-2 rounded-full"
style={{ backgroundColor: `#${color}` }} style={{ backgroundColor: `#${color}` }}
/> />
{row.original.name} {row.original.name}
</div> </div>
<p className="text-xs text-slate-500"> <p className="text-xs text-muted-foreground">
{row.original.slug} {row.original.slug}
{row.original.description {row.original.description
? ` · ${row.original.description}` ? ` · ${row.original.description}`
@ -104,9 +104,9 @@ export function TagsTable({
cell: ({ row }) => { cell: ({ row }) => {
const color = normalizeColor(row.original.color); const color = normalizeColor(row.original.color);
return ( return (
<div className="inline-flex items-center gap-2 text-xs text-slate-700"> <div className="inline-flex items-center gap-2 text-xs text-muted-foreground">
<span <span
className="h-4 w-4 rounded border border-slate-300" className="h-4 w-4 rounded border border-input"
style={{ backgroundColor: `#${color}` }} style={{ backgroundColor: `#${color}` }}
/> />
#{color.toUpperCase()} #{color.toUpperCase()}
@ -118,7 +118,7 @@ export function TagsTable({
accessorKey: "task_count", accessorKey: "task_count",
header: "Tasks", header: "Tasks",
cell: ({ row }) => ( cell: ({ row }) => (
<span className="text-sm font-medium text-slate-700"> <span className="text-sm font-medium text-muted-foreground">
{row.original.task_count ?? 0} {row.original.task_count ?? 0}
</span> </span>
), ),
@ -149,7 +149,7 @@ export function TagsTable({
table={table} table={table}
isLoading={isLoading} isLoading={isLoading}
stickyHeader={stickyHeader} stickyHeader={stickyHeader}
rowClassName="transition hover:bg-slate-50" rowClassName="transition hover:bg-muted"
cellClassName="px-6 py-4 align-top" cellClassName="px-6 py-4 align-top"
rowActions={ rowActions={
onEdit || onDelete onEdit || onDelete

View File

@ -11,7 +11,7 @@ const buttonVariants = cva(
variants: { variants: {
variant: { variant: {
primary: primary:
"bg-[color:var(--accent)] text-white shadow-sm hover:bg-[color:var(--accent-strong)]", "bg-primary text-primary-foreground shadow-sm hover:bg-[color:var(--accent-strong)]",
secondary: secondary:
"border border-[color:var(--border)] bg-[color:var(--surface)] text-strong hover:border-[color:var(--accent)] hover:text-[color:var(--accent)]", "border border-[color:var(--border)] bg-[color:var(--surface)] text-strong hover:border-[color:var(--accent)] hover:text-[color:var(--accent)]",
outline: outline:

View File

@ -17,7 +17,7 @@ const DialogOverlay = React.forwardRef<
<DialogPrimitive.Overlay <DialogPrimitive.Overlay
ref={ref} ref={ref}
className={cn( className={cn(
"fixed inset-0 z-50 bg-slate-950/40 backdrop-blur-[2px] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", "fixed inset-0 z-50 bg-foreground/40 backdrop-blur-[2px] 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} {...props}

View File

@ -29,7 +29,7 @@ const TabsTrigger = React.forwardRef<
<TabsPrimitive.Trigger <TabsPrimitive.Trigger
ref={ref} ref={ref}
className={cn( className={cn(
"rounded-full px-4 py-2 text-xs font-semibold text-muted transition data-[state=active]:bg-[color:var(--accent)] data-[state=active]:text-white", "rounded-full px-4 py-2 text-xs font-semibold text-muted transition data-[state=active]:bg-primary data-[state=active]:text-primary-foreground",
className, className,
)} )}
{...props} {...props}

View File

@ -17,7 +17,7 @@ const TooltipContent = React.forwardRef<
ref={ref} ref={ref}
sideOffset={sideOffset} sideOffset={sideOffset}
className={cn( className={cn(
"rounded-lg bg-slate-900 px-3 py-2 text-xs font-semibold text-white shadow-lg", "rounded-lg bg-foreground px-3 py-2 text-xs font-semibold text-background shadow-lg",
className, className,
)} )}
{...props} {...props}