style: Dark/Light mode contrast audit
Some checks are pending
Test / backend-test (push) Waiting to run
Test / frontend-test (push) Waiting to run

- Boost text contrast in both themes
- Strengthen border visibility (subtle borders now visible)
- Convert 39 files from hardcoded dark:/light: to CSS vars
- Tertiary text now more readable on both backgrounds
This commit is contained in:
fullsizemalt 2025-12-27 12:12:10 -08:00
parent 15a6b08e0f
commit 47de301f77
39 changed files with 179 additions and 179 deletions

View file

@ -55,8 +55,8 @@ export default function BatchTransitionModal({ batch, onClose, onSuccess }: Tran
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-fade-in"> <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-fade-in">
<div className="bg-white dark:bg-slate-800 w-full max-w-md rounded-2xl shadow-2xl overflow-hidden animate-scale-in"> <div className="bg-[var(--color-bg-elevated)] w-full max-w-md rounded-2xl shadow-2xl overflow-hidden animate-scale-in">
<div className="p-6 border-b border-slate-200 dark:border-slate-700 flex justify-between items-center"> <div className="p-6 border-b border-[var(--color-border-default)] flex justify-between items-center">
<h2 className="text-xl font-bold dark:text-white">Transition Batch</h2> <h2 className="text-xl font-bold dark:text-white">Transition Batch</h2>
<button onClick={onClose} className="text-[var(--color-text-tertiary)] hover:text-slate-700 dark:hover:text-slate-300"> <button onClick={onClose} className="text-[var(--color-text-tertiary)] hover:text-slate-700 dark:hover:text-slate-300">
<X size={24} /> <X size={24} />
@ -64,7 +64,7 @@ export default function BatchTransitionModal({ batch, onClose, onSuccess }: Tran
</div> </div>
<form onSubmit={handleSubmit} className="p-6 space-y-6"> <form onSubmit={handleSubmit} className="p-6 space-y-6">
<div className="bg-[var(--color-bg-tertiary)] p-4 rounded-xl border border-slate-200 dark:border-slate-700"> <div className="bg-[var(--color-bg-tertiary)] p-4 rounded-xl border border-[var(--color-border-default)]">
<div className="flex items-center gap-3 mb-2"> <div className="flex items-center gap-3 mb-2">
<Sprout className="text-[var(--color-primary)] dark:text-emerald-400" size={20} /> <Sprout className="text-[var(--color-primary)] dark:text-emerald-400" size={20} />
<span className="font-semibold text-[var(--color-text-primary)]">{batch.name}</span> <span className="font-semibold text-[var(--color-text-primary)]">{batch.name}</span>
@ -77,11 +77,11 @@ export default function BatchTransitionModal({ batch, onClose, onSuccess }: Tran
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">New Stage</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">New Stage</label>
<select <select
value={targetStage} value={targetStage}
onChange={(e) => setTargetStage(e.target.value as any)} onChange={(e) => setTargetStage(e.target.value as any)}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white"
> >
{STAGES.map(stage => ( {STAGES.map(stage => (
<option key={stage.id} value={stage.id}>{stage.label}</option> <option key={stage.id} value={stage.id}>{stage.label}</option>
@ -90,7 +90,7 @@ export default function BatchTransitionModal({ batch, onClose, onSuccess }: Tran
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2"> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Home size={16} /> <Home size={16} />
Move to Room Move to Room
@ -99,7 +99,7 @@ export default function BatchTransitionModal({ batch, onClose, onSuccess }: Tran
<select <select
value={targetRoomId} value={targetRoomId}
onChange={(e) => setTargetRoomId(e.target.value)} onChange={(e) => setTargetRoomId(e.target.value)}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white"
> >
<option value="">Keep current room ({batch.room?.name || 'Unassigned'})</option> <option value="">Keep current room ({batch.room?.name || 'Unassigned'})</option>
{rooms.map(room => ( {rooms.map(room => (
@ -110,12 +110,12 @@ export default function BatchTransitionModal({ batch, onClose, onSuccess }: Tran
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Plant Count</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">Plant Count</label>
<input <input
type="number" type="number"
value={metadata.plantCount} value={metadata.plantCount}
onChange={(e) => setMetadata({ ...metadata, plantCount: parseInt(e.target.value) || 0 })} onChange={(e) => setMetadata({ ...metadata, plantCount: parseInt(e.target.value) || 0 })}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white"
/> />
</div> </div>
</div> </div>

View file

@ -49,7 +49,7 @@ export class ErrorBoundary extends Component<Props, State> {
return ( return (
<div className="min-h-screen bg-[var(--color-bg-tertiary)] flex items-center justify-center p-6"> <div className="min-h-screen bg-[var(--color-bg-tertiary)] flex items-center justify-center p-6">
<div className="max-w-md w-full bg-white dark:bg-slate-800 rounded-2xl shadow-xl p-8 text-center"> <div className="max-w-md w-full bg-[var(--color-bg-elevated)] rounded-2xl shadow-xl p-8 text-center">
<div className="w-16 h-16 mx-auto bg-red-100 dark:bg-red-900/30 rounded-full flex items-center justify-center mb-6"> <div className="w-16 h-16 mx-auto bg-red-100 dark:bg-red-900/30 rounded-full flex items-center justify-center mb-6">
<AlertTriangle size={32} className="text-red-600 dark:text-red-400" /> <AlertTriangle size={32} className="text-red-600 dark:text-red-400" />
</div> </div>
@ -68,7 +68,7 @@ export class ErrorBoundary extends Component<Props, State> {
<summary className="cursor-pointer text-sm text-[var(--color-text-tertiary)] hover:text-slate-700 dark:hover:text-slate-300"> <summary className="cursor-pointer text-sm text-[var(--color-text-tertiary)] hover:text-slate-700 dark:hover:text-slate-300">
Technical Details Technical Details
</summary> </summary>
<pre className="mt-2 p-3 bg-slate-100 dark:bg-slate-700 rounded-lg text-xs text-red-600 dark:text-red-400 overflow-auto max-h-32"> <pre className="mt-2 p-3 bg-[var(--color-bg-tertiary)] rounded-lg text-xs text-red-600 dark:text-red-400 overflow-auto max-h-32">
{this.state.error.toString()} {this.state.error.toString()}
{this.state.errorInfo?.componentStack} {this.state.errorInfo?.componentStack}
</pre> </pre>
@ -85,7 +85,7 @@ export class ErrorBoundary extends Component<Props, State> {
</button> </button>
<button <button
onClick={this.handleGoHome} onClick={this.handleGoHome}
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 bg-slate-200 dark:bg-slate-700 hover:bg-slate-300 dark:hover:bg-slate-600 text-slate-700 dark:text-slate-200 font-medium rounded-xl transition-colors" className="flex-1 flex items-center justify-center gap-2 px-4 py-3 bg-slate-200 dark:bg-slate-700 hover:bg-slate-300 dark:hover:bg-slate-600 text-[var(--color-text-secondary)]late-200 font-medium rounded-xl transition-colors"
> >
<Home size={18} /> <Home size={18} />
Go Home Go Home

View file

@ -50,8 +50,8 @@ export default function TaskTemplateModal({ template, onClose, onSuccess }: Task
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-fade-in"> <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-fade-in">
<div className="bg-white dark:bg-slate-800 w-full max-w-lg rounded-2xl shadow-2xl overflow-hidden animate-scale-in flex flex-col max-h-[90vh]"> <div className="bg-[var(--color-bg-elevated)] w-full max-w-lg rounded-2xl shadow-2xl overflow-hidden animate-scale-in flex flex-col max-h-[90vh]">
<div className="p-6 border-b border-slate-200 dark:border-slate-700 flex justify-between items-center"> <div className="p-6 border-b border-[var(--color-border-default)] flex justify-between items-center">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<FileText className="text-[var(--color-primary)] dark:text-emerald-400" size={24} /> <FileText className="text-[var(--color-primary)] dark:text-emerald-400" size={24} />
<h2 className="text-xl font-bold dark:text-white"> <h2 className="text-xl font-bold dark:text-white">
@ -65,12 +65,12 @@ export default function TaskTemplateModal({ template, onClose, onSuccess }: Task
<form onSubmit={handleSubmit} className="p-6 space-y-6 overflow-y-auto flex-1"> <form onSubmit={handleSubmit} className="p-6 space-y-6 overflow-y-auto flex-1">
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Title</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">Title</label>
<input <input
type="text" type="text"
value={formData.title} value={formData.title}
onChange={(e) => setFormData({ ...formData, title: e.target.value })} onChange={(e) => setFormData({ ...formData, title: e.target.value })}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white"
placeholder="e.g. Daily Veg Watering" placeholder="e.g. Daily Veg Watering"
required required
/> />
@ -78,11 +78,11 @@ export default function TaskTemplateModal({ template, onClose, onSuccess }: Task
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Room Type</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">Room Type</label>
<select <select
value={formData.roomType} value={formData.roomType}
onChange={(e) => setFormData({ ...formData, roomType: e.target.value })} onChange={(e) => setFormData({ ...formData, roomType: e.target.value })}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white"
> >
{ROOM_TYPES.map(type => ( {ROOM_TYPES.map(type => (
<option key={type} value={type}>{type}</option> <option key={type} value={type}>{type}</option>
@ -90,39 +90,39 @@ export default function TaskTemplateModal({ template, onClose, onSuccess }: Task
</select> </select>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Est. Minutes</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">Est. Minutes</label>
<input <input
type="number" type="number"
value={formData.estimatedMinutes} value={formData.estimatedMinutes}
onChange={(e) => setFormData({ ...formData, estimatedMinutes: parseInt(e.target.value) || 0 })} onChange={(e) => setFormData({ ...formData, estimatedMinutes: parseInt(e.target.value) || 0 })}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white"
/> />
</div> </div>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Description / Instructions</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">Description / Instructions</label>
<textarea <textarea
value={formData.description} value={formData.description}
onChange={(e) => setFormData({ ...formData, description: e.target.value })} onChange={(e) => setFormData({ ...formData, description: e.target.value })}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white h-32 resize-none" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white h-32 resize-none"
placeholder="Detailed SOP instructions..." placeholder="Detailed SOP instructions..."
/> />
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Materials (comma separated)</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">Materials (comma separated)</label>
<input <input
type="text" type="text"
value={materialsInput} value={materialsInput}
onChange={(e) => setMaterialsInput(e.target.value)} onChange={(e) => setMaterialsInput(e.target.value)}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white"
placeholder="e.g. 5gal buckets, bamboo stakes, twist ties" placeholder="e.g. 5gal buckets, bamboo stakes, twist ties"
/> />
</div> </div>
</form> </form>
<div className="p-6 border-t border-slate-200 dark:border-slate-700 bg-[var(--color-bg-tertiary)]/50"> <div className="p-6 border-t border-[var(--color-border-default)] bg-[var(--color-bg-tertiary)]/50">
<button <button
onClick={handleSubmit} onClick={handleSubmit}
disabled={isSubmitting} disabled={isSubmitting}

View file

@ -45,8 +45,8 @@ export default function WeightLogModal({ batch, onClose, onSuccess }: WeightLogM
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-fade-in"> <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-fade-in">
<div className="bg-white dark:bg-slate-800 w-full max-w-md rounded-2xl shadow-2xl overflow-hidden animate-scale-in"> <div className="bg-[var(--color-bg-elevated)] w-full max-w-md rounded-2xl shadow-2xl overflow-hidden animate-scale-in">
<div className="p-6 border-b border-slate-200 dark:border-slate-700 flex justify-between items-center"> <div className="p-6 border-b border-[var(--color-border-default)] flex justify-between items-center">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Scale className="text-[var(--color-primary)] dark:text-emerald-400" size={24} /> <Scale className="text-[var(--color-primary)] dark:text-emerald-400" size={24} />
<h2 className="text-xl font-bold dark:text-white">Log Weight</h2> <h2 className="text-xl font-bold dark:text-white">Log Weight</h2>
@ -57,17 +57,17 @@ export default function WeightLogModal({ batch, onClose, onSuccess }: WeightLogM
</div> </div>
<form onSubmit={handleSubmit} className="p-6 space-y-6"> <form onSubmit={handleSubmit} className="p-6 space-y-6">
<div className="bg-[var(--color-bg-tertiary)] p-4 rounded-xl border border-slate-200 dark:border-slate-700"> <div className="bg-[var(--color-bg-tertiary)] p-4 rounded-xl border border-[var(--color-border-default)]">
<h3 className="font-semibold text-[var(--color-text-primary)]">{batch.name}</h3> <h3 className="font-semibold text-[var(--color-text-primary)]">{batch.name}</h3>
<p className="text-sm text-[var(--color-text-tertiary)]">{batch.strain}</p> <p className="text-sm text-[var(--color-text-tertiary)]">{batch.strain}</p>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Weight Type</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">Weight Type</label>
<select <select
value={weightType} value={weightType}
onChange={(e) => setWeightType(e.target.value)} onChange={(e) => setWeightType(e.target.value)}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white"
> >
{WEIGHT_TYPES.map(type => ( {WEIGHT_TYPES.map(type => (
<option key={type.id} value={type.id}>{type.label}</option> <option key={type.id} value={type.id}>{type.label}</option>
@ -77,23 +77,23 @@ export default function WeightLogModal({ batch, onClose, onSuccess }: WeightLogM
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Weight</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">Weight</label>
<input <input
type="number" type="number"
step="0.01" step="0.01"
value={weight} value={weight}
onChange={(e) => setWeight(e.target.value)} onChange={(e) => setWeight(e.target.value)}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white"
placeholder="0.00" placeholder="0.00"
required required
/> />
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Unit</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">Unit</label>
<select <select
value={unit} value={unit}
onChange={(e) => setUnit(e.target.value)} onChange={(e) => setUnit(e.target.value)}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white"
> >
<option value="lbs">lbs</option> <option value="lbs">lbs</option>
<option value="g">grams</option> <option value="g">grams</option>
@ -104,11 +104,11 @@ export default function WeightLogModal({ batch, onClose, onSuccess }: WeightLogM
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2">Notes</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">Notes</label>
<textarea <textarea
value={notes} value={notes}
onChange={(e) => setNotes(e.target.value)} onChange={(e) => setNotes(e.target.value)}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white h-24 resize-none" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white h-24 resize-none"
placeholder="Optional notes..." placeholder="Optional notes..."
/> />
</div> </div>

View file

@ -82,7 +82,7 @@ export function Navbar({ onOpenMobileMenu }: NavbarProps) {
{/* Search Mock */} {/* Search Mock */}
<button <button
onClick={() => dispatchEvent(new KeyboardEvent('keydown', { key: 'k', metaKey: true }))} onClick={() => dispatchEvent(new KeyboardEvent('keydown', { key: 'k', metaKey: true }))}
className="hidden md:flex items-center gap-3 px-4 py-2 text-xs font-bold text-[var(--color-text-tertiary)] bg-slate-100/50 hover:bg-white dark:bg-slate-900/50 dark:hover:bg-slate-800 transition-all rounded-full border border-slate-200/50 dark:border-slate-800 group" className="hidden md:flex items-center gap-3 px-4 py-2 text-xs font-bold text-[var(--color-text-tertiary)] bg-slate-100/50 hover:bg-[var(--color-bg-elevated)]/50 dark:hover:bg-slate-800 transition-all rounded-full border border-slate-200/50 dark:border-slate-800 group"
> >
<Search size={12} className="group-hover:text-indigo-500 transition-colors" /> <Search size={12} className="group-hover:text-indigo-500 transition-colors" />
<span className="uppercase tracking-widest">Search...</span> <span className="uppercase tracking-widest">Search...</span>
@ -152,7 +152,7 @@ function UserDropdown() {
transition={{ duration: 0.1 }} transition={{ duration: 0.1 }}
className="absolute top-full right-0 mt-3 w-64 p-3 bg-white/95 dark:bg-slate-900/95 backdrop-blur-2xl border border-[var(--color-border-subtle)] rounded-2xl shadow-2xl z-50 ring-1 ring-black/5" className="absolute top-full right-0 mt-3 w-64 p-3 bg-white/95 dark:bg-slate-900/95 backdrop-blur-2xl border border-[var(--color-border-subtle)] rounded-2xl shadow-2xl z-50 ring-1 ring-black/5"
> >
<div className="px-3 py-3 border-b border-slate-100 dark:border-slate-800 mb-2"> <div className="px-3 py-3 border-b border-[var(--color-border-subtle)] mb-2">
<p className="text-xs font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest mb-1">Authenticated</p> <p className="text-xs font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest mb-1">Authenticated</p>
<p className="text-sm font-bold text-[var(--color-text-primary)] truncate"> <p className="text-sm font-bold text-[var(--color-text-primary)] truncate">
{user?.name || 'Administrator'} {user?.name || 'Administrator'}

View file

@ -94,16 +94,16 @@ export function RoomStatusCard({ name, phase, status, metrics, tasks, strains }:
</div> </div>
{/* Footer / Tasks */} {/* Footer / Tasks */}
<div className="pt-4 border-t border-slate-100 dark:border-slate-800/50 flex items-center justify-between"> <div className="pt-4 border-t border-[var(--color-border-subtle)]/50 flex items-center justify-between">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<div className="flex items-center gap-1.5 text-xs text-[var(--color-text-tertiary)]"> <div className="flex items-center gap-1.5 text-xs text-[var(--color-text-tertiary)]">
<Clock size={12} /> <Clock size={12} />
<span className="font-bold text-slate-700 dark:text-slate-300">{tasks.due}</span> <span className="font-bold text-[var(--color-text-secondary)]">{tasks.due}</span>
<span>Pending</span> <span>Pending</span>
</div> </div>
<div className="flex items-center gap-1.5 text-xs text-[var(--color-text-tertiary)]"> <div className="flex items-center gap-1.5 text-xs text-[var(--color-text-tertiary)]">
<CheckCircle2 size={12} className="text-[var(--color-primary)]" /> <CheckCircle2 size={12} className="text-[var(--color-primary)]" />
<span className="font-bold text-slate-700 dark:text-slate-300">{tasks.completed}</span> <span className="font-bold text-[var(--color-text-secondary)]">{tasks.completed}</span>
<span>Done</span> <span>Done</span>
</div> </div>
</div> </div>
@ -126,7 +126,7 @@ export function RoomStatusCard({ name, phase, status, metrics, tasks, strains }:
function MetricItem({ icon, label, value, status }: { icon: React.ReactNode, label: string, value: string, status: 'ok' | 'warning' | 'critical' }) { function MetricItem({ icon, label, value, status }: { icon: React.ReactNode, label: string, value: string, status: 'ok' | 'warning' | 'critical' }) {
return ( return (
<div className="bg-[var(--color-bg-tertiary)]/50 p-2.5 rounded-xl border border-slate-100 dark:border-slate-800/50"> <div className="bg-[var(--color-bg-tertiary)]/50 p-2.5 rounded-xl border border-[var(--color-border-subtle)]/50">
<div className="flex items-center gap-1.5 mb-1"> <div className="flex items-center gap-1.5 mb-1">
{icon} {icon}
<span className="text-[10px] font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest">{label}</span> <span className="text-[10px] font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest">{label}</span>

View file

@ -100,7 +100,7 @@ export function DevTools() {
{/* Panel */} {/* Panel */}
{isOpen && ( {isOpen && (
<div className="absolute bottom-14 right-0 w-72 bg-white dark:bg-slate-800 rounded-xl shadow-2xl border border-slate-200 dark:border-slate-700 overflow-hidden animate-scale-in"> <div className="absolute bottom-14 right-0 w-72 bg-[var(--color-bg-elevated)] rounded-xl shadow-2xl border border-[var(--color-border-default)] overflow-hidden animate-scale-in">
{/* Header */} {/* Header */}
<div className="bg-[var(--color-warning)] text-white px-4 py-3 flex items-center justify-between"> <div className="bg-[var(--color-warning)] text-white px-4 py-3 flex items-center justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@ -113,7 +113,7 @@ export function DevTools() {
</div> </div>
{/* Current User */} {/* Current User */}
<div className="px-4 py-3 border-b border-slate-200 dark:border-slate-700"> <div className="px-4 py-3 border-b border-[var(--color-border-default)]">
<p className="text-[10px] uppercase text-[var(--color-text-tertiary)] font-semibold mb-1">Current User</p> <p className="text-[10px] uppercase text-[var(--color-text-tertiary)] font-semibold mb-1">Current User</p>
{user ? ( {user ? (
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@ -169,7 +169,7 @@ export function DevTools() {
{/* Demo Actions */} {/* Demo Actions */}
{user && ['OWNER', 'ADMIN'].includes(user.role) && ( {user && ['OWNER', 'ADMIN'].includes(user.role) && (
<div className="px-4 py-3 border-t border-slate-200 dark:border-slate-700"> <div className="px-4 py-3 border-t border-[var(--color-border-default)]">
<p className="text-[10px] uppercase text-[var(--color-text-tertiary)] font-semibold mb-2">Demo Actions</p> <p className="text-[10px] uppercase text-[var(--color-text-tertiary)] font-semibold mb-2">Demo Actions</p>
<button <button
onClick={handleReseedPlants} onClick={handleReseedPlants}
@ -199,7 +199,7 @@ export function DevTools() {
)} )}
{/* Footer */} {/* Footer */}
<div className="px-4 py-2 bg-[var(--color-bg-tertiary)] border-t border-slate-200 dark:border-slate-700"> <div className="px-4 py-2 bg-[var(--color-bg-tertiary)] border-t border-[var(--color-border-default)]">
<p className="text-[10px] text-[var(--color-text-tertiary)] text-center"> <p className="text-[10px] text-[var(--color-text-tertiary)] text-center">
🚧 Testing Environment Only 🚧 Testing Environment Only
</p> </p>

View file

@ -48,7 +48,7 @@ export default function BedTooltip({ bed, position, onClose }: BedTooltipProps)
return ( return (
<div <div
ref={tooltipRef} ref={tooltipRef}
className="fixed z-50 bg-white dark:bg-slate-800 rounded-lg shadow-2xl border border-slate-200 dark:border-slate-700 p-4 min-w-[280px]" className="fixed z-50 bg-[var(--color-bg-elevated)] rounded-lg shadow-2xl border border-[var(--color-border-default)] p-4 min-w-[280px]"
style={{ style={{
left: position.x + 10, left: position.x + 10,
top: position.y + 10, top: position.y + 10,
@ -134,7 +134,7 @@ export default function BedTooltip({ bed, position, onClose }: BedTooltipProps)
)} )}
{/* Actions */} {/* Actions */}
<div className="mt-3 pt-3 border-t border-slate-200 dark:border-slate-700"> <div className="mt-3 pt-3 border-t border-[var(--color-border-default)]">
<button className="text-sm text-[var(--color-primary)] dark:text-emerald-400 hover:underline"> <button className="text-sm text-[var(--color-primary)] dark:text-emerald-400 hover:underline">
View Details View Details
</button> </button>

View file

@ -140,7 +140,7 @@ export default function GrowRoomHeatmap({ roomId }: GrowRoomHeatmapProps) {
<HealthLegend /> <HealthLegend />
{/* Grid */} {/* Grid */}
<div className="bg-white dark:bg-slate-800 rounded-xl shadow-lg p-6"> <div className="bg-[var(--color-bg-elevated)] rounded-xl shadow-lg p-6">
<FloorGrid <FloorGrid
floor={currentFloor} floor={currentFloor}
rows={layout.grid.rows} rows={layout.grid.rows}

View file

@ -14,8 +14,8 @@ export default function HealthLegend() {
]; ];
return ( return (
<div className="bg-white dark:bg-slate-800 rounded-lg shadow p-4"> <div className="bg-[var(--color-bg-elevated)] rounded-lg shadow p-4">
<h3 className="text-sm font-semibold text-slate-700 dark:text-slate-300 mb-3"> <h3 className="text-sm font-semibold text-[var(--color-text-secondary)] mb-3">
Health Score Legend Health Score Legend
</h3> </h3>
<div className="flex flex-wrap gap-3"> <div className="flex flex-wrap gap-3">

View file

@ -37,8 +37,8 @@ export default function BatchHealthHistoryModal({ batch, onClose }: BatchHealthH
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-fade-in"> <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-fade-in">
<div className="bg-white dark:bg-slate-900 w-full max-w-2xl rounded-2xl shadow-2xl overflow-hidden animate-scale-in flex flex-col max-h-[90vh]"> <div className="bg-[var(--color-bg-elevated)] w-full max-w-2xl rounded-2xl shadow-2xl overflow-hidden animate-scale-in flex flex-col max-h-[90vh]">
<div className="p-6 border-b border-slate-200 dark:border-slate-700 flex justify-between items-center shrink-0"> <div className="p-6 border-b border-[var(--color-border-default)] flex justify-between items-center shrink-0">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<History className="text-[var(--color-text-tertiary)]" size={24} /> <History className="text-[var(--color-text-tertiary)]" size={24} />
<h2 className="text-xl font-bold dark:text-white">Batch Health History</h2> <h2 className="text-xl font-bold dark:text-white">Batch Health History</h2>
@ -48,7 +48,7 @@ export default function BatchHealthHistoryModal({ batch, onClose }: BatchHealthH
</button> </button>
</div> </div>
<div className="p-4 bg-slate-50 dark:bg-slate-800 border-b border-slate-200 dark:border-slate-700 shrink-0"> <div className="p-4 bg-[var(--color-bg-tertiary)] border-b border-[var(--color-border-default)] shrink-0">
<h3 className="font-bold text-[var(--color-text-primary)]">{batch.name}</h3> <h3 className="font-bold text-[var(--color-text-primary)]">{batch.name}</h3>
<p className="text-sm text-[var(--color-text-tertiary)]">{batch.strain} &bull; {batch.room?.name || 'No Room'}</p> <p className="text-sm text-[var(--color-text-tertiary)]">{batch.strain} &bull; {batch.room?.name || 'No Room'}</p>
</div> </div>
@ -59,14 +59,14 @@ export default function BatchHealthHistoryModal({ batch, onClose }: BatchHealthH
) : history.length === 0 ? ( ) : history.length === 0 ? (
<div className="text-center text-[var(--color-text-tertiary)] py-10 italic">No health or maintenance records found.</div> <div className="text-center text-[var(--color-text-tertiary)] py-10 italic">No health or maintenance records found.</div>
) : ( ) : (
<div className="relative border-l-2 border-slate-200 dark:border-slate-700 ml-4 space-y-8"> <div className="relative border-l-2 border-[var(--color-border-default)] ml-4 space-y-8">
{history.map((record) => ( {history.map((record) => (
<div key={record.id} className="relative pl-8"> <div key={record.id} className="relative pl-8">
<div className={`absolute -left-[9px] top-0 w-4 h-4 rounded-full border-2 border-white dark:border-slate-900 ${record.issuesObserved ? 'bg-red-500' : <div className={`absolute -left-[9px] top-0 w-4 h-4 rounded-full border-2 border-white dark:border-slate-900 ${record.issuesObserved ? 'bg-red-500' :
record.type === 'IPM' ? 'bg-orange-400' : 'bg-slate-300 dark:bg-slate-600' record.type === 'IPM' ? 'bg-orange-400' : 'bg-slate-300 dark:bg-slate-600'
}`} /> }`} />
<div className="bg-white dark:bg-slate-800 p-4 rounded-xl border border-slate-100 dark:border-slate-700 shadow-sm"> <div className="bg-[var(--color-bg-elevated)] p-4 rounded-xl border border-slate-100 dark:border-slate-700 shadow-sm">
<div className="flex justify-between items-start mb-2"> <div className="flex justify-between items-start mb-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
{getIcon(record.type, record.issuesObserved)} {getIcon(record.type, record.issuesObserved)}
@ -98,7 +98,7 @@ export default function BatchHealthHistoryModal({ batch, onClose }: BatchHealthH
ISSUE DETECTED ISSUE DETECTED
</span> </span>
{record.issueType && ( {record.issueType && (
<span className="text-xs bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-300 px-2 py-1 rounded"> <span className="text-xs bg-[var(--color-bg-tertiary)] text-slate-600 dark:text-slate-300 px-2 py-1 rounded">
{record.issueType} {record.issueType}
</span> </span>
)} )}

View file

@ -17,7 +17,7 @@ export function MobileNav({ onMoreClick }: MobileNavProps) {
return ( return (
<nav <nav
className="md:hidden fixed bottom-0 left-0 right-0 bg-white dark:bg-slate-800 border-t border-slate-200 dark:border-slate-700 z-50" className="md:hidden fixed bottom-0 left-0 right-0 bg-[var(--color-bg-elevated)] border-t border-[var(--color-border-default)] z-50"
style={{ paddingBottom: 'env(safe-area-inset-bottom)' }} style={{ paddingBottom: 'env(safe-area-inset-bottom)' }}
> >
<div className="flex items-center justify-around px-2 py-1"> <div className="flex items-center justify-around px-2 py-1">

View file

@ -94,8 +94,8 @@ export function PageHeaderButton({
}) { }) {
const variants = { const variants = {
primary: 'bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white shadow-sm', primary: 'bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)] text-white shadow-sm',
secondary: 'bg-slate-100 dark:bg-slate-700 hover:bg-slate-200 dark:hover:bg-slate-600 text-[var(--color-text-primary)]', secondary: 'bg-[var(--color-bg-tertiary)] hover:bg-slate-200 dark:hover:bg-slate-600 text-[var(--color-text-primary)]',
ghost: 'hover:bg-slate-100 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300' ghost: 'hover:bg-slate-100 dark:hover:bg-slate-700 text-[var(--color-text-secondary)]'
}; };
return ( return (

View file

@ -15,7 +15,7 @@ interface ShiftNotesWidgetProps {
} }
const IMPORTANCE_CONFIG: Record<string, { color: string; bgColor: string; label: string }> = { const IMPORTANCE_CONFIG: Record<string, { color: string; bgColor: string; label: string }> = {
LOW: { color: 'text-[var(--color-text-tertiary)]', bgColor: 'bg-slate-100 dark:bg-slate-700', label: 'Low' }, LOW: { color: 'text-[var(--color-text-tertiary)]', bgColor: 'bg-[var(--color-bg-tertiary)]', label: 'Low' },
NORMAL: { color: 'text-[var(--color-accent)]', bgColor: 'bg-blue-50 dark:bg-blue-900/30', label: 'Normal' }, NORMAL: { color: 'text-[var(--color-accent)]', bgColor: 'bg-blue-50 dark:bg-blue-900/30', label: 'Normal' },
HIGH: { color: 'text-[var(--color-warning)]', bgColor: 'bg-amber-50 dark:bg-amber-900/30', label: 'High' }, HIGH: { color: 'text-[var(--color-warning)]', bgColor: 'bg-amber-50 dark:bg-amber-900/30', label: 'High' },
URGENT: { color: 'text-red-500', bgColor: 'bg-red-50 dark:bg-red-900/30', label: 'Urgent' } URGENT: { color: 'text-red-500', bgColor: 'bg-red-50 dark:bg-red-900/30', label: 'Urgent' }
@ -100,10 +100,10 @@ export default function ShiftNotesWidget({
const urgentNotes = notes.filter(n => n.importance === 'URGENT' || n.importance === 'HIGH'); const urgentNotes = notes.filter(n => n.importance === 'URGENT' || n.importance === 'HIGH');
return ( return (
<div className={`bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 overflow-hidden ${className}`}> <div className={`bg-[var(--color-bg-elevated)] rounded-xl border border-[var(--color-border-default)] overflow-hidden ${className}`}>
{/* Header */} {/* Header */}
<div <div
className="p-4 border-b border-slate-200 dark:border-slate-700 flex items-center justify-between cursor-pointer" className="p-4 border-b border-[var(--color-border-default)] flex items-center justify-between cursor-pointer"
onClick={() => compact && setExpanded(!expanded)} onClick={() => compact && setExpanded(!expanded)}
> >
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
@ -143,14 +143,14 @@ export default function ShiftNotesWidget({
{/* Create Form */} {/* Create Form */}
{showCreate && expanded && ( {showCreate && expanded && (
<form onSubmit={handleSubmit} className="p-4 bg-[var(--color-bg-tertiary)]/50 border-b border-slate-200 dark:border-slate-700"> <form onSubmit={handleSubmit} className="p-4 bg-[var(--color-bg-tertiary)]/50 border-b border-[var(--color-border-default)]">
<div className="space-y-3"> <div className="space-y-3">
<textarea <textarea
value={newNote.content} value={newNote.content}
onChange={(e) => setNewNote({ ...newNote, content: e.target.value })} onChange={(e) => setNewNote({ ...newNote, content: e.target.value })}
placeholder="Add a note for the next shift..." placeholder="Add a note for the next shift..."
rows={3} rows={3}
className="w-full px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-800 text-sm resize-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" className="w-full px-3 py-2 rounded-lg border border-slate-200 dark:border-slate-600 bg-[var(--color-bg-elevated)] text-sm resize-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
autoFocus autoFocus
/> />
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
@ -223,7 +223,7 @@ export default function ShiftNotesWidget({
)} )}
</div> </div>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<p className="text-sm text-slate-700 dark:text-slate-200 whitespace-pre-wrap"> <p className="text-sm text-[var(--color-text-secondary)]late-200 whitespace-pre-wrap">
{note.content} {note.content}
</p> </p>
<div className="flex items-center gap-3 mt-2 text-xs text-[var(--color-text-tertiary)]"> <div className="flex items-center gap-3 mt-2 text-xs text-[var(--color-text-tertiary)]">
@ -259,7 +259,7 @@ export default function ShiftNotesWidget({
{/* View All Link */} {/* View All Link */}
{expanded && notes.length > 0 && ( {expanded && notes.length > 0 && (
<div className="p-3 border-t border-slate-200 dark:border-slate-700 text-center"> <div className="p-3 border-t border-[var(--color-border-default)] text-center">
<button className="text-sm text-indigo-600 hover:text-indigo-700 font-medium"> <button className="text-sm text-indigo-600 hover:text-indigo-700 font-medium">
View All Notes View All Notes
</button> </button>

View file

@ -28,8 +28,8 @@ export default function CompleteTaskModal({ task, onClose, onSuccess }: Complete
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-fade-in"> <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-fade-in">
<div className="bg-white dark:bg-slate-900 w-full max-w-md rounded-2xl shadow-2xl overflow-hidden animate-scale-in"> <div className="bg-[var(--color-bg-elevated)] w-full max-w-md rounded-2xl shadow-2xl overflow-hidden animate-scale-in">
<div className="p-6 border-b border-slate-200 dark:border-slate-700 flex justify-between items-center"> <div className="p-6 border-b border-[var(--color-border-default)] flex justify-between items-center">
<h2 className="text-xl font-bold dark:text-white flex items-center gap-2"> <h2 className="text-xl font-bold dark:text-white flex items-center gap-2">
<CheckCircle className="text-[var(--color-primary)]" /> <CheckCircle className="text-[var(--color-primary)]" />
Complete Task Complete Task
@ -40,7 +40,7 @@ export default function CompleteTaskModal({ task, onClose, onSuccess }: Complete
</div> </div>
<form onSubmit={handleSubmit} className="p-6 space-y-4"> <form onSubmit={handleSubmit} className="p-6 space-y-4">
<div className="bg-slate-50 dark:bg-slate-800 p-4 rounded-xl border border-slate-200 dark:border-slate-700"> <div className="bg-[var(--color-bg-tertiary)] p-4 rounded-xl border border-[var(--color-border-default)]">
<h3 className="font-bold text-[var(--color-text-primary)]">{task.title}</h3> <h3 className="font-bold text-[var(--color-text-primary)]">{task.title}</h3>
{task.description && ( {task.description && (
<p className="text-sm text-[var(--color-text-tertiary)] mt-1">{task.description}</p> <p className="text-sm text-[var(--color-text-tertiary)] mt-1">{task.description}</p>
@ -48,13 +48,13 @@ export default function CompleteTaskModal({ task, onClose, onSuccess }: Complete
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2"> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">
Completion Notes (Optional) Completion Notes (Optional)
</label> </label>
<textarea <textarea
value={notes} value={notes}
onChange={(e) => setNotes(e.target.value)} onChange={(e) => setNotes(e.target.value)}
className="w-full p-3 rounded-lg bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 dark:text-white h-32 resize-none" className="w-full p-3 rounded-lg bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] dark:text-white h-32 resize-none"
placeholder="e.g. Used 50gal instead of 40gal..." placeholder="e.g. Used 50gal instead of 40gal..."
/> />
</div> </div>

View file

@ -115,9 +115,9 @@ export default function CreateTaskModal({
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-in fade-in duration-200"> <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-in fade-in duration-200">
<div className="bg-white dark:bg-slate-900 w-full max-w-lg rounded-2xl shadow-xl overflow-hidden flex flex-col max-h-[90vh]"> <div className="bg-[var(--color-bg-elevated)] w-full max-w-lg rounded-2xl shadow-xl overflow-hidden flex flex-col max-h-[90vh]">
<div className="p-4 border-b border-slate-100 dark:border-slate-800 flex justify-between items-center"> <div className="p-4 border-b border-[var(--color-border-subtle)] flex justify-between items-center">
<h2 className="text-xl font-bold text-[var(--color-text-primary)]">New Task</h2> <h2 className="text-xl font-bold text-[var(--color-text-primary)]">New Task</h2>
<button onClick={onClose} className="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-full"> <button onClick={onClose} className="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-full">
<X size={20} className="text-[var(--color-text-tertiary)]" /> <X size={20} className="text-[var(--color-text-tertiary)]" />
@ -127,14 +127,14 @@ export default function CreateTaskModal({
<form onSubmit={handleSubmit} className="flex-1 overflow-y-auto p-4 space-y-4"> <form onSubmit={handleSubmit} className="flex-1 overflow-y-auto p-4 space-y-4">
{/* Template Selection */} {/* Template Selection */}
<div className="bg-slate-50 dark:bg-slate-800/50 p-3 rounded-xl border border-dashed border-slate-300 dark:border-slate-700"> <div className="bg-[var(--color-bg-tertiary)]/50 p-3 rounded-xl border border-dashed border-slate-300 dark:border-slate-700">
<label className="block text-xs font-bold text-[var(--color-text-tertiary)] uppercase tracking-wider mb-2 flex items-center gap-2"> <label className="block text-xs font-bold text-[var(--color-text-tertiary)] uppercase tracking-wider mb-2 flex items-center gap-2">
<FileText size={14} /> Quick Fill from Template <FileText size={14} /> Quick Fill from Template
</label> </label>
<select <select
value={selectedTemplateId} value={selectedTemplateId}
onChange={(e) => handleTemplateChange(e.target.value)} onChange={(e) => handleTemplateChange(e.target.value)}
className="w-full p-2 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-lg text-sm text-[var(--color-text-primary)]" className="w-full p-2 bg-[var(--color-bg-elevated)] border border-[var(--color-border-default)] rounded-lg text-sm text-[var(--color-text-primary)]"
> >
<option value="">-- Start Blank --</option> <option value="">-- Start Blank --</option>
{templates.map(t => ( {templates.map(t => (
@ -144,23 +144,23 @@ export default function CreateTaskModal({
</div> </div>
<div> <div>
<label className="block text-sm font-bold text-slate-700 dark:text-slate-300 mb-1">Task Title *</label> <label className="block text-sm font-bold text-[var(--color-text-secondary)] mb-1">Task Title *</label>
<input <input
required required
value={title} value={title}
onChange={e => setTitle(e.target.value)} onChange={e => setTitle(e.target.value)}
placeholder="e.g. Water Room A" placeholder="e.g. Water Room A"
className="w-full p-3 bg-slate-50 dark:bg-slate-800 border-none rounded-xl text-[var(--color-text-primary)] focus:ring-2 focus:ring-emerald-500" className="w-full p-3 bg-[var(--color-bg-tertiary)] border-none rounded-xl text-[var(--color-text-primary)] focus:ring-2 focus:ring-emerald-500"
/> />
</div> </div>
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Priority</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-1">Priority</label>
<select <select
value={priority} value={priority}
onChange={e => setPriority(e.target.value)} onChange={e => setPriority(e.target.value)}
className="w-full p-3 bg-slate-50 dark:bg-slate-800 border-none rounded-xl text-[var(--color-text-primary)]" className="w-full p-3 bg-[var(--color-bg-tertiary)] border-none rounded-xl text-[var(--color-text-primary)]"
> >
<option value="LOW">Low</option> <option value="LOW">Low</option>
<option value="MEDIUM">Medium</option> <option value="MEDIUM">Medium</option>
@ -169,25 +169,25 @@ export default function CreateTaskModal({
</select> </select>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Due Date</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-1">Due Date</label>
<input <input
type="date" type="date"
required required
value={dueDate} value={dueDate}
onChange={e => setDueDate(e.target.value)} onChange={e => setDueDate(e.target.value)}
className="w-full p-3 bg-slate-50 dark:bg-slate-800 border-none rounded-xl text-[var(--color-text-primary)]" className="w-full p-3 bg-[var(--color-bg-tertiary)] border-none rounded-xl text-[var(--color-text-primary)]"
/> />
</div> </div>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1 flex items-center gap-2"> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-1 flex items-center gap-2">
<User size={16} /> Assign To <User size={16} /> Assign To
</label> </label>
<select <select
value={assigneeId} value={assigneeId}
onChange={e => setAssigneeId(e.target.value)} onChange={e => setAssigneeId(e.target.value)}
className="w-full p-3 bg-slate-50 dark:bg-slate-800 border-none rounded-xl text-[var(--color-text-primary)]" className="w-full p-3 bg-[var(--color-bg-tertiary)] border-none rounded-xl text-[var(--color-text-primary)]"
> >
<option value="">-- Unassigned --</option> <option value="">-- Unassigned --</option>
{users.map(u => ( {users.map(u => (
@ -198,13 +198,13 @@ export default function CreateTaskModal({
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1 flex items-center gap-2"> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-1 flex items-center gap-2">
<MapPin size={16} /> Room (Optional) <MapPin size={16} /> Room (Optional)
</label> </label>
<select <select
value={roomId} value={roomId}
onChange={e => setRoomId(e.target.value)} onChange={e => setRoomId(e.target.value)}
className="w-full p-3 bg-slate-50 dark:bg-slate-800 border-none rounded-xl text-[var(--color-text-primary)]" className="w-full p-3 bg-[var(--color-bg-tertiary)] border-none rounded-xl text-[var(--color-text-primary)]"
> >
<option value="">-- None --</option> <option value="">-- None --</option>
{rooms.map(r => ( {rooms.map(r => (
@ -213,13 +213,13 @@ export default function CreateTaskModal({
</select> </select>
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1 flex items-center gap-2"> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-1 flex items-center gap-2">
<Box size={16} /> Batch (Optional) <Box size={16} /> Batch (Optional)
</label> </label>
<select <select
value={batchId} value={batchId}
onChange={e => setBatchId(e.target.value)} onChange={e => setBatchId(e.target.value)}
className="w-full p-3 bg-slate-50 dark:bg-slate-800 border-none rounded-xl text-[var(--color-text-primary)]" className="w-full p-3 bg-[var(--color-bg-tertiary)] border-none rounded-xl text-[var(--color-text-primary)]"
> >
<option value="">-- None --</option> <option value="">-- None --</option>
{batches.map(b => ( {batches.map(b => (
@ -230,13 +230,13 @@ export default function CreateTaskModal({
</div> </div>
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">Description / Notes</label> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-1">Description / Notes</label>
<textarea <textarea
value={description} value={description}
onChange={e => setDescription(e.target.value)} onChange={e => setDescription(e.target.value)}
rows={3} rows={3}
placeholder="Details about the task..." placeholder="Details about the task..."
className="w-full p-3 bg-slate-50 dark:bg-slate-800 border-none rounded-xl text-[var(--color-text-primary)] resize-none" className="w-full p-3 bg-[var(--color-bg-tertiary)] border-none rounded-xl text-[var(--color-text-primary)] resize-none"
/> />
</div> </div>

View file

@ -42,7 +42,7 @@ export default function TasksDueTodayWidget({ userId }: TasksDueTodayWidgetProps
if (tasks.length === 0) return null; if (tasks.length === 0) return null;
return ( return (
<div className="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700 p-6"> <div className="bg-[var(--color-bg-elevated)] rounded-2xl shadow-sm border border-[var(--color-border-default)] p-6">
<div className="flex justify-between items-center mb-4"> <div className="flex justify-between items-center mb-4">
<h3 className="text-lg font-bold text-[var(--color-text-primary)] flex items-center gap-2"> <h3 className="text-lg font-bold text-[var(--color-text-primary)] flex items-center gap-2">
<List className="text-[var(--color-primary)]" /> <List className="text-[var(--color-primary)]" />

View file

@ -110,7 +110,7 @@ export function QuickLogBar({ batchId, batchName, onSuccess, compact = false }:
} }
return ( return (
<div className="flex items-center gap-1 bg-slate-100 dark:bg-slate-700 rounded-lg p-1"> <div className="flex items-center gap-1 bg-[var(--color-bg-tertiary)] rounded-lg p-1">
{QUICK_ACTIONS.map(action => { {QUICK_ACTIONS.map(action => {
const Icon = action.icon; const Icon = action.icon;
const isLoading = loading === action.type; const isLoading = loading === action.type;

View file

@ -70,10 +70,10 @@ export default function TouchPointModal({ isOpen, onClose, preselectedBatchId, o
return ( return (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-in fade-in duration-200"> <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm animate-in fade-in duration-200">
<div className="bg-white dark:bg-slate-900 w-full max-w-md rounded-2xl shadow-xl overflow-hidden flex flex-col max-h-[90vh]"> <div className="bg-[var(--color-bg-elevated)] w-full max-w-md rounded-2xl shadow-xl overflow-hidden flex flex-col max-h-[90vh]">
{/* Header */} {/* Header */}
<div className="p-4 border-b border-slate-100 dark:border-slate-800 flex justify-between items-center"> <div className="p-4 border-b border-[var(--color-border-subtle)] flex justify-between items-center">
<h2 className="text-xl font-bold text-[var(--color-text-primary)]">Log Plant Touch</h2> <h2 className="text-xl font-bold text-[var(--color-text-primary)]">Log Plant Touch</h2>
<button onClick={onClose} className="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-full"> <button onClick={onClose} className="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-full">
<X size={20} className="text-[var(--color-text-tertiary)]" /> <X size={20} className="text-[var(--color-text-tertiary)]" />
@ -86,13 +86,13 @@ export default function TouchPointModal({ isOpen, onClose, preselectedBatchId, o
{/* Batch Selection (if not preselected) */} {/* Batch Selection (if not preselected) */}
{!preselectedBatchId && ( {!preselectedBatchId && (
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2"> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">
Select Batch Select Batch
</label> </label>
<select <select
value={selectedBatchId} value={selectedBatchId}
onChange={(e) => setSelectedBatchId(e.target.value)} onChange={(e) => setSelectedBatchId(e.target.value)}
className="w-full p-3 bg-slate-50 dark:bg-slate-800 border-none rounded-xl text-[var(--color-text-primary)] focus:ring-2 focus:ring-emerald-500" className="w-full p-3 bg-[var(--color-bg-tertiary)] border-none rounded-xl text-[var(--color-text-primary)] focus:ring-2 focus:ring-emerald-500"
> >
<option value="">-- Select Batch --</option> <option value="">-- Select Batch --</option>
{batches.map(b => ( {batches.map(b => (
@ -104,7 +104,7 @@ export default function TouchPointModal({ isOpen, onClose, preselectedBatchId, o
{/* Touch Type Grid */} {/* Touch Type Grid */}
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2"> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">
Action Type Action Type
</label> </label>
<div className="grid grid-cols-3 gap-3"> <div className="grid grid-cols-3 gap-3">
@ -113,8 +113,8 @@ export default function TouchPointModal({ isOpen, onClose, preselectedBatchId, o
key={type} key={type}
onClick={() => setSelectedType(type)} onClick={() => setSelectedType(type)}
className={`flex flex-col items-center justify-center p-3 rounded-xl gap-2 transition-all ${selectedType === type className={`flex flex-col items-center justify-center p-3 rounded-xl gap-2 transition-all ${selectedType === type
? 'ring-2 ring-emerald-500 ring-offset-2 dark:ring-offset-slate-900 bg-slate-50 dark:bg-slate-800' ? 'ring-2 ring-emerald-500 ring-offset-2 ring-offset-[var(--color-bg-primary)] bg-[var(--color-bg-tertiary)]'
: 'hover:bg-slate-50 dark:hover:bg-slate-800 border border-slate-100 dark:border-slate-800' : 'hover:bg-[var(--color-bg-tertiary)] border border-[var(--color-border-subtle)]'
}`} }`}
> >
<div className={`p-2 rounded-full ${color}`}> <div className={`p-2 rounded-full ${color}`}>
@ -128,19 +128,19 @@ export default function TouchPointModal({ isOpen, onClose, preselectedBatchId, o
{/* Notes */} {/* Notes */}
<div> <div>
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2"> <label className="block text-sm font-medium text-[var(--color-text-secondary)] mb-2">
Notes Notes
</label> </label>
<textarea <textarea
value={notes} value={notes}
onChange={(e) => setNotes(e.target.value)} onChange={(e) => setNotes(e.target.value)}
placeholder="Details about the action..." placeholder="Details about the action..."
className="w-full p-3 bg-slate-50 dark:bg-slate-800 border-none rounded-xl text-[var(--color-text-primary)] focus:ring-2 focus:ring-emerald-500 min-h-[100px] resize-none" className="w-full p-3 bg-[var(--color-bg-tertiary)] border-none rounded-xl text-[var(--color-text-primary)] focus:ring-2 focus:ring-emerald-500 min-h-[100px] resize-none"
/> />
</div> </div>
{/* Photo Placeholder */} {/* Photo Placeholder */}
<button className="w-full p-4 border-2 border-dashed border-slate-200 dark:border-slate-700 rounded-xl text-[var(--color-text-tertiary)] hover:bg-slate-50 dark:hover:bg-slate-800 flex items-center justify-center gap-2"> <button className="w-full p-4 border-2 border-dashed border-[var(--color-border-default)] rounded-xl text-[var(--color-text-tertiary)] hover:bg-[var(--color-bg-tertiary)] flex items-center justify-center gap-2">
<Camera size={20} /> <Camera size={20} />
<span>Add Photo (Optional)</span> <span>Add Photo (Optional)</span>
</button> </button>
@ -148,7 +148,7 @@ export default function TouchPointModal({ isOpen, onClose, preselectedBatchId, o
</div> </div>
{/* Footer */} {/* Footer */}
<div className="p-4 border-t border-slate-100 dark:border-slate-800"> <div className="p-4 border-t border-[var(--color-border-subtle)]">
<button <button
onClick={handleSubmit} onClick={handleSubmit}
disabled={!selectedBatchId || !selectedType || isLoading} disabled={!selectedBatchId || !selectedType || isLoading}

View file

@ -76,7 +76,7 @@ export function BottomSheet({ isOpen, onClose, title, children, height = 'auto'
{/* Sheet */} {/* Sheet */}
<div <div
ref={sheetRef} ref={sheetRef}
className={`absolute bottom-0 left-0 right-0 bg-white dark:bg-slate-800 rounded-t-2xl shadow-xl transition-transform duration-200 ${heightClasses[height]} ${isClosing ? 'translate-y-full' : 'translate-y-0'}`} className={`absolute bottom-0 left-0 right-0 bg-[var(--color-bg-elevated)] rounded-t-2xl shadow-xl transition-transform duration-200 ${heightClasses[height]} ${isClosing ? 'translate-y-full' : 'translate-y-0'}`}
style={{ transform: isClosing ? 'translateY(100%)' : `translateY(${dragOffset}px)` }} style={{ transform: isClosing ? 'translateY(100%)' : `translateY(${dragOffset}px)` }}
> >
{/* Drag Handle */} {/* Drag Handle */}
@ -91,7 +91,7 @@ export function BottomSheet({ isOpen, onClose, title, children, height = 'auto'
{/* Header */} {/* Header */}
{title && ( {title && (
<div className="flex items-center justify-between px-4 pb-4 border-b border-slate-200 dark:border-slate-700"> <div className="flex items-center justify-between px-4 pb-4 border-b border-[var(--color-border-default)]">
<h3 className="text-lg font-bold text-[var(--color-text-primary)]">{title}</h3> <h3 className="text-lg font-bold text-[var(--color-text-primary)]">{title}</h3>
<button <button
onClick={handleClose} onClick={handleClose}
@ -128,9 +128,9 @@ export function ResponsiveModal({ isOpen, onClose, title, children, className =
{/* Desktop Modal */} {/* Desktop Modal */}
<div className="hidden md:flex fixed inset-0 z-[100] items-center justify-center p-4"> <div className="hidden md:flex fixed inset-0 z-[100] items-center justify-center p-4">
<div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={onClose} /> <div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={onClose} />
<div className={`relative bg-white dark:bg-slate-800 rounded-2xl shadow-2xl max-w-lg w-full max-h-[85vh] overflow-hidden animate-scale-in ${className}`}> <div className={`relative bg-[var(--color-bg-elevated)] rounded-2xl shadow-2xl max-w-lg w-full max-h-[85vh] overflow-hidden animate-scale-in ${className}`}>
{title && ( {title && (
<div className="flex items-center justify-between p-4 border-b border-slate-200 dark:border-slate-700"> <div className="flex items-center justify-between p-4 border-b border-[var(--color-border-default)]">
<h3 className="text-lg font-bold text-[var(--color-text-primary)]">{title}</h3> <h3 className="text-lg font-bold text-[var(--color-text-primary)]">{title}</h3>
<button <button
onClick={onClose} onClick={onClose}

View file

@ -101,8 +101,8 @@ export function CommandPalette() {
return ( return (
<div className="fixed inset-0 z-[100] flex items-start justify-center pt-[15vh] p-4"> <div className="fixed inset-0 z-[100] flex items-start justify-center pt-[15vh] p-4">
<div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={() => setIsOpen(false)} /> <div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={() => setIsOpen(false)} />
<div className="relative w-full max-w-lg bg-white dark:bg-slate-800 rounded-2xl shadow-2xl overflow-hidden animate-scale-in"> <div className="relative w-full max-w-lg bg-[var(--color-bg-elevated)] rounded-2xl shadow-2xl overflow-hidden animate-scale-in">
<div className="flex items-center gap-3 p-4 border-b border-slate-200 dark:border-slate-700"> <div className="flex items-center gap-3 p-4 border-b border-[var(--color-border-default)]">
<Search size={20} className="text-[var(--color-text-tertiary)]" /> <Search size={20} className="text-[var(--color-text-tertiary)]" />
<input <input
type="text" type="text"
@ -112,7 +112,7 @@ export function CommandPalette() {
className="flex-1 bg-transparent text-[var(--color-text-primary)] placeholder-slate-400 outline-none text-lg" className="flex-1 bg-transparent text-[var(--color-text-primary)] placeholder-slate-400 outline-none text-lg"
autoFocus autoFocus
/> />
<kbd className="hidden sm:inline-flex px-2 py-1 text-xs font-mono bg-slate-100 dark:bg-slate-700 text-[var(--color-text-tertiary)] rounded">ESC</kbd> <kbd className="hidden sm:inline-flex px-2 py-1 text-xs font-mono bg-[var(--color-bg-tertiary)] text-[var(--color-text-tertiary)] rounded">ESC</kbd>
</div> </div>
<div className="max-h-80 overflow-y-auto p-2"> <div className="max-h-80 overflow-y-auto p-2">
{filteredCommands.length === 0 ? ( {filteredCommands.length === 0 ? (
@ -130,7 +130,7 @@ export function CommandPalette() {
<button <button
key={cmd.id} key={cmd.id}
onClick={() => { cmd.action(); setIsOpen(false); }} onClick={() => { cmd.action(); setIsOpen(false); }}
className={`w-full flex items-center gap-3 px-3 py-2 rounded-lg text-left transition-colors ${isSelected ? 'bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300' : 'text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700'}`} className={`w-full flex items-center gap-3 px-3 py-2 rounded-lg text-left transition-colors ${isSelected ? 'bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300' : 'text-[var(--color-text-secondary)] hover:bg-slate-100 dark:hover:bg-slate-700'}`}
> >
<Icon size={18} /> <Icon size={18} />
<span>{cmd.label}</span> <span>{cmd.label}</span>
@ -150,7 +150,7 @@ export function CommandPalette() {
<button <button
key={cmd.id} key={cmd.id}
onClick={() => { cmd.action(); setIsOpen(false); }} onClick={() => { cmd.action(); setIsOpen(false); }}
className={`w-full flex items-center gap-3 px-3 py-2 rounded-lg text-left transition-colors ${isSelected ? 'bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300' : 'text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700'}`} className={`w-full flex items-center gap-3 px-3 py-2 rounded-lg text-left transition-colors ${isSelected ? 'bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300' : 'text-[var(--color-text-secondary)] hover:bg-slate-100 dark:hover:bg-slate-700'}`}
> >
<Icon size={18} /> <Icon size={18} />
<span>{cmd.label}</span> <span>{cmd.label}</span>
@ -170,7 +170,7 @@ export function CommandPalette() {
<button <button
key={cmd.id} key={cmd.id}
onClick={() => { cmd.action(); setIsOpen(false); }} onClick={() => { cmd.action(); setIsOpen(false); }}
className={`w-full flex items-center gap-3 px-3 py-2 rounded-lg text-left transition-colors ${isSelected ? 'bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-300' : 'text-slate-700 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-700'}`} className={`w-full flex items-center gap-3 px-3 py-2 rounded-lg text-left transition-colors ${isSelected ? 'bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-300' : 'text-[var(--color-text-secondary)] hover:bg-slate-100 dark:hover:bg-slate-700'}`}
> >
<Icon size={18} /> <Icon size={18} />
<span>{cmd.label}</span> <span>{cmd.label}</span>
@ -182,15 +182,15 @@ export function CommandPalette() {
</> </>
)} )}
</div> </div>
<div className="border-t border-slate-200 dark:border-slate-700 p-3 flex items-center justify-between text-xs text-[var(--color-text-tertiary)]"> <div className="border-t border-[var(--color-border-default)] p-3 flex items-center justify-between text-xs text-[var(--color-text-tertiary)]">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<span className="flex items-center gap-1"> <span className="flex items-center gap-1">
<kbd className="px-1.5 py-0.5 bg-slate-100 dark:bg-slate-700 rounded"></kbd> <kbd className="px-1.5 py-0.5 bg-[var(--color-bg-tertiary)] rounded"></kbd>
<kbd className="px-1.5 py-0.5 bg-slate-100 dark:bg-slate-700 rounded"></kbd> <kbd className="px-1.5 py-0.5 bg-[var(--color-bg-tertiary)] rounded"></kbd>
to navigate to navigate
</span> </span>
<span className="flex items-center gap-1"> <span className="flex items-center gap-1">
<kbd className="px-1.5 py-0.5 bg-slate-100 dark:bg-slate-700 rounded"></kbd> <kbd className="px-1.5 py-0.5 bg-[var(--color-bg-tertiary)] rounded"></kbd>
to select to select
</span> </span>
</div> </div>

View file

@ -43,7 +43,7 @@ export function DataTable<T extends { id: string | number }>({
</div> </div>
<div> <div>
{Array.from({ length: 5 }).map((_, i) => ( {Array.from({ length: 5 }).map((_, i) => (
<div key={i} className="px-4 py-4 border-b border-slate-100 dark:border-slate-800/50 flex items-center gap-4"> <div key={i} className="px-4 py-4 border-b border-[var(--color-border-subtle)]/50 flex items-center gap-4">
<div className="h-4 w-1/4 bg-slate-100 dark:bg-slate-800 rounded animate-pulse" /> <div className="h-4 w-1/4 bg-slate-100 dark:bg-slate-800 rounded animate-pulse" />
<div className="h-4 w-1/4 bg-slate-100 dark:bg-slate-800 rounded animate-pulse" /> <div className="h-4 w-1/4 bg-slate-100 dark:bg-slate-800 rounded animate-pulse" />
<div className="h-4 w-1/4 bg-slate-100 dark:bg-slate-800 rounded animate-pulse" /> <div className="h-4 w-1/4 bg-slate-100 dark:bg-slate-800 rounded animate-pulse" />
@ -107,7 +107,7 @@ export function DataTable<T extends { id: string | number }>({
<td <td
key={String(col.key) + idx} key={String(col.key) + idx}
className={cn( className={cn(
"px-4 py-3 align-middle text-slate-700 dark:text-slate-300", "px-4 py-3 align-middle text-[var(--color-text-secondary)]",
col.hideOnMobile && "hidden md:table-cell", col.hideOnMobile && "hidden md:table-cell",
col.className col.className
)} )}

View file

@ -66,7 +66,7 @@ export function SectionHeader({ icon: Icon, title, count, accent = 'default' }:
{title} {title}
</h3> </h3>
{count !== undefined && ( {count !== undefined && (
<span className="px-1.5 py-0.5 rounded-full bg-slate-100 dark:bg-slate-800 text-[10px] font-bold text-[var(--color-text-tertiary)] border border-slate-200 dark:border-slate-700/50"> <span className="px-1.5 py-0.5 rounded-full bg-slate-100 dark:bg-slate-800 text-[10px] font-bold text-[var(--color-text-tertiary)] border border-[var(--color-border-default)]/50">
{count} {count}
</span> </span>
)} )}
@ -85,7 +85,7 @@ interface EmptyStateProps {
export function EmptyState({ icon: Icon, title, description, action }: EmptyStateProps) { export function EmptyState({ icon: Icon, title, description, action }: EmptyStateProps) {
return ( return (
<div className="flex flex-col items-center justify-center py-20 px-4 text-center border-2 border-dashed border-[var(--color-border-subtle)] rounded-2xl bg-slate-50/30 dark:bg-slate-900/10"> <div className="flex flex-col items-center justify-center py-20 px-4 text-center border-2 border-dashed border-[var(--color-border-subtle)] rounded-2xl bg-slate-50/30 dark:bg-slate-900/10">
<div className="w-16 h-16 bg-white dark:bg-slate-900 rounded-2xl flex items-center justify-center shadow-xl mb-6 ring-1 ring-slate-200 dark:ring-slate-800"> <div className="w-16 h-16 bg-[var(--color-bg-elevated)] rounded-2xl flex items-center justify-center shadow-xl mb-6 ring-1 ring-slate-200 dark:ring-slate-800">
<Icon size={32} className="text-slate-300 dark:text-slate-700" /> <Icon size={32} className="text-slate-300 dark:text-slate-700" />
</div> </div>
<h3 className="text-base font-bold text-[var(--color-text-primary)]">{title}</h3> <h3 className="text-base font-bold text-[var(--color-text-primary)]">{title}</h3>
@ -139,7 +139,7 @@ export function MetricCard({ icon: Icon, label, value, subtitle, accent = 'defau
<p className="text-[11px] font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest">{label}</p> <p className="text-[11px] font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest">{label}</p>
</div> </div>
{subtitle && ( {subtitle && (
<div className="mt-4 pt-4 border-t border-slate-100 dark:border-slate-800/50"> <div className="mt-4 pt-4 border-t border-[var(--color-border-subtle)]/50">
<p className="text-[10px] text-[var(--color-text-tertiary)] dark:text-[var(--color-text-tertiary)]">{subtitle}</p> <p className="text-[10px] text-[var(--color-text-tertiary)] dark:text-[var(--color-text-tertiary)]">{subtitle}</p>
</div> </div>
)} )}

View file

@ -138,7 +138,7 @@ export default function PhotoUpload({
e.stopPropagation(); e.stopPropagation();
fileInputRef.current?.click(); fileInputRef.current?.click();
}} }}
className="flex items-center gap-1 px-3 py-2 bg-slate-100 dark:bg-slate-700 rounded-lg text-sm hover:bg-slate-200 dark:hover:bg-slate-600 transition-colors" className="flex items-center gap-1 px-3 py-2 bg-[var(--color-bg-tertiary)] rounded-lg text-sm hover:bg-slate-200 dark:hover:bg-slate-600 transition-colors"
> >
<Upload size={16} /> <Upload size={16} />
Browse Browse

View file

@ -81,7 +81,7 @@ export function PullToRefresh({ onRefresh, children, disabled = false }: PullToR
opacity: progress opacity: progress
}} }}
> >
<div className={`p-2 rounded-full bg-white dark:bg-slate-800 shadow-lg ${refreshing ? 'animate-spin' : ''}`}> <div className={`p-2 rounded-full bg-[var(--color-bg-elevated)] shadow-lg ${refreshing ? 'animate-spin' : ''}`}>
<RefreshCw size={20} className="text-[var(--color-primary)]" /> <RefreshCw size={20} className="text-[var(--color-primary)]" />
</div> </div>
</div> </div>

View file

@ -12,7 +12,7 @@ export function Skeleton({ className = '' }: SkeletonProps) {
export function SkeletonCard() { export function SkeletonCard() {
return ( return (
<div className="bg-white dark:bg-slate-800 p-4 rounded-xl border border-slate-200 dark:border-slate-700"> <div className="bg-[var(--color-bg-elevated)] p-4 rounded-xl border border-[var(--color-border-default)]">
<div className="flex justify-between items-start mb-3"> <div className="flex justify-between items-start mb-3">
<div className="space-y-2"> <div className="space-y-2">
<Skeleton className="h-5 w-32" /> <Skeleton className="h-5 w-32" />
@ -30,8 +30,8 @@ export function SkeletonCard() {
export function SkeletonTable({ rows = 5 }: { rows?: number }) { export function SkeletonTable({ rows = 5 }: { rows?: number }) {
return ( return (
<div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 overflow-hidden"> <div className="bg-[var(--color-bg-elevated)] rounded-xl border border-[var(--color-border-default)] overflow-hidden">
<div className="p-4 border-b border-slate-200 dark:border-slate-700"> <div className="p-4 border-b border-[var(--color-border-default)]">
<Skeleton className="h-6 w-40" /> <Skeleton className="h-6 w-40" />
</div> </div>
<div className="divide-y divide-slate-100 dark:divide-slate-700"> <div className="divide-y divide-slate-100 dark:divide-slate-700">
@ -50,7 +50,7 @@ export function SkeletonTable({ rows = 5 }: { rows?: number }) {
export function SkeletonMetricCard() { export function SkeletonMetricCard() {
return ( return (
<div className="bg-white dark:bg-slate-800 p-4 rounded-xl border border-slate-200 dark:border-slate-700"> <div className="bg-[var(--color-bg-elevated)] p-4 rounded-xl border border-[var(--color-border-default)]">
<Skeleton className="h-10 w-10 rounded-lg mb-3" /> <Skeleton className="h-10 w-10 rounded-lg mb-3" />
<Skeleton className="h-8 w-12 mb-1" /> <Skeleton className="h-8 w-12 mb-1" />
<Skeleton className="h-3 w-24" /> <Skeleton className="h-3 w-24" />
@ -62,7 +62,7 @@ export function SkeletonList({ items = 5 }: { items?: number }) {
return ( return (
<div className="space-y-3"> <div className="space-y-3">
{Array.from({ length: items }).map((_, i) => ( {Array.from({ length: items }).map((_, i) => (
<div key={i} className="bg-white dark:bg-slate-800 p-4 rounded-xl border border-slate-200 dark:border-slate-700 flex items-center gap-4"> <div key={i} className="bg-[var(--color-bg-elevated)] p-4 rounded-xl border border-[var(--color-border-default)] flex items-center gap-4">
<Skeleton className="h-10 w-10 rounded-full" /> <Skeleton className="h-10 w-10 rounded-full" />
<div className="flex-1 space-y-2"> <div className="flex-1 space-y-2">
<Skeleton className="h-4 w-3/4" /> <Skeleton className="h-4 w-3/4" />

View file

@ -145,7 +145,7 @@ export function SwipeableRow({
transform: `translateX(${offset}px)`, transform: `translateX(${offset}px)`,
transition: isSwiping ? 'none' : 'transform 0.2s ease-out' transition: isSwiping ? 'none' : 'transform 0.2s ease-out'
}} }}
className="relative bg-white dark:bg-slate-800" className="relative bg-[var(--color-bg-elevated)]"
> >
{children} {children}
</div> </div>

View file

@ -271,10 +271,10 @@ export default function VisitorBadge({
</div> </div>
{/* Content */} {/* Content */}
<div className="bg-white dark:bg-slate-800 p-6"> <div className="bg-[var(--color-bg-elevated)] p-6">
{/* Photo + Name */} {/* Photo + Name */}
<div className="flex flex-col items-center mb-4"> <div className="flex flex-col items-center mb-4">
<div className="w-20 h-20 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center mb-3 overflow-hidden"> <div className="w-20 h-20 rounded-full bg-[var(--color-bg-tertiary)] flex items-center justify-center mb-3 overflow-hidden">
{photoUrl ? ( {photoUrl ? (
<img src={photoUrl} alt={name} className="w-full h-full object-cover" /> <img src={photoUrl} alt={name} className="w-full h-full object-cover" />
) : ( ) : (
@ -358,7 +358,7 @@ export default function VisitorBadge({
<select <select
value={selectedSize} value={selectedSize}
onChange={(e) => setSelectedSize(e.target.value as BadgeSize)} onChange={(e) => setSelectedSize(e.target.value as BadgeSize)}
className="appearance-none px-3 py-2 pr-8 rounded-lg border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-800 text-sm cursor-pointer" className="appearance-none px-3 py-2 pr-8 rounded-lg border border-slate-200 dark:border-slate-600 bg-[var(--color-bg-elevated)] text-sm cursor-pointer"
> >
<option value="standard">Standard (3.5" x 5")</option> <option value="standard">Standard (3.5" x 5")</option>
<option value="large">Large (3.5" x 6")</option> <option value="large">Large (3.5" x 6")</option>
@ -411,7 +411,7 @@ export function BadgePrintQueue({
const doneCount = queue.filter(b => b.status === 'done').length; const doneCount = queue.filter(b => b.status === 'done').length;
return ( return (
<div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4"> <div className="bg-[var(--color-bg-elevated)] rounded-xl border border-[var(--color-border-default)] p-4">
<div className="flex items-center justify-between mb-4"> <div className="flex items-center justify-between mb-4">
<div> <div>
<h3 className="font-medium text-[var(--color-text-primary)]">Print Queue</h3> <h3 className="font-medium text-[var(--color-text-primary)]">Print Queue</h3>

View file

@ -39,15 +39,15 @@
/* Light mode text */ /* Light mode text */
--color-text-primary: #0F172A; --color-text-primary: #0F172A;
--color-text-secondary: #475569; --color-text-secondary: #334155;
--color-text-tertiary: #94A3B8; --color-text-tertiary: #64748B;
--color-text-quaternary: #CBD5E1; --color-text-quaternary: #94A3B8;
--color-text-inverse: #F9FAFB; --color-text-inverse: #F9FAFB;
/* Light mode borders */ /* Light mode borders */
--color-border-default: #E2E8F0; --color-border-default: #CBD5E1;
--color-border-subtle: #F1F5F9; --color-border-subtle: #E2E8F0;
--color-border-strong: #94A3B8; --color-border-strong: #64748B;
/* Primary accent (Cultivation Green) */ /* Primary accent (Cultivation Green) */
--color-primary: #4ADE80; --color-primary: #4ADE80;
@ -115,17 +115,17 @@
--color-bg-tertiary: #151C30; --color-bg-tertiary: #151C30;
--color-bg-elevated: #11182A; --color-bg-elevated: #11182A;
/* Text */ /* Text - improved contrast */
--color-text-primary: #F9FAFB; --color-text-primary: #F8FAFC;
--color-text-secondary: #9CA3AF; --color-text-secondary: #CBD5E1;
--color-text-tertiary: #6B7280; --color-text-tertiary: #94A3B8;
--color-text-quaternary: #374151; --color-text-quaternary: #64748B;
--color-text-inverse: #020617; --color-text-inverse: #0F172A;
/* Borders */ /* Borders - more visible */
--color-border-default: #1E293B; --color-border-default: #334155;
--color-border-subtle: #151C30; --color-border-subtle: #1E293B;
--color-border-strong: #334155; --color-border-strong: #475569;
/* Primary (Emerald Green) */ /* Primary (Emerald Green) */
--color-primary: #4ADE80; --color-primary: #4ADE80;

View file

@ -108,7 +108,7 @@ export default function AuditLogPage() {
<div className="w-5 h-5 rounded bg-slate-100 dark:bg-slate-800 flex items-center justify-center border border-[var(--color-border-subtle)]"> <div className="w-5 h-5 rounded bg-slate-100 dark:bg-slate-800 flex items-center justify-center border border-[var(--color-border-subtle)]">
<User size={10} className="text-[var(--color-text-tertiary)]" /> <User size={10} className="text-[var(--color-text-tertiary)]" />
</div> </div>
<span className="text-xs font-bold text-slate-700 dark:text-slate-300 uppercase tracking-widest"> <span className="text-xs font-bold text-[var(--color-text-secondary)] uppercase tracking-widest">
{log.userName || 'SYSTEM_CORE'} {log.userName || 'SYSTEM_CORE'}
</span> </span>
</div> </div>
@ -206,7 +206,7 @@ export default function AuditLogPage() {
/> />
{/* Simplified Clinical Pagination */} {/* Simplified Clinical Pagination */}
<div className="flex items-center justify-between px-2 pt-4 border-t border-slate-100 dark:border-slate-800"> <div className="flex items-center justify-between px-2 pt-4 border-t border-[var(--color-border-subtle)]">
<p className="text-[10px] font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest"> <p className="text-[10px] font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest">
Index <span className="text-[var(--color-text-primary)]">{((pagination.page - 1) * pagination.limit) + 1}{Math.min(pagination.page * pagination.limit, pagination.total)}</span> / {pagination.total} RECORDED_EVENTS Index <span className="text-[var(--color-text-primary)]">{((pagination.page - 1) * pagination.limit) + 1}{Math.min(pagination.page * pagination.limit, pagination.total)}</span> / {pagination.total} RECORDED_EVENTS
</p> </p>

View file

@ -224,9 +224,9 @@ export default function BatchDetailPage() {
</div> </div>
<div className="space-y-4"> <div className="space-y-4">
{batch.touchPoints?.map(tp => ( {batch.touchPoints?.map(tp => (
<div key={tp.id} className="flex items-center justify-between p-3 rounded-xl bg-[var(--color-bg-tertiary)]/50 border border-slate-100 dark:border-slate-800/50"> <div key={tp.id} className="flex items-center justify-between p-3 rounded-xl bg-[var(--color-bg-tertiary)]/50 border border-[var(--color-border-subtle)]/50">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<div className="w-8 h-8 rounded-lg bg-white dark:bg-slate-800 flex items-center justify-center border border-[var(--color-border-subtle)] shadow-sm"> <div className="w-8 h-8 rounded-lg bg-[var(--color-bg-elevated)] flex items-center justify-center border border-[var(--color-border-subtle)] shadow-sm">
<Activity size={14} className="text-[var(--color-primary)]" /> <Activity size={14} className="text-[var(--color-primary)]" />
</div> </div>
<div> <div>
@ -254,7 +254,7 @@ export default function BatchDetailPage() {
<button className="px-3 py-1.5 rounded-lg text-[10px] font-bold uppercase tracking-widest">7d</button> <button className="px-3 py-1.5 rounded-lg text-[10px] font-bold uppercase tracking-widest">7d</button>
</div> </div>
</div> </div>
<div className="h-[400px] w-full bg-slate-50/50 dark:bg-slate-900/50 rounded-2xl border border-slate-100 dark:border-slate-800 flex items-center justify-center text-[var(--color-text-tertiary)]"> <div className="h-[400px] w-full bg-slate-50/50 dark:bg-slate-900/50 rounded-2xl border border-[var(--color-border-subtle)] flex items-center justify-center text-[var(--color-text-tertiary)]">
<div className="flex flex-col items-center gap-2 text-center"> <div className="flex flex-col items-center gap-2 text-center">
<TrendingUp size={32} /> <TrendingUp size={32} />
<span className="text-xs font-bold tracking-widest uppercase">Interactive Analytics Terminal</span> <span className="text-xs font-bold tracking-widest uppercase">Interactive Analytics Terminal</span>
@ -389,7 +389,7 @@ function TabButton({ active, label, icon: Icon, count, onClick }: any) {
function ActionButton({ label, icon: Icon }: any) { function ActionButton({ label, icon: Icon }: any) {
return ( return (
<button className="flex flex-col items-center justify-center p-4 rounded-xl bg-[var(--color-bg-tertiary)]/50 border border-slate-100 dark:border-slate-800/50 hover:border-emerald-500/50 hover:bg-[var(--color-primary)]/10 transition-all group"> <button className="flex flex-col items-center justify-center p-4 rounded-xl bg-[var(--color-bg-tertiary)]/50 border border-[var(--color-border-subtle)]/50 hover:border-emerald-500/50 hover:bg-[var(--color-primary)]/10 transition-all group">
<Icon size={20} className="text-[var(--color-text-tertiary)] group-hover:text-[var(--color-primary)] mb-2 transition-colors" /> <Icon size={20} className="text-[var(--color-text-tertiary)] group-hover:text-[var(--color-primary)] mb-2 transition-colors" />
<span className="text-[10px] font-bold uppercase tracking-widest text-[var(--color-text-tertiary)] group-hover:text-[var(--color-primary)]">{label}</span> <span className="text-[10px] font-bold uppercase tracking-widest text-[var(--color-text-tertiary)] group-hover:text-[var(--color-primary)]">{label}</span>
</button> </button>
@ -398,7 +398,7 @@ function ActionButton({ label, icon: Icon }: any) {
function IntegrationItem({ name, status, time }: any) { function IntegrationItem({ name, status, time }: any) {
return ( return (
<div className="flex items-center justify-between p-3 rounded-xl bg-[var(--color-bg-tertiary)]/50 border border-slate-100 dark:border-slate-800/50"> <div className="flex items-center justify-between p-3 rounded-xl bg-[var(--color-bg-tertiary)]/50 border border-[var(--color-border-subtle)]/50">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="w-1.5 h-1.5 rounded-full bg-[var(--color-primary)]" /> <div className="w-1.5 h-1.5 rounded-full bg-[var(--color-primary)]" />
<div> <div>

View file

@ -146,7 +146,7 @@ export default function BatchesPage() {
const days = Math.floor((Date.now() - new Date(batch.startDate).getTime()) / (1000 * 60 * 60 * 24)); const days = Math.floor((Date.now() - new Date(batch.startDate).getTime()) / (1000 * 60 * 60 * 24));
return ( return (
<div className="flex flex-col items-end"> <div className="flex flex-col items-end">
<span className="font-medium text-slate-700 dark:text-slate-300">Day {days}</span> <span className="font-medium text-[var(--color-text-secondary)]">Day {days}</span>
<span className="text-[10px] text-[var(--color-text-tertiary)]"> <span className="text-[10px] text-[var(--color-text-tertiary)]">
{new Date(batch.startDate).toLocaleDateString()} {new Date(batch.startDate).toLocaleDateString()}
</span> </span>

View file

@ -102,7 +102,7 @@ export default function MetrcDashboardPage() {
{ {
key: 'room', key: 'room',
header: 'Local Room', header: 'Local Room',
cell: (plant) => <span className="text-sm text-slate-700 dark:text-slate-300">{plant.room}</span> cell: (plant) => <span className="text-sm text-[var(--color-text-secondary)]">{plant.room}</span>
}, },
{ {
key: 'status', key: 'status',
@ -225,7 +225,7 @@ export default function MetrcDashboardPage() {
className={cn( className={cn(
"px-6 py-2 rounded-lg text-xs font-bold uppercase tracking-widest transition-all", "px-6 py-2 rounded-lg text-xs font-bold uppercase tracking-widest transition-all",
activeTab === tab activeTab === tab
? "bg-white dark:bg-slate-800 text-[var(--color-text-primary)] shadow-sm" ? "bg-[var(--color-bg-elevated)] text-[var(--color-text-primary)] shadow-sm"
: "text-[var(--color-text-tertiary)] hover:text-slate-600 dark:hover:text-slate-200" : "text-[var(--color-text-tertiary)] hover:text-slate-600 dark:hover:text-slate-200"
)} )}
> >

View file

@ -118,7 +118,7 @@ export default function RoomsPage() {
))} ))}
</div> </div>
) : rooms.length === 0 ? ( ) : rooms.length === 0 ? (
<div className="py-16 text-center rounded-2xl border-2 border-dashed border-slate-100 dark:border-slate-800"> <div className="py-16 text-center rounded-2xl border-2 border-dashed border-[var(--color-border-subtle)]">
<Home size={40} className="mx-auto text-slate-300 dark:text-slate-700 mb-4" /> <Home size={40} className="mx-auto text-slate-300 dark:text-slate-700 mb-4" />
<p className="text-sm font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest mb-4">No Cultivation Zones Configured</p> <p className="text-sm font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest mb-4">No Cultivation Zones Configured</p>
{isManager && ( {isManager && (
@ -149,7 +149,7 @@ export default function RoomsPage() {
> >
<Card className="p-0 overflow-hidden bg-[var(--color-bg-elevated)] border-[var(--color-border-subtle)] hover:border-emerald-500/50 transition-all"> <Card className="p-0 overflow-hidden bg-[var(--color-bg-elevated)] border-[var(--color-border-subtle)] hover:border-emerald-500/50 transition-all">
{/* Header */} {/* Header */}
<div className={cn("px-5 py-4 border-b border-slate-100 dark:border-slate-800 flex items-center justify-between", accentClasses[accent as keyof typeof accentClasses])}> <div className={cn("px-5 py-4 border-b border-[var(--color-border-subtle)] flex items-center justify-between", accentClasses[accent as keyof typeof accentClasses])}>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Icon size={16} /> <Icon size={16} />
<span className="text-[10px] font-black uppercase tracking-[0.2em]">{room.type}</span> <span className="text-[10px] font-black uppercase tracking-[0.2em]">{room.type}</span>
@ -169,7 +169,7 @@ export default function RoomsPage() {
</div> </div>
{/* Environmental Vitals */} {/* Environmental Vitals */}
<div className="grid grid-cols-2 gap-4 py-4 border-y border-slate-100 dark:border-slate-800"> <div className="grid grid-cols-2 gap-4 py-4 border-y border-[var(--color-border-subtle)]">
<div className="text-center"> <div className="text-center">
<div className="flex items-center justify-center gap-1.5 text-xl font-black tracking-tighter text-[var(--color-text-primary)]"> <div className="flex items-center justify-center gap-1.5 text-xl font-black tracking-tighter text-[var(--color-text-primary)]">
<Thermometer size={14} className="text-[var(--color-error)]" /> <Thermometer size={14} className="text-[var(--color-error)]" />
@ -190,7 +190,7 @@ export default function RoomsPage() {
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className={cn("w-2 h-2 rounded-full", room.batches?.length > 0 ? 'bg-[var(--color-primary)]' : 'bg-slate-300 dark:bg-slate-700')} /> <div className={cn("w-2 h-2 rounded-full", room.batches?.length > 0 ? 'bg-[var(--color-primary)]' : 'bg-slate-300 dark:bg-slate-700')} />
<span className="text-xs font-bold text-slate-700 dark:text-slate-300"> <span className="text-xs font-bold text-[var(--color-text-secondary)]">
{room.batches?.length || 0} Active Batch{room.batches?.length === 1 ? '' : 'es'} {room.batches?.length || 0} Active Batch{room.batches?.length === 1 ? '' : 'es'}
</span> </span>
</div> </div>

View file

@ -143,7 +143,7 @@ export default function SuppliesPage() {
className: 'w-48', className: 'w-48',
cell: (item) => ( cell: (item) => (
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="flex items-center bg-slate-100 dark:bg-slate-800 rounded-lg p-0.5 border border-slate-200 dark:border-slate-700/50"> <div className="flex items-center bg-slate-100 dark:bg-slate-800 rounded-lg p-0.5 border border-[var(--color-border-default)]/50">
<button <button
onClick={(e) => { e.stopPropagation(); handleQuantityAdjust(item.id, -1); }} onClick={(e) => { e.stopPropagation(); handleQuantityAdjust(item.id, -1); }}
disabled={item.quantity <= 0} disabled={item.quantity <= 0}
@ -292,7 +292,7 @@ export default function SuppliesPage() {
className={cn( className={cn(
"px-6 py-2 rounded-lg text-xs font-bold uppercase tracking-widest transition-all", "px-6 py-2 rounded-lg text-xs font-bold uppercase tracking-widest transition-all",
view === 'all' view === 'all'
? "bg-white dark:bg-slate-800 text-[var(--color-text-primary)] shadow-sm" ? "bg-[var(--color-bg-elevated)] text-[var(--color-text-primary)] shadow-sm"
: "text-[var(--color-text-tertiary)] hover:text-slate-700 dark:hover:text-slate-300" : "text-[var(--color-text-tertiary)] hover:text-slate-700 dark:hover:text-slate-300"
)} )}
> >
@ -303,7 +303,7 @@ export default function SuppliesPage() {
className={cn( className={cn(
"px-6 py-2 rounded-lg text-xs font-bold uppercase tracking-widest transition-all relative", "px-6 py-2 rounded-lg text-xs font-bold uppercase tracking-widest transition-all relative",
view === 'shopping' view === 'shopping'
? "bg-white dark:bg-slate-800 text-[var(--color-text-primary)] shadow-sm" ? "bg-[var(--color-bg-elevated)] text-[var(--color-text-primary)] shadow-sm"
: "text-[var(--color-text-tertiary)] hover:text-slate-700 dark:hover:text-slate-300" : "text-[var(--color-text-tertiary)] hover:text-slate-700 dark:hover:text-slate-300"
)} )}
> >
@ -388,7 +388,7 @@ export default function SuppliesPage() {
exit={{ opacity: 0, scale: 0.95, y: 20 }} exit={{ opacity: 0, scale: 0.95, y: 20 }}
className="relative w-full max-w-lg bg-white dark:bg-[#0C0C0C] border border-[var(--color-border-subtle)] rounded-3xl shadow-2xl overflow-hidden" className="relative w-full max-w-lg bg-white dark:bg-[#0C0C0C] border border-[var(--color-border-subtle)] rounded-3xl shadow-2xl overflow-hidden"
> >
<div className="p-6 border-b border-slate-100 dark:border-slate-800 flex justify-between items-center"> <div className="p-6 border-b border-[var(--color-border-subtle)] flex justify-between items-center">
<h2 className="text-xl font-bold tracking-tight">Add Supply Record</h2> <h2 className="text-xl font-bold tracking-tight">Add Supply Record</h2>
<button onClick={() => setIsAddModalOpen(false)} className="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-xl transition-colors"> <button onClick={() => setIsAddModalOpen(false)} className="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-xl transition-colors">
<X size={20} className="text-[var(--color-text-tertiary)]" /> <X size={20} className="text-[var(--color-text-tertiary)]" />

View file

@ -164,7 +164,7 @@ export default function TasksPage() {
))} ))}
</AnimatePresence> </AnimatePresence>
{pendingTasks.length === 0 && ( {pendingTasks.length === 0 && (
<div className="py-12 text-center rounded-2xl border-2 border-dashed border-slate-100 dark:border-slate-800"> <div className="py-12 text-center rounded-2xl border-2 border-dashed border-[var(--color-border-subtle)]">
<CheckCircle2 size={32} className="mx-auto text-[var(--color-primary)]/20 mb-3" /> <CheckCircle2 size={32} className="mx-auto text-[var(--color-primary)]/20 mb-3" />
<p className="text-sm font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest">All Actions Complete</p> <p className="text-sm font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest">All Actions Complete</p>
</div> </div>
@ -174,14 +174,14 @@ export default function TasksPage() {
{/* Recently Completed Section */} {/* Recently Completed Section */}
{completedTasks.length > 0 && ( {completedTasks.length > 0 && (
<div className="space-y-4 pt-4 border-t border-slate-100 dark:border-slate-800"> <div className="space-y-4 pt-4 border-t border-[var(--color-border-subtle)]">
<div className="flex items-center justify-between px-2"> <div className="flex items-center justify-between px-2">
<h3 className="text-xs font-bold uppercase tracking-[0.2em] text-[var(--color-text-tertiary)]">Archive / Verification</h3> <h3 className="text-xs font-bold uppercase tracking-[0.2em] text-[var(--color-text-tertiary)]">Archive / Verification</h3>
<button className="text-[10px] font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest hover:text-[var(--color-primary)]">View History</button> <button className="text-[10px] font-bold text-[var(--color-text-tertiary)] uppercase tracking-widest hover:text-[var(--color-primary)]">View History</button>
</div> </div>
<div className="opacity-60 saturate-50 hover:opacity-100 transition-all duration-500 space-y-2"> <div className="opacity-60 saturate-50 hover:opacity-100 transition-all duration-500 space-y-2">
{completedTasks.slice(0, 3).map(task => ( {completedTasks.slice(0, 3).map(task => (
<div key={task.id} className="flex items-center justify-between p-4 bg-slate-50/50 dark:bg-slate-900/30 rounded-xl border border-slate-100 dark:border-slate-800/50"> <div key={task.id} className="flex items-center justify-between p-4 bg-slate-50/50 dark:bg-slate-900/30 rounded-xl border border-[var(--color-border-subtle)]/50">
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<CheckCircle2 size={16} className="text-[var(--color-primary)]" /> <CheckCircle2 size={16} className="text-[var(--color-primary)]" />
<div> <div>

View file

@ -263,7 +263,7 @@ export default function VisitorManagementPage() {
className={cn( className={cn(
"px-5 py-2 rounded-lg text-xs font-bold uppercase tracking-widest transition-all flex items-center gap-2", "px-5 py-2 rounded-lg text-xs font-bold uppercase tracking-widest transition-all flex items-center gap-2",
activeTab === tab.id activeTab === tab.id
? "bg-white dark:bg-slate-800 text-[var(--color-text-primary)] shadow-sm" ? "bg-[var(--color-bg-elevated)] text-[var(--color-text-primary)] shadow-sm"
: "text-[var(--color-text-tertiary)] hover:text-slate-700 dark:hover:text-slate-300" : "text-[var(--color-text-tertiary)] hover:text-slate-700 dark:hover:text-slate-300"
)} )}
> >
@ -382,7 +382,7 @@ export default function VisitorManagementPage() {
<p className="text-xs text-[var(--color-text-tertiary)] leading-relaxed">{zone.description || 'No zone constraints defined.'}</p> <p className="text-xs text-[var(--color-text-tertiary)] leading-relaxed">{zone.description || 'No zone constraints defined.'}</p>
</div> </div>
<div className="mt-8 pt-6 border-t border-slate-100 dark:border-slate-800/50 flex items-center justify-between"> <div className="mt-8 pt-6 border-t border-[var(--color-border-subtle)]/50 flex items-center justify-between">
<div className="flex -space-x-2"> <div className="flex -space-x-2">
{[1, 2].map(i => ( {[1, 2].map(i => (
<div key={i} className="w-6 h-6 rounded-full bg-slate-200 dark:bg-slate-800 border-2 border-white dark:border-[#0C0C0C]" /> <div key={i} className="w-6 h-6 rounded-full bg-slate-200 dark:bg-slate-800 border-2 border-white dark:border-[#0C0C0C]" />

View file

@ -68,17 +68,17 @@ export default function PageTemplate() {
placeholder="Search..." placeholder="Search..."
value={searchQuery} value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)} onChange={(e) => setSearchQuery(e.target.value)}
className="w-full pl-10 pr-4 py-2.5 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-sm focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500 outline-none" className="w-full pl-10 pr-4 py-2.5 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-elevated)] text-sm focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500 outline-none"
/> />
</div> </div>
<button className="flex items-center gap-2 px-4 py-2.5 rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-sm hover:bg-slate-50 dark:hover:bg-slate-700"> <button className="flex items-center gap-2 px-4 py-2.5 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-elevated)] text-sm hover:bg-slate-50 dark:hover:bg-slate-700">
<Filter size={16} /> <Filter size={16} />
Filters Filters
</button> </button>
</div> </div>
{/* Content Area */} {/* Content Area */}
<div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 shadow-sm"> <div className="bg-[var(--color-bg-elevated)] rounded-xl border border-[var(--color-border-default)] shadow-sm">
{isLoading ? ( {isLoading ? (
<div className="flex items-center justify-center p-12"> <div className="flex items-center justify-center p-12">
<div className="animate-spin w-8 h-8 border-2 border-emerald-500 border-t-transparent rounded-full" /> <div className="animate-spin w-8 h-8 border-2 border-emerald-500 border-t-transparent rounded-full" />
@ -86,7 +86,7 @@ export default function PageTemplate() {
) : items.length === 0 ? ( ) : items.length === 0 ? (
/* Empty State */ /* Empty State */
<div className="flex flex-col items-center justify-center p-12 text-center"> <div className="flex flex-col items-center justify-center p-12 text-center">
<div className="w-16 h-16 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center mb-4"> <div className="w-16 h-16 rounded-full bg-[var(--color-bg-tertiary)] flex items-center justify-center mb-4">
<FileText size={32} className="text-[var(--color-text-tertiary)]" /> <FileText size={32} className="text-[var(--color-text-tertiary)]" />
</div> </div>
<h3 className="text-lg font-semibold text-[var(--color-text-primary)] mb-2"> <h3 className="text-lg font-semibold text-[var(--color-text-primary)] mb-2">

View file

@ -70,11 +70,11 @@ export function WidgetTemplate({
const trendColor = data?.trend === 'up' ? 'text-[var(--color-primary)]' : data?.trend === 'down' ? 'text-red-500' : 'text-[var(--color-text-tertiary)]'; const trendColor = data?.trend === 'up' ? 'text-[var(--color-primary)]' : data?.trend === 'down' ? 'text-red-500' : 'text-[var(--color-text-tertiary)]';
return ( return (
<div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 shadow-sm"> <div className="bg-[var(--color-bg-elevated)] rounded-xl border border-[var(--color-border-default)] p-4 shadow-sm">
{/* Header */} {/* Header */}
<div className="flex items-center justify-between mb-3"> <div className="flex items-center justify-between mb-3">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className={`p-2 rounded-lg bg-slate-100 dark:bg-slate-700 ${iconColor}`}> <div className={`p-2 rounded-lg bg-[var(--color-bg-tertiary)] ${iconColor}`}>
<Icon size={18} /> <Icon size={18} />
</div> </div>
<h3 className="text-sm font-medium text-[var(--color-text-primary)]">{title}</h3> <h3 className="text-sm font-medium text-[var(--color-text-primary)]">{title}</h3>