From 2c19b7a4274d8d15c120712140868ee367a1e30f Mon Sep 17 00:00:00 2001 From: Dmitrii Krosh Date: Thu, 23 Jul 2026 02:24:32 +0300 Subject: [PATCH] theme fix --- src/App.css | 37 ++++++++++++++++++-------------- src/App.test.tsx | 20 +++++++++++++++++ src/App.tsx | 1 + src/features/settings/options.ts | 6 +++--- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/App.css b/src/App.css index 7d2921b..a5124e9 100644 --- a/src/App.css +++ b/src/App.css @@ -28,7 +28,6 @@ background-image: var(--background-image); background-position: center; background-size: cover; - transition: background-image 350ms ease; } .app::after { @@ -63,11 +62,14 @@ --accent: #a84524; } -.app.theme-black .orb, -.app.theme-white .orb { +.app .orb { display: none; } +.app.theme-violet .orb { + display: block; +} + .app.theme-light::after { background: rgb(0 0 0 / var(--light-overlay-opacity, 0.07)); } @@ -168,12 +170,6 @@ animation: liquid-float 22s ease-in-out infinite alternate; } -.app.theme-motion-lava .orb, -.app.theme-motion-liquid .orb { - opacity: 0.38; - animation: orb-breathe 14s ease-in-out infinite alternate; -} - .topbar { display: flex; align-items: center; @@ -264,11 +260,25 @@ position: fixed; inset: 0; z-index: 2; - display: grid; - place-items: center; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 1.1rem; cursor: default; } +.focus-mode-phase { + margin: 0; + color: var(--clock-color, currentColor); + font-family: var(--app-font, 'Space Grotesk', sans-serif); + font-size: clamp(0.75rem, 1.8vw, 1rem); + font-weight: 700; + letter-spacing: 0.18em; + opacity: 0.72; + text-transform: uppercase; +} + .focus-mode-time { color: var(--clock-color, currentColor); font-family: var(--app-font, 'Space Grotesk', sans-serif); @@ -882,11 +892,6 @@ h1 { 100% { background-position: 35% 55%; transform: scale(1.04) rotate(-1deg); } } -@keyframes orb-breathe { - 0% { transform: translate3d(-4%, 2%, 0) scale(0.9); } - 100% { transform: translate3d(8%, -7%, 0) scale(1.18); } -} - @keyframes fade-in { from { opacity: 0; } } diff --git a/src/App.test.tsx b/src/App.test.tsx index 001b346..7ab96b9 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -136,6 +136,7 @@ describe('Pomodoro app', () => { const focusModeTrigger = screen.getByRole('button', { name: 'Enter focus mode' }) fireEvent.click(focusModeTrigger) expect(screen.getByLabelText('Current time with seconds')).toHaveTextContent('10:08:09') + expect(screen.getByText('Focus session')).toBeInTheDocument() expect(screen.queryByRole('button', { name: 'Customize' })).not.toBeInTheDocument() expect(screen.queryByLabelText('Time remaining')).not.toBeInTheDocument() @@ -181,6 +182,7 @@ describe('Pomodoro app', () => { fireEvent.click(screen.getByRole('button', { name: 'Enter focus mode' })) expect(screen.getByLabelText('Short break time remaining')).toHaveTextContent('05:00') + expect(screen.getByText('Short break')).toBeInTheDocument() }) it('starts, pauses, resumes, and resets the countdown', async () => { @@ -345,13 +347,31 @@ describe('Pomodoro app', () => { fireEvent.click(screen.getByRole('radio', { name: 'Lava bloom' })) const app = screen.getByTestId('app') expect(app).toHaveClass('theme-motion-lava') + expect(app.style.getPropertyValue('--background-image')).not.toMatch(/,\s*#[0-9a-f]{6}$/i) fireEvent.click(screen.getByRole('radio', { name: 'Liquid aurora' })) expect(app).toHaveClass('theme-motion-liquid') + expect(app.style.getPropertyValue('--background-image')).not.toMatch(/,\s*#[0-9a-f]{6}$/i) expect(appCss).toMatch(/@keyframes lava-drift/) expect(appCss).toMatch(/@keyframes liquid-float/) }) + it('shows the decorative color orbs only on Violet haze', async () => { + await renderHydratedApp() + expect(appCss).toMatch(/\.app \.orb\s*{[\s\S]*display:\s*none/) + expect(appCss).toMatch(/\.app\.theme-violet \.orb\s*{[\s\S]*display:\s*block/) + }) + + it('applies a valid green background to Quiet aurora', async () => { + await renderHydratedApp() + fireEvent.click(screen.getByRole('button', { name: 'Customize' })) + fireEvent.click(screen.getByRole('radio', { name: 'Quiet aurora' })) + + const background = screen.getByTestId('app').style.getPropertyValue('--background-image') + expect(background).toContain('#2e9f83') + expect(background).not.toMatch(/,\s*#[0-9a-f]{6}$/i) + }) + it('keeps a custom clock color behind a separate control when themes change', async () => { const store = new MemorySettingsStore() await renderHydratedApp(store) diff --git a/src/App.tsx b/src/App.tsx index ac7c35b..4cd815f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -455,6 +455,7 @@ function App({ {focusMode && (
+

{PHASE_LABELS[timer.phase]}

{timer.status === 'idle' ? (