mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-20 17:50:12 +02:00
fix(ui): resolve light-theme low-contrast semantic text app-wide (#1909)
The app was built dark-first, so hundreds of hardcoded Tailwind semantic text/icon utilities at light shades (text-amber-400, text-blue-300, ...) had no dark: variant. With darkMode:'class' they applied in light theme too, producing washed-out text on pale tints and white cards — including the three reported spots (AMS Drying banner, Archives no-3MF warning, debug-logging banner). Give each a theme-aware pair: a darker readable shade in light theme with the original pinned to dark:, so dark theme is unchanged. ~100 files. The bambu-* CSS-variable palette (self-correcting) and the dark-only SpoolBuddy kiosk are left untouched. Plain text-white is already theme-aware via the existing index.css .text-white override, so it needed no changes.
This commit is contained in:
@@ -194,9 +194,9 @@ export function FilamentMapping({
|
||||
<Circle className="w-4 h-4" fill={statusColor} stroke="none" />
|
||||
<span>{t('printModal.filamentMapping')}</span>
|
||||
{hasTypeMismatch ? (
|
||||
<span className="text-xs text-orange-400">(Type not found)</span>
|
||||
<span className="text-xs text-orange-700 dark:text-orange-400">(Type not found)</span>
|
||||
) : hasColorMismatch ? (
|
||||
<span className="text-xs text-yellow-400">(Color mismatch)</span>
|
||||
<span className="text-xs text-yellow-700 dark:text-yellow-400">(Color mismatch)</span>
|
||||
) : (
|
||||
<span className="text-xs text-bambu-green">(Ready)</span>
|
||||
)}
|
||||
@@ -264,8 +264,8 @@ export function FilamentMapping({
|
||||
item.status === 'match'
|
||||
? 'border-bambu-green/50 text-bambu-green'
|
||||
: item.status === 'type_only'
|
||||
? 'border-yellow-400/50 text-yellow-400'
|
||||
: 'border-orange-400/50 text-orange-400'
|
||||
? 'border-yellow-500 dark:border-yellow-400/50 text-yellow-700 dark:text-yellow-400'
|
||||
: 'border-orange-500 dark:border-orange-400/50 text-orange-700 dark:text-orange-400'
|
||||
} ${item.isManual ? 'ring-1 ring-blue-400/50' : ''}`}
|
||||
title={item.isManual ? 'Manually selected' : 'Auto-matched'}
|
||||
>
|
||||
@@ -315,11 +315,11 @@ export function FilamentMapping({
|
||||
<Check className="w-3 h-3 text-bambu-green" />
|
||||
) : item.status === 'type_only' ? (
|
||||
<span title="Same type, different color">
|
||||
<AlertTriangle className="w-3 h-3 text-yellow-400" />
|
||||
<AlertTriangle className="w-3 h-3 text-yellow-600 dark:text-yellow-400" />
|
||||
</span>
|
||||
) : (
|
||||
<span title="Filament type not loaded">
|
||||
<AlertTriangle className="w-3 h-3 text-orange-400" />
|
||||
<AlertTriangle className="w-3 h-3 text-orange-600 dark:text-orange-400" />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -346,7 +346,7 @@ export function FilamentMapping({
|
||||
</span>
|
||||
</div>
|
||||
{hasTypeMismatch && (
|
||||
<p className="text-xs text-orange-400 mt-2">Required filament type not found in printer.</p>
|
||||
<p className="text-xs text-orange-700 dark:text-orange-400 mt-2">Required filament type not found in printer.</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -118,7 +118,7 @@ export function FilamentOverride({
|
||||
disabled={compatible.length === 0}
|
||||
className={`flex-1 px-2 py-1 rounded border text-xs bg-bambu-dark-secondary focus:outline-none focus:ring-1 focus:ring-bambu-green ${
|
||||
isOverridden
|
||||
? 'border-blue-400/50 text-blue-400'
|
||||
? 'border-blue-500/50 dark:border-blue-400/50 text-blue-700 dark:text-blue-400'
|
||||
: 'border-bambu-gray/30 text-bambu-gray'
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -35,7 +35,7 @@ export function PlateSelector({
|
||||
<Layers className="w-4 h-4 text-bambu-gray" />
|
||||
<span className="text-sm text-bambu-gray">Select Plate{multiSelect ? 's' : ''} to Print</span>
|
||||
{selectedPlates.size === 0 && (
|
||||
<span className="text-xs text-orange-400 flex items-center gap-1">
|
||||
<span className="text-xs text-orange-700 dark:text-orange-400 flex items-center gap-1">
|
||||
<AlertTriangle className="w-3 h-3" />
|
||||
Selection required
|
||||
</span>
|
||||
|
||||
@@ -109,7 +109,7 @@ export function PrintOptionsPanel({
|
||||
bypasses the per-filament-type derivation. */}
|
||||
<div className="pt-2 mt-1 border-t border-bambu-dark-tertiary/60">
|
||||
<div className="flex items-center gap-2 mb-1.5">
|
||||
<Flame className="w-3.5 h-3.5 text-amber-400" />
|
||||
<Flame className="w-3.5 h-3.5 text-amber-600 dark:text-amber-400" />
|
||||
<span className="text-sm text-white">{t('settings.preheatTitle', 'Preheat & Heat Soak')}</span>
|
||||
</div>
|
||||
<p className="text-xs text-bambu-gray mb-2">
|
||||
|
||||
@@ -171,8 +171,8 @@ function InlineMappingEditor({
|
||||
status === 'match'
|
||||
? 'border-bambu-green/50 text-bambu-green'
|
||||
: status === 'type_only'
|
||||
? 'border-yellow-400/50 text-yellow-400'
|
||||
: 'border-orange-400/50 text-orange-400'
|
||||
? 'border-yellow-500 dark:border-yellow-400/50 text-yellow-700 dark:text-yellow-400'
|
||||
: 'border-orange-500 dark:border-orange-400/50 text-orange-700 dark:text-orange-400'
|
||||
} ${isManual ? 'ring-1 ring-blue-400/50' : ''}`}
|
||||
title={isManual ? 'Manually selected' : 'Auto-matched'}
|
||||
>
|
||||
@@ -190,11 +190,11 @@ function InlineMappingEditor({
|
||||
<Check className="w-3 h-3 text-bambu-green" />
|
||||
) : status === 'type_only' ? (
|
||||
<span title="Same type, different color">
|
||||
<AlertTriangle className="w-3 h-3 text-yellow-400" />
|
||||
<AlertTriangle className="w-3 h-3 text-yellow-600 dark:text-yellow-400" />
|
||||
</span>
|
||||
) : (
|
||||
<span title="Filament type not loaded">
|
||||
<AlertTriangle className="w-3 h-3 text-orange-400" />
|
||||
<AlertTriangle className="w-3 h-3 text-orange-600 dark:text-orange-400" />
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -330,7 +330,7 @@ export function PrinterSelector({
|
||||
|
||||
if (displayPrinters.length === 0) {
|
||||
return (
|
||||
<div className="flex items-center gap-2 text-red-400 text-sm mb-4">
|
||||
<div className="flex items-center gap-2 text-red-700 dark:text-red-400 text-sm mb-4">
|
||||
<AlertCircle className="w-4 h-4" />
|
||||
No {showInactive ? '' : 'active '}printers available
|
||||
</div>
|
||||
@@ -562,7 +562,7 @@ export function PrinterSelector({
|
||||
{stateLabel && (
|
||||
<span className={`text-xs px-2 py-0.5 rounded-full ${
|
||||
busy
|
||||
? 'bg-yellow-500/20 text-yellow-400'
|
||||
? 'bg-yellow-100 dark:bg-yellow-500/20 text-yellow-700 dark:text-yellow-400'
|
||||
: 'bg-bambu-green/20 text-bambu-green'
|
||||
}`}>
|
||||
{stateLabel}
|
||||
@@ -606,8 +606,8 @@ export function PrinterSelector({
|
||||
mappingResult.matchStatus === 'full'
|
||||
? 'text-bambu-green'
|
||||
: mappingResult.matchStatus === 'partial'
|
||||
? 'text-yellow-400'
|
||||
: 'text-orange-400'
|
||||
? 'text-yellow-700 dark:text-yellow-400'
|
||||
: 'text-orange-700 dark:text-orange-400'
|
||||
}`}>
|
||||
({mappingResult.exactMatches}/{mappingResult.totalSlots} matched)
|
||||
</span>
|
||||
@@ -654,7 +654,7 @@ export function PrinterSelector({
|
||||
onClick={() => setShowAllPrinters(true)}
|
||||
className="text-xs text-bambu-gray hover:text-white transition-colors mt-2 flex items-center gap-1"
|
||||
>
|
||||
<AlertTriangle className="w-3 h-3 text-yellow-400" />
|
||||
<AlertTriangle className="w-3 h-3 text-yellow-600 dark:text-yellow-400" />
|
||||
{hiddenPrinterCount} other printer{hiddenPrinterCount > 1 ? 's' : ''} hidden (different model) —
|
||||
<span className="underline">show all</span>
|
||||
</button>
|
||||
@@ -673,7 +673,7 @@ export function PrinterSelector({
|
||||
|
||||
{/* Warning when no printer selected (only in printer mode) */}
|
||||
{assignmentMode === 'printer' && selectedCount === 0 && (
|
||||
<p className="text-xs text-orange-400 mt-1 flex items-center gap-1">
|
||||
<p className="text-xs text-orange-700 dark:text-orange-400 mt-1 flex items-center gap-1">
|
||||
<AlertCircle className="w-3 h-3" />
|
||||
Select at least one printer
|
||||
</p>
|
||||
@@ -681,7 +681,7 @@ export function PrinterSelector({
|
||||
|
||||
{/* Warning when no model selected (only in model mode) */}
|
||||
{assignmentMode === 'model' && !targetModel && (
|
||||
<p className="text-xs text-orange-400 mt-1 flex items-center gap-1">
|
||||
<p className="text-xs text-orange-700 dark:text-orange-400 mt-1 flex items-center gap-1">
|
||||
<AlertCircle className="w-3 h-3" />
|
||||
Select a target printer model
|
||||
</p>
|
||||
|
||||
@@ -219,7 +219,7 @@ export function ScheduleOptionsPanel({
|
||||
</div>
|
||||
</div>
|
||||
{(!isDateValid || !isTimeValid) && (
|
||||
<p className="mt-1 text-xs text-red-400">
|
||||
<p className="mt-1 text-xs text-red-700 dark:text-red-400">
|
||||
{t('printModal.invalidDateTime')}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -1127,9 +1127,9 @@ export function PrintModal({
|
||||
const selectedPrinter = printers?.find(p => p.id === selectedPrinters[0]);
|
||||
if (selectedPrinter && selectedPrinter.model && slicedForModel !== selectedPrinter.model) {
|
||||
return (
|
||||
<div className="p-3 mb-2 bg-yellow-500/10 border border-yellow-500/30 rounded-lg flex items-center gap-2">
|
||||
<AlertTriangle className="w-4 h-4 text-yellow-400 flex-shrink-0" />
|
||||
<span className="text-sm text-yellow-400">
|
||||
<div className="p-3 mb-2 bg-yellow-50 dark:bg-yellow-500/10 border border-yellow-300 dark:border-yellow-500/30 rounded-lg flex items-center gap-2">
|
||||
<AlertTriangle className="w-4 h-4 text-yellow-600 dark:text-yellow-400 flex-shrink-0" />
|
||||
<span className="text-sm text-yellow-700 dark:text-yellow-400">
|
||||
File was sliced for {slicedForModel}, but printing on {selectedPrinter.model}
|
||||
</span>
|
||||
</div>
|
||||
@@ -1140,9 +1140,9 @@ export function PrintModal({
|
||||
|
||||
{/* Warning when archive data couldn't be loaded */}
|
||||
{archiveDataMissing && (
|
||||
<div className="flex items-start gap-2 p-3 mb-2 bg-orange-500/10 border border-orange-500/30 rounded-lg text-sm">
|
||||
<AlertCircle className="w-4 h-4 text-orange-400 mt-0.5 flex-shrink-0" />
|
||||
<p className="text-orange-400">
|
||||
<div className="flex items-start gap-2 p-3 mb-2 bg-orange-50 dark:bg-orange-500/10 border border-orange-300 dark:border-orange-500/30 rounded-lg text-sm">
|
||||
<AlertCircle className="w-4 h-4 text-orange-600 dark:text-orange-400 mt-0.5 flex-shrink-0" />
|
||||
<p className="text-orange-700 dark:text-orange-400">
|
||||
Archive data unavailable. The source file may have been deleted. Filament mapping is disabled.
|
||||
</p>
|
||||
</div>
|
||||
@@ -1212,7 +1212,7 @@ export function PrintModal({
|
||||
|
||||
{/* Error message */}
|
||||
{updateQueueMutation.isError && (
|
||||
<div className="mb-4 p-3 bg-red-500/20 border border-red-500/50 rounded-lg text-sm text-red-400">
|
||||
<div className="mb-4 p-3 bg-red-100 dark:bg-red-500/20 border border-red-500/50 rounded-lg text-sm text-red-700 dark:text-red-400">
|
||||
{(updateQueueMutation.error as Error)?.message || 'Failed to complete operation'}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user