ci: update CI/CD configuration
This commit is contained in:
parent
411cc17c3c
commit
2e2f3c25ca
0
.windsurf/workflows/comi.md
Normal file
0
.windsurf/workflows/comi.md
Normal file
102
web/scripts/fix-colors.cjs
Normal file
102
web/scripts/fix-colors.cjs
Normal 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`);
|
||||||
@ -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)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -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 · No signup · Works offline
|
<Zap size={12} /> Free · No signup · 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>
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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'}
|
||||||
|
|||||||
@ -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'}
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -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}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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'}
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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]}
|
||||||
|
|||||||
@ -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)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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() {
|
||||||
|
|||||||
@ -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', () => {
|
||||||
|
|||||||
@ -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',
|
||||||
|
|||||||
@ -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: [],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user