feat: implement monochrome design system across entire frontend
Migrate all 84 frontend files from the old themed/colored design to a monochrome glass-morphism design system. Pure black backgrounds, white text with opacity levels, glass-card components with backdrop-blur, and functional color reserved for status indicators only. Foundation: remap CSS variables to monochrome, simplify Tailwind config, remove theme toggle, convert brand logo/wordmark to white. Pages: all 14 pages updated. Components: all common, library, session, step-library, tree-editor, tree-preview, admin, and subscription components converted. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -64,10 +64,10 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
|
||||
<Play className="h-5 w-5 text-blue-500" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-blue-600 dark:text-blue-400">
|
||||
<h3 className="font-semibold text-blue-400">
|
||||
Starting Question
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
<p className="mt-1 text-sm text-white/40">
|
||||
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-foreground">
|
||||
{isRootNode ? 'Starting Question' : 'Question'} <span className="text-destructive">*</span>
|
||||
<label className="block text-sm font-medium text-white">
|
||||
{isRootNode ? 'Starting Question' : 'Question'} <span className="text-red-400">*</span>
|
||||
</label>
|
||||
{isRootNode && (
|
||||
<p className="mt-0.5 text-xs text-muted-foreground">
|
||||
<p className="mt-0.5 text-xs text-white/40">
|
||||
What's the main question to diagnose the issue?
|
||||
</p>
|
||||
)}
|
||||
@@ -95,19 +95,19 @@ 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-background text-foreground placeholder:text-muted-foreground',
|
||||
'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary',
|
||||
questionError ? 'border-destructive' : 'border-input'
|
||||
'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'
|
||||
)}
|
||||
/>
|
||||
{questionError && (
|
||||
<p className="mt-1 text-xs text-destructive">{questionError.message}</p>
|
||||
<p className="mt-1 text-xs text-red-400">{questionError.message}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Help Text */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-foreground">
|
||||
<label className="block text-sm font-medium text-white">
|
||||
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-input px-3 py-2 text-sm',
|
||||
'mt-1 block w-full rounded-md border border-white/10 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,20 +125,20 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
|
||||
|
||||
{/* Options */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-foreground">
|
||||
{isRootNode ? 'Answer Options (Branches)' : 'Options'} <span className="text-destructive">*</span>
|
||||
<label className="block text-sm font-medium text-white">
|
||||
{isRootNode ? 'Answer Options (Branches)' : 'Options'} <span className="text-red-400">*</span>
|
||||
</label>
|
||||
{isRootNode ? (
|
||||
<p className="mt-0.5 text-xs text-muted-foreground">
|
||||
<p className="mt-0.5 text-xs text-white/40">
|
||||
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-muted-foreground">
|
||||
<p className="mt-0.5 text-xs text-white/40">
|
||||
Each option can branch to a different next step.
|
||||
</p>
|
||||
)}
|
||||
{optionsError && (
|
||||
<p className="mt-1 text-xs text-destructive">{optionsError.message}</p>
|
||||
<p className="mt-1 text-xs text-red-400">{optionsError.message}</p>
|
||||
)}
|
||||
<div className="mt-2">
|
||||
<DynamicArrayField
|
||||
@@ -158,14 +158,14 @@ export function NodeFormDecision({ node, onUpdate }: NodeFormDecisionProps) {
|
||||
const letter = indexToLetter(index)
|
||||
|
||||
return (
|
||||
<div className="rounded-md border border-input bg-muted/30 p-3">
|
||||
<div className="rounded-md border border-white/10 bg-white/[0.04] 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-600 dark:text-blue-400'
|
||||
: 'bg-muted text-muted-foreground'
|
||||
? 'bg-blue-500/20 text-blue-400'
|
||||
: 'bg-white/10 text-white/50'
|
||||
)}>
|
||||
{letter}
|
||||
</span>
|
||||
@@ -180,12 +180,12 @@ 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-destructive' : 'border-input'
|
||||
optionLabelError ? 'border-red-400' : 'border-white/10'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{optionLabelError && (
|
||||
<p className="mb-2 text-xs text-destructive">{optionLabelError.message}</p>
|
||||
<p className="mb-2 text-xs text-red-400">{optionLabelError.message}</p>
|
||||
)}
|
||||
<div className="pl-8">
|
||||
<NodePicker
|
||||
@@ -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-muted-foreground/30 bg-muted/20 p-3 text-xs text-muted-foreground">
|
||||
<div className="mt-3 rounded-md border border-dashed border-white/10 bg-white/[0.02] p-3 text-xs text-white/40">
|
||||
<strong>Tip:</strong> Most troubleshooting trees start with 2-5 main branches.
|
||||
For example: "Connection Issues", "Performance Problems", "Error Messages", "Other".
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user