feat: partial UI redesign - TabBar, ManaDisplay, StatsTab sub-sections
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 42s

Design token migration:
- TabBar: replaced hardcoded colors/shadows with --bg-panel, --border-subtle,
  --font-display tokens. Removed rounded-full pills, added Cinzel font tracking.
- ManaDisplay: replaced bg-gray-900/text-blue-400 with --mana-raw, --bg-panel,
  element-specific --mana-* tokens. Updated progress bar styling.
- StatsTab/* (all 7 sub-sections): replaced hardcoded gray/red/blue color values
  with semantic design tokens (--bg-panel, --border-subtle, --text-muted,
  element-themed mana colors)

NOTE: This is a partial implementation. TASK-011 paused to address
foundational issues (missing types, duplicate stat functions) first.
See issue #14 for full context.
This commit is contained in:
2026-05-14 12:03:09 +02:00
parent ba231ac9dd
commit 3e5b634815
9 changed files with 228 additions and 237 deletions
+32 -16
View File
@@ -39,26 +39,37 @@ export function ManaDisplay({
.sort((a, b) => b[1].current - a[1].current);
return (
<Card className="bg-gray-900/80 border-gray-700">
<Card className="bg-[var(--bg-panel)] border-[var(--border-subtle)]">
<CardContent className="pt-4 space-y-3">
{/* Raw Mana - Main Display */}
<div>
<div className="flex items-baseline gap-1">
<span className="text-3xl font-bold game-mono text-blue-400">{fmt(rawMana)}</span>
<span className="text-sm text-gray-400">/ {fmt(maxMana)}</span>
<span className="text-3xl font-bold game-mono" style={{ color: 'var(--mana-raw)' }}>{fmt(rawMana)}</span>
<span className="text-sm" style={{ color: 'var(--text-muted)' }}>/ {fmt(maxMana)}</span>
</div>
<div className="text-xs text-gray-400">
+{fmtDec(effectiveRegen)} mana/hr {meditationMultiplier > 1.01 && <span className="text-purple-400">({fmtDec(meditationMultiplier, 1)}x med)</span>}
<div className="text-xs" style={{ color: 'var(--text-muted)' }}>
+{fmtDec(effectiveRegen)} mana/hr {meditationMultiplier > 1.01 && <span style={{ color: 'var(--mana-light)' }}>({fmtDec(meditationMultiplier, 1)}x med)</span>}
</div>
</div>
<Progress
value={(rawMana / maxMana) * 100}
className="h-2 bg-gray-800"
className="h-2 bg-[var(--bg-sunken)]"
style={{ '--progress-bg': 'var(--mana-raw)' } as React.CSSProperties}
/>
<Button
className={`w-full bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 ${isGathering ? 'animate-pulse' : ''}`}
className={`w-full transition-all text-[var(--font-display)] tracking-wider
${isGathering
? 'animate-gather-glow'
: 'hover:scale-[1.02]'}
`}
style={{
background: 'var(--mana-raw)',
border: '1px solid var(--border-accent)',
color: '#0C1020',
fontWeight: 600,
}}
onMouseDown={onGatherStart}
onMouseUp={onGatherEnd}
onMouseLeave={onGatherEnd}
@@ -67,22 +78,23 @@ export function ManaDisplay({
>
<Zap className="w-4 h-4 mr-2" />
Gather +{clickMana} Mana
{isGathering && <span className="ml-2 text-xs">(Holding...)</span>}
{isGathering && <span className="ml-2 text-xs" style={{ opacity: 0.8 }}>(Holding...)</span>}
</Button>
{/* Elemental Mana Pools */}
{unlockedElements.length > 0 && (
<div className="border-t border-gray-700 pt-3 mt-3">
<div className="border-t border-[var(--border-subtle)] pt-3 mt-3">
<button
onClick={() => setExpanded(!expanded)}
className="flex items-center justify-between w-full text-xs text-gray-400 hover:text-gray-300 mb-2"
className="flex items-center justify-between w-full text-xs transition-colors"
style={{ color: 'var(--text-muted)' }}
>
<span>Elemental Mana ({unlockedElements.length})</span>
<span style={{ fontFamily: 'var(--font-display)', letterSpacing: '0.5px' }}>ELEMENTAL MANA ({unlockedElements.length})</span>
{expanded ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />}
</button>
{expanded && (
<div className="grid grid-cols-2 gap-2">
<div className="grid grid-cols-2 gap-2 mt-2">
{unlockedElements.map(([id, state]) => {
const elem = ELEMENTS[id];
if (!elem) return null;
@@ -90,7 +102,11 @@ export function ManaDisplay({
return (
<div
key={id}
className="p-2 rounded bg-gray-800/50 border border-gray-700"
className="p-2 transition-all border rounded-sm"
style={{
background: 'var(--bg-sunken)/30',
borderColor: `${elem.color}30`,
}}
>
<div className="flex items-center gap-1 mb-1">
<span style={{ color: elem.color }}>{elem.sym}</span>
@@ -98,16 +114,16 @@ export function ManaDisplay({
{elem.name}
</span>
</div>
<div className="h-1.5 bg-gray-700 rounded-full overflow-hidden mb-1">
<div className="h-1.5 rounded-full overflow-hidden" style={{ background: 'var(--bg-void)' }}>
<div
className="h-full rounded-full transition-all"
className="h-full transition-all rounded-full"
style={{
width: `${Math.min(100, (state.current / state.max) * 100)}%`,
backgroundColor: elem.color
}}
/>
</div>
<div className="text-xs text-gray-400 game-mono">
<div className="text-xs game-mono" style={{ color: 'var(--text-muted)' }}>
{fmt(state.current)}/{fmt(state.max)}
</div>
</div>