Louis/theme cleanup (#582)

* lightmode

* diagonal bg

* contrast

* diffs

* colors

* fix darkmode

* lint
This commit is contained in:
Louis Knight-Webb
2025-08-28 16:34:55 +01:00
committed by GitHub
parent 5538d4bbca
commit 1a1add7618
31 changed files with 136 additions and 265 deletions

View File

@@ -35,7 +35,7 @@ const getEntryIcon = (entryType: NormalizedEntryType) => {
return <User className="h-4 w-4 text-blue-600" />;
}
if (entryType.type === 'assistant_message') {
return <Bot className="h-4 w-4 text-green-600" />;
return <Bot className="h-4 w-4 text-success" />;
}
if (entryType.type === 'system_message') {
return <Settings className="h-4 w-4 text-gray-600" />;
@@ -44,7 +44,7 @@ const getEntryIcon = (entryType: NormalizedEntryType) => {
return <Brain className="h-4 w-4 text-purple-600" />;
}
if (entryType.type === 'error_message') {
return <AlertCircle className="h-4 w-4 text-red-600" />;
return <AlertCircle className="h-4 w-4 text-destructive" />;
}
if (entryType.type === 'tool_use') {
const { action_type, tool_name } = entryType;
@@ -65,7 +65,7 @@ const getEntryIcon = (entryType: NormalizedEntryType) => {
if (action_type.action === 'file_read') {
return <Eye className="h-4 w-4 text-orange-600" />;
} else if (action_type.action === 'file_edit') {
return <Edit className="h-4 w-4 text-red-600" />;
return <Edit className="h-4 w-4 text-destructive" />;
} else if (action_type.action === 'command_run') {
return <Terminal className="h-4 w-4 text-yellow-600" />;
} else if (action_type.action === 'search') {
@@ -93,7 +93,7 @@ const getContentClassName = (entryType: NormalizedEntryType) => {
}
if (entryType.type === 'error_message') {
return `${baseClasses} text-red-600 font-mono bg-red-50 dark:bg-red-950/20 px-2 py-1 rounded`;
return `${baseClasses} text-destructive font-mono bg-red-50 dark:bg-red-950/20 px-2 py-1 rounded`;
}
// Special styling for TODO lists
@@ -227,7 +227,7 @@ function DisplayConversationEntry({ entry, expansionKey }: Props) {
{entry.content.split('\n')[0]}
<button
onClick={() => setIsExpanded()}
className="ml-2 inline-flex items-center gap-1 text-xs text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 transition-colors"
className="ml-2 inline-flex items-center gap-1 text-xs text-destructive hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 transition-colors"
>
<ChevronRight className="h-3 w-3" />
Show more
@@ -238,7 +238,7 @@ function DisplayConversationEntry({ entry, expansionKey }: Props) {
{isExpanded && (
<button
onClick={() => setIsExpanded()}
className="flex items-center gap-1 text-xs text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 transition-colors"
className="flex items-center gap-1 text-xs text-destructive hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 transition-colors"
>
<ChevronUp className="h-3 w-3" />
Show less
@@ -346,8 +346,8 @@ function DisplayConversationEntry({ entry, expansionKey }: Props) {
className={
'h-4 w-4 ' +
(commandSuccess
? 'text-green-600'
: 'text-red-600')
? 'text-success'
: 'text-destructive')
}
/>
)}

View File

@@ -93,7 +93,7 @@ export function PrivacyOptInDialog({
</div>
</div>
<div className="flex items-start gap-2">
<XCircle className="h-4 w-4 text-red-500 mt-0.5 flex-shrink-0" />
<XCircle className="h-4 w-4 text-destructive mt-0.5 flex-shrink-0" />
<div className="min-w-0">
<p className="text-sm font-medium">We do NOT collect</p>
<p className="text-xs text-muted-foreground">

View File

@@ -314,7 +314,7 @@ export function TaskTemplateManager({
rows={4}
/>
</div>
{error && <div className="text-sm text-red-600">{error}</div>}
{error && <div className="text-sm text-destructive">{error}</div>}
</div>
<DialogFooter>
<Button

View File

@@ -25,7 +25,7 @@ const RawLogText = memo(
<Component
className={clsx(
'font-mono text-xs break-all whitespace-pre-wrap',
shouldApplyStderrFallback && 'text-red-600',
shouldApplyStderrFallback && 'text-destructive',
className
)}
>

View File

@@ -58,7 +58,7 @@ export function Navbar() {
};
return (
<div className="border-b bg-secondary">
<div className="border-b bg-background">
<div className="w-full px-3">
<div className="flex items-center h-12 py-2">
<div className="flex-1">

View File

@@ -57,7 +57,7 @@ function LogEntryRow({
);
default:
return (
<div className="text-red-500 text-xs">
<div className="text-destructive text-xs">
Unknown log type: {entry.channel}
</div>
);

View File

@@ -128,7 +128,7 @@ export function ProjectList() {
}, []);
return (
<div className="space-y-6 p-8 bg-secondary h-full">
<div className="space-y-6 p-8 h-full">
<div className="flex justify-between items-center">
<div>
<h1 className="text-3xl font-bold tracking-tight">Projects</h1>

View File

@@ -54,7 +54,7 @@ export function SearchBar({
onChange={(e) => onChange?.(e.target.value)}
disabled={disabled}
placeholder={project ? `Search ${project.name}...` : 'Search...'}
className="pl-8 pr-14 h-8"
className="pl-8 pr-14 h-8 bg-muted"
/>
<kbd className="absolute right-2.5 top-1/2 -translate-y-1/2 pointer-events-none select-none font-mono text-[10px] text-muted-foreground rounded border bg-muted px-1 py-0.5">
S

View File

@@ -58,26 +58,24 @@ export function AttemptHeaderCard({
};
return (
<Card className="border-b border-dashed bg-secondary flex items-center text-sm text-muted-foreground">
<Card className="border-b border-dashed bg-background flex items-center text-sm">
<div className="flex-1 flex gap-6 p-3">
<p>
Attempt &middot;{' '}
<span className="text-primary">
{attemptNumber}/{totalAttempts}
</span>
<span className="text-secondary-foreground">Attempt &middot; </span>
{attemptNumber}/{totalAttempts}
</p>
<p>
Profile &middot;{' '}
<span className="text-primary">{selectedAttempt?.profile}</span>
<span className="text-secondary-foreground">Profile &middot; </span>
{selectedAttempt?.profile}
</p>
{selectedAttempt?.branch && (
<p className="max-w-30 truncate">
Branch &middot;{' '}
<span className="text-primary">{selectedAttempt.branch}</span>
<span className="text-secondary-foreground">Branch &middot; </span>
{selectedAttempt.branch}
</p>
)}
{fileCount > 0 && (
<p>
<p className="text-secondary-foreground">
<Button
variant="ghost"
size="sm"
@@ -86,8 +84,8 @@ export function AttemptHeaderCard({
>
Diffs
</Button>{' '}
&middot; <span className="text-green-600">+{added}</span>{' '}
<span className="text-red-600">-{deleted}</span>
&middot; <span className="text-success">+{added}</span>{' '}
<span className="text-destructive">-{deleted}</span>
</p>
)}
</div>

View File

@@ -90,7 +90,7 @@ export function TaskCard({
)}
{/* Failed Indicator */}
{task.last_attempt_failed && !task.has_merged_attempt && (
<XCircle className="h-3 w-3 text-red-500" />
<XCircle className="h-3 w-3 text-destructive" />
)}
{/* Actions Menu */}
<div
@@ -127,7 +127,7 @@ export function TaskCard({
</div>
</div>
{task.description && (
<p className="flex-1 text-xs text-muted-foreground break-words">
<p className="flex-1 text-sm text-secondary-foreground break-words">
{task.description.length > 130
? `${task.description.substring(0, 130)}...`
: task.description}

View File

@@ -41,7 +41,7 @@ function ProcessCard({ process }: ProcessCardProps) {
case 'completed':
return <CheckCircle className="h-4 w-4 text-green-500" />;
case 'failed':
return <AlertCircle className="h-4 w-4 text-red-500" />;
return <AlertCircle className="h-4 w-4 text-destructive" />;
case 'killed':
return <Square className="h-4 w-4 text-gray-500" />;
default:
@@ -146,7 +146,9 @@ function ProcessCard({ process }: ProcessCardProps) {
{showLogs && (
<div className="mt-3">
{error && <div className="text-red-500 text-sm mb-2">{error}</div>}
{error && (
<div className="text-destructive text-sm mb-2">{error}</div>
)}
{isCodingAgent ? (
// Normalized conversation display for coding agents

View File

@@ -34,7 +34,7 @@ function ProcessesTab({ attemptId }: ProcessesTabProps) {
case 'completed':
return <CheckCircle className="h-4 w-4 text-green-500" />;
case 'failed':
return <AlertCircle className="h-4 w-4 text-red-500" />;
return <AlertCircle className="h-4 w-4 text-destructive" />;
case 'killed':
return <Square className="h-4 w-4 text-gray-500" />;
default:

View File

@@ -17,54 +17,42 @@ function TabNavigation({
selectedAttempt,
}: Props) {
const { attemptData } = useAttemptExecution(selectedAttempt?.id);
return (
<div className="border-b border-dashed bg-secondary sticky top-0 z-10">
<div className="flex items-center px-4">
<button
onClick={() => {
setActiveTab('logs');
}}
className={`flex items-center px-4 py-2 text-sm font-medium ${
activeTab === 'logs'
? 'text-primary bg-background'
: 'text-muted-foreground hover:text-foreground hover:bg-muted/50'
}`}
>
<MessageSquare className="h-4 w-4 mr-2" />
Logs
</button>
<button
onClick={() => {
setActiveTab('diffs');
}}
className={`flex items-center px-4 py-2 text-sm font-medium ${
activeTab === 'diffs'
? 'text-primary bg-background'
: 'text-muted-foreground hover:text-foreground hover:bg-muted/50'
}`}
>
<GitCompare className="h-4 w-4 mr-2" />
Diffs
</button>
<button
onClick={() => {
setActiveTab('processes');
}}
className={`flex items-center px-4 py-2 text-sm font-medium ${
activeTab === 'processes'
? 'text-primary bg-background'
: 'text-muted-foreground hover:text-foreground hover:bg-muted/50'
}`}
>
<Cog className="h-4 w-4 mr-2" />
Processes
{attemptData.processes && attemptData.processes.length > 0 && (
<span className="ml-2 px-1.5 py-0.5 text-xs bg-primary/10 text-primary rounded-full">
{attemptData.processes.length}
</span>
)}
</button>
const tabs = [
{ id: 'logs' as TabType, label: 'Logs', icon: MessageSquare },
{ id: 'diffs' as TabType, label: 'Diffs', icon: GitCompare },
{ id: 'processes' as TabType, label: 'Processes', icon: Cog },
];
const getTabClassName = (tabId: TabType) => {
const baseClasses = 'flex items-center py-2 px-2 text-sm font-medium';
const activeClasses = 'text-primary-foreground';
const inactiveClasses =
'text-secondary-foreground hover:text-primary-foreground';
return `${baseClasses} ${activeTab === tabId ? activeClasses : inactiveClasses}`;
};
return (
<div className="border-b border-dashed bg-background sticky top-0 z-10">
<div className="flex items-center px-3 space-x-3">
{tabs.map(({ id, label, icon: Icon }) => (
<button
key={id}
onClick={() => setActiveTab(id)}
className={getTabClassName(id)}
>
<Icon className="h-4 w-4 mr-2" />
{label}
{id === 'processes' &&
attemptData.processes &&
attemptData.processes.length > 0 && (
<span className="ml-2 px-1.5 py-0.5 text-xs bg-primary/10 text-primary rounded-full">
{attemptData.processes.length}
</span>
)}
</button>
))}
<div className="ml-auto flex items-center">{rightContent}</div>
</div>
</div>

View File

@@ -15,7 +15,7 @@ export function TaskTitleDescription({ task }: TaskTitleDescriptionProps) {
<h2 className="text-lg font-medium mb-1 line-clamp-2">{task.title}</h2>
<div className="mt-2">
<div className="flex items-start gap-2 text-sm text-muted-foreground">
<div className="flex items-start gap-2 text-sm text-secondary-foreground">
{task.description ? (
<div className="flex-1 min-w-0">
<p
@@ -34,7 +34,7 @@ export function TaskTitleDescription({ task }: TaskTitleDescriptionProps) {
onClick={() =>
setIsDescriptionExpanded(!isDescriptionExpanded)
}
className="mt-1 p-0 h-auto text-xs text-muted-foreground hover:text-foreground"
className="mt-1 p-0 h-auto text-sm text-secondary-foreground hover:text-foreground"
>
{isDescriptionExpanded ? (
<>

View File

@@ -36,7 +36,7 @@ function TaskDetailsHeader({
return (
<div>
<Card
className="flex shrink-0 items-center gap-2 border-b border-dashed bg-secondary"
className="flex shrink-0 items-center gap-2 border-b border-dashed bg-background"
style={{}}
>
<div className="p-3 flex flex-1 items-center truncate">
@@ -107,7 +107,7 @@ function TaskDetailsHeader({
size="icon"
onClick={() => onDeleteTask(task.id)}
>
<Trash2 className="h-4 w-4 text-red-500" />
<Trash2 className="h-4 w-4 text-destructive" />
</Button>
</TooltipTrigger>
<TooltipContent>

View File

@@ -202,7 +202,7 @@ function TaskDetailsToolbar({
{/* Error Display */}
{ui.error && (
<div className="mb-4 p-3 bg-red-50 border border-red-200">
<div className="text-red-600 text-sm">{ui.error}</div>
<div className="text-destructive text-sm">{ui.error}</div>
</div>
)}
@@ -222,7 +222,7 @@ function TaskDetailsToolbar({
/>
) : (
<div className="">
<Card className="bg-secondary border-y border-dashed p-3 text-sm">
<Card className="bg-background border-y border-dashed p-3 text-sm">
Actions
</Card>
<div className="p-3">

View File

@@ -247,7 +247,7 @@ export function TaskFollowUpSection({
<div className="flex-1 flex gap-2">
{/* Image button */}
<Button
variant="outline"
variant="secondary"
size="sm"
className="h-10 w-10 p-0"
onClick={() => setShowImageUpload(!showImageUpload)}
@@ -273,7 +273,7 @@ export function TaskFollowUpSection({
<DropdownMenuTrigger asChild>
<Button
ref={variantButtonRef}
variant="outline"
variant="secondary"
size="sm"
className={cn(
'h-10 w-24 px-2 flex items-center justify-between transition-all',

View File

@@ -10,7 +10,7 @@ import { Card } from '../ui/card';
function getStatusIcon(status?: string) {
const s = (status || '').toLowerCase();
if (s === 'completed')
return <CircleCheckBig aria-hidden className="h-4 w-4 text-green-600" />;
return <CircleCheckBig aria-hidden className="h-4 w-4 text-success" />;
if (s === 'in_progress' || s === 'in-progress')
return <CircleDotDashed aria-hidden className="h-4 w-4 text-blue-500" />;
return <Circle aria-hidden className="h-4 w-4 text-muted-foreground" />;
@@ -39,7 +39,7 @@ export function TodoPanel({ selectedAttempt }: TodoPanelProps) {
return (
<div>
<Card className="bg-secondary p-3 border border-dashed text-sm">
<Card className="bg-background p-3 border border-dashed text-sm">
Todos
</Card>
<div className="p-3">

View File

@@ -144,7 +144,7 @@ function CreateAttempt({
return (
<div className="">
<Card className="bg-secondary p-3 text-sm border-y border-dashed">
<Card className="bg-background p-3 text-sm border-y border-dashed">
Create Attempt
</Card>
<div className="space-y-3 px-3">
@@ -172,7 +172,7 @@ function CreateAttempt({
<div className="space-y-1">
<div className="flex items-center gap-1.5">
<label className="text-xs font-medium text-muted-foreground">
Base branch <span className="text-red-500">*</span>
Base branch <span className="text-destructive">*</span>
</label>
</div>
<BranchSelector

View File

@@ -176,7 +176,7 @@ function CreatePrDialog() {
</Select>
</div>
{error && (
<div className="text-sm text-red-600 bg-red-50 p-2 rounded">
<div className="text-sm text-destructive bg-red-50 p-2 rounded">
{error}
</div>
)}

View File

@@ -55,7 +55,7 @@ const AutoExpandingTextarea = React.forwardRef<
return (
<textarea
className={cn(
'bg-background p-0 min-h-[80px] w-full text-sm placeholder:text-muted-foreground outline-none disabled:cursor-not-allowed disabled:opacity-50 resize-none overflow-y-auto',
'bg-muted p-0 min-h-[80px] w-full text-sm placeholder:text-muted-foreground outline-none disabled:cursor-not-allowed disabled:opacity-50 resize-none overflow-y-auto',
className
)}
ref={textareaRef}

View File

@@ -9,15 +9,16 @@ const buttonVariants = cva(
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
default:
'bg-primary text-primary-foreground hover:bg-primary/90 border border-foreground',
destructive:
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline:
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary:
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:text-primary/50',
link: 'text-primary underline-offset-4 hover:underline',
'bg-secondary text-secondary-foreground hover:bg-secondary/80 border',
ghost: 'hover:text-primary-foreground/50',
link: 'hover:underline',
},
size: {
default: 'h-10 px-4 py-2',

View File

@@ -243,7 +243,7 @@ export function FolderPicker({
>
{entry.is_directory ? (
entry.is_git_repo ? (
<FolderOpen className="h-4 w-4 text-green-600 flex-shrink-0" />
<FolderOpen className="h-4 w-4 text-success flex-shrink-0" />
) : (
<Folder className="h-4 w-4 text-blue-600 flex-shrink-0" />
)
@@ -254,7 +254,7 @@ export function FolderPicker({
{entry.name}
</span>
{entry.is_git_repo && (
<span className="text-xs text-green-600 bg-green-100 px-2 py-1 rounded flex-shrink-0">
<span className="text-xs text-success bg-green-100 px-2 py-1 rounded flex-shrink-0">
git repo
</span>
)}

View File

@@ -11,7 +11,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
<input
type={type}
className={cn(
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
'flex h-10 w-full rounded-md border bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}

View File

@@ -42,7 +42,7 @@ export const KanbanBoard = ({ id, children, className }: KanbanBoardProps) => {
return (
<div
className={cn(
'flex h-full min-h-40 flex-col bg-secondary',
'flex h-full min-h-40 flex-col',
isOver ? 'outline-primary' : 'outline-black',
className
)}
@@ -144,7 +144,7 @@ export const KanbanHeader = (props: KanbanHeaderProps) =>
<Card
className={cn(
'sticky top-0 z-20 flex shrink-0 items-center gap-2 p-3 border-b border-dashed',
'bg-secondary',
'bg-background',
props.className
)}
style={{

View File

@@ -40,11 +40,11 @@ export const getTaskPanelClasses = (forceFullScreen: boolean) => {
`${PANEL_SIDE_BY_SIDE_BREAKPOINT}:w-[800px]`,
].join(' ');
return `fixed flex flex-col items-center inset-y-0 right-0 z-50 ${overlayClasses} ${sideBySideClasses} bg-muted border-l shadow-lg overflow-hidden `;
return `fixed flex flex-col items-center inset-y-0 right-0 z-50 ${overlayClasses} ${sideBySideClasses} bg-diagonal-lines shadow-lg overflow-hidden `;
};
export const getTaskPanelInnerClasses = () => {
return `flex-1 flex flex-col min-h-0 w-full max-w-[1400px] bg-background`;
return `flex-1 flex flex-col min-h-0 w-full max-w-[1400px] bg-muted border-x`;
};
// Generate classes for backdrop (only show in overlay mode)

View File

@@ -287,7 +287,7 @@ export function McpServers() {
minHeight={300}
/>
{mcpError && !mcpError.includes('does not support MCP') && (
<p className="text-sm text-red-600 dark:text-red-400">
<p className="text-sm text-destructive dark:text-red-400">
{mcpError}
</p>
)}

View File

@@ -329,7 +329,7 @@ export function ProjectTasks() {
</Card>
</div>
) : (
<div className="w-full h-full overflow-x-auto bg-secondary">
<div className="w-full h-full overflow-x-auto">
<TaskKanbanBoard
tasks={tasks}
searchQuery={searchQuery}

View File

@@ -363,7 +363,7 @@
}
.diff-tailwindcss-wrapper .diff-style-root {
--diff-border--: var(--background);
--diff-border--: var(--border);
--diff-add-content--: hsl(var(--console-success) / 0.2);
--diff-del-content--: hsl(var(--console-error) / 0.2);
--diff-add-lineNumber--: color-mix(
@@ -372,19 +372,19 @@
hsl(var(--background)) 80%
);
--diff-del-lineNumber--: hsl(var(--console-error) / 0.2);
--diff-plain-content--: hsl(var(--background));
--diff-expand-content--: hsl(var(--background));
--diff-plain-lineNumber--: hsl(var(--background));
--diff-expand-lineNumber--: hsl(var(--background));
--diff-plain-content--: hsl(var(--muted));
--diff-expand-content--: hsl(var(--muted));
--diff-plain-lineNumber--: hsl(var(--muted));
--diff-expand-lineNumber--: hsl(var(--muted));
--diff-plain-lineNumber-color--: hsl(var(--muted-foreground) / 0.7);
--diff-expand-lineNumber-color--: hsl(var(--muted-foreground) / 0.7);
--diff-hunk-content--: hsl(var(--background));
--diff-hunk-lineNumber--: hsl(var(--background));
--diff-hunk-content--: hsl(var(--muted));
--diff-hunk-lineNumber--: hsl(var(--muted));
--diff-hunk-lineNumber-hover--: hsl(var(--muted-foreground) / 0.7);
--diff-add-content-highlight--: hsl(var(--console-success) / 0.4);
--diff-del-content-highlight--: hsl(var(--console-error) / 0.4);
--diff-add-widget--: hsl(var(--muted-foreground) / 0.7);
--diff-add-widget-color--: hsl(var(--background));
--diff-add-widget-color--: hsl(var(--muted));
--diff-empty-content--: hsl(var(--background));
--diff-hunk-content-color--: hsl(var(--muted-foreground) / 0.7);
}

View File

@@ -6,24 +6,20 @@
@layer base {
/* Light defaults */
:root {
--_background: 0 0% 100%;
--_background: 48 33% 97%;
--_foreground: 222.2 84% 4.9%;
--_card: 0 0% 100%;
--_card-foreground: 222.2 84% 4.9%;
--_popover: 0 0% 100%;
--_popover-foreground: 222.2 84% 4.9%;
--_primary: 222.2 47.4% 11.2%;
--_primary-foreground: 210 40% 98%;
--_secondary: 48, 33%, 97%;
--_secondary-foreground: 222.2 84% 4.9%;
--_muted: 210 40% 96%;
--_muted-foreground: 215.4 16.3% 46.9%;
--_accent: 210 40% 96%;
--_primary: var(--_muted);
--_primary-foreground: var(--_muted-foreground);
--_secondary: var(--_muted);
--_secondary-foreground: 215.4 16.3% 46.9%;
--_muted: 0 0% 100%;
--_muted-foreground: var(--_foreground);
--_accent: var(--_background);
--_accent-foreground: 222.2 84% 4.9%;
--_destructive: 0 84.2% 60.2%;
--_destructive-foreground: 210 40% 98%;
--_destructive-foreground: var(--_background);
--_border: 214.3 31.8% 91.4%;
--_input: 214.3 31.8% 91.4%;
--_input: var(--_border);
--_ring: 222.2 84% 4.9%;
--_radius: 0.5rem;
@@ -46,24 +42,20 @@
/* Dark defaults (used if no theme class but user prefers dark) */
.dark {
--_background: 60, 2%, 18%;
--_foreground: 210 40% 98%;
--_card: 60, 2%, 18%;
--_card-foreground: 210 40% 98%;
--_popover: 222.2 84% 4.9%;
--_popover-foreground: 210 40% 98%;
--_primary: 210 40% 98%;
--_primary-foreground: 222.2 47.4% 11.2%;
--_secondary: 60, 3%, 15%;
--_secondary-foreground: 210 40% 98%;
--_muted: 30, 3%, 12%;
--_muted-foreground: 215 20.2% 65.1%;
--_accent: 217.2 32.6% 17.5%;
--_background: 60 2% 18%;
--_foreground: 48 7% 95%;
--_primary: var(--_muted);
--_primary-foreground: var(--_muted-foreground);
--_secondary: var(--_muted);
--_secondary-foreground: 48 7% 73%;
--_muted: 60 2% 20%;
--_muted-foreground: var(--_foreground);
--_accent: var(--_background);
--_accent-foreground: 210 40% 98%;
--_destructive: 0 62.8% 30.6%;
--_destructive-foreground: 210 40% 98%;
--_border: 30, 3%, 12%;
--_input: 210 40% 98%;
--_destructive: 0 62.8% 50.6%;
--_destructive-foreground: var(--_background);
--_border: 60 2% 25%;
--_input: var(--_border);
--_ring: 212.7 26.8% 83.9%;
/* Status (dark) */
@@ -82,116 +74,6 @@
--_console-success: 138.5 76.5% 47.7%;
--_console-error: 0 84.2% 60.2%;
}
.purple {
--_background: 266 100% 6%;
--_foreground: 266 20% 95%;
--_card: 266 100% 6%;
--_card-foreground: 266 20% 95%;
--_popover: 266 100% 6%;
--_popover-foreground: 266 20% 95%;
--_primary: 266 80% 75%;
--_primary-foreground: 266 100% 6%;
--_secondary: 266 20% 15%;
--_secondary-foreground: 266 20% 95%;
--_muted: 266 20% 15%;
--_muted-foreground: 266 15% 65%;
--_accent: 266 20% 15%;
--_accent-foreground: 266 20% 95%;
--_destructive: 0 62.8% 30.6%;
--_destructive-foreground: 266 20% 95%;
--_border: 266 20% 15%;
--_input: 266 20% 15%;
--_ring: 266 80% 75%;
}
.green {
--_background: 120 100% 6%;
--_foreground: 120 20% 95%;
--_card: 120 100% 6%;
--_card-foreground: 120 20% 95%;
--_popover: 120 100% 6%;
--_popover-foreground: 120 20% 95%;
--_primary: 120 80% 75%;
--_primary-foreground: 120 100% 6%;
--_secondary: 120 20% 15%;
--_secondary-foreground: 120 20% 95%;
--_muted: 120 20% 15%;
--_muted-foreground: 120 15% 65%;
--_accent: 120 20% 15%;
--_accent-foreground: 120 20% 95%;
--_destructive: 0 62.8% 30.6%;
--_destructive-foreground: 120 20% 95%;
--_border: 120 20% 15%;
--_input: 120 20% 15%;
--_ring: 120 80% 75%;
}
.blue {
--_background: 210 100% 6%;
--_foreground: 210 20% 95%;
--_card: 210 100% 6%;
--_card-foreground: 210 20% 95%;
--_popover: 210 100% 6%;
--_popover-foreground: 210 20% 95%;
--_primary: 210 80% 75%;
--_primary-foreground: 210 100% 6%;
--_secondary: 210 20% 15%;
--_secondary-foreground: 210 20% 95%;
--_muted: 210 20% 15%;
--_muted-foreground: 210 15% 65%;
--_accent: 210 20% 15%;
--_accent-foreground: 210 20% 95%;
--_destructive: 0 62.8% 30.6%;
--_destructive-foreground: 210 20% 95%;
--_border: 210 20% 15%;
--_input: 210 20% 15%;
--_ring: 210 80% 75%;
}
.orange {
--_background: 30 100% 6%;
--_foreground: 30 20% 95%;
--_card: 30 100% 6%;
--_card-foreground: 30 20% 95%;
--_popover: 30 100% 6%;
--_popover-foreground: 30 20% 95%;
--_primary: 30 80% 75%;
--_primary-foreground: 30 100% 6%;
--_secondary: 30 20% 15%;
--_secondary-foreground: 30 20% 95%;
--_muted: 30 20% 15%;
--_muted-foreground: 30 15% 65%;
--_accent: 30 20% 15%;
--_accent-foreground: 30 20% 95%;
--_destructive: 0 62.8% 30.6%;
--_destructive-foreground: 30 20% 95%;
--_border: 30 20% 15%;
--_input: 30 20% 15%;
--_ring: 30 80% 75%;
}
.red {
--_background: 0 100% 6%;
--_foreground: 0 20% 95%;
--_card: 0 100% 6%;
--_card-foreground: 0 20% 95%;
--_popover: 0 100% 6%;
--_popover-foreground: 0 20% 95%;
--_primary: 0 80% 75%;
--_primary-foreground: 0 100% 6%;
--_secondary: 0 20% 15%;
--_secondary-foreground: 0 20% 95%;
--_muted: 0 20% 15%;
--_muted-foreground: 0 15% 65%;
--_accent: 0 20% 15%;
--_accent-foreground: 0 20% 95%;
--_destructive: 0 62.8% 30.6%;
--_destructive-foreground: 0 20% 95%;
--_border: 0 20% 15%;
--_input: 0 20% 15%;
--_ring: 0 80% 75%;
}
}
/* 2) PUBLIC TOKENS: prefer VS Code, else fall back to theme tokens */
@@ -200,16 +82,10 @@
--background: var(--vscode-editor-background, var(--_background));
--foreground: var(--vscode-editor-foreground, var(--_foreground));
--card: var(--vscode-editorWidget-background, var(--_card));
--card-foreground: var(
--vscode-editorWidget-foreground,
var(--_card-foreground)
);
--popover: var(--vscode-editorWidget-background, var(--_popover));
--popover-foreground: var(
--vscode-editorWidget-foreground,
var(--_popover-foreground)
);
--card: var(--muted);
--card-foreground: var(--muted-foreground);
--popover: var(--background);
--popover-foreground: var(--foreground);
--primary: var(--vscode-button-background, var(--_primary));
--primary-foreground: var(

View File

@@ -31,6 +31,12 @@ module.exports = {
},
},
extend: {
backgroundImage: {
'diagonal-lines': `
repeating-linear-gradient(-45deg, hsl(var(--border) / 0.4) 0 2px, transparent 1px 12px),
linear-gradient(hsl(var(--background)), hsl(var(--background)))
`,
},
ringColor: {
DEFAULT: 'hsl(var(--primary))', // e.g. Tailwind's blue-500
},