refactor: migrate remaining components to new design system

Migrates 38 files: tree-editor forms, session modals, step library,
common components, library views, tree preview, and misc UI to use
design tokens (bg-card, border-border, text-foreground, bg-accent,
bg-gradient-brand) replacing old monochrome patterns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-15 21:31:22 -05:00
parent 5e710fcffd
commit fe94f16b61
38 changed files with 384 additions and 384 deletions

View File

@@ -60,23 +60,23 @@ export function Modal({ isOpen, onClose, title, children, footer, size = 'md' }:
{/* Modal Content */}
<div
className={cn(
'relative flex w-full flex-col border border-white/[0.06] bg-[#0a0a0a] shadow-lg',
'relative flex w-full flex-col border border-border bg-card shadow-lg',
'max-h-[100vh] rounded-t-2xl sm:max-h-[85vh] sm:rounded-2xl',
'animate-scale-in',
sizeClasses[size]
)}
>
{/* Header - Fixed at top */}
<div className="flex flex-shrink-0 items-center justify-between border-b border-white/[0.06] px-4 py-3 sm:px-6 sm:py-4">
<h2 id="modal-title" className="text-lg font-semibold text-white">
<div className="flex flex-shrink-0 items-center justify-between border-b border-border px-4 py-3 sm:px-6 sm:py-4">
<h2 id="modal-title" className="text-lg font-semibold text-foreground">
{title}
</h2>
<button
onClick={onClose}
className={cn(
'rounded-md p-1.5 text-white/40 transition-colors sm:p-1',
'hover:bg-white/10 hover:text-white',
'focus:outline-none focus:ring-2 focus:ring-white/20'
'rounded-md p-1.5 text-muted-foreground transition-colors sm:p-1',
'hover:bg-accent hover:text-foreground',
'focus:outline-none focus:ring-2 focus:ring-primary/20'
)}
aria-label="Close modal"
>
@@ -91,7 +91,7 @@ export function Modal({ isOpen, onClose, title, children, footer, size = 'md' }:
{/* Footer - Fixed at bottom */}
{footer && (
<div className="flex-shrink-0 border-t border-white/[0.06] px-4 py-3 sm:px-6 sm:py-4">
<div className="flex-shrink-0 border-t border-border px-4 py-3 sm:px-6 sm:py-4">
{footer}
</div>
)}

View File

@@ -2,8 +2,8 @@ export function PageLoader() {
return (
<div className="flex h-screen items-center justify-center bg-black">
<div className="flex flex-col items-center gap-4">
<div className="h-12 w-12 animate-spin rounded-full border-4 border-white/20 border-t-white" />
<p className="text-sm text-white/40">Loading...</p>
<div className="h-12 w-12 animate-spin rounded-full border-4 border-border border-t-foreground" />
<p className="text-sm text-muted-foreground">Loading...</p>
</div>
</div>
)

View File

@@ -19,7 +19,7 @@ export function PasswordInput({ className, ...props }: PasswordInputProps) {
<button
type="button"
onClick={() => setVisible((v) => !v)}
className="absolute right-2 top-1/2 -translate-y-1/2 rounded p-1 text-white/40 hover:bg-white/10 hover:text-white"
className="absolute right-2 top-1/2 -translate-y-1/2 rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
tabIndex={-1}
title={visible ? 'Hide password' : 'Show password'}
>

View File

@@ -19,17 +19,17 @@ export function RouteError() {
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-black p-8">
<div className="max-w-md text-center">
<h1 className="mb-2 text-4xl font-bold text-white">Oops!</h1>
<h1 className="mb-2 text-4xl font-bold text-foreground">Oops!</h1>
<h2 className="mb-2 text-xl font-semibold text-red-400">{errorMessage}</h2>
{errorDetails && (
<p className="mb-4 text-white/70">{errorDetails}</p>
<p className="mb-4 text-muted-foreground">{errorDetails}</p>
)}
<div className="flex justify-center gap-4">
<button
onClick={() => navigate(-1)}
className={cn(
'rounded-xl border border-white/10 px-4 py-2 text-sm font-medium text-white/60',
'hover:bg-white/10 hover:text-white'
'rounded-xl border border-border px-4 py-2 text-sm font-medium text-muted-foreground',
'hover:bg-accent hover:text-foreground'
)}
>
Go Back
@@ -37,8 +37,8 @@ export function RouteError() {
<button
onClick={() => navigate('/trees')}
className={cn(
'rounded-xl bg-white px-4 py-2 text-sm font-medium text-black',
'hover:bg-white/90'
'rounded-xl bg-gradient-brand px-4 py-2 text-sm font-medium text-white shadow-lg shadow-primary/20',
'hover:opacity-90'
)}
>
Go Home

View File

@@ -48,14 +48,14 @@ export function StarRating({
sizeClasses[size],
star <= value
? 'fill-yellow-400 text-yellow-400'
: 'fill-none text-white/30',
: 'fill-none text-muted-foreground',
!readonly && 'hover:text-yellow-300'
)}
/>
</button>
))}
{showCount && (
<span className="ml-1 text-sm text-white/40">
<span className="ml-1 text-sm text-muted-foreground">
({value}/5)
</span>
)}

View File

@@ -37,8 +37,8 @@ export function TagBadges({
'rounded-full transition-colors',
size === 'sm' ? 'px-2 py-0.5 text-xs' : 'px-2.5 py-1 text-sm',
variant === 'default'
? 'bg-white/10 text-white/70 hover:bg-white/15'
: 'bg-white/5 text-white/40 hover:bg-white/10',
? 'bg-accent text-muted-foreground hover:bg-accent'
: 'bg-accent/50 text-muted-foreground hover:bg-accent',
!onTagClick && 'cursor-default'
)}
>
@@ -50,7 +50,7 @@ export function TagBadges({
className={cn(
'rounded-full',
size === 'sm' ? 'px-2 py-0.5 text-xs' : 'px-2.5 py-1 text-sm',
'bg-white/5 text-white/40'
'bg-accent/50 text-muted-foreground'
)}
title={tags.slice(maxVisible).join(', ')}
>

View File

@@ -123,10 +123,10 @@ export function TagInput({
<div
className={cn(
'flex flex-wrap gap-1.5 rounded-xl border px-2 py-1.5',
'bg-black/50 text-white',
'focus-within:border-white/30 focus-within:ring-1 focus-within:ring-white/20',
'bg-card text-foreground',
'focus-within:border-primary focus-within:ring-1 focus-within:ring-primary/20',
disabled ? 'cursor-not-allowed opacity-50' : '',
'border-white/10'
'border-border'
)}
onClick={() => inputRef.current?.focus()}
>
@@ -136,7 +136,7 @@ export function TagInput({
key={tag}
className={cn(
'inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs',
'bg-white/10 text-white/70'
'bg-accent text-muted-foreground'
)}
>
{tag}
@@ -147,7 +147,7 @@ export function TagInput({
e.stopPropagation()
removeTag(tag)
}}
className="rounded-full p-0.5 hover:bg-white/20"
className="rounded-full p-0.5 hover:bg-accent"
>
<X className="h-3 w-3" />
</button>
@@ -184,8 +184,8 @@ export function TagInput({
placeholder={tags.length === 0 ? placeholder : ''}
disabled={disabled}
className={cn(
'flex-1 min-w-[80px] border-0 bg-transparent px-1 py-0.5 text-sm text-white',
'placeholder:text-white/40',
'flex-1 min-w-[80px] border-0 bg-transparent px-1 py-0.5 text-sm text-foreground',
'placeholder:text-muted-foreground',
'focus:outline-none focus:ring-0'
)}
/>
@@ -196,8 +196,8 @@ export function TagInput({
{showSuggestions && suggestions.length > 0 && (
<div
className={cn(
'absolute z-10 mt-1 w-full rounded-xl border border-white/[0.06]',
'bg-[#0a0a0a] shadow-lg'
'absolute z-10 mt-1 w-full rounded-xl border border-border',
'bg-card shadow-lg'
)}
>
{suggestions.map((suggestion, index) => (
@@ -206,13 +206,13 @@ export function TagInput({
type="button"
onClick={() => addTag(suggestion.name)}
className={cn(
'flex w-full items-center justify-between px-3 py-2 text-sm text-white/70',
'hover:bg-white/10',
index === selectedIndex && 'bg-white/10'
'flex w-full items-center justify-between px-3 py-2 text-sm text-muted-foreground',
'hover:bg-accent',
index === selectedIndex && 'bg-accent'
)}
>
<span>{suggestion.name}</span>
<span className="text-xs text-white/40">
<span className="text-xs text-muted-foreground">
{suggestion.usage_count} trees
</span>
</button>
@@ -225,8 +225,8 @@ export function TagInput({
type="button"
onClick={() => addTag(inputValue)}
className={cn(
'flex w-full items-center gap-2 border-t border-white/[0.06] px-3 py-2 text-sm',
'hover:bg-white/10 text-white'
'flex w-full items-center gap-2 border-t border-border px-3 py-2 text-sm',
'hover:bg-accent text-foreground'
)}
>
<Plus className="h-4 w-4" />
@@ -237,7 +237,7 @@ export function TagInput({
)}
{/* Helper text */}
<p className="mt-1 text-xs text-white/40">
<p className="mt-1 text-xs text-muted-foreground">
{tags.length}/{maxTags} tags. Press Enter, Tab, comma, or semicolon to add.
</p>
</div>

View File

@@ -15,7 +15,7 @@ export function ProtectedRoute({ requiredRole, children }: ProtectedRouteProps)
if (isLoading) {
return (
<div className="flex h-screen items-center justify-center">
<div className="h-8 w-8 animate-spin rounded-full border-4 border-white/20 border-t-white" />
<div className="h-8 w-8 animate-spin rounded-full border-4 border-border border-t-foreground" />
</div>
)
}

View File

@@ -89,8 +89,8 @@ export function AddToFolderMenu({ treeId, onFolderCreated }: AddToFolderMenuProp
setIsOpen(!isOpen)
}}
className={cn(
'rounded-md border border-white/10 p-1.5 text-white/60',
'hover:bg-white/10 hover:text-white'
'rounded-md border border-border p-1.5 text-muted-foreground',
'hover:bg-accent hover:text-foreground'
)}
title="Add to folder"
aria-label="Add to folder"
@@ -101,14 +101,14 @@ export function AddToFolderMenu({ treeId, onFolderCreated }: AddToFolderMenuProp
{isOpen && (
<div
className={cn(
'absolute right-0 top-full z-20 mt-1 w-48 rounded-md border border-white/10',
'bg-black/90 backdrop-blur-sm py-1 shadow-lg'
'absolute right-0 top-full z-20 mt-1 w-48 rounded-md border border-border',
'bg-card backdrop-blur-sm py-1 shadow-lg'
)}
>
{isLoading ? (
<div className="px-3 py-2 text-sm text-white/40">Loading...</div>
<div className="px-3 py-2 text-sm text-muted-foreground">Loading...</div>
) : folders.length === 0 ? (
<div className="px-3 py-2 text-sm text-white/40">No folders yet</div>
<div className="px-3 py-2 text-sm text-muted-foreground">No folders yet</div>
) : (
folders.map((folder) => (
<button
@@ -117,7 +117,7 @@ export function AddToFolderMenu({ treeId, onFolderCreated }: AddToFolderMenuProp
e.stopPropagation()
toggleFolder(folder.id)
}}
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-white/70 hover:bg-white/[0.06] hover:text-white"
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
>
<div
className="h-3 w-3 rounded-sm"
@@ -125,13 +125,13 @@ export function AddToFolderMenu({ treeId, onFolderCreated }: AddToFolderMenuProp
/>
<span className="flex-1 truncate text-left">{folder.name}</span>
{treeFolderIds.has(folder.id) && (
<Check className="h-4 w-4 text-white" />
<Check className="h-4 w-4 text-foreground" />
)}
</button>
))
)}
<div className="border-t border-white/10 my-1" />
<div className="border-t border-border my-1" />
<button
onClick={(e) => {
@@ -139,7 +139,7 @@ export function AddToFolderMenu({ treeId, onFolderCreated }: AddToFolderMenuProp
setIsOpen(false)
onFolderCreated?.()
}}
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-white/70 hover:bg-white/[0.06] hover:text-white"
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
>
<Plus className="h-4 w-4" />
Create new folder

View File

@@ -113,8 +113,8 @@ function FolderItem({
onClick={() => onFolderSelect(folder.id)}
className={cn(
'flex w-full items-center gap-1 rounded-md py-1.5 text-sm',
'transition-colors hover:bg-white/[0.06]',
selectedFolderId === folder.id && 'bg-white/10 text-white font-medium'
'transition-colors hover:bg-accent',
selectedFolderId === folder.id && 'bg-accent text-foreground font-medium'
)}
style={{ paddingLeft: `${8 + depth * 16}px`, paddingRight: '8px' }}
>
@@ -125,7 +125,7 @@ function FolderItem({
e.stopPropagation()
onToggleExpand(folder.id)
}}
className="shrink-0 p-0.5 hover:bg-white/[0.06] rounded"
className="shrink-0 p-0.5 hover:bg-accent rounded"
>
{isExpanded ? (
<ChevronDown className="h-3 w-3" />
@@ -138,7 +138,7 @@ function FolderItem({
)}
<Folder className="h-4 w-4 shrink-0" style={{ color: folder.color }} />
<span className="flex-1 truncate text-left">{folder.name}</span>
<span className="text-xs text-white/40 group-hover:hidden">{folder.tree_count}</span>
<span className="text-xs text-muted-foreground group-hover:hidden">{folder.tree_count}</span>
</button>
{/* Folder menu button - replaces tree count on hover */}
@@ -150,7 +150,7 @@ function FolderItem({
className={cn(
'absolute right-1 top-1/2 -translate-y-1/2 rounded p-1',
'hidden group-hover:block',
'hover:bg-white/[0.06]'
'hover:bg-accent'
)}
>
<MoreVertical className="h-3 w-3" />
@@ -160,8 +160,8 @@ function FolderItem({
{menuOpenId === folder.id && (
<div
className={cn(
'absolute right-0 top-full z-10 mt-1 w-40 rounded-md border border-white/10',
'bg-black/90 backdrop-blur-sm py-1 shadow-lg'
'absolute right-0 top-full z-10 mt-1 w-40 rounded-md border border-border',
'bg-card backdrop-blur-sm py-1 shadow-lg'
)}
>
<button
@@ -170,7 +170,7 @@ function FolderItem({
onEditFolder(folder)
onMenuToggle(null)
}}
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-white/70 hover:bg-white/[0.06] hover:text-white"
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
>
<Pencil className="h-3 w-3" />
Edit
@@ -182,7 +182,7 @@ function FolderItem({
onAddSubfolder(folder.id)
onMenuToggle(null)
}}
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-white/70 hover:bg-white/[0.06] hover:text-white"
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
>
<FolderPlus className="h-3 w-3" />
Add Subfolder
@@ -362,7 +362,7 @@ export function FolderSidebar({
/>
)}
<div className={cn(
'w-56 shrink-0 border-r border-white/[0.06] bg-transparent',
'w-56 shrink-0 border-r border-border bg-transparent',
'hidden md:block',
mobileOpen && 'fixed inset-y-0 left-0 z-50 block animate-slide-in-left md:relative md:animate-none'
)}>
@@ -370,10 +370,10 @@ export function FolderSidebar({
{/* Mobile close button */}
{mobileOpen && (
<div className="mb-3 flex items-center justify-between md:hidden">
<span className="text-sm font-medium text-white">Folders</span>
<span className="text-sm font-medium text-foreground">Folders</span>
<button
onClick={onMobileClose}
className="rounded-md p-1.5 text-white/40 hover:bg-white/[0.06]"
className="rounded-md p-1.5 text-muted-foreground hover:bg-accent"
aria-label="Close folders"
>
<X className="h-4 w-4" />
@@ -382,7 +382,7 @@ export function FolderSidebar({
)}
<button
onClick={() => setIsExpanded(!isExpanded)}
className="flex w-full items-center gap-2 text-sm font-medium text-white"
className="flex w-full items-center gap-2 text-sm font-medium text-foreground"
>
{isExpanded ? (
<ChevronDown className="h-4 w-4" />
@@ -399,8 +399,8 @@ export function FolderSidebar({
onClick={() => onFolderSelect(null)}
className={cn(
'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm',
'transition-colors hover:bg-white/[0.06]',
selectedFolderId === null && 'bg-white/10 text-white font-medium'
'transition-colors hover:bg-accent',
selectedFolderId === null && 'bg-accent text-foreground font-medium'
)}
>
<Folder className="h-4 w-4" />
@@ -409,7 +409,7 @@ export function FolderSidebar({
{/* Loading state */}
{isLoading ? (
<div className="px-2 py-1.5 text-sm text-white/40">Loading...</div>
<div className="px-2 py-1.5 text-sm text-muted-foreground">Loading...</div>
) : (
<>
{/* User folders (hierarchical) */}
@@ -439,7 +439,7 @@ export function FolderSidebar({
onClick={() => onCreateFolder(null)}
className={cn(
'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm',
'text-white/50 transition-colors hover:bg-white/[0.06] hover:text-white'
'text-muted-foreground transition-colors hover:bg-accent hover:text-foreground'
)}
>
<Plus className="h-4 w-4" />
@@ -454,8 +454,8 @@ export function FolderSidebar({
{contextMenu && (
<div
className={cn(
'fixed z-50 w-44 rounded-md border border-white/10',
'bg-black/90 backdrop-blur-sm py-1 shadow-lg'
'fixed z-50 w-44 rounded-md border border-border',
'bg-card backdrop-blur-sm py-1 shadow-lg'
)}
style={{ left: contextMenu.x, top: contextMenu.y }}
onClick={(e) => e.stopPropagation()}
@@ -465,7 +465,7 @@ export function FolderSidebar({
onEditFolder(contextMenu.folder)
closeContextMenu()
}}
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-white/70 hover:bg-white/[0.06] hover:text-white"
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
>
<Pencil className="h-3 w-3" />
Edit
@@ -476,7 +476,7 @@ export function FolderSidebar({
handleAddSubfolder(contextMenu.folder.id)
closeContextMenu()
}}
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-white/70 hover:bg-white/[0.06] hover:text-white"
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
>
<FolderPlus className="h-3 w-3" />
Add Subfolder

View File

@@ -21,7 +21,7 @@ const sortOptions: { value: SortBy; label: string }[] = [
export function SortDropdown({ value, onChange, className }: SortDropdownProps) {
return (
<div className={cn('relative inline-flex items-center', className)}>
<span className="mr-2 flex items-center gap-1.5 text-sm text-white/40">
<span className="mr-2 flex items-center gap-1.5 text-sm text-muted-foreground">
<ArrowUpDown className="h-4 w-4" />
<span className="hidden sm:inline">Sort:</span>
</span>
@@ -29,8 +29,8 @@ export function SortDropdown({ value, onChange, className }: SortDropdownProps)
value={value}
onChange={(e) => onChange(e.target.value as SortBy)}
className={cn(
'rounded-md border border-white/10 bg-black/50 px-3 py-1.5 text-sm',
'text-white focus:border-white/30 focus:outline-none focus:ring-1 focus:ring-white/20'
'rounded-md border border-border bg-card px-3 py-1.5 text-sm',
'text-foreground focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/20'
)}
>
{sortOptions.map((option) => (

View File

@@ -70,12 +70,12 @@ export function TreeTableView({
}
return (
<div className="overflow-x-auto rounded-2xl border border-white/[0.06]">
<div className="overflow-x-auto rounded-2xl border border-border">
<table className="w-full">
<thead className="bg-white/[0.02] sticky top-0 z-10">
<tr className="border-b border-white/[0.06]">
<thead className="bg-accent/50 sticky top-0 z-10">
<tr className="border-b border-border">
<th
className="px-4 py-3 text-left text-sm font-medium text-white/50 cursor-pointer hover:text-white"
className="px-4 py-3 text-left text-sm font-medium text-muted-foreground cursor-pointer hover:text-foreground"
onClick={() => handleSort('name')}
>
<div className="flex items-center gap-1">
@@ -83,11 +83,11 @@ export function TreeTableView({
{getSortIcon('name')}
</div>
</th>
<th className="hidden md:table-cell px-4 py-3 text-left text-sm font-medium text-white/50">
<th className="hidden md:table-cell px-4 py-3 text-left text-sm font-medium text-muted-foreground">
Description
</th>
<th
className="hidden lg:table-cell px-4 py-3 text-left text-sm font-medium text-white/50 cursor-pointer hover:text-white"
className="hidden lg:table-cell px-4 py-3 text-left text-sm font-medium text-muted-foreground cursor-pointer hover:text-foreground"
onClick={() => handleSort('category')}
>
<div className="flex items-center gap-1">
@@ -95,11 +95,11 @@ export function TreeTableView({
{getSortIcon('category')}
</div>
</th>
<th className="hidden xl:table-cell px-4 py-3 text-left text-sm font-medium text-white/50">
<th className="hidden xl:table-cell px-4 py-3 text-left text-sm font-medium text-muted-foreground">
Tags
</th>
<th
className="hidden sm:table-cell px-4 py-3 text-center text-sm font-medium text-white/50 cursor-pointer hover:text-white"
className="hidden sm:table-cell px-4 py-3 text-center text-sm font-medium text-muted-foreground cursor-pointer hover:text-foreground"
onClick={() => handleSort('version')}
>
<div className="flex items-center justify-center gap-1">
@@ -108,7 +108,7 @@ export function TreeTableView({
</div>
</th>
<th
className="hidden sm:table-cell px-4 py-3 text-center text-sm font-medium text-white/50 cursor-pointer hover:text-white"
className="hidden sm:table-cell px-4 py-3 text-center text-sm font-medium text-muted-foreground cursor-pointer hover:text-foreground"
onClick={() => handleSort('usage')}
>
<div className="flex items-center justify-center gap-1">
@@ -117,7 +117,7 @@ export function TreeTableView({
</div>
</th>
<th
className="hidden md:table-cell px-4 py-3 text-left text-sm font-medium text-white/50 cursor-pointer hover:text-white"
className="hidden md:table-cell px-4 py-3 text-left text-sm font-medium text-muted-foreground cursor-pointer hover:text-foreground"
onClick={() => handleSort('updated')}
>
<div className="flex items-center gap-1">
@@ -125,17 +125,17 @@ export function TreeTableView({
{getSortIcon('updated')}
</div>
</th>
<th className="px-4 py-3 text-right text-sm font-medium text-white/50">
<th className="px-4 py-3 text-right text-sm font-medium text-muted-foreground">
Actions
</th>
</tr>
</thead>
<tbody className="bg-transparent">
{trees.map((tree) => (
<tr key={tree.id} className="border-b border-white/[0.06] last:border-0 hover:bg-white/[0.04]">
<tr key={tree.id} className="border-b border-border last:border-0 hover:bg-accent/50">
<td className="px-4 py-3">
<div className="flex items-center gap-2">
<span className="font-medium text-white truncate max-w-[200px]">
<span className="font-medium text-foreground truncate max-w-[200px]">
{tree.name}
</span>
{tree.status === 'draft' && (
@@ -146,23 +146,23 @@ export function TreeTableView({
)}
{tree.is_public ? (
<span title="Public tree">
<Globe className="h-3.5 w-3.5 text-white/40 flex-shrink-0" />
<Globe className="h-3.5 w-3.5 text-muted-foreground flex-shrink-0" />
</span>
) : (
<span title="Private tree">
<Lock className="h-3.5 w-3.5 text-white/40 flex-shrink-0" />
<Lock className="h-3.5 w-3.5 text-muted-foreground flex-shrink-0" />
</span>
)}
</div>
</td>
<td className="hidden md:table-cell px-4 py-3 text-sm text-white/70">
<td className="hidden md:table-cell px-4 py-3 text-sm text-muted-foreground">
<span className="truncate block max-w-[250px]">
{tree.description || 'No description'}
</span>
</td>
<td className="hidden lg:table-cell px-4 py-3">
{tree.category_info && (
<span className="inline-block rounded-full bg-white/10 px-2 py-0.5 text-xs text-white/70">
<span className="inline-block rounded-full bg-accent px-2 py-0.5 text-xs text-muted-foreground">
{tree.category_info.name}
</span>
)}
@@ -172,13 +172,13 @@ export function TreeTableView({
<TagBadges tags={tree.tags} maxVisible={2} onTagClick={onTagClick} />
)}
</td>
<td className="hidden sm:table-cell px-4 py-3 text-center text-sm text-white/70">
<td className="hidden sm:table-cell px-4 py-3 text-center text-sm text-muted-foreground">
v{tree.version}
</td>
<td className="hidden sm:table-cell px-4 py-3 text-center text-sm text-white/70">
<td className="hidden sm:table-cell px-4 py-3 text-center text-sm text-muted-foreground">
{tree.usage_count}
</td>
<td className="hidden md:table-cell px-4 py-3 text-sm text-white/70">
<td className="hidden md:table-cell px-4 py-3 text-sm text-muted-foreground">
{formatDate(tree.updated_at)}
</td>
<td className="px-4 py-3">
@@ -189,8 +189,8 @@ export function TreeTableView({
type="button"
onClick={() => onForkTree(tree.id)}
className={cn(
'rounded-md border border-white/10 p-1.5 text-white/60',
'hover:bg-white/10 hover:text-white'
'rounded-md border border-border p-1.5 text-muted-foreground',
'hover:bg-accent hover:text-foreground'
)}
title="Fork tree"
aria-label="Fork tree"
@@ -203,8 +203,8 @@ export function TreeTableView({
<Link
to={`/trees/${tree.id}/edit`}
className={cn(
'rounded-md border border-white/10 p-1.5 text-white/60',
'hover:bg-white/10 hover:text-white'
'rounded-md border border-border p-1.5 text-muted-foreground',
'hover:bg-accent hover:text-foreground'
)}
title="Edit tree"
aria-label="Edit tree"
@@ -215,7 +215,7 @@ export function TreeTableView({
type="button"
onClick={() => onDeleteTree(tree)}
className={cn(
'rounded-md border border-white/10 p-1.5 text-white/60',
'rounded-md border border-border p-1.5 text-muted-foreground',
'hover:bg-red-500/20 hover:text-red-400'
)}
title="Delete tree"
@@ -229,8 +229,8 @@ export function TreeTableView({
type="button"
onClick={() => onStartSession(tree.id, tree.tree_type)}
className={cn(
'rounded-md bg-white px-3 py-1.5 text-xs font-medium text-black',
'hover:bg-white/90 whitespace-nowrap'
'rounded-md bg-gradient-brand px-3 py-1.5 text-xs font-medium text-white shadow-lg shadow-primary/20',
'hover:opacity-90 whitespace-nowrap'
)}
>
Start

View File

@@ -11,15 +11,15 @@ interface ViewToggleProps {
export function ViewToggle({ view, onChange, className }: ViewToggleProps) {
return (
<div className={cn('flex items-center gap-1 rounded-md border border-white/10 p-1', className)}>
<div className={cn('flex items-center gap-1 rounded-md border border-border p-1', className)}>
<button
type="button"
onClick={() => onChange('grid')}
className={cn(
'rounded p-1.5 transition-colors',
view === 'grid'
? 'bg-white/10 text-white border-white/20'
: 'text-white/50 hover:bg-white/[0.06] hover:text-white'
? 'bg-accent text-foreground border-border'
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
)}
title="Grid view"
aria-label="Grid view"
@@ -32,8 +32,8 @@ export function ViewToggle({ view, onChange, className }: ViewToggleProps) {
className={cn(
'rounded p-1.5 transition-colors',
view === 'list'
? 'bg-white/10 text-white border-white/20'
: 'text-white/50 hover:bg-white/[0.06] hover:text-white'
? 'bg-accent text-foreground border-border'
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
)}
title="List view"
aria-label="List view"
@@ -46,8 +46,8 @@ export function ViewToggle({ view, onChange, className }: ViewToggleProps) {
className={cn(
'rounded p-1.5 transition-colors',
view === 'table'
? 'bg-white/10 text-white border-white/20'
: 'text-white/50 hover:bg-white/[0.06] hover:text-white'
? 'bg-accent text-foreground border-border'
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
)}
title="Table view"
aria-label="Table view"

View File

@@ -60,7 +60,7 @@ export function StepList() {
return (
<div
key={step.id}
className="flex items-center gap-2 rounded-lg border border-dashed border-border bg-white/[0.02] px-3 py-2"
className="flex items-center gap-2 rounded-lg border border-dashed border-border bg-accent/50 px-3 py-2"
>
<CheckCircle2 className="h-4 w-4 text-emerald-400/50" />
<input
@@ -142,7 +142,7 @@ export function StepList() {
<div
className={cn(
'group flex items-center gap-2 rounded-xl border border-border px-3 py-2.5 transition-colors',
'hover:border-primary/30 hover:bg-white/[0.03]'
'hover:border-primary/30 hover:bg-accent/50'
)}
>
<GripVertical className="h-4 w-4 shrink-0 cursor-grab text-muted-foreground group-hover:text-muted-foreground" />

View File

@@ -20,24 +20,24 @@ export function ProgressBar({ currentStep, totalSteps, elapsedMinutes, estimated
return (
<div className="space-y-1.5">
<div className="flex items-center justify-between text-xs">
<span className="text-white/60">
<span className="text-muted-foreground">
Step {currentStep} of {totalSteps}
</span>
<div className="flex items-center gap-3">
{elapsedMinutes !== undefined && (
<span className="text-white/50">
<span className="text-muted-foreground">
{formatTime(elapsed)}
{estimatedTotalMinutes ? (
<span className="text-white/25"> / est. {formatTime(estimatedTotalMinutes)}</span>
<span className="text-muted-foreground"> / est. {formatTime(estimatedTotalMinutes)}</span>
) : null}
</span>
)}
<span className="font-medium text-white/70">{percentage}%</span>
<span className="font-medium text-muted-foreground">{percentage}%</span>
</div>
</div>
<div className="h-1.5 overflow-hidden rounded-full bg-white/10">
<div className="h-1.5 overflow-hidden rounded-full bg-accent">
<div
className="h-full rounded-full bg-white transition-all duration-300"
className="h-full rounded-full bg-gradient-brand transition-all duration-300"
style={{ width: `${percentage}%` }}
/>
</div>

View File

@@ -45,7 +45,7 @@ export function ContinuationModal({
{/* Descendant Selection */}
{hasDescendants && (
<div>
<p className="mb-4 text-sm text-white/70">
<p className="mb-4 text-sm text-muted-foreground">
Select the next step in your troubleshooting path:
</p>
@@ -56,20 +56,20 @@ export function ContinuationModal({
onClick={() => onSelectNode(node.id)}
title={`From: ${node.parentOptionLabel}`}
className={cn(
'flex w-full items-center gap-3 rounded-lg border border-white/[0.06] p-3 text-left transition-colors',
'hover:border-white/20 hover:bg-white/10'
'flex w-full items-center gap-3 rounded-lg border border-border p-3 text-left transition-colors',
'hover:border-border hover:bg-accent'
)}
>
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-white/10">
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-accent">
{nodeTypeIcons[node.type]}
</div>
<div className="min-w-0 flex-1">
<p className="truncate font-medium text-white">{node.label}</p>
<p className="text-xs text-white/40">
<p className="truncate font-medium text-foreground">{node.label}</p>
<p className="text-xs text-muted-foreground">
{nodeTypeLabels[node.type]}
</p>
</div>
<ArrowRight className="h-4 w-4 flex-shrink-0 text-white/40" />
<ArrowRight className="h-4 w-4 flex-shrink-0 text-muted-foreground" />
</button>
))}
</div>
@@ -79,11 +79,11 @@ export function ContinuationModal({
{/* Divider */}
{hasDescendants && (
<div className="flex items-center gap-4">
<div className="h-px flex-1 bg-white/[0.06]" />
<span className="text-xs font-medium uppercase tracking-wide text-white/40">
<div className="h-px flex-1 bg-border" />
<span className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
Or
</span>
<div className="h-px flex-1 bg-white/[0.06]" />
<div className="h-px flex-1 bg-border" />
</div>
)}
@@ -100,8 +100,8 @@ export function ContinuationModal({
<GitBranch className="h-5 w-5 text-amber-500" />
</div>
<div className="flex-1">
<p className="font-medium text-white">Build Custom Branch</p>
<p className="text-sm text-white/70">
<p className="font-medium text-foreground">Build Custom Branch</p>
<p className="text-sm text-muted-foreground">
Create your own troubleshooting path with custom steps
</p>
</div>

View File

@@ -69,9 +69,9 @@ export function ExportPreviewModal({
<Modal isOpen={isOpen} onClose={handleClose} title="Export Preview" size="xl">
{/* Filename, format info, and controls */}
<div className="mb-3 flex flex-wrap items-center justify-between gap-2">
<p className="text-sm text-white/70">
Filename: <span className="font-mono text-white">{filename}</span>
<span className="ml-3 rounded bg-white/10 px-2 py-0.5 text-xs text-white/70">
<p className="text-sm text-muted-foreground">
Filename: <span className="font-mono text-foreground">{filename}</span>
<span className="ml-3 rounded bg-accent px-2 py-0.5 text-xs text-muted-foreground">
{format === 'markdown' ? 'Markdown' : format === 'html' ? 'HTML' : format === 'psa' ? 'PSA' : 'Plain Text'}
</span>
{isModified && (
@@ -81,23 +81,23 @@ export function ExportPreviewModal({
<div className="flex flex-col items-end gap-1">
<div className="flex items-center gap-3">
{onToggleSummary && (
<label className="flex items-center gap-2 text-sm text-white/60 cursor-pointer">
<label className="flex items-center gap-2 text-sm text-muted-foreground cursor-pointer">
<input
type="checkbox"
checked={includeSummary}
onChange={(e) => onToggleSummary(e.target.checked)}
className="h-4 w-4 rounded border-white/20 bg-black/50"
className="h-4 w-4 rounded border-border bg-card"
/>
Include Summary
</label>
)}
{onToggleRedaction && (
<label className="flex items-center gap-2 text-sm text-white/60 cursor-pointer">
<label className="flex items-center gap-2 text-sm text-muted-foreground cursor-pointer">
<input
type="checkbox"
checked={redactionEnabled}
onChange={(e) => onToggleRedaction(e.target.checked)}
className="h-4 w-4 rounded border-white/20 bg-black/50"
className="h-4 w-4 rounded border-border bg-card"
/>
Mask Sensitive Data
</label>
@@ -114,13 +114,13 @@ export function ExportPreviewModal({
</p>
)}
{redactionEnabled && redactionSummary && redactionSummary.total === 0 && (
<p className="text-xs text-white/40">No sensitive data detected</p>
<p className="text-xs text-muted-foreground">No sensitive data detected</p>
)}
{isModified && (
<button
type="button"
onClick={handleReset}
className="flex items-center gap-1 text-xs text-white/40 hover:text-white"
className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground"
title="Reset to original"
>
<RotateCcw className="h-3 w-3" />
@@ -139,9 +139,9 @@ export function ExportPreviewModal({
value={editedContent}
onChange={(e) => setEditedContent(e.target.value)}
className={cn(
'h-96 w-full resize-y rounded-md border border-white/10 bg-black/50 p-4',
'font-mono text-sm text-white',
'focus:border-white/30 focus:outline-none focus:ring-1 focus:ring-white/20'
'h-96 w-full resize-y rounded-md border border-border bg-card p-4',
'font-mono text-sm text-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/20'
)}
/>
@@ -151,9 +151,9 @@ export function ExportPreviewModal({
type="button"
onClick={handleCopy}
className={cn(
'flex items-center gap-2 rounded-md border border-white/10 px-3 py-2 text-sm font-medium',
'text-white/60 hover:bg-white/10 hover:text-white',
'focus:outline-none focus:ring-2 focus:ring-white/20'
'flex items-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium',
'text-muted-foreground hover:bg-accent hover:text-foreground',
'focus:outline-none focus:ring-2 focus:ring-primary/20'
)}
>
{copied ? (
@@ -172,8 +172,8 @@ export function ExportPreviewModal({
type="button"
onClick={handleDownload}
className={cn(
'flex items-center gap-2 rounded-md bg-white px-3 py-2 text-sm font-medium text-black',
'hover:bg-white/90 focus:outline-none focus:ring-2 focus:ring-white/20'
'flex items-center gap-2 rounded-md bg-gradient-brand text-white shadow-lg shadow-primary/20 px-3 py-2 text-sm font-medium',
'hover:opacity-90 focus:outline-none focus:ring-2 focus:ring-primary/20'
)}
>
<Download className="h-4 w-4" />

View File

@@ -49,7 +49,7 @@ export function ForkTreeModal({
disabled={isSaving}
className={cn(
'rounded-md px-4 py-2 text-sm font-medium transition-colors',
'text-white/60 hover:bg-white/10 hover:text-white',
'text-muted-foreground hover:bg-accent hover:text-foreground',
'disabled:cursor-not-allowed disabled:opacity-50'
)}
>
@@ -59,8 +59,8 @@ export function ForkTreeModal({
onClick={handleFork}
disabled={isSaving || !name.trim()}
className={cn(
'flex items-center gap-2 rounded-md bg-white px-4 py-2 text-sm font-medium text-black transition-colors',
'hover:bg-white/90',
'flex items-center gap-2 rounded-md bg-gradient-brand text-white shadow-lg shadow-primary/20 px-4 py-2 text-sm font-medium transition-colors',
'hover:opacity-90',
'disabled:cursor-not-allowed disabled:opacity-50'
)}
>
@@ -82,13 +82,13 @@ export function ForkTreeModal({
return (
<Modal isOpen={isOpen} onClose={onClose} title="Save Custom Tree?" footer={footer}>
<div className="space-y-4">
<div className="flex items-start gap-3 rounded-lg bg-white/5 p-4">
<div className="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full bg-white/10">
<GitFork className="h-5 w-5 text-white" />
<div className="flex items-start gap-3 rounded-lg bg-accent/50 p-4">
<div className="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full bg-accent">
<GitFork className="h-5 w-5 text-foreground" />
</div>
<div>
<p className="font-medium text-white">You've created a custom troubleshooting path!</p>
<p className="mt-1 text-sm text-white/70">
<p className="font-medium text-foreground">You've created a custom troubleshooting path!</p>
<p className="mt-1 text-sm text-muted-foreground">
Save it as your own personal tree to reuse this troubleshooting flow in the future.
</p>
</div>
@@ -96,7 +96,7 @@ export function ForkTreeModal({
<div className="space-y-4">
<div>
<label htmlFor="tree-name" className="mb-1.5 block text-sm font-medium text-white">
<label htmlFor="tree-name" className="mb-1.5 block text-sm font-medium text-foreground">
Tree Name <span className="text-red-400">*</span>
</label>
<input
@@ -106,15 +106,15 @@ export function ForkTreeModal({
onChange={(e) => setName(e.target.value)}
placeholder="My Custom Tree"
className={cn(
'w-full rounded-md border border-white/10 bg-black/50 px-3 py-2 text-sm text-white',
'focus:outline-none focus:border-white/30 focus:ring-1 focus:ring-white/20'
'w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground',
'focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/20'
)}
/>
</div>
<div>
<label htmlFor="tree-description" className="mb-1.5 block text-sm font-medium text-white">
Description <span className="text-white/40">(optional)</span>
<label htmlFor="tree-description" className="mb-1.5 block text-sm font-medium text-foreground">
Description <span className="text-muted-foreground">(optional)</span>
</label>
<textarea
id="tree-description"
@@ -123,8 +123,8 @@ export function ForkTreeModal({
placeholder="Describe what this tree helps troubleshoot..."
rows={3}
className={cn(
'w-full rounded-md border border-white/10 bg-black/50 px-3 py-2 text-sm text-white',
'focus:outline-none focus:border-white/30 focus:ring-1 focus:ring-white/20',
'w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground',
'focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/20',
'resize-none'
)}
/>
@@ -135,7 +135,7 @@ export function ForkTreeModal({
<p className="text-sm text-red-400">{error}</p>
)}
<p className="text-xs text-white/40">
<p className="text-xs text-muted-foreground">
The new tree will include your custom steps and will be saved to your personal tree library.
</p>
</div>

View File

@@ -28,8 +28,8 @@ export function PostStepActionModal({
return (
<Modal isOpen={isOpen} onClose={onClose} title="What would you like to do?">
<div className="space-y-3">
<p className="mb-4 text-sm text-white/70">
You've created: <strong className="text-white">{step.title}</strong>
<p className="mb-4 text-sm text-muted-foreground">
You've created: <strong className="text-foreground">{step.title}</strong>
</p>
{/* Save for Later - Only show if not already from library */}
@@ -48,8 +48,8 @@ export function PostStepActionModal({
<Bookmark className="h-5 w-5 text-blue-500" />
</div>
<div>
<p className="font-medium text-white">Save for Later</p>
<p className="text-sm text-white/70">
<p className="font-medium text-foreground">Save for Later</p>
<p className="text-sm text-muted-foreground">
Add to your step library for future use
</p>
</div>
@@ -62,8 +62,8 @@ export function PostStepActionModal({
onClick={onUseNow}
disabled={isSaving}
className={cn(
'w-full rounded-lg border border-white/[0.06] p-4 text-left transition-colors',
'hover:border-white/20 hover:bg-white/10',
'w-full rounded-lg border border-border p-4 text-left transition-colors',
'hover:border-border hover:bg-accent',
'disabled:cursor-not-allowed disabled:opacity-50'
)}
>
@@ -96,8 +96,8 @@ export function PostStepActionModal({
<BookmarkPlus className="h-5 w-5 text-purple-500" />
</div>
<div>
<p className="font-medium text-white">Do Both</p>
<p className="text-sm text-white/70">
<p className="font-medium text-foreground">Do Both</p>
<p className="text-sm text-muted-foreground">
Save to library AND use in this session
</p>
</div>
@@ -106,7 +106,7 @@ export function PostStepActionModal({
)}
{isSaving && (
<p className="text-center text-sm text-white/40">Saving...</p>
<p className="text-center text-sm text-muted-foreground">Saving...</p>
)}
</div>
</Modal>

View File

@@ -124,8 +124,8 @@ export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenCha
onClick={() => setIsCollapsed(false)}
className={cn(
'fixed right-2 top-1/2 z-40 -translate-y-1/2 rounded-md p-2.5',
'bg-[#0a0a0a] border border-white/[0.06] shadow-md',
'text-white/40 hover:bg-white/10 hover:text-white',
'bg-card border border-border shadow-md',
'text-muted-foreground hover:bg-accent hover:text-foreground',
'transition-opacity duration-200',
isCollapsed ? 'opacity-100' : 'pointer-events-none opacity-0'
)}
@@ -153,29 +153,29 @@ export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenCha
'fixed z-40',
'inset-0 sm:inset-auto sm:right-2 sm:top-1/2 sm:-translate-y-1/2',
'flex w-full flex-col sm:h-[55vh] sm:w-[420px]',
'border-white/[0.06] bg-[#0a0a0a]/95 backdrop-blur-md shadow-xl sm:rounded-lg sm:border',
'border-border bg-card/95 backdrop-blur-md shadow-xl sm:rounded-lg sm:border',
'transition-transform duration-200 ease-out',
isCollapsed ? 'translate-x-full' : 'translate-x-0'
)}
>
{/* Header */}
<div className="flex items-center justify-between border-b border-white/[0.06] px-3 py-2">
<div className="flex items-center justify-between border-b border-border px-3 py-2">
<div className="flex items-center gap-2">
<StickyNote className="h-4 w-4 text-white/40" />
<span className="text-sm font-medium text-white">Scratchpad</span>
<span className="text-xs text-white/30">Ctrl+/</span>
<StickyNote className="h-4 w-4 text-muted-foreground" />
<span className="text-sm font-medium text-foreground">Scratchpad</span>
<span className="text-xs text-muted-foreground">Ctrl+/</span>
</div>
<div className="flex items-center gap-1">
<button
onClick={() => setShowPreview(!showPreview)}
className="rounded p-1 text-white/40 hover:bg-white/10 hover:text-white"
className="rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
title={showPreview ? 'Edit' : 'Preview'}
>
{showPreview ? <Pencil className="h-3.5 w-3.5" /> : <Eye className="h-3.5 w-3.5" />}
</button>
<button
onClick={() => setIsCollapsed(true)}
className="rounded p-1 text-white/40 hover:bg-white/10 hover:text-white"
className="rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
title="Close scratchpad"
aria-label="Close scratchpad"
>
@@ -191,7 +191,7 @@ export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenCha
{content.trim() ? (
<MarkdownContent content={content} className="text-sm" />
) : (
<p className="text-sm italic text-white/40">Nothing to preview</p>
<p className="text-sm italic text-muted-foreground">Nothing to preview</p>
)}
</div>
) : (
@@ -202,7 +202,7 @@ export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenCha
placeholder={"Capture IPs, error codes, server names, user info...\n\nSupports markdown formatting."}
className={cn(
'h-full min-h-[200px] w-full resize-none rounded-md border-0 bg-transparent p-0 text-sm',
'text-white placeholder:text-white/40',
'text-foreground placeholder:text-muted-foreground',
'focus:outline-none focus:ring-0'
)}
/>
@@ -210,15 +210,15 @@ export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenCha
</div>
{/* Save Indicator */}
<div className="border-t border-white/[0.06] px-3 py-1.5">
<div className="border-t border-border px-3 py-1.5">
<div className="flex items-center gap-1.5 text-xs">
{saveStatus === 'unsaved' && (
<span className="text-white/40">Unsaved changes</span>
<span className="text-muted-foreground">Unsaved changes</span>
)}
{saveStatus === 'saving' && (
<>
<Loader2 className="h-3 w-3 animate-spin text-white/40" />
<span className="text-white/40">Saving...</span>
<Loader2 className="h-3 w-3 animate-spin text-muted-foreground" />
<span className="text-muted-foreground">Saving...</span>
</>
)}
{saveStatus === 'saved' && (
@@ -228,7 +228,7 @@ export function ScratchpadSidebar({ sessionId, initialContent, onSave, onOpenCha
<span className="text-red-400">Save failed</span>
)}
{saveStatus === 'idle' && (
<span className="text-white/30">Markdown supported</span>
<span className="text-muted-foreground">Markdown supported</span>
)}
</div>
</div>

View File

@@ -51,8 +51,8 @@ export function SessionOutcomeModal({
onClick={onClose}
disabled={isSubmitting}
className={cn(
'rounded-md border border-white/10 px-4 py-2 text-sm font-medium text-white/60',
'hover:bg-white/10 hover:text-white disabled:opacity-50'
'rounded-md border border-border px-4 py-2 text-sm font-medium text-muted-foreground',
'hover:bg-accent hover:text-foreground disabled:opacity-50'
)}
>
Cancel
@@ -62,8 +62,8 @@ export function SessionOutcomeModal({
onClick={handleSubmit}
disabled={isSubmitting}
className={cn(
'rounded-md bg-white px-4 py-2 text-sm font-medium text-black',
'hover:bg-white/90 disabled:opacity-50'
'rounded-md bg-gradient-brand text-white shadow-lg shadow-primary/20 px-4 py-2 text-sm font-medium',
'hover:opacity-90 disabled:opacity-50'
)}
>
{isSubmitting ? 'Completing...' : 'Complete Session'}
@@ -72,7 +72,7 @@ export function SessionOutcomeModal({
)}
>
<form key={String(isOpen)} ref={formRef} className="space-y-4">
<p className="text-sm text-white/70">
<p className="text-sm text-muted-foreground">
Select the session outcome before completion.
</p>
<div className="space-y-2">
@@ -80,8 +80,8 @@ export function SessionOutcomeModal({
<label
key={option.value}
className={cn(
'block cursor-pointer rounded-lg border border-white/10 p-3 transition-colors',
'hover:bg-white/[0.04]'
'block cursor-pointer rounded-lg border border-border p-3 transition-colors',
'hover:bg-accent/50'
)}
>
<div className="flex items-start gap-3">
@@ -93,8 +93,8 @@ export function SessionOutcomeModal({
className="mt-1 h-4 w-4"
/>
<div>
<p className="text-sm font-medium text-white">{option.label}</p>
<p className="text-xs text-white/50">{option.description}</p>
<p className="text-sm font-medium text-foreground">{option.label}</p>
<p className="text-xs text-muted-foreground">{option.description}</p>
</div>
</div>
</label>
@@ -102,31 +102,31 @@ export function SessionOutcomeModal({
</div>
<div>
<label className="block text-sm font-medium text-white">Outcome Notes (optional)</label>
<label className="block text-sm font-medium text-foreground">Outcome Notes (optional)</label>
<textarea
name="outcome-notes"
defaultValue=""
rows={3}
placeholder="Add context for this outcome..."
className={cn(
'mt-1 block w-full rounded-md border border-white/10 bg-black/50 px-3 py-2',
'text-sm text-white placeholder:text-white/40',
'focus:border-white/30 focus:outline-none focus:ring-1 focus:ring-white/20'
'mt-1 block w-full rounded-md border border-border bg-card px-3 py-2',
'text-sm text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/20'
)}
/>
</div>
<div>
<label className="block text-sm font-medium text-white">Next Steps / Follow-Up (optional)</label>
<label className="block text-sm font-medium text-foreground">Next Steps / Follow-Up (optional)</label>
<textarea
name="next-steps"
defaultValue=""
rows={3}
placeholder="Actions to take after this session..."
className={cn(
'mt-1 block w-full rounded-md border border-white/10 bg-black/50 px-3 py-2',
'text-sm text-white placeholder:text-white/40',
'focus:border-white/30 focus:outline-none focus:ring-1 focus:ring-white/20'
'mt-1 block w-full rounded-md border border-border bg-card px-3 py-2',
'text-sm text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/20'
)}
/>
</div>

View File

@@ -65,13 +65,13 @@ export function CustomStepModal({ isOpen, onClose, onInsertStep }: CustomStepMod
return (
<div className="fixed inset-0 z-50 flex items-end justify-center bg-black/80 backdrop-blur-sm sm:items-center sm:p-4">
<div className="relative flex h-[95vh] w-full max-w-full flex-col border border-white/[0.06] bg-[#0a0a0a] shadow-lg sm:h-[90vh] sm:max-w-4xl sm:rounded-2xl">
<div className="relative flex h-[95vh] w-full max-w-full flex-col border border-border bg-card shadow-lg sm:h-[90vh] sm:max-w-4xl sm:rounded-2xl">
{/* Header */}
<div className="flex items-center justify-between border-b border-white/[0.06] p-4">
<h2 className="text-lg font-semibold text-white">Add Custom Step</h2>
<div className="flex items-center justify-between border-b border-border p-4">
<h2 className="text-lg font-semibold text-foreground">Add Custom Step</h2>
<button
onClick={onClose}
className="rounded-md p-1.5 text-white/40 hover:bg-white/10 hover:text-white"
className="rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground"
aria-label="Close"
>
<X className="h-5 w-5" />
@@ -79,15 +79,15 @@ export function CustomStepModal({ isOpen, onClose, onInsertStep }: CustomStepMod
</div>
{/* Tabs */}
<div className="flex border-b border-white/[0.06]">
<div className="flex border-b border-border">
{canCreateSteps && (
<button
onClick={() => setActiveTab('create')}
className={cn(
'flex-1 px-4 py-3 text-sm font-medium transition-colors',
activeTab === 'create'
? 'border-b-2 border-white bg-white/5 text-white'
: 'text-white/40 hover:bg-white/10 hover:text-white'
? 'border-b-2 border-primary bg-primary/5 text-foreground'
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
)}
>
Type My Own
@@ -134,8 +134,8 @@ export function CustomStepModal({ isOpen, onClose, onInsertStep }: CustomStepMod
{isSubmitting && (
<div className="absolute inset-0 flex items-center justify-center bg-black/80 backdrop-blur-sm">
<div className="flex flex-col items-center gap-3">
<div className="h-8 w-8 animate-spin rounded-full border-4 border-white/20 border-t-white" />
<p className="text-sm text-white/40">Creating step...</p>
<div className="h-8 w-8 animate-spin rounded-full border-4 border-border border-t-foreground" />
<p className="text-sm text-muted-foreground">Creating step...</p>
</div>
</div>
)}

View File

@@ -27,7 +27,7 @@ export function StepCard({ step, onPreview, onInsert }: StepCardProps) {
const remainingTags = step.tags.length - 3
return (
<div className="group rounded-lg border border-white/[0.06] bg-[#0a0a0a] p-4 transition-shadow hover:shadow-md">
<div className="group rounded-lg border border-border bg-card p-4 transition-shadow hover:shadow-md">
{/* Header */}
<div className="mb-3 flex items-start justify-between gap-2">
<div className="flex-1">
@@ -52,12 +52,12 @@ export function StepCard({ step, onPreview, onInsert }: StepCardProps) {
</div>
{/* Title */}
<h3 className="font-semibold text-white line-clamp-2">{step.title}</h3>
<h3 className="font-semibold text-foreground line-clamp-2">{step.title}</h3>
</div>
</div>
{/* Metadata */}
<div className="mb-3 space-y-1.5 text-sm text-white/40">
<div className="mb-3 space-y-1.5 text-sm text-muted-foreground">
{/* Category */}
{step.category_name && (
<div className="flex items-center gap-1.5">
@@ -103,7 +103,7 @@ export function StepCard({ step, onPreview, onInsert }: StepCardProps) {
{visibleTags.map(tag => (
<span
key={tag}
className="rounded-full bg-white/10 px-2 py-0.5 text-xs text-white/70"
className="rounded-full bg-accent px-2 py-0.5 text-xs text-muted-foreground"
>
{tag}
</span>
@@ -121,8 +121,8 @@ export function StepCard({ step, onPreview, onInsert }: StepCardProps) {
<button
onClick={() => onPreview(step)}
className={cn(
'flex flex-1 items-center justify-center gap-2 rounded-md border border-white/10 px-3 py-2 text-sm font-medium text-white/60',
'hover:bg-white/10 hover:text-white transition-colors'
'flex flex-1 items-center justify-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-muted-foreground',
'hover:bg-accent hover:text-foreground transition-colors'
)}
>
<Eye className="h-4 w-4" />
@@ -131,8 +131,8 @@ export function StepCard({ step, onPreview, onInsert }: StepCardProps) {
<button
onClick={() => onInsert(step)}
className={cn(
'flex flex-1 items-center justify-center gap-2 rounded-md bg-white px-3 py-2 text-sm font-medium text-black',
'hover:bg-white/90 transition-colors'
'flex flex-1 items-center justify-center gap-2 rounded-md bg-gradient-brand text-white shadow-lg shadow-primary/20 px-3 py-2 text-sm font-medium',
'hover:opacity-90 transition-colors'
)}
>
<Plus className="h-4 w-4" />

View File

@@ -136,7 +136,7 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
<form onSubmit={handleSubmit} className="space-y-6">
{/* Step Type */}
<div>
<label className="mb-2 block text-sm font-medium text-white">
<label className="mb-2 block text-sm font-medium text-foreground">
Step Type <span className="text-red-400">*</span>
</label>
<div className="grid grid-cols-3 gap-2">
@@ -150,15 +150,15 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
className={cn(
'rounded-lg border p-3 text-left transition-colors',
stepType === option.value
? 'border-white/20 bg-white/10 ring-2 ring-white/20'
: 'border-white/[0.06] hover:border-white/20'
? 'border-border bg-accent ring-2 ring-primary/20'
: 'border-border hover:border-border'
)}
>
<div className="mb-1 flex items-center gap-2">
<Icon className="h-4 w-4" />
<span className="font-medium text-sm text-white">{option.label}</span>
<span className="font-medium text-sm text-foreground">{option.label}</span>
</div>
<p className="text-xs text-white/40">{option.description}</p>
<p className="text-xs text-muted-foreground">{option.description}</p>
</button>
)
})}
@@ -167,7 +167,7 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
{/* Title */}
<div>
<label htmlFor="title" className="mb-2 block text-sm font-medium text-white">
<label htmlFor="title" className="mb-2 block text-sm font-medium text-foreground">
Title <span className="text-red-400">*</span>
</label>
<input
@@ -177,8 +177,8 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
onChange={(e) => setTitle(e.target.value)}
placeholder="Enter step title"
className={cn(
'w-full rounded-md border bg-black/50 px-3 py-2 text-sm text-white focus:outline-none focus:border-white/30 focus:ring-1 focus:ring-white/20',
errors.title ? 'border-red-400/50' : 'border-white/10'
'w-full rounded-md border bg-card px-3 py-2 text-sm text-foreground focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/20',
errors.title ? 'border-red-400/50' : 'border-border'
)}
/>
{errors.title && (
@@ -188,9 +188,9 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
{/* Instructions */}
<div>
<label htmlFor="instructions" className="mb-2 block text-sm font-medium text-white">
<label htmlFor="instructions" className="mb-2 block text-sm font-medium text-foreground">
Instructions <span className="text-red-400">*</span>
<span className="ml-2 text-xs font-normal text-white/40">(Markdown supported)</span>
<span className="ml-2 text-xs font-normal text-muted-foreground">(Markdown supported)</span>
</label>
<textarea
id="instructions"
@@ -199,8 +199,8 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
placeholder="Describe what to do in this step..."
rows={6}
className={cn(
'w-full rounded-md border bg-black/50 px-3 py-2 text-sm text-white focus:outline-none focus:border-white/30 focus:ring-1 focus:ring-white/20',
errors.instructions ? 'border-red-400/50' : 'border-white/10'
'w-full rounded-md border bg-card px-3 py-2 text-sm text-foreground focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/20',
errors.instructions ? 'border-red-400/50' : 'border-border'
)}
/>
{errors.instructions && (
@@ -210,8 +210,8 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
{/* Help Text */}
<div>
<label htmlFor="helpText" className="mb-2 block text-sm font-medium text-white">
Help Text <span className="text-xs font-normal text-white/40">(Optional)</span>
<label htmlFor="helpText" className="mb-2 block text-sm font-medium text-foreground">
Help Text <span className="text-xs font-normal text-muted-foreground">(Optional)</span>
</label>
<textarea
id="helpText"
@@ -219,20 +219,20 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
onChange={(e) => setHelpText(e.target.value)}
placeholder="Additional context or tips..."
rows={3}
className="w-full rounded-md border border-white/10 bg-black/50 px-3 py-2 text-sm text-white focus:outline-none focus:border-white/30 focus:ring-1 focus:ring-white/20"
className="w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/20"
/>
</div>
{/* Commands */}
<div>
<div className="mb-2 flex items-center justify-between">
<label className="text-sm font-medium text-white">
Commands <span className="text-xs font-normal text-white/40">(Optional)</span>
<label className="text-sm font-medium text-foreground">
Commands <span className="text-xs font-normal text-muted-foreground">(Optional)</span>
</label>
<button
type="button"
onClick={addCommand}
className="flex items-center gap-1 rounded-md bg-white/10 px-2 py-1 text-xs font-medium text-white/70 hover:bg-white/20 hover:text-white"
className="flex items-center gap-1 rounded-md bg-accent px-2 py-1 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground"
>
<Plus className="h-3 w-3" />
Add Command
@@ -241,13 +241,13 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
{commands.length > 0 && (
<div className="space-y-3">
{commands.map((cmd, index) => (
<div key={index} className="rounded-lg border border-white/[0.06] bg-white/5 p-3">
<div key={index} className="rounded-lg border border-border bg-accent/50 p-3">
<div className="mb-2 flex items-center justify-between">
<span className="text-xs font-medium text-white/40">Command {index + 1}</span>
<span className="text-xs font-medium text-muted-foreground">Command {index + 1}</span>
<button
type="button"
onClick={() => removeCommand(index)}
className="rounded p-1 text-white/40 hover:bg-red-400/10 hover:text-red-400"
className="rounded p-1 text-muted-foreground hover:bg-red-400/10 hover:text-red-400"
>
<X className="h-3 w-3" />
</button>
@@ -259,8 +259,8 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
onChange={(e) => updateCommand(index, 'label', e.target.value)}
placeholder="Command label (e.g., 'Restart service')"
className={cn(
'w-full rounded-md border bg-black/50 px-3 py-1.5 text-sm text-white',
errors[`command_${index}_label`] ? 'border-red-400/50' : 'border-white/10'
'w-full rounded-md border bg-card px-3 py-1.5 text-sm text-foreground',
errors[`command_${index}_label`] ? 'border-red-400/50' : 'border-border'
)}
/>
<input
@@ -269,8 +269,8 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
onChange={(e) => updateCommand(index, 'command', e.target.value)}
placeholder="Command (e.g., 'systemctl restart nginx')"
className={cn(
'w-full rounded-md border bg-black/50 px-3 py-1.5 font-mono text-sm text-white',
errors[`command_${index}_command`] ? 'border-red-400/50' : 'border-white/10'
'w-full rounded-md border bg-card px-3 py-1.5 font-mono text-sm text-foreground',
errors[`command_${index}_command`] ? 'border-red-400/50' : 'border-border'
)}
/>
{(errors[`command_${index}_label`] || errors[`command_${index}_command`]) && (
@@ -287,14 +287,14 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
{/* Category */}
<div>
<label htmlFor="category" className="mb-2 block text-sm font-medium text-white">
Category <span className="text-xs font-normal text-white/40">(Optional)</span>
<label htmlFor="category" className="mb-2 block text-sm font-medium text-foreground">
Category <span className="text-xs font-normal text-muted-foreground">(Optional)</span>
</label>
<select
id="category"
value={categoryId}
onChange={(e) => setCategoryId(e.target.value)}
className="w-full rounded-md border border-white/10 bg-black/50 px-3 py-2 text-sm text-white focus:outline-none focus:border-white/30 focus:ring-1 focus:ring-white/20"
className="w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/20"
>
<option value="">None</option>
{categories.map(cat => (
@@ -305,8 +305,8 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
{/* Tags */}
<div>
<label htmlFor="tagInput" className="mb-2 block text-sm font-medium text-white">
Tags <span className="text-xs font-normal text-white/40">(Optional)</span>
<label htmlFor="tagInput" className="mb-2 block text-sm font-medium text-foreground">
Tags <span className="text-xs font-normal text-muted-foreground">(Optional)</span>
</label>
<div className="flex gap-2">
<input
@@ -316,12 +316,12 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
onChange={(e) => setTagInput(e.target.value)}
onKeyDown={handleTagInputKeyDown}
placeholder="Type tag and press Enter"
className="flex-1 rounded-md border border-white/10 bg-black/50 px-3 py-2 text-sm text-white focus:outline-none focus:border-white/30 focus:ring-1 focus:ring-white/20"
className="flex-1 rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/20"
/>
<button
type="button"
onClick={addTag}
className="rounded-md bg-white/10 px-4 py-2 text-sm font-medium text-white/70 hover:bg-white/20 hover:text-white"
className="rounded-md bg-accent px-4 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-foreground"
>
Add
</button>
@@ -331,13 +331,13 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
{tags.map(tag => (
<span
key={tag}
className="flex items-center gap-1 rounded-full bg-white/10 px-2.5 py-1 text-xs text-white/70"
className="flex items-center gap-1 rounded-full bg-accent px-2.5 py-1 text-xs text-muted-foreground"
>
{tag}
<button
type="button"
onClick={() => removeTag(tag)}
className="rounded-full hover:bg-white/20"
className="rounded-full hover:bg-accent"
aria-label={`Remove tag ${tag}`}
>
<X className="h-3 w-3" />
@@ -350,14 +350,14 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
{/* Visibility */}
<div>
<label htmlFor="visibility" className="mb-2 block text-sm font-medium text-white">
<label htmlFor="visibility" className="mb-2 block text-sm font-medium text-foreground">
Visibility
</label>
<select
id="visibility"
value={visibility}
onChange={(e) => setVisibility(e.target.value as 'private' | 'team' | 'public')}
className="w-full rounded-md border border-white/10 bg-black/50 px-3 py-2 text-sm text-white focus:outline-none focus:border-white/30 focus:ring-1 focus:ring-white/20"
className="w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/20"
>
<option value="private">Private (only me)</option>
<option value="team">Team (my team members)</option>
@@ -370,13 +370,13 @@ export function StepForm({ onSubmit, onCancel, initialData }: StepFormProps) {
<button
type="button"
onClick={onCancel}
className="flex-1 rounded-md border border-white/10 px-4 py-2 text-sm font-medium text-white/60 hover:bg-white/10 hover:text-white"
className="flex-1 rounded-md border border-border px-4 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-foreground"
>
Cancel
</button>
<button
type="submit"
className="flex-1 rounded-md bg-white px-4 py-2 text-sm font-medium text-black hover:bg-white/90"
className="flex-1 rounded-md bg-gradient-brand text-white shadow-lg shadow-primary/20 px-4 py-2 text-sm font-medium hover:opacity-90"
>
Insert Step
</button>

View File

@@ -51,7 +51,7 @@ export function DynamicArrayField<T>({
type="button"
onClick={() => handleMoveUp(index)}
disabled={index === 0}
className="rounded p-0.5 text-white/50 hover:bg-white/[0.06] hover:text-white disabled:opacity-30"
className="rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-30"
title="Move up"
aria-label="Move up"
>
@@ -61,7 +61,7 @@ export function DynamicArrayField<T>({
type="button"
onClick={() => handleMoveDown(index)}
disabled={index === items.length - 1}
className="rounded p-0.5 text-white/50 hover:bg-white/[0.06] hover:text-white disabled:opacity-30"
className="rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-30"
title="Move down"
aria-label="Move down"
>
@@ -78,7 +78,7 @@ export function DynamicArrayField<T>({
<button
type="button"
onClick={() => onRemove(index)}
className="mt-1 rounded p-1 text-white/50 hover:bg-red-400/20 hover:text-red-400"
className="mt-1 rounded p-1 text-muted-foreground hover:bg-red-400/20 hover:text-red-400"
title="Remove"
aria-label="Remove"
>
@@ -94,9 +94,9 @@ export function DynamicArrayField<T>({
type="button"
onClick={onAdd}
className={cn(
'flex w-full items-center justify-center gap-1 rounded-md border border-dashed border-white/10',
'px-3 py-2 text-sm text-white/50',
'hover:border-white/30 hover:text-white'
'flex w-full items-center justify-center gap-1 rounded-md border border-dashed border-border',
'px-3 py-2 text-sm text-muted-foreground',
'hover:border-border hover:text-foreground'
)}
>
<Plus className="h-4 w-4" />
@@ -106,7 +106,7 @@ export function DynamicArrayField<T>({
{/* Empty state */}
{items.length === 0 && !canAdd && (
<p className="text-center text-sm text-white/40">No items</p>
<p className="text-center text-sm text-muted-foreground">No items</p>
)}
</div>
)

View File

@@ -68,14 +68,14 @@ export function NodeEditorModal({ node, onClose, isNewNode = false }: NodeEditor
<button
type="button"
onClick={handleCancel}
className="rounded-md border border-white/10 px-4 py-2 text-sm font-medium text-white/60 hover:bg-white/10 hover:text-white"
className="rounded-md border border-border px-4 py-2 text-sm font-medium text-muted-foreground hover:bg-accent hover:text-foreground"
>
Cancel
</button>
<button
type="button"
onClick={handleSave}
className="rounded-md bg-white px-4 py-2 text-sm font-medium text-black hover:bg-white/90"
className="rounded-md bg-gradient-brand text-white shadow-lg shadow-primary/20 px-4 py-2 text-sm font-medium hover:opacity-90"
>
Done
</button>
@@ -85,8 +85,8 @@ export function NodeEditorModal({ node, onClose, isNewNode = false }: NodeEditor
return (
<Modal isOpen={true} onClose={onClose} title={getTitle()} size="lg" footer={footerContent}>
{/* Node ID display */}
<div className="mb-4 text-xs text-white/40">
Node ID: <code className="rounded bg-white/10 px-1 py-0.5">{node.id}</code>
<div className="mb-4 text-xs text-muted-foreground">
Node ID: <code className="rounded bg-accent px-1 py-0.5">{node.id}</code>
</div>
{/* Validation errors */}

View File

@@ -52,7 +52,7 @@ export function NodeFormAction({ node, onUpdate }: NodeFormActionProps) {
<div className="space-y-4">
{/* Title */}
<div>
<label className="block text-sm font-medium text-white">
<label className="block text-sm font-medium text-foreground">
Title <span className="text-red-400">*</span>
</label>
<input
@@ -62,9 +62,9 @@ export function NodeFormAction({ node, onUpdate }: NodeFormActionProps) {
placeholder="e.g., Restart the Service"
className={cn(
'mt-1 block w-full rounded-md border px-3 py-2 text-sm',
'bg-black/50 text-white placeholder:text-white/40',
'focus:border-white/30 focus:outline-none focus:ring-1 focus:ring-white/20',
titleError ? 'border-red-400' : 'border-white/10'
'bg-card text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/20',
titleError ? 'border-red-400' : 'border-border'
)}
/>
{titleError && (
@@ -75,24 +75,24 @@ export function NodeFormAction({ node, onUpdate }: NodeFormActionProps) {
{/* Description */}
<div>
<div className="flex items-center justify-between">
<label className="block text-sm font-medium text-white">
<label className="block text-sm font-medium text-foreground">
Description
</label>
{node.description && (
<button
type="button"
onClick={() => setShowPreview(!showPreview)}
className="text-xs text-white/50 hover:text-white hover:underline"
className="text-xs text-muted-foreground hover:text-foreground hover:underline"
>
{showPreview ? 'Edit' : 'Preview'}
</button>
)}
</div>
<p className="mb-1 text-xs text-white/40">
<p className="mb-1 text-xs text-muted-foreground">
Supports markdown: **bold**, *italic*, - lists, 1. numbered lists, `code`
</p>
{showPreview && node.description ? (
<div className="mt-1 rounded-md border border-white/10 bg-white/[0.04] p-3 text-sm">
<div className="mt-1 rounded-md border border-border bg-accent/50 p-3 text-sm">
<MarkdownContent content={node.description} />
</div>
) : (
@@ -108,7 +108,7 @@ export function NodeFormAction({ node, onUpdate }: NodeFormActionProps) {
**Note:** Important information here"
rows={5}
className={cn(
'mt-1 block w-full rounded-md border border-white/10 px-3 py-2 text-sm',
'mt-1 block w-full rounded-md border border-border px-3 py-2 text-sm',
'bg-background text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary'
)}
@@ -118,10 +118,10 @@ export function NodeFormAction({ node, onUpdate }: NodeFormActionProps) {
{/* Commands */}
<div>
<label className="block text-sm font-medium text-white">
<label className="block text-sm font-medium text-foreground">
Commands
</label>
<p className="mb-2 text-xs text-white/40">
<p className="mb-2 text-xs text-muted-foreground">
PowerShell or CLI commands to execute
</p>
<DynamicArrayField
@@ -137,7 +137,7 @@ export function NodeFormAction({ node, onUpdate }: NodeFormActionProps) {
onChange={(e) => handleUpdateCommand(index, e.target.value)}
placeholder="e.g., Get-Service BrokerAgent"
className={cn(
'block w-full rounded-md border border-white/10 px-3 py-2 font-mono text-sm',
'block w-full rounded-md border border-border px-3 py-2 font-mono text-sm',
'bg-background text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary'
)}
@@ -148,7 +148,7 @@ export function NodeFormAction({ node, onUpdate }: NodeFormActionProps) {
{/* Expected Outcome */}
<div>
<label className="block text-sm font-medium text-white">
<label className="block text-sm font-medium text-foreground">
Expected Outcome
</label>
<input
@@ -157,7 +157,7 @@ export function NodeFormAction({ node, onUpdate }: NodeFormActionProps) {
onChange={(e) => onUpdate({ expected_outcome: e.target.value })}
placeholder="e.g., Service should show as Running"
className={cn(
'mt-1 block w-full rounded-md border border-white/10 px-3 py-2 text-sm',
'mt-1 block w-full rounded-md border border-border px-3 py-2 text-sm',
'bg-background text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary'
)}

View File

@@ -67,7 +67,7 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
<h3 className="font-semibold text-blue-400">
Starting Question
</h3>
<p className="mt-1 text-sm text-white/40">
<p className="mt-1 text-sm text-muted-foreground">
This is the first question users will see when they start this troubleshooting tree.
Each option below creates a different troubleshooting path.
</p>
@@ -78,11 +78,11 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
{/* Question */}
<div>
<label className="block text-sm font-medium text-white">
<label className="block text-sm font-medium text-foreground">
{isRootNode ? 'Starting Question' : 'Question'} <span className="text-red-400">*</span>
</label>
{isRootNode && (
<p className="mt-0.5 text-xs text-white/40">
<p className="mt-0.5 text-xs text-muted-foreground">
What's the main question to diagnose the issue?
</p>
)}
@@ -95,9 +95,9 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
: "e.g., Can you ping the server?"}
className={cn(
'mt-1 block w-full rounded-md border px-3 py-2 text-sm',
'bg-black/50 text-white placeholder:text-white/40',
'focus:border-white/30 focus:outline-none focus:ring-1 focus:ring-white/20',
questionError ? 'border-red-400' : 'border-white/10'
'bg-card text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/20',
questionError ? 'border-red-400' : 'border-border'
)}
/>
{questionError && (
@@ -107,7 +107,7 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
{/* Help Text */}
<div>
<label className="block text-sm font-medium text-white">
<label className="block text-sm font-medium text-foreground">
Help Text
</label>
<textarea
@@ -116,7 +116,7 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
placeholder="Additional context or instructions for this decision..."
rows={2}
className={cn(
'mt-1 block w-full rounded-md border border-white/10 px-3 py-2 text-sm',
'mt-1 block w-full rounded-md border border-border px-3 py-2 text-sm',
'bg-background text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary'
)}
@@ -125,15 +125,15 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
{/* Options */}
<div>
<label className="block text-sm font-medium text-white">
<label className="block text-sm font-medium text-foreground">
{isRootNode ? 'Answer Options (Branches)' : 'Options'} <span className="text-red-400">*</span>
</label>
{isRootNode ? (
<p className="mt-0.5 text-xs text-white/40">
<p className="mt-0.5 text-xs text-muted-foreground">
Add as many options as needed (A, B, C, D...). Each option leads to a completely different troubleshooting path.
</p>
) : (
<p className="mt-0.5 text-xs text-white/40">
<p className="mt-0.5 text-xs text-muted-foreground">
Each option can branch to a different next step.
</p>
)}
@@ -158,14 +158,14 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
const letter = indexToLetter(index)
return (
<div className="rounded-md border border-white/10 bg-white/[0.04] p-3">
<div className="rounded-md border border-border bg-accent/50 p-3">
<div className="mb-2 flex items-center gap-2">
{/* Letter badge */}
<span className={cn(
'flex h-6 w-6 items-center justify-center rounded-full text-xs font-bold',
isRootNode
? 'bg-blue-500/20 text-blue-400'
: 'bg-white/10 text-white/50'
: 'bg-accent text-muted-foreground'
)}>
{letter}
</span>
@@ -180,7 +180,7 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
'block flex-1 rounded-md border px-3 py-2 text-sm',
'bg-background text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary',
optionLabelError ? 'border-red-400' : 'border-white/10'
optionLabelError ? 'border-red-400' : 'border-border'
)}
/>
</div>
@@ -207,7 +207,7 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
{/* Example hint for root node */}
{isRootNode && (node.options?.length || 0) < 2 && (
<div className="mt-3 rounded-md border border-dashed border-white/10 bg-white/[0.02] p-3 text-xs text-white/40">
<div className="mt-3 rounded-md border border-dashed border-border bg-accent/50 p-3 text-xs text-muted-foreground">
<strong>Tip:</strong> Most troubleshooting trees start with 2-5 main branches.
For example: "Connection Issues", "Performance Problems", "Error Messages", "Other".
</div>

View File

@@ -47,7 +47,7 @@ export function NodeFormResolution({ node, onUpdate }: NodeFormResolutionProps)
<div className="space-y-4">
{/* Title */}
<div>
<label className="block text-sm font-medium text-white">
<label className="block text-sm font-medium text-foreground">
Title <span className="text-red-400">*</span>
</label>
<input
@@ -57,9 +57,9 @@ export function NodeFormResolution({ node, onUpdate }: NodeFormResolutionProps)
placeholder="e.g., VDA Successfully Registered"
className={cn(
'mt-1 block w-full rounded-md border px-3 py-2 text-sm',
'bg-black/50 text-white placeholder:text-white/40',
'focus:border-white/30 focus:outline-none focus:ring-1 focus:ring-white/20',
titleError ? 'border-red-400' : 'border-white/10'
'bg-card text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/20',
titleError ? 'border-red-400' : 'border-border'
)}
/>
{titleError && (
@@ -70,24 +70,24 @@ export function NodeFormResolution({ node, onUpdate }: NodeFormResolutionProps)
{/* Description */}
<div>
<div className="flex items-center justify-between">
<label className="block text-sm font-medium text-white">
<label className="block text-sm font-medium text-foreground">
Description
</label>
{node.description && (
<button
type="button"
onClick={() => setShowPreview(!showPreview)}
className="text-xs text-white/50 hover:text-white hover:underline"
className="text-xs text-muted-foreground hover:text-foreground hover:underline"
>
{showPreview ? 'Edit' : 'Preview'}
</button>
)}
</div>
<p className="mb-1 text-xs text-white/40">
<p className="mb-1 text-xs text-muted-foreground">
Supports markdown: **bold**, *italic*, - lists, 1. numbered lists, `code`
</p>
{showPreview && node.description ? (
<div className="mt-1 rounded-md border border-white/10 bg-white/[0.04] p-3 text-sm">
<div className="mt-1 rounded-md border border-border bg-accent/50 p-3 text-sm">
<MarkdownContent content={node.description} />
</div>
) : (
@@ -102,7 +102,7 @@ Document what was done and the outcome.
**Close ticket as:** Resolved"
rows={5}
className={cn(
'mt-1 block w-full rounded-md border border-white/10 px-3 py-2 text-sm',
'mt-1 block w-full rounded-md border border-border px-3 py-2 text-sm',
'bg-background text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary'
)}
@@ -112,10 +112,10 @@ Document what was done and the outcome.
{/* Resolution Steps */}
<div>
<label className="block text-sm font-medium text-white">
<label className="block text-sm font-medium text-foreground">
Resolution Steps
</label>
<p className="mb-2 text-xs text-white/40">
<p className="mb-2 text-xs text-muted-foreground">
Step-by-step instructions for resolving the issue
</p>
<DynamicArrayField
@@ -135,7 +135,7 @@ Document what was done and the outcome.
onChange={(e) => handleUpdateStep(index, e.target.value)}
placeholder={`Step ${index + 1}`}
className={cn(
'block w-full rounded-md border border-white/10 px-3 py-2 text-sm',
'block w-full rounded-md border border-border px-3 py-2 text-sm',
'bg-background text-foreground placeholder:text-muted-foreground',
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary'
)}

View File

@@ -95,9 +95,9 @@ function NodeListItem({
}
const nodeTypeColors: Record<NodeType, string> = {
decision: 'bg-blue-500/20 text-blue-600 dark:text-blue-400',
action: 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-400',
solution: 'bg-green-500/20 text-green-600 dark:text-green-400'
decision: 'bg-blue-500/20 text-blue-400',
action: 'bg-yellow-500/20 text-yellow-400',
solution: 'bg-green-500/20 text-green-400'
}
const getNodeLabel = () => {
@@ -223,7 +223,7 @@ function NodeListItem({
{/* Node type icon - special treatment for root */}
{isRootNode ? (
<span className="flex items-center gap-1 rounded px-1.5 py-0.5 text-xs bg-blue-500/30 text-blue-600 dark:text-blue-400 font-semibold">
<span className="flex items-center gap-1 rounded px-1.5 py-0.5 text-xs bg-blue-500/30 text-blue-400 font-semibold">
<Play className="h-4 w-4" />
<span className="hidden sm:inline">START</span>
</span>
@@ -254,7 +254,7 @@ function NodeListItem({
'flex items-center gap-1 rounded px-1.5 py-0.5 text-xs',
hasError
? 'bg-destructive/20 text-destructive'
: 'bg-yellow-500/20 text-yellow-600 dark:text-yellow-500'
: 'bg-yellow-500/20 text-yellow-500'
)}
>
{hasError ? (

View File

@@ -28,12 +28,12 @@ export function TreeEditorLayout({ isMobile = false }: TreeEditorLayoutProps) {
<>
{/* Code Mode: Monaco editor (60%) + Preview (40%) */}
<div className={cn(
'flex flex-col overflow-hidden border-white/[0.06]',
'flex flex-col overflow-hidden border-border',
isMobile ? 'h-full w-full border-b' : 'w-3/5 border-r'
)}>
<Suspense fallback={
<div className="flex h-full items-center justify-center bg-[#0a0a0a]">
<div className="h-6 w-6 animate-spin rounded-full border-2 border-white/20 border-t-white" />
<div className="flex h-full items-center justify-center bg-card">
<div className="h-6 w-6 animate-spin rounded-full border-2 border-border border-t-foreground" />
</div>
}>
<CodeModeEditor />
@@ -42,7 +42,7 @@ export function TreeEditorLayout({ isMobile = false }: TreeEditorLayoutProps) {
{/* Right Panel - Preview */}
<div className={cn(
'flex-1 overflow-hidden bg-white/[0.02]',
'flex-1 overflow-hidden bg-accent/50',
isMobile ? 'hidden' : 'block'
)}>
<TreePreviewPanel />
@@ -52,7 +52,7 @@ export function TreeEditorLayout({ isMobile = false }: TreeEditorLayoutProps) {
<>
{/* Flow Mode: Form editor (60%) + Preview (40%) */}
<div className={cn(
'flex flex-col overflow-y-auto border-white/[0.06]',
'flex flex-col overflow-y-auto border-border',
isMobile ? 'h-full w-full border-b' : 'w-3/5 border-r'
)}>
<div className="space-y-4 p-4">
@@ -63,7 +63,7 @@ export function TreeEditorLayout({ isMobile = false }: TreeEditorLayoutProps) {
{/* Right Panel - Preview */}
<div className={cn(
'flex-1 overflow-hidden bg-white/[0.02]',
'flex-1 overflow-hidden bg-accent/50',
isMobile ? 'hidden' : 'block'
)}>
<TreePreviewPanel />

View File

@@ -35,7 +35,7 @@ export function ValidationSummary({ errors, onSelectNode }: ValidationSummaryPro
<button
onClick={() => setIsExpanded(!isExpanded)}
className={cn(
'flex w-full items-center justify-between p-3 text-left transition-colors hover:bg-white/5',
'flex w-full items-center justify-between p-3 text-left transition-colors hover:bg-accent',
errorItems.length > 0 ? 'text-red-400' : 'text-yellow-400'
)}
>
@@ -81,7 +81,7 @@ export function ValidationSummary({ errors, onSelectNode }: ValidationSummaryPro
<div className="flex-1">
<p className="text-red-400">{error.message}</p>
{error.nodeId && (
<p className="mt-0.5 text-xs text-white/40">
<p className="mt-0.5 text-xs text-muted-foreground">
Click to select node: {error.nodeId}
</p>
)}
@@ -105,7 +105,7 @@ export function ValidationSummary({ errors, onSelectNode }: ValidationSummaryPro
<div className="flex-1">
<p className="text-yellow-400">{warning.message}</p>
{warning.nodeId && (
<p className="mt-0.5 text-xs text-white/40">
<p className="mt-0.5 text-xs text-muted-foreground">
Click to select node: {warning.nodeId}
</p>
)}

View File

@@ -166,8 +166,8 @@ export function CodeModeEditor() {
beforeMount={handleEditorWillMount}
onMount={handleEditorDidMount}
loading={
<div className="flex h-full items-center justify-center bg-[#0a0a0a]">
<div className="h-6 w-6 animate-spin rounded-full border-2 border-white/20 border-t-white" />
<div className="flex h-full items-center justify-center bg-card">
<div className="h-6 w-6 animate-spin rounded-full border-2 border-border border-t-foreground" />
</div>
}
options={{

View File

@@ -91,15 +91,15 @@ export function CodeModeToolbar({
}, [])
return (
<div className="flex items-center justify-between border-b border-white/[0.06] bg-black/50 px-3 py-1.5">
<div className="flex items-center justify-between border-b border-border bg-card px-3 py-1.5">
<div className="flex items-center gap-2">
{/* Insert Node dropdown */}
<div className="relative" ref={dropdownRef}>
<button
onClick={() => setInsertOpen(!insertOpen)}
className={cn(
'flex items-center gap-1 rounded-md border border-white/10 px-2.5 py-1 text-xs font-medium text-white/60',
'hover:bg-white/10 hover:text-white'
'flex items-center gap-1 rounded-md border border-border px-2.5 py-1 text-xs font-medium text-muted-foreground',
'hover:bg-accent hover:text-foreground'
)}
>
<Plus className="h-3 w-3" />
@@ -107,24 +107,24 @@ export function CodeModeToolbar({
<ChevronDown className="h-3 w-3" />
</button>
{insertOpen && (
<div className="absolute left-0 top-full z-50 mt-1 w-44 rounded-lg border border-white/10 bg-[#111] py-1 shadow-xl">
<div className="absolute left-0 top-full z-50 mt-1 w-44 rounded-lg border border-border bg-card py-1 shadow-xl">
<button
onClick={() => { onInsertTemplate(NODE_TEMPLATES.decision); setInsertOpen(false) }}
className="flex w-full items-center gap-2 px-3 py-1.5 text-xs text-white/70 hover:bg-white/10"
className="flex w-full items-center gap-2 px-3 py-1.5 text-xs text-muted-foreground hover:bg-accent"
>
<span className="h-2 w-2 rounded-full bg-blue-400" />
Decision
</button>
<button
onClick={() => { onInsertTemplate(NODE_TEMPLATES.action); setInsertOpen(false) }}
className="flex w-full items-center gap-2 px-3 py-1.5 text-xs text-white/70 hover:bg-white/10"
className="flex w-full items-center gap-2 px-3 py-1.5 text-xs text-muted-foreground hover:bg-accent"
>
<span className="h-2 w-2 rounded-full bg-amber-400" />
Action
</button>
<button
onClick={() => { onInsertTemplate(NODE_TEMPLATES.solution); setInsertOpen(false) }}
className="flex w-full items-center gap-2 px-3 py-1.5 text-xs text-white/70 hover:bg-white/10"
className="flex w-full items-center gap-2 px-3 py-1.5 text-xs text-muted-foreground hover:bg-accent"
>
<span className="h-2 w-2 rounded-full bg-emerald-400" />
Solution
@@ -139,8 +139,8 @@ export function CodeModeToolbar({
<div className="flex items-center gap-1.5 text-xs">
{isValidating ? (
<>
<Loader2 className="h-3 w-3 animate-spin text-white/40" />
<span className="text-white/40">Validating...</span>
<Loader2 className="h-3 w-3 animate-spin text-muted-foreground" />
<span className="text-muted-foreground">Validating...</span>
</>
) : isValid ? (
<>
@@ -173,8 +173,8 @@ export function CodeModeToolbar({
className={cn(
'flex items-center gap-1 rounded-md px-2 py-1 text-xs',
syntaxHelpOpen
? 'bg-white/10 text-white'
: 'text-white/40 hover:bg-white/[0.06] hover:text-white/60'
? 'bg-accent text-foreground'
: 'text-muted-foreground hover:bg-accent hover:text-muted-foreground'
)}
>
<HelpCircle className="h-3 w-3" />

View File

@@ -10,17 +10,17 @@ export function SyntaxHelpPanel({ open, onClose }: SyntaxHelpPanelProps) {
if (!open) return null
return (
<div className="flex h-full flex-col border-l border-white/[0.06] bg-[#0a0a0a]">
<div className="flex items-center justify-between border-b border-white/[0.06] px-3 py-2">
<span className="text-xs font-medium text-white/60">Syntax Reference</span>
<div className="flex h-full flex-col border-l border-border bg-card">
<div className="flex items-center justify-between border-b border-border px-3 py-2">
<span className="text-xs font-medium text-muted-foreground">Syntax Reference</span>
<button
onClick={onClose}
className="rounded p-0.5 text-white/30 hover:bg-white/10 hover:text-white/60"
className="rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-muted-foreground"
>
<X className="h-3.5 w-3.5" />
</button>
</div>
<div className="flex-1 overflow-y-auto px-3 py-3 text-[11px] leading-relaxed text-white/50">
<div className="flex-1 overflow-y-auto px-3 py-3 text-[11px] leading-relaxed text-muted-foreground">
<Section title="Node Structure">
<Code>{`---
id: node_id
@@ -82,7 +82,7 @@ Description paragraph.
function Section({ title, children }: { title: string; children: React.ReactNode }) {
return (
<div className="mb-4">
<h4 className="mb-1.5 text-[11px] font-semibold uppercase tracking-wider text-white/30">{title}</h4>
<h4 className="mb-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground">{title}</h4>
{children}
</div>
)
@@ -91,8 +91,8 @@ function Section({ title, children }: { title: string; children: React.ReactNode
function Code({ children }: { children: string }) {
return (
<pre className={cn(
'mb-2 overflow-x-auto rounded-md border border-white/[0.06] bg-black/50 px-2 py-1.5',
'text-[10px] leading-relaxed text-white/50 whitespace-pre'
'mb-2 overflow-x-auto rounded-md border border-border bg-card px-2 py-1.5',
'text-[10px] leading-relaxed text-muted-foreground whitespace-pre'
)}>
{children}
</pre>
@@ -102,8 +102,8 @@ function Code({ children }: { children: string }) {
function Row({ label, code }: { label: string; code: string }) {
return (
<div className="flex items-center justify-between py-0.5">
<span className="text-white/40">{label}</span>
<code className="rounded bg-white/[0.06] px-1 py-0.5 text-[10px] text-white/50">{code}</code>
<span className="text-muted-foreground">{label}</span>
<code className="rounded bg-accent px-1 py-0.5 text-[10px] text-muted-foreground">{code}</code>
</div>
)
}

View File

@@ -154,8 +154,8 @@ export function TreePreviewNode({
<div className="relative">
{/* From option label */}
{fromOption && (
<div className="mb-1 text-xs font-medium text-white/40">
<span className="rounded bg-white/10 px-1.5 py-0.5">{fromOption}</span>
<div className="mb-1 text-xs font-medium text-muted-foreground">
<span className="rounded bg-accent px-1.5 py-0.5">{fromOption}</span>
</div>
)}
@@ -185,7 +185,7 @@ export function TreePreviewNode({
className="absolute -top-1.5 -right-1.5 flex items-center justify-center rounded-full bg-green-500/90 p-0.5 shadow-sm"
title="This branch leads to a solution"
>
<CheckCircle className="h-3 w-3 text-white" />
<CheckCircle className="h-3 w-3 text-foreground" />
</div>
)}
{/* Root node START header */}
@@ -206,12 +206,12 @@ export function TreePreviewNode({
<button
type="button"
onClick={toggleCollapse}
className="mt-0.5 rounded p-0.5 hover:bg-white/10"
className="mt-0.5 rounded p-0.5 hover:bg-accent"
>
{isCollapsed ? (
<ChevronRight className="h-4 w-4 text-white/50" />
<ChevronRight className="h-4 w-4 text-muted-foreground" />
) : (
<ChevronDown className="h-4 w-4 text-white/50" />
<ChevronDown className="h-4 w-4 text-muted-foreground" />
)}
</button>
) : (
@@ -222,14 +222,14 @@ export function TreePreviewNode({
{isRootNode && <HelpCircle className="h-4 w-4 text-blue-500" />}
<div className="flex-1 min-w-0">
<p className="text-sm font-medium text-white leading-tight">
<p className="text-sm font-medium text-foreground leading-tight">
{getNodeLabel()}
</p>
{/* Node ID with copy button */}
<div className="flex items-center gap-1 mt-1">
<span
className="text-xs text-white/40 cursor-help"
className="text-xs text-muted-foreground cursor-help"
title={`Full ID: ${node.id}`}
>
{node.id === 'root' ? 'root' : node.id.slice(0, 8) + '...'}
@@ -237,7 +237,7 @@ export function TreePreviewNode({
<button
type="button"
onClick={handleCopyId}
className="rounded p-0.5 text-white/40 hover:bg-white/10 hover:text-white"
className="rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-foreground"
title="Copy full ID"
>
{copiedId ? (
@@ -252,8 +252,8 @@ export function TreePreviewNode({
{/* Show options for decision nodes */}
{node.type === 'decision' && node.options && node.options.length > 0 && (
<div className="mt-2 space-y-1 border-t border-white/[0.06] pt-2">
<p className="text-[10px] uppercase tracking-wide text-white/40">Options:</p>
<div className="mt-2 space-y-1 border-t border-border pt-2">
<p className="text-[10px] uppercase tracking-wide text-muted-foreground">Options:</p>
{node.options.map((opt, i) => {
const leadsToSolution = nodeLeadsToSolution(opt.next_node_id)
return (
@@ -261,15 +261,15 @@ export function TreePreviewNode({
key={opt.id}
className={cn(
'flex items-center gap-1 text-xs rounded px-1 py-0.5 -mx-1',
opt.next_node_id && 'hover:bg-white/[0.06] cursor-pointer'
opt.next_node_id && 'hover:bg-accent cursor-pointer'
)}
onMouseEnter={() => opt.next_node_id && onHoverNodeId?.(opt.next_node_id)}
onMouseLeave={() => onHoverNodeId?.(null)}
>
<span className="inline-flex h-4 w-4 items-center justify-center rounded bg-white/10 text-[10px] font-medium text-white/50">
<span className="inline-flex h-4 w-4 items-center justify-center rounded bg-accent text-[10px] font-medium text-muted-foreground">
{i + 1}
</span>
<span className="truncate text-white/70">{opt.label || 'Untitled'}</span>
<span className="truncate text-muted-foreground">{opt.label || 'Untitled'}</span>
<span className="ml-auto flex items-center gap-1">
{leadsToSolution && (
<span title="Leads to solution">
@@ -279,7 +279,7 @@ export function TreePreviewNode({
{opt.next_node_id ? (
<span className="text-blue-500"></span>
) : (
<span className="text-white/30 text-[10px]">(no link)</span>
<span className="text-muted-foreground text-[10px]">(no link)</span>
)}
</span>
</div>
@@ -308,12 +308,12 @@ export function TreePreviewNode({
return (
<div
className="mt-2 text-xs border-t border-white/[0.06] pt-2 hover:bg-white/[0.04] cursor-pointer rounded px-1 -mx-1"
className="mt-2 text-xs border-t border-border pt-2 hover:bg-accent/50 cursor-pointer rounded px-1 -mx-1"
onMouseEnter={() => onHoverNodeId?.(node.next_node_id!)}
onMouseLeave={() => onHoverNodeId?.(null)}
>
<div className="flex items-center gap-1.5">
<span className="text-white/40">Next:</span>
<span className="text-muted-foreground">Next:</span>
{isSharedTarget && (
<span title={sharedTooltip} className="flex items-center">
<Users className="h-3 w-3 text-purple-500" />
@@ -321,7 +321,7 @@ export function TreePreviewNode({
)}
<span className={cn(
'truncate',
nextNode?.type === 'solution' ? 'text-green-500 font-medium' : 'text-white/70'
nextNode?.type === 'solution' ? 'text-green-500 font-medium' : 'text-muted-foreground'
)}>
{nextNodeLabel.slice(0, 30)}{nextNodeLabel.length > 30 ? '...' : ''}
</span>
@@ -347,7 +347,7 @@ export function TreePreviewNode({
{/* Children - show as branches */}
{hasChildren && !isCollapsed && (
<div className="relative mt-3 ml-6 pl-6 border-l-2 border-white/[0.06]">
<div className="relative mt-3 ml-6 pl-6 border-l-2 border-border">
<div className="space-y-4">
{node.children!.map((child) => {
const optionLabel = getOptionLabelForChild(child.id)
@@ -355,7 +355,7 @@ export function TreePreviewNode({
return (
<div key={child.id} className="relative">
{/* Horizontal connector line */}
<div className="absolute -left-6 top-6 h-0.5 w-6 bg-white/[0.06]" />
<div className="absolute -left-6 top-6 h-0.5 w-6 bg-border" />
<TreePreviewNode
node={child}
@@ -377,8 +377,8 @@ export function TreePreviewNode({
{/* Show collapsed indicator */}
{hasChildren && isCollapsed && (
<div className="mt-2 ml-6 text-xs text-white/40">
<span className="rounded bg-white/10 px-2 py-1">
<div className="mt-2 ml-6 text-xs text-muted-foreground">
<span className="rounded bg-accent px-2 py-1">
{node.children!.length} child node{node.children!.length !== 1 ? 's' : ''} hidden
</span>
</div>

View File

@@ -56,7 +56,7 @@ export function TreePreviewPanel() {
if (!treeStructure) {
return (
<div className="flex h-full items-center justify-center p-4 text-sm text-white/40">
<div className="flex h-full items-center justify-center p-4 text-sm text-muted-foreground">
No tree structure to preview
</div>
)
@@ -65,11 +65,11 @@ export function TreePreviewPanel() {
return (
<div className="flex h-full flex-col">
{/* Header */}
<div className="border-b border-white/[0.06] px-4 py-2">
<h3 className="text-sm font-semibold text-white">
<div className="border-b border-border px-4 py-2">
<h3 className="text-sm font-semibold text-foreground">
Preview: {name || 'Untitled Tree'}
</h3>
<p className="text-xs text-white/40">
<p className="text-xs text-muted-foreground">
Click a node to select Hover options to highlight targets
</p>
</div>
@@ -91,8 +91,8 @@ export function TreePreviewPanel() {
</div>
{/* Legend */}
<div className="border-t border-white/[0.06] px-4 py-2">
<div className="flex flex-wrap gap-4 text-xs text-white/40">
<div className="border-t border-border px-4 py-2">
<div className="flex flex-wrap gap-4 text-xs text-muted-foreground">
<div className="flex items-center gap-1">
<div className="h-3 w-3 rounded bg-blue-500/50" />
<span>Decision</span>

View File

@@ -12,7 +12,7 @@ interface MarkdownContentProps {
*/
export function MarkdownContent({ content, className }: MarkdownContentProps) {
return (
<div className={cn('prose prose-sm dark:prose-invert max-w-none', className)}>
<div className={cn('prose prose-sm prose-invert max-w-none', className)}>
<ReactMarkdown
components={{
// Style paragraphs
@@ -21,7 +21,7 @@ export function MarkdownContent({ content, className }: MarkdownContentProps) {
),
// Style bold text
strong: ({ children }) => (
<strong className="font-semibold text-white">{children}</strong>
<strong className="font-semibold text-foreground">{children}</strong>
),
// Style ordered lists
ol: ({ children }) => (
@@ -33,7 +33,7 @@ export function MarkdownContent({ content, className }: MarkdownContentProps) {
),
// Style list items
li: ({ children }) => (
<li className="text-white/60">{children}</li>
<li className="text-muted-foreground">{children}</li>
),
// Style inline code
code: ({ className, children, ...props }) => {
@@ -43,7 +43,7 @@ export function MarkdownContent({ content, className }: MarkdownContentProps) {
return (
<code
className={cn(
'block rounded bg-white/10 p-3 font-mono text-sm overflow-x-auto',
'block rounded bg-accent p-3 font-mono text-sm overflow-x-auto',
className
)}
{...props}
@@ -54,7 +54,7 @@ export function MarkdownContent({ content, className }: MarkdownContentProps) {
}
return (
<code
className="rounded bg-white/10 px-1.5 py-0.5 font-mono text-sm"
className="rounded bg-accent px-1.5 py-0.5 font-mono text-sm"
{...props}
>
{children}
@@ -63,25 +63,25 @@ export function MarkdownContent({ content, className }: MarkdownContentProps) {
},
// Style code blocks (pre)
pre: ({ children }) => (
<pre className="mb-3 overflow-x-auto rounded bg-white/10 p-0 last:mb-0">
<pre className="mb-3 overflow-x-auto rounded bg-accent p-0 last:mb-0">
{children}
</pre>
),
// Style headers
h1: ({ children }) => (
<h1 className="mb-3 text-lg font-bold text-white">{children}</h1>
<h1 className="mb-3 text-lg font-bold text-foreground">{children}</h1>
),
h2: ({ children }) => (
<h2 className="mb-2 text-base font-bold text-white">{children}</h2>
<h2 className="mb-2 text-base font-bold text-foreground">{children}</h2>
),
h3: ({ children }) => (
<h3 className="mb-2 text-sm font-bold text-white">{children}</h3>
<h3 className="mb-2 text-sm font-bold text-foreground">{children}</h3>
),
// Style horizontal rules
hr: () => <hr className="my-4 border-white/[0.06]" />,
hr: () => <hr className="my-4 border-border" />,
// Style blockquotes
blockquote: ({ children }) => (
<blockquote className="mb-3 border-l-4 border-white/20 pl-4 italic text-white/50 last:mb-0">
<blockquote className="mb-3 border-l-4 border-border pl-4 italic text-muted-foreground last:mb-0">
{children}
</blockquote>
),