Redesign: bright modern aesthetic

- New color palette: warm coral/tangerine accent on cream white
- Typography: Bricolage Grotesque (display) + DM Sans (body)
- Soft shadows, rounded pill buttons, gradient progress bars
- Subtle animations: fadeUp cards, scaleIn gate banner
- Mobile-friendly: safe-area-inset, backdrop blur nav
- All dark-mode hardcoded colors replaced with CSS variables
- Login page: gradient background, segmented toggle, logo card
- Dashboard: warm gate banners, purple weekly progress
- Onboarding: display font headings, improved spacing
This commit is contained in:
claude 2026-03-15 10:41:01 +00:00
parent d79129efc2
commit 22f5e8fae3
6 changed files with 375 additions and 202 deletions

View file

@ -23,14 +23,8 @@ export default function Login() {
data = await api.register(username, password, displayName || username)
}
setToken(data.access_token)
// Check onboarding status
const status = await api.onboardingStatus()
if (!status.phase1_completed) {
navigate('/onboarding')
} else {
navigate('/')
}
navigate(status.phase1_completed ? '/' : '/onboarding')
} catch (err) {
setError(err.message)
} finally {
@ -39,48 +33,66 @@ export default function Login() {
}
return (
<div className="page" style={{ paddingTop: '80px' }}>
<div style={{ textAlign: 'center', marginBottom: '40px' }}>
<div style={{ fontSize: '3rem', marginBottom: '8px' }}>🏆</div>
<h1 style={{ fontSize: '1.8rem', fontWeight: 800 }}>Fitness Rewards</h1>
<p style={{ color: 'var(--text-muted)', marginTop: '8px' }}>Earn your rewards. Every day.</p>
</div>
<div style={{ minHeight: '100dvh', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '24px', background: 'linear-gradient(160deg, #fff7f0 0%, #faf8f5 40%, #f0f4ff 100%)' }}>
<div style={{ width: '100%', maxWidth: '400px' }}>
<div className="card">
<div style={{ display: 'flex', gap: '8px', marginBottom: '20px' }}>
<button
className={mode === 'login' ? 'btn-primary btn-full' : 'btn-outline btn-full'}
onClick={() => setMode('login')}
type="button"
>Sign In</button>
<button
className={mode === 'register' ? 'btn-primary btn-full' : 'btn-outline btn-full'}
onClick={() => setMode('register')}
type="button"
>Sign Up</button>
{/* Logo & branding */}
<div style={{ textAlign: 'center', marginBottom: '36px' }}>
<div style={{
width: '72px', height: '72px', borderRadius: '20px', margin: '0 auto 16px',
background: 'linear-gradient(135deg, #ff6b35 0%, #ff8f5e 100%)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
fontSize: '2rem', boxShadow: '0 8px 24px rgba(255, 107, 53, 0.3)',
}}>🏆</div>
<h1 style={{ fontFamily: 'var(--font-display)', fontSize: '2rem', fontWeight: 800, letterSpacing: '-0.03em', color: 'var(--text)' }}>
Fitness Rewards
</h1>
<p style={{ color: 'var(--text-muted)', marginTop: '6px', fontSize: '0.95rem' }}>
Earn your rewards. Every day.
</p>
</div>
{error && <div className="error-msg">{error}</div>}
{/* Card */}
<div className="card" style={{ padding: '28px', boxShadow: 'var(--shadow-lg)' }}>
{/* Tab toggle */}
<div style={{
display: 'flex', gap: '4px', marginBottom: '24px', padding: '4px',
background: 'var(--bg)', borderRadius: 'var(--radius-full)',
}}>
<button
className={mode === 'login' ? 'btn-primary btn-full' : 'btn-ghost btn-full'}
onClick={() => setMode('login')} type="button"
style={{ borderRadius: 'var(--radius-full)' }}
>Sign In</button>
<button
className={mode === 'register' ? 'btn-primary btn-full' : 'btn-ghost btn-full'}
onClick={() => setMode('register')} type="button"
style={{ borderRadius: 'var(--radius-full)' }}
>Sign Up</button>
</div>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label className="form-label">Username</label>
<input value={username} onChange={e => setUsername(e.target.value)} required autoComplete="username" />
</div>
<div className="form-group">
<label className="form-label">Password</label>
<input type="password" value={password} onChange={e => setPassword(e.target.value)} required autoComplete="current-password" />
</div>
{mode === 'register' && (
{error && <div className="error-msg">{error}</div>}
<form onSubmit={handleSubmit}>
<div className="form-group">
<label className="form-label">Display Name</label>
<input value={displayName} onChange={e => setDisplayName(e.target.value)} placeholder="What should we call you?" />
<label className="form-label">Username</label>
<input value={username} onChange={e => setUsername(e.target.value)} required autoComplete="username" placeholder="your username" />
</div>
)}
<button type="submit" className="btn-primary btn-full" disabled={loading}>
{loading ? '...' : mode === 'login' ? 'Sign In' : 'Create Account'}
</button>
</form>
<div className="form-group">
<label className="form-label">Password</label>
<input type="password" value={password} onChange={e => setPassword(e.target.value)} required autoComplete="current-password" placeholder="your password" />
</div>
{mode === 'register' && (
<div className="form-group">
<label className="form-label">Display Name</label>
<input value={displayName} onChange={e => setDisplayName(e.target.value)} placeholder="What should we call you?" />
</div>
)}
<button type="submit" className="btn-primary btn-full" disabled={loading} style={{ padding: '14px', fontSize: '1rem', marginTop: '4px' }}>
{loading ? 'Working...' : mode === 'login' ? 'Sign In' : 'Create Account'}
</button>
</form>
</div>
</div>
</div>
)