adeism commited on
Commit
29d0808
·
verified ·
1 Parent(s): fd9c416

Add 1 files

Browse files
Files changed (1) hide show
  1. index.html +642 -38
index.html CHANGED
@@ -1,41 +1,645 @@
1
  <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>My app</title>
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <meta charset="utf-8">
 
 
7
  <style>
8
- body {
9
- display: flex;
10
- justify-content: center;
11
- align-items: center;
12
- overflow: hidden;
13
- height: 100dvh;
14
- font-family: "Arial", sans-serif;
15
- text-align: center;
16
- }
17
- .arrow {
18
- position: absolute;
19
- bottom: 32px;
20
- left: 0px;
21
- width: 100px;
22
- transform: rotate(30deg);
23
- }
24
- h1 {
25
- font-size: 50px;
26
- }
27
- h1 span {
28
- color: #acacac;
29
- font-size: 32px;
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  </style>
32
- </head>
33
- <body>
34
- <h1>
35
- <span>I'm ready to work,</span><br />
36
- Ask me anything.
37
- </h1>
38
- <img src="https://enzostvs-deepsite.hf.space/arrow.svg" class="arrow" />
39
- <script></script>
40
- <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=adeism/padomoro-timer" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
41
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Serene Pomodoro Timer</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
11
+
12
+ body {
13
+ font-family: 'Poppins', sans-serif;
14
+ background-image: url('https://images.unsplash.com/photo-1500382018106-4073a5091250?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80');
15
+ background-size: cover;
16
+ background-position: center;
17
+ background-attachment: fixed;
18
+ transition: background-color 0.5s ease;
19
+ }
20
+
21
+ .timer-container {
22
+ backdrop-filter: blur(10px);
23
+ background-color: rgba(255, 255, 255, 0.85);
24
+ box-shadow: 0 8px 32px rgba(31, 38, 135, 0.15);
25
+ }
26
+
27
+ .progress-ring__circle {
28
+ transition: stroke-dashoffset 0.35s;
29
+ transform: rotate(-90deg);
30
+ transform-origin: 50% 50%;
31
+ }
32
+
33
+ .tab-active {
34
+ position: relative;
35
+ }
36
+
37
+ .tab-active::after {
38
+ content: '';
39
+ position: absolute;
40
+ bottom: -8px;
41
+ left: 50%;
42
+ transform: translateX(-50%);
43
+ width: 30px;
44
+ height: 3px;
45
+ background-color: #4F46E5;
46
+ border-radius: 3px;
47
+ }
48
+
49
+ .settings-panel {
50
+ max-height: 0;
51
+ overflow: hidden;
52
+ transition: max-height 0.3s ease-out;
53
+ }
54
+
55
+ .settings-open {
56
+ max-height: 600px; /* Increased to accommodate sound options */
57
+ overflow-y: auto; /* Add scroll if needed */
58
+ }
59
+
60
+ /* Custom range slider */
61
+ input[type="range"] {
62
+ -webkit-appearance: none;
63
+ height: 6px;
64
+ background: #E5E7EB;
65
+ border-radius: 5px;
66
+ background-image: linear-gradient(#4F46E5, #4F46E5);
67
+ background-size: 0% 100%;
68
+ background-repeat: no-repeat;
69
+ }
70
+
71
+ input[type="range"]::-webkit-slider-thumb {
72
+ -webkit-appearance: none;
73
+ height: 20px;
74
+ width: 20px;
75
+ border-radius: 50%;
76
+ background: #4F46E5;
77
+ cursor: pointer;
78
+ box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1);
79
+ transition: all 0.3s ease;
80
+ }
81
+
82
+ input[type="range"]::-webkit-slider-thumb:hover {
83
+ transform: scale(1.2);
84
+ box-shadow: 0 0 5px rgba(79, 70, 229, 0.5);
85
+ }
86
+
87
+ /* Toggle switch */
88
+ .toggle-checkbox:checked {
89
+ right: 0;
90
+ border-color: #4F46E5;
91
+ }
92
+
93
+ .toggle-checkbox:checked + .toggle-label {
94
+ background-color: #4F46E5;
95
+ }
96
+
97
+ /* Nature sounds selector */
98
+ .sound-option {
99
+ transition: all 0.2s ease;
100
+ }
101
+
102
+ .sound-option:hover {
103
+ transform: translateY(-2px);
104
+ }
105
+
106
+ .sound-option.selected {
107
+ border-color: #4F46E5;
108
+ background-color: rgba(79, 70, 229, 0.1);
109
+ }
110
+
111
+ /* Animation for timer buttons */
112
+ @keyframes pulse {
113
+ 0% { transform: scale(1); }
114
+ 50% { transform: scale(1.05); }
115
+ 100% { transform: scale(1); }
116
+ }
117
+
118
+ .pulse {
119
+ animation: pulse 2s infinite;
120
+ }
121
+
122
+ /* Custom scrollbar for settings panel */
123
+ .settings-panel::-webkit-scrollbar {
124
+ width: 6px;
125
+ }
126
+
127
+ .settings-panel::-webkit-scrollbar-track {
128
+ background: rgba(0, 0, 0, 0.05);
129
+ border-radius: 3px;
130
+ }
131
+
132
+ .settings-panel::-webkit-scrollbar-thumb {
133
+ background: rgba(79, 70, 229, 0.3);
134
+ border-radius: 3px;
135
+ }
136
+
137
+ .settings-panel::-webkit-scrollbar-thumb:hover {
138
+ background: rgba(79, 70, 229, 0.5);
139
+ }
140
  </style>
141
+ </head>
142
+ <body class="min-h-screen flex items-center justify-center p-4">
143
+ <div class="timer-container rounded-2xl p-8 w-full max-w-md">
144
+ <!-- Timer Mode Tabs -->
145
+ <div class="flex justify-center mb-8">
146
+ <div class="flex space-x-6 bg-gray-100 p-1 rounded-full">
147
+ <button id="pomodoro-tab" class="tab-active px-4 py-2 text-indigo-600 font-medium focus:outline-none">
148
+ Pomodoro
149
+ </button>
150
+ <button id="short-break-tab" class="px-4 py-2 text-gray-600 font-medium focus:outline-none">
151
+ Short Break
152
+ </button>
153
+ <button id="long-break-tab" class="px-4 py-2 text-gray-600 font-medium focus:outline-none">
154
+ Long Break
155
+ </button>
156
+ </div>
157
+ </div>
158
+
159
+ <!-- Timer Display -->
160
+ <div class="flex justify-center mb-8">
161
+ <div class="relative w-64 h-64">
162
+ <svg class="w-full h-full" viewBox="0 0 100 100">
163
+ <circle class="text-gray-200" stroke-width="6" stroke="currentColor" fill="transparent" r="45" cx="50" cy="50" />
164
+ <circle id="progress-ring" class="progress-ring__circle text-indigo-500" stroke-width="6" stroke-linecap="round" stroke="currentColor" fill="transparent" r="45" cx="50" cy="50" />
165
+ </svg>
166
+ <div class="absolute inset-0 flex flex-col items-center justify-center">
167
+ <div id="time-display" class="text-5xl font-bold text-gray-800">25:00</div>
168
+ <button id="timer-control" class="mt-4 px-8 py-2 bg-indigo-600 text-white rounded-full font-medium focus:outline-none hover:bg-indigo-700 transition">
169
+ START
170
+ </button>
171
+ </div>
172
+ </div>
173
+ </div>
174
+
175
+ <!-- Current Session Info -->
176
+ <div id="session-info" class="text-center text-gray-600 mb-8">
177
+ <p>Session #1 • Focus Time</p>
178
+ </div>
179
+
180
+ <!-- Settings Button -->
181
+ <div class="flex justify-center mb-4">
182
+ <button id="settings-button" class="text-gray-600 hover:text-indigo-600 focus:outline-none transition">
183
+ <i class="fas fa-cog text-2xl"></i>
184
+ </button>
185
+ </div>
186
+
187
+ <!-- Settings Panel -->
188
+ <div id="settings-panel" class="settings-panel bg-gray-50 rounded-xl p-6">
189
+ <h3 class="text-lg font-semibold text-gray-800 mb-4">Timer Settings</h3>
190
+
191
+ <div class="space-y-6">
192
+ <!-- Pomodoro Duration -->
193
+ <div>
194
+ <label class="block text-sm font-medium text-gray-700 mb-2">Pomodoro (minutes)</label>
195
+ <div class="flex items-center space-x-4">
196
+ <input id="pomodoro-duration" type="range" min="5" max="60" value="25" class="w-full">
197
+ <span id="pomodoro-value" class="text-gray-700 font-medium w-10 text-center">25</span>
198
+ </div>
199
+ </div>
200
+
201
+ <!-- Short Break Duration -->
202
+ <div>
203
+ <label class="block text-sm font-medium text-gray-700 mb-2">Short Break (minutes)</label>
204
+ <div class="flex items-center space-x-4">
205
+ <input id="short-break-duration" type="range" min="1" max="15" value="5" class="w-full">
206
+ <span id="short-break-value" class="text-gray-700 font-medium w-10 text-center">5</span>
207
+ </div>
208
+ </div>
209
+
210
+ <!-- Long Break Duration -->
211
+ <div>
212
+ <label class="block text-sm font-medium text-gray-700 mb-2">Long Break (minutes)</label>
213
+ <div class="flex items-center space-x-4">
214
+ <input id="long-break-duration" type="range" min="10" max="30" value="15" class="w-full">
215
+ <span id="long-break-value" class="text-gray-700 font-medium w-10 text-center">15</span>
216
+ </div>
217
+ </div>
218
+
219
+ <!-- Auto-start Breaks -->
220
+ <div class="flex items-center justify-between">
221
+ <label class="text-sm font-medium text-gray-700">Auto-start Breaks</label>
222
+ <div class="relative inline-block w-10 mr-2 align-middle select-none">
223
+ <input type="checkbox" id="auto-start-breaks" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"/>
224
+ <label for="auto-start-breaks" class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label>
225
+ </div>
226
+ </div>
227
+
228
+ <!-- Auto-start Pomodoros -->
229
+ <div class="flex items-center justify-between">
230
+ <label class="text-sm font-medium text-gray-700">Auto-start Pomodoros</label>
231
+ <div class="relative inline-block w-10 mr-2 align-middle select-none">
232
+ <input type="checkbox" id="auto-start-pomodoros" class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer"/>
233
+ <label for="auto-start-pomodoros" class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label>
234
+ </div>
235
+ </div>
236
+
237
+ <!-- Long Break Interval -->
238
+ <div>
239
+ <label class="block text-sm font-medium text-gray-700 mb-2">Long Break Interval (pomodoros)</label>
240
+ <div class="flex items-center space-x-4">
241
+ <input id="long-break-interval" type="range" min="2" max="8" value="4" class="w-full">
242
+ <span id="long-break-interval-value" class="text-gray-700 font-medium w-10 text-center">4</span>
243
+ </div>
244
+ </div>
245
+
246
+ <!-- Nature Sounds -->
247
+ <div>
248
+ <label class="block text-sm font-medium text-gray-700 mb-2">Nature Sounds</label>
249
+ <div class="grid grid-cols-3 gap-3">
250
+ <div class="sound-option border rounded-lg p-3 text-center cursor-pointer">
251
+ <i class="fas fa-wind text-xl text-gray-600 mb-1"></i>
252
+ <p class="text-xs">Forest</p>
253
+ </div>
254
+ <div class="sound-option border rounded-lg p-3 text-center cursor-pointer selected">
255
+ <i class="fas fa-water text-xl text-gray-600 mb-1"></i>
256
+ <p class="text-xs">Rain</p>
257
+ </div>
258
+ <div class="sound-option border rounded-lg p-3 text-center cursor-pointer">
259
+ <i class="fas fa-feather text-xl text-gray-600 mb-1"></i>
260
+ <p class="text-xs">Birds</p>
261
+ </div>
262
+ <div class="sound-option border rounded-lg p-3 text-center cursor-pointer">
263
+ <i class="fas fa-fire text-xl text-gray-600 mb-1"></i>
264
+ <p class="text-xs">Fire</p>
265
+ </div>
266
+ <div class="sound-option border rounded-lg p-3 text-center cursor-pointer">
267
+ <i class="fas fa-umbrella-beach text-xl text-gray-600 mb-1"></i>
268
+ <p class="text-xs">Waves</p>
269
+ </div>
270
+ <div class="sound-option border rounded-lg p-3 text-center cursor-pointer">
271
+ <i class="fas fa-volume-mute text-xl text-gray-600 mb-1"></i>
272
+ <p class="text-xs">None</p>
273
+ </div>
274
+ </div>
275
+ </div>
276
+ </div>
277
+
278
+ <div class="mt-6 flex justify-end">
279
+ <button id="save-settings" class="px-4 py-2 bg-indigo-600 text-white rounded-lg font-medium focus:outline-none hover:bg-indigo-700 transition">
280
+ Save Settings
281
+ </button>
282
+ </div>
283
+ </div>
284
+ </div>
285
+
286
+ <audio id="tick-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-clock-countdown-bleeps-916.mp3" preload="auto"></audio>
287
+ <audio id="alarm-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-alarm-digital-clock-beep-989.mp3" preload="auto"></audio>
288
+ <audio id="nature-sound" loop src="https://assets.mixkit.co/sfx/preview/mixkit-rain-loop-1243.mp3" preload="auto"></audio>
289
+
290
+ <script>
291
+ document.addEventListener('DOMContentLoaded', function() {
292
+ // DOM Elements
293
+ const timeDisplay = document.getElementById('time-display');
294
+ const timerControl = document.getElementById('timer-control');
295
+ const sessionInfo = document.getElementById('session-info');
296
+ const progressRing = document.getElementById('progress-ring');
297
+ const settingsButton = document.getElementById('settings-button');
298
+ const settingsPanel = document.getElementById('settings-panel');
299
+ const saveSettings = document.getElementById('save-settings');
300
+ const pomodoroTab = document.getElementById('pomodoro-tab');
301
+ const shortBreakTab = document.getElementById('short-break-tab');
302
+ const longBreakTab = document.getElementById('long-break-tab');
303
+ const tickSound = document.getElementById('tick-sound');
304
+ const alarmSound = document.getElementById('alarm-sound');
305
+ const natureSound = document.getElementById('nature-sound');
306
+
307
+ // Timer state
308
+ let timer;
309
+ let isRunning = false;
310
+ let timeLeft = 25 * 60; // 25 minutes in seconds
311
+ let totalTime = 25 * 60;
312
+ let currentMode = 'pomodoro'; // 'pomodoro', 'shortBreak', 'longBreak'
313
+ let sessionsCompleted = 0;
314
+ let longBreakInterval = 4;
315
+ let autoStartBreaks = false;
316
+ let autoStartPomodoros = false;
317
+ let natureSoundEnabled = true;
318
+
319
+ // Initialize UI
320
+ updateTimeDisplay();
321
+ updateProgressRing();
322
+ setupRangeInputs();
323
+ setupSoundOptions();
324
+
325
+ // Event Listeners
326
+ timerControl.addEventListener('click', toggleTimer);
327
+ settingsButton.addEventListener('click', toggleSettings);
328
+ saveSettings.addEventListener('click', saveTimerSettings);
329
+ pomodoroTab.addEventListener('click', () => switchMode('pomodoro'));
330
+ shortBreakTab.addEventListener('click', () => switchMode('shortBreak'));
331
+ longBreakTab.addEventListener('click', () => switchMode('longBreak'));
332
+
333
+ // Timer Functions
334
+ function toggleTimer() {
335
+ if (isRunning) {
336
+ pauseTimer();
337
+ } else {
338
+ startTimer();
339
+ }
340
+ }
341
+
342
+ function startTimer() {
343
+ if (!isRunning) {
344
+ isRunning = true;
345
+ timerControl.textContent = 'PAUSE';
346
+ timerControl.classList.remove('bg-indigo-600', 'hover:bg-indigo-700');
347
+ timerControl.classList.add('bg-amber-500', 'hover:bg-amber-600');
348
+
349
+ if (natureSoundEnabled) {
350
+ natureSound.play().catch(e => console.log("Audio play failed:", e));
351
+ }
352
+
353
+ timer = setInterval(() => {
354
+ timeLeft--;
355
+ updateTimeDisplay();
356
+ updateProgressRing();
357
+
358
+ // Play tick sound every second
359
+ if (timeLeft > 0 && timeLeft % 60 === 0) {
360
+ tickSound.currentTime = 0;
361
+ tickSound.play().catch(e => console.log("Tick sound play failed:", e));
362
+ }
363
+
364
+ if (timeLeft <= 0) {
365
+ clearInterval(timer);
366
+ timerComplete();
367
+ }
368
+ }, 1000);
369
+ }
370
+ }
371
+
372
+ function pauseTimer() {
373
+ if (isRunning) {
374
+ isRunning = false;
375
+ timerControl.textContent = 'RESUME';
376
+ timerControl.classList.remove('bg-amber-500', 'hover:bg-amber-600');
377
+ timerControl.classList.add('bg-indigo-600', 'hover:bg-indigo-700');
378
+
379
+ natureSound.pause();
380
+ clearInterval(timer);
381
+ }
382
+ }
383
+
384
+ function timerComplete() {
385
+ isRunning = false;
386
+ alarmSound.play().catch(e => console.log("Alarm sound play failed:", e));
387
+ natureSound.pause();
388
+
389
+ if (currentMode === 'pomodoro') {
390
+ sessionsCompleted++;
391
+
392
+ // Check if it's time for a long break
393
+ if (sessionsCompleted % longBreakInterval === 0) {
394
+ if (autoStartBreaks) {
395
+ setTimeout(() => switchMode('longBreak'), 1000);
396
+ } else {
397
+ timerControl.textContent = 'START LONG BREAK';
398
+ updateSessionInfo(`Pomodoro completed! Take a long break.`);
399
+ }
400
+ } else {
401
+ if (autoStartBreaks) {
402
+ setTimeout(() => switchMode('shortBreak'), 1000);
403
+ } else {
404
+ timerControl.textContent = 'START SHORT BREAK';
405
+ updateSessionInfo(`Pomodoro completed! Take a short break.`);
406
+ }
407
+ }
408
+ } else {
409
+ if (autoStartPomodoros) {
410
+ setTimeout(() => switchMode('pomodoro'), 1000);
411
+ } else {
412
+ timerControl.textContent = 'START POMODORO';
413
+ updateSessionInfo(`Break completed! Ready for next pomodoro?`);
414
+ }
415
+ }
416
+
417
+ timerControl.classList.remove('bg-amber-500', 'hover:bg-amber-600');
418
+ timerControl.classList.add('bg-green-500', 'hover:bg-green-600', 'pulse');
419
+ }
420
+
421
+ function switchMode(mode) {
422
+ // Reset timer state
423
+ clearInterval(timer);
424
+ isRunning = false;
425
+ timerControl.classList.remove('pulse', 'bg-green-500', 'hover:bg-green-600', 'bg-amber-500', 'hover:bg-amber-600');
426
+ timerControl.classList.add('bg-indigo-600', 'hover:bg-indigo-700');
427
+ timerControl.textContent = 'START';
428
+ natureSound.pause();
429
+
430
+ // Update UI for selected tab
431
+ pomodoroTab.classList.remove('tab-active', 'text-indigo-600');
432
+ pomodoroTab.classList.add('text-gray-600');
433
+ shortBreakTab.classList.remove('tab-active', 'text-indigo-600');
434
+ shortBreakTab.classList.add('text-gray-600');
435
+ longBreakTab.classList.remove('tab-active', 'text-indigo-600');
436
+ longBreakTab.classList.add('text-gray-600');
437
+
438
+ // Set new mode
439
+ currentMode = mode;
440
+
441
+ // Set time based on mode
442
+ if (mode === 'pomodoro') {
443
+ timeLeft = parseInt(document.getElementById('pomodoro-duration').value) * 60;
444
+ totalTime = timeLeft;
445
+ pomodoroTab.classList.add('tab-active', 'text-indigo-600');
446
+ updateSessionInfo(`Session #${Math.floor(sessionsCompleted/longBreakInterval) + 1} • Focus Time`);
447
+ } else if (mode === 'shortBreak') {
448
+ timeLeft = parseInt(document.getElementById('short-break-duration').value) * 60;
449
+ totalTime = timeLeft;
450
+ shortBreakTab.classList.add('tab-active', 'text-indigo-600');
451
+ updateSessionInfo(`Short Break • Relax`);
452
+ } else if (mode === 'longBreak') {
453
+ timeLeft = parseInt(document.getElementById('long-break-duration').value) * 60;
454
+ totalTime = timeLeft;
455
+ longBreakTab.classList.add('tab-active', 'text-indigo-600');
456
+ updateSessionInfo(`Long Break • Recharge`);
457
+ }
458
+
459
+ updateTimeDisplay();
460
+ updateProgressRing();
461
+
462
+ // Auto-start if enabled
463
+ if ((mode === 'shortBreak' || mode === 'longBreak') && autoStartBreaks) {
464
+ startTimer();
465
+ } else if (mode === 'pomodoro' && autoStartPomodoros) {
466
+ startTimer();
467
+ }
468
+ }
469
+
470
+ function updateTimeDisplay() {
471
+ const minutes = Math.floor(timeLeft / 60);
472
+ const seconds = timeLeft % 60;
473
+ timeDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
474
+ }
475
+
476
+ function updateProgressRing() {
477
+ const circumference = 2 * Math.PI * 45;
478
+ const offset = circumference - (timeLeft / totalTime) * circumference;
479
+ progressRing.style.strokeDasharray = `${circumference} ${circumference}`;
480
+ progressRing.style.strokeDashoffset = offset;
481
+
482
+ // Change color based on time left
483
+ if (timeLeft / totalTime < 0.25) {
484
+ progressRing.classList.remove('text-indigo-500', 'text-amber-500');
485
+ progressRing.classList.add('text-red-500');
486
+ } else if (timeLeft / totalTime < 0.5) {
487
+ progressRing.classList.remove('text-indigo-500', 'text-red-500');
488
+ progressRing.classList.add('text-amber-500');
489
+ } else {
490
+ progressRing.classList.remove('text-amber-500', 'text-red-500');
491
+ progressRing.classList.add('text-indigo-500');
492
+ }
493
+ }
494
+
495
+ function updateSessionInfo(text) {
496
+ sessionInfo.textContent = text;
497
+ }
498
+
499
+ // Settings Functions
500
+ function toggleSettings() {
501
+ settingsPanel.classList.toggle('settings-open');
502
+ settingsButton.innerHTML = settingsPanel.classList.contains('settings-open') ?
503
+ '<i class="fas fa-times text-2xl"></i>' : '<i class="fas fa-cog text-2xl"></i>';
504
+ }
505
+
506
+ function setupRangeInputs() {
507
+ // Pomodoro duration
508
+ const pomodoroDuration = document.getElementById('pomodoro-duration');
509
+ const pomodoroValue = document.getElementById('pomodoro-value');
510
+ pomodoroDuration.addEventListener('input', () => {
511
+ pomodoroValue.textContent = pomodoroDuration.value;
512
+ updateBackgroundSize(pomodoroDuration);
513
+ });
514
+ updateBackgroundSize(pomodoroDuration);
515
+
516
+ // Short break duration
517
+ const shortBreakDuration = document.getElementById('short-break-duration');
518
+ const shortBreakValue = document.getElementById('short-break-value');
519
+ shortBreakDuration.addEventListener('input', () => {
520
+ shortBreakValue.textContent = shortBreakDuration.value;
521
+ updateBackgroundSize(shortBreakDuration);
522
+ });
523
+ updateBackgroundSize(shortBreakDuration);
524
+
525
+ // Long break duration
526
+ const longBreakDuration = document.getElementById('long-break-duration');
527
+ const longBreakValue = document.getElementById('long-break-value');
528
+ longBreakDuration.addEventListener('input', () => {
529
+ longBreakValue.textContent = longBreakDuration.value;
530
+ updateBackgroundSize(longBreakDuration);
531
+ });
532
+ updateBackgroundSize(longBreakDuration);
533
+
534
+ // Long break interval
535
+ const longBreakIntervalInput = document.getElementById('long-break-interval');
536
+ const longBreakIntervalValue = document.getElementById('long-break-interval-value');
537
+ longBreakIntervalInput.addEventListener('input', () => {
538
+ longBreakIntervalValue.textContent = longBreakIntervalInput.value;
539
+ updateBackgroundSize(longBreakIntervalInput);
540
+ });
541
+ updateBackgroundSize(longBreakIntervalInput);
542
+ }
543
+
544
+ function updateBackgroundSize(rangeInput) {
545
+ const value = rangeInput.value;
546
+ const min = rangeInput.min ? rangeInput.min : 0;
547
+ const max = rangeInput.max ? rangeInput.max : 100;
548
+ const percentage = (value - min) / (max - min) * 100;
549
+ rangeInput.style.backgroundSize = `${percentage}% 100%`;
550
+ }
551
+
552
+ function setupSoundOptions() {
553
+ const soundOptions = document.querySelectorAll('.sound-option');
554
+ soundOptions.forEach(option => {
555
+ option.addEventListener('click', function() {
556
+ soundOptions.forEach(opt => opt.classList.remove('selected'));
557
+ this.classList.add('selected');
558
+
559
+ // Change nature sound based on selection
560
+ const soundType = this.querySelector('p').textContent.toLowerCase();
561
+ changeNatureSound(soundType);
562
+ });
563
+ });
564
+ }
565
+
566
+ function changeNatureSound(soundType) {
567
+ if (soundType === 'none') {
568
+ natureSoundEnabled = false;
569
+ natureSound.pause();
570
+ return;
571
+ }
572
+
573
+ natureSoundEnabled = true;
574
+ let soundSrc = '';
575
+
576
+ switch(soundType) {
577
+ case 'forest':
578
+ soundSrc = 'https://assets.mixkit.co/sfx/preview/mixkit-forest-stream-1353.mp3';
579
+ break;
580
+ case 'rain':
581
+ soundSrc = 'https://assets.mixkit.co/sfx/preview/mixkit-rain-loop-1243.mp3';
582
+ break;
583
+ case 'birds':
584
+ soundSrc = 'https://assets.mixkit.co/sfx/preview/mixkit-birds-chirping-1480.mp3';
585
+ break;
586
+ case 'fire':
587
+ soundSrc = 'https://assets.mixkit.co/sfx/preview/mixkit-crackling-fireplace-1352.mp3';
588
+ break;
589
+ case 'waves':
590
+ soundSrc = 'https://assets.mixkit.co/sfx/preview/mixkit-waves-coming-to-shore-1170.mp3';
591
+ break;
592
+ default:
593
+ soundSrc = 'https://assets.mixkit.co/sfx/preview/mixkit-rain-loop-1243.mp3';
594
+ }
595
+
596
+ natureSound.src = soundSrc;
597
+ if (isRunning) {
598
+ natureSound.play().catch(e => console.log("Nature sound play failed:", e));
599
+ }
600
+ }
601
+
602
+ function saveTimerSettings() {
603
+ // Get values from inputs
604
+ const pomodoroMinutes = parseInt(document.getElementById('pomodoro-duration').value);
605
+ const shortBreakMinutes = parseInt(document.getElementById('short-break-duration').value);
606
+ const longBreakMinutes = parseInt(document.getElementById('long-break-duration').value);
607
+ longBreakInterval = parseInt(document.getElementById('long-break-interval').value);
608
+ autoStartBreaks = document.getElementById('auto-start-breaks').checked;
609
+ autoStartPomodoros = document.getElementById('auto-start-pomodoros').checked;
610
+
611
+ // Update current timer if needed
612
+ if (!isRunning) {
613
+ if (currentMode === 'pomodoro') {
614
+ timeLeft = pomodoroMinutes * 60;
615
+ totalTime = timeLeft;
616
+ } else if (currentMode === 'shortBreak') {
617
+ timeLeft = shortBreakMinutes * 60;
618
+ totalTime = timeLeft;
619
+ } else if (currentMode === 'longBreak') {
620
+ timeLeft = longBreakMinutes * 60;
621
+ totalTime = timeLeft;
622
+ }
623
+ updateTimeDisplay();
624
+ updateProgressRing();
625
+ }
626
+
627
+ // Close settings
628
+ toggleSettings();
629
+
630
+ // Show confirmation
631
+ const originalText = saveSettings.textContent;
632
+ saveSettings.textContent = 'Saved!';
633
+ saveSettings.classList.remove('bg-indigo-600');
634
+ saveSettings.classList.add('bg-green-500');
635
+
636
+ setTimeout(() => {
637
+ saveSettings.textContent = originalText;
638
+ saveSettings.classList.remove('bg-green-500');
639
+ saveSettings.classList.add('bg-indigo-600');
640
+ }, 2000);
641
+ }
642
+ });
643
+ </script>
644
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=adeism/padomoro-timer" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
645
+ </html>