ci: update CI/CD configuration

This commit is contained in:
saravanakumardb1 2026-03-04 20:01:34 -08:00
parent 411cc17c3c
commit 2e2f3c25ca
29 changed files with 243 additions and 112 deletions

View File

102
web/scripts/fix-colors.cjs Normal file
View File

@ -0,0 +1,102 @@
#!/usr/bin/env node
/**
* Batch fix hardcoded colors in ChronoMind Web
*/
const { readFileSync, writeFileSync, readdirSync, statSync } = require('fs');
const { join, extname } = require('path');
const REPLACEMENTS = [
{ from: /'#fff'/g, to: "'var(--cm-white)'" },
{ from: /'#ffffff'/g, to: "'var(--cm-white)'" },
{ from: /'#FFF'/g, to: "'var(--cm-white)'" },
{ from: /'#FFFFFF'/g, to: "'var(--cm-white)'" },
{ from: /'#000'/g, to: "'var(--cm-black)'" },
{ from: /'#000000'/g, to: "'var(--cm-black)'" },
{ from: /"#fff"/g, to: '"var(--cm-white)"' },
{ from: /"#ffffff"/g, to: '"var(--cm-white)"' },
{ from: /"#000"/g, to: '"var(--cm-black)"' },
{ from: /rgba\(6,\s*7,\s*10,\s*0\.85\)/g, to: 'var(--cm-bg-canvas-85)' },
{ from: /rgba\(90,\s*140,\s*255,\s*0\.1\)/g, to: 'var(--cm-accent-10)' },
{ from: /rgba\(90,\s*140,\s*255,\s*0\.08\)/g, to: 'var(--cm-accent-08)' },
{ from: /rgba\(90,\s*140,\s*255,\s*0\.12\)/g, to: 'var(--cm-accent-12)' },
{ from: /rgba\(90,\s*140,\s*255,\s*0\.15\)/g, to: 'var(--cm-accent-15)' },
{ from: /rgba\(90,\s*140,\s*255,\s*0\.2\)/g, to: 'var(--cm-accent-20)' },
{ from: /rgba\(90,\s*140,\s*255,\s*0\.3\)/g, to: 'var(--cm-accent-30)' },
{ from: /rgba\(255,\s*71,\s*87,\s*0\.1\)/g, to: 'var(--cm-critical-10)' },
{ from: /rgba\(255,\s*71,\s*87,\s*0\.15\)/g, to: 'var(--cm-critical-15)' },
{ from: /rgba\(255,\s*71,\s*87,\s*0\.2\)/g, to: 'var(--cm-critical-20)' },
{ from: /rgba\(255,\s*71,\s*87,\s*0\.4\)/g, to: 'var(--cm-critical-40)' },
{ from: /rgba\(52,\s*211,\s*153,\s*0\.12\)/g, to: 'var(--cm-success-12)' },
{ from: /rgba\(52,\s*211,\s*153,\s*0\.15\)/g, to: 'var(--cm-success-15)' },
{ from: /rgba\(46,\s*230,\s*214,\s*0\.1\)/g, to: 'var(--cm-accent-secondary-10)' },
{ from: /rgba\(46,\s*230,\s*214,\s*0\.15\)/g, to: 'var(--cm-accent-secondary-15)' },
{ from: /rgba\(46,\s*230,\s*214,\s*0\.3\)/g, to: 'var(--cm-accent-secondary-30)' },
{ from: /rgba\(245,\s*158,\s*11,\s*0\.1\)/g, to: 'var(--cm-warning-10)' },
{ from: /rgba\(245,\s*158,\s*11,\s*0\.15\)/g, to: 'var(--cm-warning-15)' },
{ from: /rgba\(245,\s*158,\s*11,\s*0\.3\)/g, to: 'var(--cm-warning-30)' },
{ from: /rgba\(165,\s*177,\s*199,\s*0\.1\)/g, to: 'var(--cm-passive-10)' },
{ from: /rgba\(165,\s*177,\s*199,\s*0\.2\)/g, to: 'var(--cm-passive-20)' },
{ from: /rgba\(0,\s*0,\s*0,\s*0\.8\)/g, to: 'var(--cm-black-80)' },
{ from: /rgba\(255,\s*159,\s*67,\s*0\.1\)/g, to: 'var(--cm-important-10)' },
{ from: /rgba\(255,\s*159,\s*67,\s*0\.15\)/g, to: 'var(--cm-important-15)' },
{ from: /rgba\(255,\s*159,\s*67,\s*0\.4\)/g, to: 'var(--cm-important-40)' },
{ from: /rgba\(254,\s*202,\s*87,\s*0\.15\)/g, to: 'var(--cm-standard-15)' },
{ from: /rgba\(254,\s*202,\s*87,\s*0\.4\)/g, to: 'var(--cm-standard-40)' },
{ from: /rgba\(46,\s*213,\s*115,\s*0\.15\)/g, to: 'var(--cm-gentle-15)' },
{ from: /rgba\(46,\s*213,\s*115,\s*0\.4\)/g, to: 'var(--cm-gentle-40)' },
// Hex urgency colors in lib/urgency.ts
{ from: /'#FF4757'/g, to: "'var(--cm-critical)'" },
{ from: /'#FF9F43'/g, to: "'var(--cm-important)'" },
{ from: /'#FECA57'/g, to: "'var(--cm-standard)'" },
{ from: /'#2ED573'/g, to: "'var(--cm-gentle)'" },
{ from: /'#2EE6D6'/g, to: "'var(--cm-accent-secondary)'" },
{ from: /'#A5B1C7'/g, to: "'var(--cm-passive)'" },
{ from: /'#5A8CFF'/g, to: "'var(--cm-accent)'" },
{ from: /"#FF4757"/g, to: '"var(--cm-critical)"' },
{ from: /"#FF9F43"/g, to: '"var(--cm-important)"' },
{ from: /"#FECA57"/g, to: '"var(--cm-standard)"' },
{ from: /"#2ED573"/g, to: '"var(--cm-gentle)"' },
{ from: /"#2EE6D6"/g, to: '"var(--cm-accent-secondary)"' },
{ from: /"#A5B1C7"/g, to: '"var(--cm-passive)"' },
{ from: /"#5A8CFF"/g, to: '"var(--cm-accent)"' },
];
function findFiles(dir, files = []) {
const items = readdirSync(dir);
for (const item of items) {
const fullPath = join(dir, item);
if (item === 'node_modules' || item === '.next' || item === 'dist') continue;
const stat = statSync(fullPath);
if (stat.isDirectory()) {
findFiles(fullPath, files);
} else if (['.tsx', '.ts', '.jsx', '.js'].includes(extname(item))) {
files.push(fullPath);
}
}
return files;
}
const srcDir = process.argv[2] || 'src';
const files = findFiles(srcDir);
let totalChanges = 0;
for (const file of files) {
let content = readFileSync(file, 'utf-8');
let changed = false;
for (const { from, to } of REPLACEMENTS) {
if (from.test(content)) {
content = content.replace(from, to);
changed = true;
totalChanges++;
}
}
if (changed) {
writeFileSync(file, content);
console.log(`${file.replace(srcDir + '/', '')}`);
}
}
console.log(`\nFixed ${totalChanges} color instances across ${files.length} files`);

View File

@ -18,7 +18,7 @@ export default function FocusPage() {
<header <header
className="sticky top-0 z-40 border-b backdrop-blur-md" className="sticky top-0 z-40 border-b backdrop-blur-md"
style={{ style={{
backgroundColor: 'rgba(6, 7, 10, 0.85)', backgroundColor: 'var(--cm-bg-canvas-85)',
borderColor: 'var(--cm-border)', borderColor: 'var(--cm-border)',
}} }}
> >

View File

@ -27,6 +27,35 @@
--cm-success: #34D399; --cm-success: #34D399;
--cm-warning: #F59E0B; --cm-warning: #F59E0B;
--cm-danger: #FF6E6E; --cm-danger: #FF6E6E;
--cm-white: #FFFFFF;
--cm-black: #000000;
/* Opacity variants for rgba() values */
--cm-critical-15: rgba(255, 71, 87, 0.15);
--cm-critical-20: rgba(255, 71, 87, 0.2);
--cm-critical-40: rgba(255, 71, 87, 0.4);
--cm-important-10: rgba(255, 159, 67, 0.1);
--cm-important-15: rgba(255, 159, 67, 0.15);
--cm-important-40: rgba(255, 159, 67, 0.4);
--cm-standard-15: rgba(254, 202, 87, 0.15);
--cm-standard-40: rgba(254, 202, 87, 0.4);
--cm-gentle-15: rgba(46, 213, 115, 0.15);
--cm-gentle-40: rgba(46, 213, 115, 0.4);
--cm-passive-10: rgba(165, 177, 199, 0.1);
--cm-passive-20: rgba(165, 177, 199, 0.2);
--cm-accent-10: rgba(90, 140, 255, 0.1);
--cm-accent-12: rgba(90, 140, 255, 0.12);
--cm-accent-15: rgba(90, 140, 255, 0.15);
--cm-accent-20: rgba(90, 140, 255, 0.2);
--cm-accent-30: rgba(90, 140, 255, 0.3);
--cm-accent-secondary-10: rgba(46, 230, 214, 0.1);
--cm-accent-secondary-15: rgba(46, 230, 214, 0.15);
--cm-accent-secondary-30: rgba(46, 230, 214, 0.3);
--cm-success-12: rgba(52, 211, 153, 0.12);
--cm-success-15: rgba(52, 211, 153, 0.15);
--cm-bg-canvas-85: rgba(6, 7, 10, 0.85);
--cm-black-80: rgba(0, 0, 0, 0.8);
--cm-black-90: rgba(0, 0, 0, 0.9);
--background: var(--cm-bg-canvas); --background: var(--cm-bg-canvas);
--foreground: var(--cm-text-primary); --foreground: var(--cm-text-primary);

View File

@ -301,8 +301,8 @@ export default function HistoryPage() {
<div <div
className="rounded-xl border p-4 text-sm" className="rounded-xl border p-4 text-sm"
style={{ style={{
backgroundColor: 'rgba(245, 158, 11, 0.1)', backgroundColor: 'var(--cm-warning-10)',
borderColor: 'rgba(245, 158, 11, 0.3)', borderColor: 'var(--cm-warning-30)',
color: 'var(--cm-warning)', color: 'var(--cm-warning)',
}} }}
> >
@ -326,7 +326,7 @@ export default function HistoryPage() {
onClick={handleExport} onClick={handleExport}
disabled={timers.length === 0 && routines.length === 0} disabled={timers.length === 0 && routines.length === 0}
className="flex items-center gap-1.5 px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-30" className="flex items-center gap-1.5 px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-30"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
<Download size={14} /> Export JSON <Download size={14} /> Export JSON
</button> </button>
@ -396,14 +396,14 @@ export default function HistoryPage() {
<button <button
onClick={confirmIcsImport} onClick={confirmIcsImport}
className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-xs font-medium cursor-pointer" className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-xs font-medium cursor-pointer"
style={{ backgroundColor: 'rgba(52,211,153,0.15)', color: 'var(--cm-success)' }} style={{ backgroundColor: 'var(--cm-success-15)', color: 'var(--cm-success)' }}
> >
<Check size={14} /> Import All <Check size={14} /> Import All
</button> </button>
<button <button
onClick={() => setIcsPreview(null)} onClick={() => setIcsPreview(null)}
className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-xs font-medium cursor-pointer" className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-xs font-medium cursor-pointer"
style={{ backgroundColor: 'rgba(255,71,87,0.15)', color: 'var(--cm-danger)' }} style={{ backgroundColor: 'var(--cm-critical-15)', color: 'var(--cm-danger)' }}
> >
<X size={14} /> Cancel <X size={14} /> Cancel
</button> </button>
@ -423,7 +423,7 @@ export default function HistoryPage() {
</span> </span>
</div> </div>
{evt.conflicts.length > 0 && ( {evt.conflicts.length > 0 && (
<span className="text-xs px-1.5 py-0.5 rounded" style={{ backgroundColor: 'rgba(245,158,11,0.15)', color: 'var(--cm-warning)' }}> <span className="text-xs px-1.5 py-0.5 rounded" style={{ backgroundColor: 'var(--cm-warning-15)', color: 'var(--cm-warning)' }}>
Conflict Conflict
</span> </span>
)} )}

View File

@ -48,7 +48,7 @@ export default function LandingPage() {
<Link <Link
href="/" href="/"
className="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-medium" className="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-medium"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
Try it now <ArrowRight size={14} /> Try it now <ArrowRight size={14} />
</Link> </Link>
@ -60,9 +60,9 @@ export default function LandingPage() {
<div <div
className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full text-xs font-medium mb-6" className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full text-xs font-medium mb-6"
style={{ style={{
backgroundColor: 'rgba(90, 140, 255, 0.1)', backgroundColor: 'var(--cm-accent-10)',
color: 'var(--cm-accent)', color: 'var(--cm-accent)',
border: '1px solid rgba(90, 140, 255, 0.2)', border: '1px solid var(--cm-accent-20)',
}} }}
> >
<Zap size={12} /> Free &middot; No signup &middot; Works offline <Zap size={12} /> Free &middot; No signup &middot; Works offline
@ -86,7 +86,7 @@ export default function LandingPage() {
<Link <Link
href="/" href="/"
className="flex items-center gap-2 px-8 py-3.5 rounded-xl text-base font-semibold" className="flex items-center gap-2 px-8 py-3.5 rounded-xl text-base font-semibold"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
Try it now free <ArrowRight size={16} /> Try it now free <ArrowRight size={16} />
</Link> </Link>
@ -154,7 +154,7 @@ export default function LandingPage() {
<Link <Link
href="/" href="/"
className="inline-flex items-center gap-2 px-8 py-3.5 rounded-xl text-base font-semibold" className="inline-flex items-center gap-2 px-8 py-3.5 rounded-xl text-base font-semibold"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
Launch ChronoMind <ArrowRight size={16} /> Launch ChronoMind <ArrowRight size={16} />
</Link> </Link>

View File

@ -15,7 +15,7 @@ const jetbrainsMono = JetBrains_Mono({
}); });
export const viewport: Viewport = { export const viewport: Viewport = {
themeColor: "#5A8CFF", themeColor: "var(--cm-accent)",
width: "device-width", width: "device-width",
initialScale: 1, initialScale: 1,
maximumScale: 1, maximumScale: 1,

View File

@ -74,7 +74,7 @@ function ResetPasswordForm() {
{error && <p className="text-xs" style={{ color: 'var(--cm-danger)' }}>{error}</p>} {error && <p className="text-xs" style={{ color: 'var(--cm-danger)' }}>{error}</p>}
{successMessage && ( {successMessage && (
<div> <div>
<p className="text-xs" style={{ color: 'var(--cm-success, #34d399)' }}>{successMessage}</p> <p className="text-xs" style={{ color: 'var(--cm-success, var(--cm-success))' }}>{successMessage}</p>
<Link href="/settings" className="text-xs mt-2 inline-block" style={{ color: 'var(--cm-accent)' }}> <Link href="/settings" className="text-xs mt-2 inline-block" style={{ color: 'var(--cm-accent)' }}>
Go to Sign In Go to Sign In
</Link> </Link>
@ -85,7 +85,7 @@ function ResetPasswordForm() {
onClick={handleSubmit} onClick={handleSubmit}
disabled={submitting || newPassword.length < 8 || newPassword !== confirmPassword} disabled={submitting || newPassword.length < 8 || newPassword !== confirmPassword}
className="w-full px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-40" className="w-full px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-40"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
{submitting ? 'Resetting…' : 'Reset Password'} {submitting ? 'Resetting…' : 'Reset Password'}
</button> </button>

View File

@ -52,7 +52,7 @@ export default function RoutinesPage() {
<button <button
onClick={() => setShowEditor(true)} onClick={() => setShowEditor(true)}
className="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-medium cursor-pointer" className="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-medium cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
<Plus size={16} /> New Routine <Plus size={16} /> New Routine
</button> </button>
@ -95,7 +95,7 @@ export default function RoutinesPage() {
onClick={() => startFromTemplate(tmpl.id)} onClick={() => startFromTemplate(tmpl.id)}
disabled={!!activeRoutine} disabled={!!activeRoutine}
className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-medium cursor-pointer disabled:opacity-30" className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-medium cursor-pointer disabled:opacity-30"
style={{ backgroundColor: 'rgba(52,211,153,0.15)', color: 'var(--cm-success)' }} style={{ backgroundColor: 'var(--cm-success-15)', color: 'var(--cm-success)' }}
> >
<Play size={14} /> Start <Play size={14} /> Start
</button> </button>
@ -140,7 +140,7 @@ export default function RoutinesPage() {
onClick={() => start(r.id)} onClick={() => start(r.id)}
disabled={!!activeRoutine} disabled={!!activeRoutine}
className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-medium cursor-pointer disabled:opacity-30" className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-xs font-medium cursor-pointer disabled:opacity-30"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
<Play size={14} /> Start <Play size={14} /> Start
</button> </button>

View File

@ -142,13 +142,13 @@ export default function SettingsPage() {
<button <button
onClick={logout} onClick={logout}
className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-sm font-medium cursor-pointer" className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-sm font-medium cursor-pointer"
style={{ backgroundColor: 'rgba(255,71,87,0.15)', color: 'var(--cm-danger)' }} style={{ backgroundColor: 'var(--cm-critical-15)', color: 'var(--cm-danger)' }}
> >
<LogOut size={14} /> Sign Out <LogOut size={14} /> Sign Out
</button> </button>
</div> </div>
{authError && <p className="text-xs mt-2" style={{ color: 'var(--cm-danger)' }}>{authError}</p>} {authError && <p className="text-xs mt-2" style={{ color: 'var(--cm-danger)' }}>{authError}</p>}
{successMessage && <p className="text-xs mt-2" style={{ color: 'var(--cm-success, #34d399)' }}>{successMessage}</p>} {successMessage && <p className="text-xs mt-2" style={{ color: 'var(--cm-success, var(--cm-success))' }}>{successMessage}</p>}
{/* Change Password */} {/* Change Password */}
<div className="mt-4 pt-4" style={{ borderTop: '1px solid var(--cm-border)' }}> <div className="mt-4 pt-4" style={{ borderTop: '1px solid var(--cm-border)' }}>
@ -182,7 +182,7 @@ export default function SettingsPage() {
<button onClick={handleChangePassword} <button onClick={handleChangePassword}
disabled={authSubmitting || !changePwCurrent || changePwNew.length < 8 || changePwNew !== changePwConfirm} disabled={authSubmitting || !changePwCurrent || changePwNew.length < 8 || changePwNew !== changePwConfirm}
className="w-full px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-40" className="w-full px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-40"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
{authSubmitting ? 'Updating…' : 'Update Password'} {authSubmitting ? 'Updating…' : 'Update Password'}
</button> </button>
@ -212,7 +212,7 @@ export default function SettingsPage() {
<button onClick={handleDeleteAccount} <button onClick={handleDeleteAccount}
disabled={authSubmitting || !deleteConfirmPw} disabled={authSubmitting || !deleteConfirmPw}
className="w-full px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-40" className="w-full px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-40"
style={{ backgroundColor: 'var(--cm-danger)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-danger)', color: 'var(--cm-white)' }}
> >
{authSubmitting ? 'Deleting…' : 'Permanently Delete Account'} {authSubmitting ? 'Deleting…' : 'Permanently Delete Account'}
</button> </button>
@ -231,7 +231,7 @@ export default function SettingsPage() {
className="px-3 py-1.5 rounded-lg text-xs font-medium cursor-pointer" className="px-3 py-1.5 rounded-lg text-xs font-medium cursor-pointer"
style={{ style={{
backgroundColor: authMode === 'login' ? 'var(--cm-accent)' : 'var(--cm-surface-muted)', backgroundColor: authMode === 'login' ? 'var(--cm-accent)' : 'var(--cm-surface-muted)',
color: authMode === 'login' ? '#fff' : 'var(--cm-text-secondary)', color: authMode === 'login' ? 'var(--cm-white)' : 'var(--cm-text-secondary)',
}} }}
> >
Sign In Sign In
@ -241,7 +241,7 @@ export default function SettingsPage() {
className="px-3 py-1.5 rounded-lg text-xs font-medium cursor-pointer" className="px-3 py-1.5 rounded-lg text-xs font-medium cursor-pointer"
style={{ style={{
backgroundColor: authMode === 'register' ? 'var(--cm-accent)' : 'var(--cm-surface-muted)', backgroundColor: authMode === 'register' ? 'var(--cm-accent)' : 'var(--cm-surface-muted)',
color: authMode === 'register' ? '#fff' : 'var(--cm-text-secondary)', color: authMode === 'register' ? 'var(--cm-white)' : 'var(--cm-text-secondary)',
}} }}
> >
Create Account Create Account
@ -292,13 +292,13 @@ export default function SettingsPage() {
<p className="text-xs" style={{ color: 'var(--cm-danger)' }}>{authError}</p> <p className="text-xs" style={{ color: 'var(--cm-danger)' }}>{authError}</p>
)} )}
{successMessage && ( {successMessage && (
<p className="text-xs" style={{ color: 'var(--cm-success, #34d399)' }}>{successMessage}</p> <p className="text-xs" style={{ color: 'var(--cm-success, var(--cm-success))' }}>{successMessage}</p>
)} )}
<button <button
onClick={handleAuthSubmit} onClick={handleAuthSubmit}
disabled={authSubmitting || !authEmail || (authMode !== 'forgot' && !authPassword) || (authMode === 'register' && !authName)} disabled={authSubmitting || !authEmail || (authMode !== 'forgot' && !authPassword) || (authMode === 'register' && !authName)}
className="w-full px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-40" className="w-full px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-40"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
{authSubmitting ? 'Please wait…' : authMode === 'login' ? 'Sign In' : authMode === 'register' ? 'Create Account' : 'Send Reset Link'} {authSubmitting ? 'Please wait…' : authMode === 'login' ? 'Sign In' : authMode === 'register' ? 'Create Account' : 'Send Reset Link'}
</button> </button>
@ -366,7 +366,7 @@ export default function SettingsPage() {
className="px-4 py-2 rounded-lg text-sm font-medium cursor-pointer" className="px-4 py-2 rounded-lg text-sm font-medium cursor-pointer"
style={{ style={{
backgroundColor: compactMode ? 'var(--cm-accent)' : 'var(--cm-surface-muted)', backgroundColor: compactMode ? 'var(--cm-accent)' : 'var(--cm-surface-muted)',
color: compactMode ? '#fff' : 'var(--cm-text-secondary)', color: compactMode ? 'var(--cm-white)' : 'var(--cm-text-secondary)',
}} }}
> >
{compactMode ? 'On' : 'Off'} {compactMode ? 'On' : 'Off'}
@ -400,7 +400,7 @@ export default function SettingsPage() {
setNotifPerm(result); setNotifPerm(result);
}} }}
className="px-4 py-2 rounded-lg text-sm font-medium cursor-pointer" className="px-4 py-2 rounded-lg text-sm font-medium cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
Enable Enable
</button> </button>
@ -477,7 +477,7 @@ export default function SettingsPage() {
onClick={clearHistory} onClick={clearHistory}
disabled={completedCount === 0} disabled={completedCount === 0}
className="px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-30" className="px-4 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:opacity-30"
style={{ backgroundColor: 'rgba(255,71,87,0.15)', color: 'var(--cm-danger)' }} style={{ backgroundColor: 'var(--cm-critical-15)', color: 'var(--cm-danger)' }}
> >
Clear Clear
</button> </button>

View File

@ -36,8 +36,8 @@ function VerifyEmailForm() {
)} )}
{status === 'success' && ( {status === 'success' && (
<> <>
<CheckCircle size={48} style={{ color: 'var(--cm-success, #34d399)', margin: '0 auto' }} /> <CheckCircle size={48} style={{ color: 'var(--cm-success, var(--cm-success))', margin: '0 auto' }} />
<p className="text-sm font-medium" style={{ color: 'var(--cm-success, #34d399)' }}>{message}</p> <p className="text-sm font-medium" style={{ color: 'var(--cm-success, var(--cm-success))' }}>{message}</p>
<Link href="/settings" className="text-sm inline-block" style={{ color: 'var(--cm-accent)' }}> <Link href="/settings" className="text-sm inline-block" style={{ color: 'var(--cm-accent)' }}>
Go to Settings Go to Settings
</Link> </Link>

View File

@ -25,8 +25,8 @@ export function AlarmOverlay() {
className="absolute inset-0" className="absolute inset-0"
style={{ style={{
background: isCritical background: isCritical
? `radial-gradient(ellipse at center, ${urgencyConfig.bgColor} 0%, rgba(0,0,0,0.9) 100%)` ? `radial-gradient(ellipse at center, ${urgencyConfig.bgColor} 0%, var(--cm-black-90) 100%)`
: 'rgba(0,0,0,0.8)', : 'var(--cm-black-80)',
}} }}
/> />
@ -63,7 +63,7 @@ export function AlarmOverlay() {
<button <button
onClick={() => advancePom(timer.id)} onClick={() => advancePom(timer.id)}
className="w-full py-3 rounded-xl text-base font-semibold transition-colors cursor-pointer" className="w-full py-3 rounded-xl text-base font-semibold transition-colors cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
{timer.pomodoroState?.isBreak ? 'Start Next Round' : 'Start Break'} {timer.pomodoroState?.isBreak ? 'Start Next Round' : 'Start Break'}
</button> </button>
@ -98,8 +98,8 @@ export function AlarmOverlay() {
onClick={() => dismiss(timer.id)} onClick={() => dismiss(timer.id)}
className="w-full py-3 rounded-xl text-sm font-medium transition-colors cursor-pointer" className="w-full py-3 rounded-xl text-sm font-medium transition-colors cursor-pointer"
style={{ style={{
backgroundColor: isCritical ? urgencyConfig.color : 'rgba(255,71,87,0.2)', backgroundColor: isCritical ? urgencyConfig.color : 'var(--cm-critical-20)',
color: isCritical ? '#fff' : 'var(--cm-danger)', color: isCritical ? 'var(--cm-white)' : 'var(--cm-danger)',
}} }}
> >
{isCritical ? 'Confirm Dismiss' : 'Dismiss'} {isCritical ? 'Confirm Dismiss' : 'Dismiss'}

View File

@ -259,7 +259,7 @@ export function CreateTimerModal({ isOpen, onClose }: CreateTimerModalProps) {
<button <button
onClick={handleNlCreate} onClick={handleNlCreate}
className="px-4 py-2 rounded-lg text-xs font-medium transition-colors cursor-pointer" className="px-4 py-2 rounded-lg text-xs font-medium transition-colors cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent-secondary)', color: '#000' }} style={{ backgroundColor: 'var(--cm-accent-secondary)', color: 'var(--cm-black)' }}
> >
Create Create
</button> </button>
@ -466,7 +466,7 @@ export function CreateTimerModal({ isOpen, onClose }: CreateTimerModalProps) {
className="px-2.5 py-1 rounded-lg text-xs font-medium transition-all cursor-pointer" className="px-2.5 py-1 rounded-lg text-xs font-medium transition-all cursor-pointer"
style={{ style={{
backgroundColor: !category ? 'var(--cm-accent)' : 'var(--cm-surface-muted)', backgroundColor: !category ? 'var(--cm-accent)' : 'var(--cm-surface-muted)',
color: !category ? '#fff' : 'var(--cm-text-tertiary)', color: !category ? 'var(--cm-white)' : 'var(--cm-text-tertiary)',
border: !category ? '1px solid var(--cm-accent)' : '1px solid transparent', border: !category ? '1px solid var(--cm-accent)' : '1px solid transparent',
}} }}
> >
@ -572,7 +572,7 @@ export function CreateTimerModal({ isOpen, onClose }: CreateTimerModalProps) {
className="w-full py-3 rounded-xl text-sm font-semibold transition-colors cursor-pointer" className="w-full py-3 rounded-xl text-sm font-semibold transition-colors cursor-pointer"
style={{ style={{
backgroundColor: 'var(--cm-accent)', backgroundColor: 'var(--cm-accent)',
color: '#fff', color: 'var(--cm-white)',
}} }}
> >
Create {tab === 'pomodoro' ? 'Pomodoro' : tab === 'alarm' ? 'Alarm' : 'Countdown'} Create {tab === 'pomodoro' ? 'Pomodoro' : tab === 'alarm' ? 'Alarm' : 'Countdown'}

View File

@ -124,7 +124,7 @@ export function Dashboard() {
<a <a
href="#main-content" href="#main-content"
className="sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-[60] focus:px-4 focus:py-2 focus:rounded-lg focus:text-sm focus:font-semibold" className="sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-[60] focus:px-4 focus:py-2 focus:rounded-lg focus:text-sm focus:font-semibold"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
Skip to content Skip to content
</a> </a>
@ -139,7 +139,7 @@ export function Dashboard() {
<header <header
className="sticky top-0 z-40 border-b backdrop-blur-md" className="sticky top-0 z-40 border-b backdrop-blur-md"
style={{ style={{
backgroundColor: 'rgba(6, 7, 10, 0.85)', backgroundColor: 'var(--cm-bg-canvas-85)',
borderColor: 'var(--cm-border)', borderColor: 'var(--cm-border)',
}} }}
> >
@ -221,7 +221,7 @@ export function Dashboard() {
<button <button
onClick={() => setIsCreateOpen(true)} onClick={() => setIsCreateOpen(true)}
className="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-medium transition-all cursor-pointer" className="flex items-center gap-2 px-4 py-2 rounded-xl text-sm font-medium transition-all cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
<Plus size={16} /> New Timer <Plus size={16} /> New Timer
</button> </button>
@ -271,7 +271,7 @@ export function Dashboard() {
className="px-3 py-1 rounded-full text-xs font-medium whitespace-nowrap transition-colors cursor-pointer" className="px-3 py-1 rounded-full text-xs font-medium whitespace-nowrap transition-colors cursor-pointer"
style={{ style={{
backgroundColor: !filterCategory ? 'var(--cm-accent)' : 'var(--cm-surface-muted)', backgroundColor: !filterCategory ? 'var(--cm-accent)' : 'var(--cm-surface-muted)',
color: !filterCategory ? '#fff' : 'var(--cm-text-tertiary)', color: !filterCategory ? 'var(--cm-white)' : 'var(--cm-text-tertiary)',
}} }}
> >
All All
@ -303,8 +303,8 @@ export function Dashboard() {
key={suggestion.labelPattern} key={suggestion.labelPattern}
className="rounded-xl border p-3 flex items-center justify-between" className="rounded-xl border p-3 flex items-center justify-between"
style={{ style={{
backgroundColor: 'rgba(90,140,255,0.08)', backgroundColor: 'var(--cm-accent-08)',
borderColor: 'rgba(90,140,255,0.2)', borderColor: 'var(--cm-accent-20)',
}} }}
> >
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
@ -339,7 +339,7 @@ export function Dashboard() {
setDismissedSuggestions((prev) => new Set([...prev, suggestion.labelPattern])); setDismissedSuggestions((prev) => new Set([...prev, suggestion.labelPattern]));
}} }}
className="text-xs px-2 py-1 rounded-lg cursor-pointer" className="text-xs px-2 py-1 rounded-lg cursor-pointer"
style={{ backgroundColor: 'rgba(90,140,255,0.2)', color: 'var(--cm-accent)' }} style={{ backgroundColor: 'var(--cm-accent-20)', color: 'var(--cm-accent)' }}
> >
Accept Accept
</button> </button>
@ -385,7 +385,7 @@ export function Dashboard() {
<button <button
onClick={() => setIsCreateOpen(true)} onClick={() => setIsCreateOpen(true)}
className="inline-flex items-center gap-2 px-6 py-3 rounded-xl text-sm font-semibold transition-all cursor-pointer" className="inline-flex items-center gap-2 px-6 py-3 rounded-xl text-sm font-semibold transition-all cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
<Plus size={18} /> Create Timer <Plus size={18} /> Create Timer
</button> </button>

View File

@ -20,7 +20,7 @@ export function FeedbackButton() {
className="fixed bottom-6 right-6 z-30 p-3 rounded-full shadow-lg transition-all cursor-pointer hover:scale-110" className="fixed bottom-6 right-6 z-30 p-3 rounded-full shadow-lg transition-all cursor-pointer hover:scale-110"
style={{ style={{
backgroundColor: 'var(--cm-accent)', backgroundColor: 'var(--cm-accent)',
color: '#fff', color: 'var(--cm-white)',
}} }}
title="Send feedback" title="Send feedback"
> >
@ -69,7 +69,7 @@ export function FeedbackButton() {
rel="noopener noreferrer" rel="noopener noreferrer"
className="flex items-center gap-2 w-full px-3 py-2 rounded-lg text-sm font-medium transition-colors" className="flex items-center gap-2 w-full px-3 py-2 rounded-lg text-sm font-medium transition-colors"
style={{ style={{
backgroundColor: 'rgba(255,71,87,0.1)', backgroundColor: 'var(--cm-critical-10)',
color: 'var(--cm-danger)', color: 'var(--cm-danger)',
}} }}
> >

View File

@ -138,7 +138,7 @@ export function FocusView({ onExit }: FocusViewProps) {
<div className="text-center max-w-md w-full"> <div className="text-center max-w-md w-full">
<div <div
className="w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6" className="w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6"
style={{ backgroundColor: 'rgba(90, 140, 255, 0.12)' }} style={{ backgroundColor: 'var(--cm-accent-12)' }}
> >
<Eye size={40} style={{ color: 'var(--cm-accent)' }} /> <Eye size={40} style={{ color: 'var(--cm-accent)' }} />
</div> </div>
@ -181,9 +181,9 @@ export function FocusView({ onExit }: FocusViewProps) {
onClick={() => startFocus('until_next', untilNextMs)} onClick={() => startFocus('until_next', untilNextMs)}
className="w-full py-3 rounded-xl text-sm font-medium transition-all cursor-pointer mb-4" className="w-full py-3 rounded-xl text-sm font-medium transition-all cursor-pointer mb-4"
style={{ style={{
backgroundColor: 'rgba(46, 230, 214, 0.1)', backgroundColor: 'var(--cm-accent-secondary-10)',
color: 'var(--cm-accent-secondary)', color: 'var(--cm-accent-secondary)',
border: '1px solid rgba(46, 230, 214, 0.3)', border: '1px solid var(--cm-accent-secondary-30)',
}} }}
> >
<div className="flex items-center justify-center gap-2"> <div className="flex items-center justify-center gap-2">
@ -201,9 +201,9 @@ export function FocusView({ onExit }: FocusViewProps) {
onClick={() => startFocus('pomodoro', 25 * 60_000)} onClick={() => startFocus('pomodoro', 25 * 60_000)}
className="w-full py-3 rounded-xl text-sm font-medium transition-all cursor-pointer" className="w-full py-3 rounded-xl text-sm font-medium transition-all cursor-pointer"
style={{ style={{
backgroundColor: 'rgba(90, 140, 255, 0.1)', backgroundColor: 'var(--cm-accent-10)',
color: 'var(--cm-accent)', color: 'var(--cm-accent)',
border: '1px solid rgba(90, 140, 255, 0.3)', border: '1px solid var(--cm-accent-30)',
}} }}
> >
<div className="flex items-center justify-center gap-2"> <div className="flex items-center justify-center gap-2">
@ -226,7 +226,7 @@ export function FocusView({ onExit }: FocusViewProps) {
<div className="text-center max-w-md w-full"> <div className="text-center max-w-md w-full">
<div <div
className="w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6" className="w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-6"
style={{ backgroundColor: 'rgba(52, 211, 153, 0.12)' }} style={{ backgroundColor: 'var(--cm-success-12)' }}
> >
<Trophy size={40} style={{ color: 'var(--cm-success)' }} /> <Trophy size={40} style={{ color: 'var(--cm-success)' }} />
</div> </div>
@ -279,7 +279,7 @@ export function FocusView({ onExit }: FocusViewProps) {
<button <button
onClick={() => setSession(null)} onClick={() => setSession(null)}
className="px-6 py-3 rounded-xl text-sm font-medium cursor-pointer" className="px-6 py-3 rounded-xl text-sm font-medium cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
Start Another Start Another
</button> </button>
@ -319,7 +319,7 @@ export function FocusView({ onExit }: FocusViewProps) {
> >
{/* Shield badge */} {/* Shield badge */}
<div className="absolute top-6 left-1/2 -translate-x-1/2 flex items-center gap-2 px-4 py-2 rounded-full" <div className="absolute top-6 left-1/2 -translate-x-1/2 flex items-center gap-2 px-4 py-2 rounded-full"
style={{ backgroundColor: 'rgba(90, 140, 255, 0.08)', border: '1px solid rgba(90, 140, 255, 0.2)' }} style={{ backgroundColor: 'var(--cm-accent-08)', border: '1px solid var(--cm-accent-20)' }}
> >
<Shield size={14} style={{ color: 'var(--cm-accent)' }} /> <Shield size={14} style={{ color: 'var(--cm-accent)' }} />
<span className="text-xs font-medium" style={{ color: 'var(--cm-accent)' }}> <span className="text-xs font-medium" style={{ color: 'var(--cm-accent)' }}>
@ -354,7 +354,7 @@ export function FocusView({ onExit }: FocusViewProps) {
<button <button
onClick={resumeFocus} onClick={resumeFocus}
className="flex items-center gap-2 px-6 py-3 rounded-xl text-sm font-medium cursor-pointer" className="flex items-center gap-2 px-6 py-3 rounded-xl text-sm font-medium cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
<Play size={16} /> Resume <Play size={16} /> Resume
</button> </button>
@ -371,7 +371,7 @@ export function FocusView({ onExit }: FocusViewProps) {
<button <button
onClick={endFocus} onClick={endFocus}
className="flex items-center gap-2 px-6 py-3 rounded-xl text-sm font-medium cursor-pointer" className="flex items-center gap-2 px-6 py-3 rounded-xl text-sm font-medium cursor-pointer"
style={{ backgroundColor: 'rgba(255,71,87,0.15)', color: 'var(--cm-danger)' }} style={{ backgroundColor: 'var(--cm-critical-15)', color: 'var(--cm-danger)' }}
> >
<X size={16} /> End Session <X size={16} /> End Session
</button> </button>
@ -400,9 +400,9 @@ export function FocusView({ onExit }: FocusViewProps) {
}} }}
className="px-3 py-1.5 rounded-lg text-xs font-medium transition-all cursor-pointer" className="px-3 py-1.5 rounded-lg text-xs font-medium transition-all cursor-pointer"
style={{ style={{
backgroundColor: ambientType === sound.type ? 'rgba(46,230,214,0.15)' : 'var(--cm-surface-muted)', backgroundColor: ambientType === sound.type ? 'var(--cm-accent-secondary-15)' : 'var(--cm-surface-muted)',
color: ambientType === sound.type ? 'var(--cm-accent-secondary)' : 'var(--cm-text-tertiary)', color: ambientType === sound.type ? 'var(--cm-accent-secondary)' : 'var(--cm-text-tertiary)',
border: ambientType === sound.type ? '1px solid rgba(46,230,214,0.3)' : '1px solid transparent', border: ambientType === sound.type ? '1px solid var(--cm-accent-secondary-30)' : '1px solid transparent',
}} }}
title={sound.description} title={sound.description}
> >

View File

@ -88,7 +88,7 @@ export function InstallPrompt() {
<button <button
onClick={handleInstall} onClick={handleInstall}
className="px-3 py-1.5 rounded-lg text-xs font-semibold transition-colors cursor-pointer whitespace-nowrap" className="px-3 py-1.5 rounded-lg text-xs font-semibold transition-colors cursor-pointer whitespace-nowrap"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
Install Install
</button> </button>

View File

@ -100,7 +100,7 @@ export function OnboardingOverlay() {
<div className="px-6 pt-6 pb-4 text-center"> <div className="px-6 pt-6 pb-4 text-center">
<div <div
className="w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-4" className="w-16 h-16 rounded-2xl flex items-center justify-center mx-auto mb-4"
style={{ backgroundColor: 'rgba(90,140,255,0.12)', color: 'var(--cm-accent)' }} style={{ backgroundColor: 'var(--cm-accent-12)', color: 'var(--cm-accent)' }}
> >
{current.icon} {current.icon}
</div> </div>
@ -143,7 +143,7 @@ export function OnboardingOverlay() {
className="flex-1 py-2.5 rounded-xl text-sm font-semibold transition-colors cursor-pointer flex items-center justify-center gap-1" className="flex-1 py-2.5 rounded-xl text-sm font-semibold transition-colors cursor-pointer flex items-center justify-center gap-1"
style={{ style={{
backgroundColor: 'var(--cm-accent)', backgroundColor: 'var(--cm-accent)',
color: '#fff', color: 'var(--cm-white)',
}} }}
> >
{step === STEPS.length - 1 ? 'Get Started' : 'Next'} {step === STEPS.length - 1 ? 'Get Started' : 'Next'}

View File

@ -49,7 +49,7 @@ export function PomodoroView({ timer }: PomodoroViewProps) {
<div className="flex justify-center mb-4"> <div className="flex justify-center mb-4">
<div <div
className="w-16 h-16 rounded-full flex items-center justify-center" className="w-16 h-16 rounded-full flex items-center justify-center"
style={{ backgroundColor: 'rgba(52,211,153,0.15)' }} style={{ backgroundColor: 'var(--cm-success-15)' }}
> >
<Trophy size={32} style={{ color: 'var(--cm-success)' }} /> <Trophy size={32} style={{ color: 'var(--cm-success)' }} />
</div> </div>
@ -162,7 +162,7 @@ export function PomodoroView({ timer }: PomodoroViewProps) {
<button <button
onClick={() => resume(timer.id)} onClick={() => resume(timer.id)}
className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium transition-colors cursor-pointer" className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium transition-colors cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
<Play size={16} /> Resume <Play size={16} /> Resume
</button> </button>
@ -172,7 +172,7 @@ export function PomodoroView({ timer }: PomodoroViewProps) {
<button <button
onClick={() => advancePom(timer.id)} onClick={() => advancePom(timer.id)}
className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium transition-colors cursor-pointer" className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium transition-colors cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
<SkipForward size={16} /> {isBreak ? 'Start Work' : 'Start Break'} <SkipForward size={16} /> {isBreak ? 'Start Work' : 'Start Break'}
</button> </button>
@ -181,7 +181,7 @@ export function PomodoroView({ timer }: PomodoroViewProps) {
<button <button
onClick={() => dismiss(timer.id)} onClick={() => dismiss(timer.id)}
className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium transition-colors cursor-pointer" className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium transition-colors cursor-pointer"
style={{ backgroundColor: 'rgba(255,71,87,0.15)', color: 'var(--cm-danger)' }} style={{ backgroundColor: 'var(--cm-critical-15)', color: 'var(--cm-danger)' }}
> >
<X size={16} /> End <X size={16} /> End
</button> </button>

View File

@ -41,9 +41,9 @@ export function QuickTimerBar() {
onClick={() => addPomodoro({ label: 'Focus Session' })} onClick={() => addPomodoro({ label: 'Focus Session' })}
className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-sm font-medium transition-all cursor-pointer hover:scale-105" className="flex items-center gap-1.5 px-3 py-2 rounded-lg text-sm font-medium transition-all cursor-pointer hover:scale-105"
style={{ style={{
backgroundColor: 'rgba(90, 140, 255, 0.1)', backgroundColor: 'var(--cm-accent-10)',
color: 'var(--cm-accent)', color: 'var(--cm-accent)',
border: '1px solid rgba(90, 140, 255, 0.2)', border: '1px solid var(--cm-accent-20)',
}} }}
> >
<Coffee size={14} /> Pomodoro <Coffee size={14} /> Pomodoro

View File

@ -277,7 +277,7 @@ export function RoutineEditor({
style={{ style={{
width: `${Math.max(pct, 2)}%`, width: `${Math.max(pct, 2)}%`,
backgroundColor: `hsl(${hue}, 60%, 45%)`, backgroundColor: `hsl(${hue}, 60%, 45%)`,
color: '#fff', color: 'var(--cm-white)',
borderRight: idx < steps.length - 1 ? '1px solid var(--cm-bg-elevated)' : undefined, borderRight: idx < steps.length - 1 ? '1px solid var(--cm-bg-elevated)' : undefined,
}} }}
title={`${step.label || `Step ${idx + 1}`}: ${step.durationMinutes}m`} title={`${step.label || `Step ${idx + 1}`}: ${step.durationMinutes}m`}
@ -360,7 +360,7 @@ export function RoutineEditor({
onClick={handleSave} onClick={handleSave}
disabled={!canSave} disabled={!canSave}
className="flex-1 py-2.5 rounded-xl text-sm font-semibold cursor-pointer disabled:opacity-40" className="flex-1 py-2.5 rounded-xl text-sm font-semibold cursor-pointer disabled:opacity-40"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
{saveAsTemplate ? 'Save Template' : 'Create Routine'} {saveAsTemplate ? 'Save Template' : 'Create Routine'}
</button> </button>

View File

@ -59,7 +59,7 @@ export function RoutineRunner({ routine }: RoutineRunnerProps) {
<div className="flex justify-center mb-4"> <div className="flex justify-center mb-4">
<div <div
className="w-16 h-16 rounded-full flex items-center justify-center" className="w-16 h-16 rounded-full flex items-center justify-center"
style={{ backgroundColor: isCompleted ? 'rgba(52,211,153,0.15)' : 'rgba(255,107,107,0.15)' }} style={{ backgroundColor: isCompleted ? 'var(--cm-success-15)' : 'rgba(255,107,107,0.15)' }}
> >
{isCompleted ? ( {isCompleted ? (
<Trophy size={32} style={{ color: 'var(--cm-success)' }} /> <Trophy size={32} style={{ color: 'var(--cm-success)' }} />
@ -204,7 +204,7 @@ export function RoutineRunner({ routine }: RoutineRunnerProps) {
<button <button
onClick={() => resume(routine.id)} onClick={() => resume(routine.id)}
className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium cursor-pointer" className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent)', color: '#fff' }} style={{ backgroundColor: 'var(--cm-accent)', color: 'var(--cm-white)' }}
> >
<Play size={16} /> Resume <Play size={16} /> Resume
</button> </button>
@ -213,7 +213,7 @@ export function RoutineRunner({ routine }: RoutineRunnerProps) {
<button <button
onClick={() => completeStep(routine.id)} onClick={() => completeStep(routine.id)}
className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium cursor-pointer" className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium cursor-pointer"
style={{ backgroundColor: 'rgba(52,211,153,0.15)', color: 'var(--cm-success)' }} style={{ backgroundColor: 'var(--cm-success-15)', color: 'var(--cm-success)' }}
> >
<CheckCircle2 size={16} /> Done <CheckCircle2 size={16} /> Done
</button> </button>
@ -229,7 +229,7 @@ export function RoutineRunner({ routine }: RoutineRunnerProps) {
<button <button
onClick={() => cancel(routine.id)} onClick={() => cancel(routine.id)}
className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium cursor-pointer" className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-medium cursor-pointer"
style={{ backgroundColor: 'rgba(255,71,87,0.15)', color: 'var(--cm-danger)' }} style={{ backgroundColor: 'var(--cm-critical-15)', color: 'var(--cm-danger)' }}
> >
<X size={16} /> End <X size={16} /> End
</button> </button>

View File

@ -54,7 +54,7 @@ export function StatsView() {
return { return {
name: cat?.label ?? c.categoryId, name: cat?.label ?? c.categoryId,
value: c.count, value: c.count,
color: cat?.color ?? '#5A8CFF', color: cat?.color ?? 'var(--cm-accent)',
}; };
}); });
@ -69,7 +69,7 @@ export function StatsView() {
className="px-3 py-1.5 rounded-lg text-xs font-medium transition-colors cursor-pointer" className="px-3 py-1.5 rounded-lg text-xs font-medium transition-colors cursor-pointer"
style={{ style={{
backgroundColor: range === r ? 'var(--cm-accent)' : 'var(--cm-surface-muted)', backgroundColor: range === r ? 'var(--cm-accent)' : 'var(--cm-surface-muted)',
color: range === r ? '#fff' : 'var(--cm-text-tertiary)', color: range === r ? 'var(--cm-white)' : 'var(--cm-text-tertiary)',
}} }}
> >
{RANGE_LABELS[r]} {RANGE_LABELS[r]}

View File

@ -23,7 +23,7 @@ export function StreakCard({ streak }: StreakCardProps) {
{streakFreezeUsed && ( {streakFreezeUsed && (
<span <span
className="flex items-center gap-1 text-xs px-2 py-0.5 rounded-full" className="flex items-center gap-1 text-xs px-2 py-0.5 rounded-full"
style={{ backgroundColor: 'rgba(90, 140, 255, 0.15)', color: 'var(--cm-accent)' }} style={{ backgroundColor: 'var(--cm-accent-15)', color: 'var(--cm-accent)' }}
> >
<Shield size={12} /> Freeze used <Shield size={12} /> Freeze used
</span> </span>
@ -79,8 +79,8 @@ export function StreakCard({ streak }: StreakCardProps) {
className="mt-3 px-3 py-1.5 rounded-lg text-xs font-medium text-center" className="mt-3 px-3 py-1.5 rounded-lg text-xs font-medium text-center"
style={{ style={{
backgroundColor: currentStreak >= 30 backgroundColor: currentStreak >= 30
? 'rgba(255, 159, 67, 0.15)' ? 'var(--cm-important-15)'
: 'rgba(46, 213, 115, 0.15)', : 'var(--cm-gentle-15)',
color: currentStreak >= 30 ? 'var(--cm-important)' : 'var(--cm-gentle)', color: currentStreak >= 30 ? 'var(--cm-important)' : 'var(--cm-gentle)',
}} }}
> >

View File

@ -106,7 +106,7 @@ export function TimerCard({ timer }: TimerCardProps) {
{timer.recurringTimerId && ( {timer.recurringTimerId && (
<span <span
className="text-xs px-1.5 py-0.5 rounded-full flex items-center gap-0.5" className="text-xs px-1.5 py-0.5 rounded-full flex items-center gap-0.5"
style={{ backgroundColor: 'rgba(46,230,214,0.15)', color: 'var(--cm-accent-secondary)' }} style={{ backgroundColor: 'var(--cm-accent-secondary-15)', color: 'var(--cm-accent-secondary)' }}
title="Recurring timer" title="Recurring timer"
> >
<Repeat size={10} /> <Repeat size={10} />
@ -115,7 +115,7 @@ export function TimerCard({ timer }: TimerCardProps) {
{timer.linkedTimerId && ( {timer.linkedTimerId && (
<span <span
className="text-xs px-1.5 py-0.5 rounded-full" className="text-xs px-1.5 py-0.5 rounded-full"
style={{ backgroundColor: 'rgba(90,140,255,0.15)', color: 'var(--cm-accent)' }} style={{ backgroundColor: 'var(--cm-accent-15)', color: 'var(--cm-accent)' }}
title="Part of a chain" title="Part of a chain"
> >
<Link2 size={12} /> <Link2 size={12} />
@ -126,7 +126,7 @@ export function TimerCard({ timer }: TimerCardProps) {
className="text-xs font-mono px-2 py-0.5 rounded" className="text-xs font-mono px-2 py-0.5 rounded"
style={{ style={{
backgroundColor: isFiring ? urgencyConfig.color : 'var(--cm-surface-muted)', backgroundColor: isFiring ? urgencyConfig.color : 'var(--cm-surface-muted)',
color: isFiring ? '#fff' : 'var(--cm-text-tertiary)', color: isFiring ? 'var(--cm-white)' : 'var(--cm-text-tertiary)',
}} }}
> >
{stateLabel} {stateLabel}
@ -279,7 +279,7 @@ export function TimerCard({ timer }: TimerCardProps) {
className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors cursor-pointer" className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors cursor-pointer"
style={{ style={{
backgroundColor: 'var(--cm-accent)', backgroundColor: 'var(--cm-accent)',
color: '#fff', color: 'var(--cm-white)',
}} }}
> >
<Play size={14} /> Resume <Play size={14} /> Resume
@ -306,7 +306,7 @@ export function TimerCard({ timer }: TimerCardProps) {
<button <button
onClick={() => advancePom(timer.id)} onClick={() => advancePom(timer.id)}
className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors cursor-pointer" className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors cursor-pointer"
style={{ backgroundColor: 'var(--cm-accent-secondary)', color: '#000' }} style={{ backgroundColor: 'var(--cm-accent-secondary)', color: 'var(--cm-black)' }}
> >
Next Next
</button> </button>
@ -318,7 +318,7 @@ export function TimerCard({ timer }: TimerCardProps) {
<button <button
onClick={() => dismiss(timer.id)} onClick={() => dismiss(timer.id)}
className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors cursor-pointer ml-auto" className="flex items-center gap-1 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors cursor-pointer ml-auto"
style={{ backgroundColor: 'rgba(255,71,87,0.15)', color: 'var(--cm-danger)' }} style={{ backgroundColor: 'var(--cm-critical-15)', color: 'var(--cm-danger)' }}
> >
<X size={14} /> Dismiss <X size={14} /> Dismiss
</button> </button>

View File

@ -45,10 +45,10 @@ const ICONS = {
}; };
const COLORS = { const COLORS = {
info: { bg: 'var(--cm-accent)', text: '#fff' }, info: { bg: 'var(--cm-accent)', text: 'var(--cm-white)' },
warning: { bg: 'var(--cm-warning)', text: '#000' }, warning: { bg: 'var(--cm-warning)', text: 'var(--cm-black)' },
success: { bg: 'var(--cm-success)', text: '#000' }, success: { bg: 'var(--cm-success)', text: 'var(--cm-black)' },
alarm: { bg: 'var(--cm-critical)', text: '#fff' }, alarm: { bg: 'var(--cm-critical)', text: 'var(--cm-white)' },
}; };
export function ToastContainer() { export function ToastContainer() {

View File

@ -162,7 +162,7 @@ describe('Categories', () => {
describe('getCategoryColor', () => { describe('getCategoryColor', () => {
it('returns color for valid category', () => { it('returns color for valid category', () => {
expect(getCategoryColor('work')).toBe('#5A8CFF'); expect(getCategoryColor('work')).toBe('var(--cm-accent)');
}); });
it('returns undefined for undefined category', () => { it('returns undefined for undefined category', () => {

View File

@ -20,7 +20,7 @@ export const BUILT_IN_CATEGORIES: Category[] = [
{ {
id: 'work', id: 'work',
label: 'Work', label: 'Work',
color: '#5A8CFF', color: 'var(--cm-accent)',
icon: 'Briefcase', icon: 'Briefcase',
defaultUrgency: 'important', defaultUrgency: 'important',
defaultCascade: 'standard', defaultCascade: 'standard',
@ -38,7 +38,7 @@ export const BUILT_IN_CATEGORIES: Category[] = [
{ {
id: 'health', id: 'health',
label: 'Health', label: 'Health',
color: '#34D399', color: 'var(--cm-success)',
icon: 'Heart', icon: 'Heart',
defaultUrgency: 'important', defaultUrgency: 'important',
defaultCascade: 'standard', defaultCascade: 'standard',
@ -47,7 +47,7 @@ export const BUILT_IN_CATEGORIES: Category[] = [
{ {
id: 'cooking', id: 'cooking',
label: 'Cooking', label: 'Cooking',
color: '#F59E0B', color: 'var(--cm-warning)',
icon: 'ChefHat', icon: 'ChefHat',
defaultUrgency: 'standard', defaultUrgency: 'standard',
defaultCascade: 'light', defaultCascade: 'light',
@ -56,7 +56,7 @@ export const BUILT_IN_CATEGORIES: Category[] = [
{ {
id: 'exercise', id: 'exercise',
label: 'Exercise', label: 'Exercise',
color: '#2EE6D6', color: 'var(--cm-accent-secondary)',
icon: 'Dumbbell', icon: 'Dumbbell',
defaultUrgency: 'standard', defaultUrgency: 'standard',
defaultCascade: 'minimal', defaultCascade: 'minimal',
@ -65,7 +65,7 @@ export const BUILT_IN_CATEGORIES: Category[] = [
{ {
id: 'study', id: 'study',
label: 'Study', label: 'Study',
color: '#FF9F43', color: 'var(--cm-important)',
icon: 'BookOpen', icon: 'BookOpen',
defaultUrgency: 'standard', defaultUrgency: 'standard',
defaultCascade: 'light', defaultCascade: 'light',

View File

@ -22,9 +22,9 @@ export const URGENCY_CONFIGS: Record<UrgencyLevel, UrgencyConfig> = {
critical: { critical: {
level: 'critical', level: 'critical',
label: 'Critical', label: 'Critical',
color: '#FF4757', color: 'var(--cm-critical)',
bgColor: 'rgba(255, 71, 87, 0.15)', bgColor: 'var(--cm-critical-15)',
borderColor: 'rgba(255, 71, 87, 0.4)', borderColor: 'var(--cm-critical-40)',
notificationStyle: 'persistent', notificationStyle: 'persistent',
soundEnabled: true, soundEnabled: true,
vibrationPattern: [200, 100, 200, 100, 400], vibrationPattern: [200, 100, 200, 100, 400],
@ -36,9 +36,9 @@ export const URGENCY_CONFIGS: Record<UrgencyLevel, UrgencyConfig> = {
important: { important: {
level: 'important', level: 'important',
label: 'Important', label: 'Important',
color: '#FF9F43', color: 'var(--cm-important)',
bgColor: 'rgba(255, 159, 67, 0.15)', bgColor: 'var(--cm-important-15)',
borderColor: 'rgba(255, 159, 67, 0.4)', borderColor: 'var(--cm-important-40)',
notificationStyle: 'prominent', notificationStyle: 'prominent',
soundEnabled: true, soundEnabled: true,
vibrationPattern: [200, 100, 200], vibrationPattern: [200, 100, 200],
@ -50,9 +50,9 @@ export const URGENCY_CONFIGS: Record<UrgencyLevel, UrgencyConfig> = {
standard: { standard: {
level: 'standard', level: 'standard',
label: 'Standard', label: 'Standard',
color: '#FECA57', color: 'var(--cm-standard)',
bgColor: 'rgba(254, 202, 87, 0.15)', bgColor: 'var(--cm-standard-15)',
borderColor: 'rgba(254, 202, 87, 0.4)', borderColor: 'var(--cm-standard-40)',
notificationStyle: 'default', notificationStyle: 'default',
soundEnabled: true, soundEnabled: true,
vibrationPattern: [200], vibrationPattern: [200],
@ -64,9 +64,9 @@ export const URGENCY_CONFIGS: Record<UrgencyLevel, UrgencyConfig> = {
gentle: { gentle: {
level: 'gentle', level: 'gentle',
label: 'Gentle', label: 'Gentle',
color: '#2ED573', color: 'var(--cm-gentle)',
bgColor: 'rgba(46, 213, 115, 0.15)', bgColor: 'var(--cm-gentle-15)',
borderColor: 'rgba(46, 213, 115, 0.4)', borderColor: 'var(--cm-gentle-40)',
notificationStyle: 'subtle', notificationStyle: 'subtle',
soundEnabled: true, soundEnabled: true,
vibrationPattern: [100], vibrationPattern: [100],
@ -78,9 +78,9 @@ export const URGENCY_CONFIGS: Record<UrgencyLevel, UrgencyConfig> = {
passive: { passive: {
level: 'passive', level: 'passive',
label: 'Passive', label: 'Passive',
color: '#A5B1C7', color: 'var(--cm-passive)',
bgColor: 'rgba(165, 177, 199, 0.1)', bgColor: 'var(--cm-passive-10)',
borderColor: 'rgba(165, 177, 199, 0.2)', borderColor: 'var(--cm-passive-20)',
notificationStyle: 'badge', notificationStyle: 'badge',
soundEnabled: false, soundEnabled: false,
vibrationPattern: [], vibrationPattern: [],