@jjlmoya/utils-cooking 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/package.json +60 -0
  2. package/src/category/i18n/en.ts +24 -0
  3. package/src/category/i18n/es.ts +208 -0
  4. package/src/category/i18n/fr.ts +24 -0
  5. package/src/category/index.ts +37 -0
  6. package/src/category/seo.astro +15 -0
  7. package/src/components/PreviewNavSidebar.astro +116 -0
  8. package/src/components/PreviewToolbar.astro +143 -0
  9. package/src/data.ts +11 -0
  10. package/src/env.d.ts +5 -0
  11. package/src/index.ts +32 -0
  12. package/src/layouts/PreviewLayout.astro +117 -0
  13. package/src/pages/[locale]/[slug].astro +146 -0
  14. package/src/pages/[locale].astro +251 -0
  15. package/src/pages/index.astro +4 -0
  16. package/src/tests/faq_count.test.ts +19 -0
  17. package/src/tests/i18n-titles.test.ts +66 -0
  18. package/src/tests/locale_completeness.test.ts +42 -0
  19. package/src/tests/mocks/astro_mock.js +2 -0
  20. package/src/tests/no_h1_in_components.test.ts +48 -0
  21. package/src/tests/seo_length.test.ts +22 -0
  22. package/src/tests/tool_validation.test.ts +17 -0
  23. package/src/tool/american-kitchen-converter/AmericanKitchenEngine.ts +259 -0
  24. package/src/tool/american-kitchen-converter/bibliography.astro +6 -0
  25. package/src/tool/american-kitchen-converter/component.astro +838 -0
  26. package/src/tool/american-kitchen-converter/i18n/en.ts +282 -0
  27. package/src/tool/american-kitchen-converter/i18n/es.ts +281 -0
  28. package/src/tool/american-kitchen-converter/i18n/fr.ts +292 -0
  29. package/src/tool/american-kitchen-converter/index.ts +24 -0
  30. package/src/tool/american-kitchen-converter/seo.astro +8 -0
  31. package/src/tool/banana-ripeness/BananaCare.css +587 -0
  32. package/src/tool/banana-ripeness/BananaEngine.ts +79 -0
  33. package/src/tool/banana-ripeness/bibliography.astro +6 -0
  34. package/src/tool/banana-ripeness/component.astro +285 -0
  35. package/src/tool/banana-ripeness/i18n/en.ts +177 -0
  36. package/src/tool/banana-ripeness/i18n/es.ts +177 -0
  37. package/src/tool/banana-ripeness/i18n/fr.ts +177 -0
  38. package/src/tool/banana-ripeness/index.ts +24 -0
  39. package/src/tool/banana-ripeness/seo.astro +8 -0
  40. package/src/tool/brine/bibliography.astro +6 -0
  41. package/src/tool/brine/component.astro +884 -0
  42. package/src/tool/brine/i18n/en.ts +221 -0
  43. package/src/tool/brine/i18n/es.ts +222 -0
  44. package/src/tool/brine/i18n/fr.ts +221 -0
  45. package/src/tool/brine/index.ts +26 -0
  46. package/src/tool/brine/seo.astro +8 -0
  47. package/src/tool/cookware-guide/CookwareGuide.css +487 -0
  48. package/src/tool/cookware-guide/bibliography.astro +6 -0
  49. package/src/tool/cookware-guide/component.astro +164 -0
  50. package/src/tool/cookware-guide/i18n/en.ts +163 -0
  51. package/src/tool/cookware-guide/i18n/es.ts +163 -0
  52. package/src/tool/cookware-guide/i18n/fr.ts +164 -0
  53. package/src/tool/cookware-guide/index.ts +24 -0
  54. package/src/tool/cookware-guide/init.ts +174 -0
  55. package/src/tool/cookware-guide/seo.astro +8 -0
  56. package/src/tool/egg-timer/EggTimer.css +503 -0
  57. package/src/tool/egg-timer/bibliography.astro +14 -0
  58. package/src/tool/egg-timer/component.astro +281 -0
  59. package/src/tool/egg-timer/i18n/en.ts +230 -0
  60. package/src/tool/egg-timer/i18n/es.ts +222 -0
  61. package/src/tool/egg-timer/i18n/fr.ts +121 -0
  62. package/src/tool/egg-timer/index.ts +27 -0
  63. package/src/tool/egg-timer/seo.astro +39 -0
  64. package/src/tool/ingredient-rescaler/IngredientRescaler.css +308 -0
  65. package/src/tool/ingredient-rescaler/bibliography.astro +6 -0
  66. package/src/tool/ingredient-rescaler/component.astro +107 -0
  67. package/src/tool/ingredient-rescaler/i18n/en.ts +265 -0
  68. package/src/tool/ingredient-rescaler/i18n/es.ts +268 -0
  69. package/src/tool/ingredient-rescaler/i18n/fr.ts +207 -0
  70. package/src/tool/ingredient-rescaler/index.ts +24 -0
  71. package/src/tool/ingredient-rescaler/init.ts +200 -0
  72. package/src/tool/ingredient-rescaler/seo.astro +8 -0
  73. package/src/tool/kitchen-timer/KitchenTimer.css +325 -0
  74. package/src/tool/kitchen-timer/bibliography.astro +6 -0
  75. package/src/tool/kitchen-timer/component.astro +341 -0
  76. package/src/tool/kitchen-timer/i18n/en.ts +154 -0
  77. package/src/tool/kitchen-timer/i18n/es.ts +154 -0
  78. package/src/tool/kitchen-timer/i18n/fr.ts +154 -0
  79. package/src/tool/kitchen-timer/index.ts +26 -0
  80. package/src/tool/kitchen-timer/init.ts +55 -0
  81. package/src/tool/kitchen-timer/lib/AudioHelper.ts +27 -0
  82. package/src/tool/kitchen-timer/lib/DockManager.ts +97 -0
  83. package/src/tool/kitchen-timer/lib/KitchenTimer.ts +264 -0
  84. package/src/tool/kitchen-timer/seo.astro +8 -0
  85. package/src/tool/meringue-peak/MeringueCalculator.css +298 -0
  86. package/src/tool/meringue-peak/bibliography.astro +6 -0
  87. package/src/tool/meringue-peak/component.astro +169 -0
  88. package/src/tool/meringue-peak/i18n/en.ts +257 -0
  89. package/src/tool/meringue-peak/i18n/es.ts +234 -0
  90. package/src/tool/meringue-peak/i18n/fr.ts +234 -0
  91. package/src/tool/meringue-peak/index.ts +24 -0
  92. package/src/tool/meringue-peak/seo.astro +8 -0
  93. package/src/tool/mold-scaler/MoldScaler.css +406 -0
  94. package/src/tool/mold-scaler/bibliography.astro +6 -0
  95. package/src/tool/mold-scaler/component.astro +126 -0
  96. package/src/tool/mold-scaler/i18n/en.ts +268 -0
  97. package/src/tool/mold-scaler/i18n/es.ts +269 -0
  98. package/src/tool/mold-scaler/i18n/fr.ts +276 -0
  99. package/src/tool/mold-scaler/index.ts +26 -0
  100. package/src/tool/mold-scaler/init.ts +264 -0
  101. package/src/tool/mold-scaler/seo.astro +8 -0
  102. package/src/tool/pizza/Pizza.css +569 -0
  103. package/src/tool/pizza/bibliography.astro +6 -0
  104. package/src/tool/pizza/calculator.ts +143 -0
  105. package/src/tool/pizza/component.astro +237 -0
  106. package/src/tool/pizza/i18n/en.ts +288 -0
  107. package/src/tool/pizza/i18n/es.ts +289 -0
  108. package/src/tool/pizza/i18n/fr.ts +288 -0
  109. package/src/tool/pizza/index.ts +27 -0
  110. package/src/tool/pizza/seo.astro +8 -0
  111. package/src/tool/roux-guide/RouxGuide.css +483 -0
  112. package/src/tool/roux-guide/bibliography.astro +6 -0
  113. package/src/tool/roux-guide/component.astro +194 -0
  114. package/src/tool/roux-guide/i18n/en.ts +233 -0
  115. package/src/tool/roux-guide/i18n/es.ts +225 -0
  116. package/src/tool/roux-guide/i18n/fr.ts +225 -0
  117. package/src/tool/roux-guide/index.ts +24 -0
  118. package/src/tool/roux-guide/init.ts +187 -0
  119. package/src/tool/roux-guide/seo.astro +8 -0
  120. package/src/tool/sourdough-calculator/SourdoughCalculator.css +369 -0
  121. package/src/tool/sourdough-calculator/bibliography.astro +6 -0
  122. package/src/tool/sourdough-calculator/component.astro +198 -0
  123. package/src/tool/sourdough-calculator/i18n/en.ts +242 -0
  124. package/src/tool/sourdough-calculator/i18n/es.ts +243 -0
  125. package/src/tool/sourdough-calculator/i18n/fr.ts +248 -0
  126. package/src/tool/sourdough-calculator/index.ts +24 -0
  127. package/src/tool/sourdough-calculator/init.ts +131 -0
  128. package/src/tool/sourdough-calculator/seo.astro +8 -0
  129. package/src/tools.ts +29 -0
  130. package/src/types.ts +73 -0
@@ -0,0 +1,8 @@
1
+ ---
2
+ import { SEORenderer } from "@jjlmoya/utils-shared";
3
+ import { content } from "./i18n/es";
4
+
5
+ const locale = "es";
6
+ ---
7
+
8
+ <SEORenderer content={{ sections: content.seo, locale }} />
@@ -0,0 +1,325 @@
1
+ .kitchen-timer-wrapper {
2
+ --kt-primary: #ea580c;
3
+ --kt-secondary: #f97316;
4
+ --kt-bg: #fff;
5
+ --kt-bg-secondary: #f8fafc;
6
+ --kt-border: #e2e8f0;
7
+ --kt-text: #0f172a;
8
+ --kt-text-muted: #64748b;
9
+ --card-br: 1.5rem;
10
+ }
11
+
12
+ .theme-dark .kitchen-timer-wrapper {
13
+ --kt-primary: #fb923c;
14
+ --kt-secondary: #fdba74;
15
+ --kt-bg: #0f172a;
16
+ --kt-bg-secondary: #1e293b;
17
+ --kt-border: #334155;
18
+ --kt-text: #f8fafc;
19
+ --kt-text-muted: #94a3b8;
20
+ }
21
+
22
+ .kitchen-timer-master-card {
23
+ background: var(--kt-bg);
24
+ border: 1px solid var(--kt-border);
25
+ border-radius: var(--card-br);
26
+ box-shadow: var(--sc-shadow-lg);
27
+ overflow: hidden;
28
+ }
29
+
30
+ .timers-grid {
31
+ display: grid;
32
+ grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
33
+ gap: 0;
34
+ }
35
+
36
+ .timer-card {
37
+ background: transparent;
38
+ border: none;
39
+ border-right: 1px solid var(--kt-border);
40
+ border-bottom: 1px solid var(--kt-border);
41
+ border-radius: 0;
42
+ position: relative;
43
+ overflow: hidden;
44
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
45
+ box-shadow: none;
46
+ }
47
+
48
+ .timer-card:hover {
49
+ transform: none;
50
+ background: var(--kt-bg-secondary);
51
+ }
52
+
53
+ .progress-bar {
54
+ position: absolute;
55
+ top: 0;
56
+ left: 0;
57
+ width: 100%;
58
+ height: 4px;
59
+ background: var(--kt-bg-secondary);
60
+ }
61
+
62
+ .progress-fill {
63
+ width: 100%;
64
+ height: 100%;
65
+ background: var(--kt-primary);
66
+ transform-origin: left;
67
+ transform: scaleX(0);
68
+ transition: transform 0.1s linear;
69
+ }
70
+
71
+ .timer-content {
72
+ padding: 1.5rem;
73
+ }
74
+
75
+ .timer-header {
76
+ display: flex;
77
+ justify-content: space-between;
78
+ align-items: center;
79
+ margin-bottom: 1.5rem;
80
+ }
81
+
82
+ .timer-name-wrapper {
83
+ flex: 1;
84
+ min-width: 0;
85
+ margin-right: 0.5rem;
86
+ }
87
+
88
+ .timer-name {
89
+ background: transparent;
90
+ border: none;
91
+ border-bottom: 2px solid transparent;
92
+ font-weight: 700;
93
+ font-size: 1.1rem;
94
+ color: var(--kt-text);
95
+ width: 100%;
96
+ outline: none;
97
+ transition: border-color 0.2s;
98
+ white-space: nowrap;
99
+ overflow: hidden;
100
+ text-overflow: ellipsis;
101
+ }
102
+
103
+ .timer-name:focus {
104
+ border-color: var(--kt-primary);
105
+ }
106
+
107
+ .status-badge {
108
+ padding: 0.25rem 0.75rem;
109
+ background: var(--kt-bg-secondary);
110
+ border-radius: 2rem;
111
+ font-size: 0.75rem;
112
+ font-weight: 700;
113
+ color: var(--kt-text-muted);
114
+ border: 1px solid var(--kt-border);
115
+ flex-shrink: 0;
116
+ }
117
+
118
+ .timer-display {
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ gap: 1rem;
123
+ margin: 2rem 0;
124
+ }
125
+
126
+ .time-input-group {
127
+ display: flex;
128
+ flex-direction: column;
129
+ align-items: center;
130
+ gap: 0.5rem;
131
+ }
132
+
133
+ .time-input {
134
+ width: 80px;
135
+ background: var(--kt-bg-secondary);
136
+ border: 2px solid var(--kt-border);
137
+ border-radius: 1rem;
138
+ font-size: 2.5rem;
139
+ font-weight: 900;
140
+ text-align: center;
141
+ color: var(--kt-text);
142
+ padding: 0.5rem;
143
+ outline: none;
144
+ transition: all 0.2s;
145
+ }
146
+
147
+ .time-input:focus {
148
+ border-color: var(--kt-primary);
149
+ background: var(--kt-bg);
150
+ }
151
+
152
+ .time-label {
153
+ font-size: 0.65rem;
154
+ font-weight: 800;
155
+ text-transform: uppercase;
156
+ letter-spacing: 0.1em;
157
+ color: var(--kt-text-muted);
158
+ }
159
+
160
+ .time-separator {
161
+ font-size: 2rem;
162
+ font-weight: 900;
163
+ color: var(--kt-border);
164
+ margin-top: -1.5rem;
165
+ }
166
+
167
+ .timer-controls {
168
+ display: flex;
169
+ flex-direction: column;
170
+ gap: 1rem;
171
+ }
172
+
173
+ .timer-buttons {
174
+ display: grid;
175
+ grid-template-columns: 1fr 1fr;
176
+ gap: 0.75rem;
177
+ }
178
+
179
+ .btn-toggle, .btn-reset {
180
+ padding: 0.75rem;
181
+ border-radius: 1rem;
182
+ font-weight: 700;
183
+ cursor: pointer;
184
+ display: flex;
185
+ align-items: center;
186
+ justify-content: center;
187
+ gap: 0.5rem;
188
+ transition: all 0.2s;
189
+ border: none;
190
+ }
191
+
192
+ .btn-toggle {
193
+ background: var(--kt-primary);
194
+ color: var(--kt-bg);
195
+ }
196
+
197
+ .btn-toggle:hover:not(:disabled) {
198
+ background: var(--kt-secondary);
199
+ transform: scale(1.02);
200
+ }
201
+
202
+ .btn-toggle:disabled {
203
+ opacity: 0.5;
204
+ cursor: not-allowed;
205
+ }
206
+
207
+ .btn-reset {
208
+ background: var(--kt-bg-secondary);
209
+ color: var(--kt-text);
210
+ border: 1px solid var(--kt-border);
211
+ }
212
+
213
+ .btn-reset:hover {
214
+ border-color: var(--kt-primary);
215
+ }
216
+
217
+ .timer-quick-buttons {
218
+ display: flex;
219
+ gap: 0.5rem;
220
+ }
221
+
222
+ .timer-quick-buttons button {
223
+ flex: 1;
224
+ padding: 0.5rem;
225
+ border-radius: 0.75rem;
226
+ background: var(--kt-bg-secondary);
227
+ border: 1px solid var(--kt-border);
228
+ font-size: 0.8rem;
229
+ font-weight: 600;
230
+ color: var(--kt-text-muted);
231
+ cursor: pointer;
232
+ transition: all 0.2s;
233
+ }
234
+
235
+ .timer-quick-buttons button:hover {
236
+ color: var(--kt-primary);
237
+ border-color: var(--kt-primary);
238
+ }
239
+
240
+ .add-timer-container {
241
+ padding: 1.5rem 2.5rem;
242
+ display: flex;
243
+ align-items: center;
244
+ justify-content: space-between;
245
+ background: var(--kt-bg-secondary);
246
+ border-top: 1px solid var(--kt-border);
247
+ gap: 1.5rem;
248
+ }
249
+
250
+ .add-timer-btn {
251
+ background: var(--kt-primary);
252
+ border: none;
253
+ border-radius: 1rem;
254
+ width: auto;
255
+ padding: 0.75rem 2rem;
256
+ height: auto;
257
+ display: flex;
258
+ flex-direction: row;
259
+ align-items: center;
260
+ justify-content: center;
261
+ gap: 0.75rem;
262
+ color: var(--kt-bg);
263
+ font-weight: 700;
264
+ font-size: 1rem;
265
+ cursor: pointer;
266
+ transition: all 0.2s;
267
+ box-shadow: 0 4px 6px -1px rgba(234, 88, 12, 0.2);
268
+ }
269
+
270
+ .add-timer-btn:hover {
271
+ background: var(--kt-secondary);
272
+ transform: translateY(-2px);
273
+ box-shadow: 0 10px 15px -3px rgba(234, 88, 12, 0.3);
274
+ }
275
+
276
+ .add-timer-icon {
277
+ font-size: 1.25rem;
278
+ display: flex;
279
+ align-items: center;
280
+ }
281
+
282
+ .stop-all-container {
283
+ flex-shrink: 0;
284
+ }
285
+
286
+ .stop-all-btn {
287
+ background: #1e293b;
288
+ padding: 0.75rem 1.5rem;
289
+ border-radius: 1rem;
290
+ color: var(--kt-bg);
291
+ border: 1px solid rgba(255, 255, 255, 0.1);
292
+ font-weight: 700;
293
+ font-size: 0.9rem;
294
+ display: flex;
295
+ align-items: center;
296
+ gap: 0.5rem;
297
+ cursor: pointer;
298
+ transition: all 0.2s;
299
+ }
300
+
301
+ .stop-all-btn:hover {
302
+ background: #000;
303
+ transform: translateY(-2px);
304
+ }
305
+
306
+ .timer-card.finished {
307
+ animation: pulse-border 1.5s infinite;
308
+ }
309
+
310
+ @keyframes pulse-border {
311
+ 0% {
312
+ border-color: var(--kt-primary);
313
+ box-shadow: 0 0 0 0 rgba(234, 88, 12, 0.4);
314
+ }
315
+ 70% {
316
+ border-color: var(--kt-secondary);
317
+ box-shadow: 0 0 0 15px rgba(234, 88, 12, 0);
318
+ }
319
+ 100% {
320
+ border-color: var(--kt-primary);
321
+ box-shadow: 0 0 0 0 rgba(234, 88, 12, 0);
322
+ }
323
+ }
324
+
325
+
@@ -0,0 +1,6 @@
1
+ ---
2
+ import { Bibliography } from "@jjlmoya/utils-shared";
3
+ import { content } from "./i18n/es";
4
+ ---
5
+
6
+ <Bibliography links={content.bibliography} />
@@ -0,0 +1,341 @@
1
+ ---
2
+ import { Icon } from "astro-icon/components";
3
+ import "./KitchenTimer.css";
4
+
5
+ interface Props {
6
+ ui: Record<string, string>;
7
+ }
8
+
9
+ const { ui } = Astro.props;
10
+ ---
11
+
12
+ <div class="kitchen-timer-wrapper">
13
+ <div class="kitchen-timer-master-card">
14
+ <div id="timers-grid" class="timers-grid">
15
+ <div class="timer-card" data-index="0">
16
+ <div class="progress-bar">
17
+ <div class="progress-fill"></div>
18
+ </div>
19
+
20
+ <div class="timer-content">
21
+ <div class="timer-header">
22
+ <div class="timer-name-wrapper">
23
+ <input
24
+ type="text"
25
+ value={ui.timerDefault1}
26
+ class="timer-name"
27
+ placeholder={ui.label}
28
+ />
29
+ </div>
30
+ <div class="status-badge">
31
+ <span class="status-text">{ui.ready}</span>
32
+ </div>
33
+ </div>
34
+
35
+ <div class="timer-display">
36
+ <div class="time-input-group">
37
+ <input
38
+ type="number"
39
+ min="0"
40
+ max="999"
41
+ value="00"
42
+ class="time-input minutes"
43
+ placeholder="00"
44
+ />
45
+ <label class="time-label">{ui.minutes}</label>
46
+ </div>
47
+
48
+ <span class="time-separator">:</span>
49
+
50
+ <div class="time-input-group">
51
+ <input
52
+ type="number"
53
+ min="0"
54
+ max="59"
55
+ value="00"
56
+ class="time-input seconds"
57
+ placeholder="00"
58
+ />
59
+ <label class="time-label">{ui.seconds}</label>
60
+ </div>
61
+ </div>
62
+
63
+ <div class="timer-controls">
64
+ <div class="timer-buttons">
65
+ <button class="btn-toggle" disabled>
66
+ <span class="icon-play">
67
+ <Icon name="mdi:play" />
68
+ </span>
69
+ <span class="icon-pause" style="display: none;">
70
+ <Icon name="mdi:pause" />
71
+ </span>
72
+ <span class="btn-text">{ui.start}</span>
73
+ </button>
74
+
75
+ <button class="btn-reset">
76
+ <Icon name="mdi:refresh" />
77
+ {ui.reset}
78
+ </button>
79
+ </div>
80
+
81
+ <div class="timer-quick-buttons">
82
+ <button class="btn-add-1m">{ui.addOneMin}</button>
83
+ <button class="btn-add-5m">{ui.addFiveMin}</button>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </div>
88
+
89
+ <div class="timer-card" data-index="1">
90
+ <div class="progress-bar">
91
+ <div class="progress-fill"></div>
92
+ </div>
93
+
94
+ <div class="timer-content">
95
+ <div class="timer-header">
96
+ <div class="timer-name-wrapper">
97
+ <input
98
+ type="text"
99
+ value={ui.timerDefault2}
100
+ class="timer-name"
101
+ placeholder={ui.label}
102
+ />
103
+ </div>
104
+ <div class="status-badge">
105
+ <span class="status-text">{ui.ready}</span>
106
+ </div>
107
+ </div>
108
+
109
+ <div class="timer-display">
110
+ <div class="time-input-group">
111
+ <input
112
+ type="number"
113
+ min="0"
114
+ max="999"
115
+ value="00"
116
+ class="time-input minutes"
117
+ placeholder="00"
118
+ />
119
+ <label class="time-label">{ui.minutes}</label>
120
+ </div>
121
+
122
+ <span class="time-separator">:</span>
123
+
124
+ <div class="time-input-group">
125
+ <input
126
+ type="number"
127
+ min="0"
128
+ max="59"
129
+ value="00"
130
+ class="time-input seconds"
131
+ placeholder="00"
132
+ />
133
+ <label class="time-label">{ui.seconds}</label>
134
+ </div>
135
+ </div>
136
+
137
+ <div class="timer-controls">
138
+ <div class="timer-buttons">
139
+ <button class="btn-toggle" disabled>
140
+ <span class="icon-play">
141
+ <Icon name="mdi:play" />
142
+ </span>
143
+ <span class="icon-pause" style="display: none;">
144
+ <Icon name="mdi:pause" />
145
+ </span>
146
+ <span class="btn-text">{ui.start}</span>
147
+ </button>
148
+
149
+ <button class="btn-reset">
150
+ <Icon name="mdi:refresh" />
151
+ {ui.reset}
152
+ </button>
153
+ </div>
154
+
155
+ <div class="timer-quick-buttons">
156
+ <button class="btn-add-1m">{ui.addOneMin}</button>
157
+ <button class="btn-add-5m">{ui.addFiveMin}</button>
158
+ </div>
159
+ </div>
160
+ </div>
161
+ </div>
162
+
163
+ <div class="timer-card" data-index="2">
164
+ <div class="progress-bar">
165
+ <div class="progress-fill"></div>
166
+ </div>
167
+
168
+ <div class="timer-content">
169
+ <div class="timer-header">
170
+ <div class="timer-name-wrapper">
171
+ <input
172
+ type="text"
173
+ value={ui.timerDefault3}
174
+ class="timer-name"
175
+ placeholder={ui.label}
176
+ />
177
+ </div>
178
+ <div class="status-badge">
179
+ <span class="status-text">{ui.ready}</span>
180
+ </div>
181
+ </div>
182
+
183
+ <div class="timer-display">
184
+ <div class="time-input-group">
185
+ <input
186
+ type="number"
187
+ min="0"
188
+ max="999"
189
+ value="00"
190
+ class="time-input minutes"
191
+ placeholder="00"
192
+ />
193
+ <label class="time-label">{ui.minutes}</label>
194
+ </div>
195
+
196
+ <span class="time-separator">:</span>
197
+
198
+ <div class="time-input-group">
199
+ <input
200
+ type="number"
201
+ min="0"
202
+ max="59"
203
+ value="00"
204
+ class="time-input seconds"
205
+ placeholder="00"
206
+ />
207
+ <label class="time-label">{ui.seconds}</label>
208
+ </div>
209
+ </div>
210
+
211
+ <div class="timer-controls">
212
+ <div class="timer-buttons">
213
+ <button class="btn-toggle" disabled>
214
+ <span class="icon-play">
215
+ <Icon name="mdi:play" />
216
+ </span>
217
+ <span class="icon-pause" style="display: none;">
218
+ <Icon name="mdi:pause" />
219
+ </span>
220
+ <span class="btn-text">{ui.start}</span>
221
+ </button>
222
+
223
+ <button class="btn-reset">
224
+ <Icon name="mdi:refresh" />
225
+ {ui.reset}
226
+ </button>
227
+ </div>
228
+
229
+ <div class="timer-quick-buttons">
230
+ <button class="btn-add-1m">{ui.addOneMin}</button>
231
+ <button class="btn-add-5m">{ui.addFiveMin}</button>
232
+ </div>
233
+ </div>
234
+ </div>
235
+ </div>
236
+ </div>
237
+
238
+ <div class="add-timer-container">
239
+ <button id="add-timer-btn" class="add-timer-btn">
240
+ <div class="add-timer-icon">
241
+ <Icon name="mdi:plus" />
242
+ </div>
243
+ <span>{ui.addTimer}</span>
244
+ </button>
245
+
246
+ <div class="stop-all-container">
247
+ <button id="stop-all" class="stop-all-btn">
248
+ <Icon name="mdi:stop-circle-outline" />
249
+ {ui.stopAll}
250
+ </button>
251
+ </div>
252
+ </div>
253
+ </div>
254
+
255
+ <template id="timer-template">
256
+ <div class="timer-card" data-index="-1">
257
+ <div class="progress-bar">
258
+ <div class="progress-fill"></div>
259
+ </div>
260
+
261
+ <div class="timer-content">
262
+ <div class="timer-header">
263
+ <div class="timer-name-wrapper">
264
+ <input
265
+ type="text"
266
+ value={ui.newTimerName}
267
+ class="timer-name"
268
+ placeholder={ui.label}
269
+ />
270
+ </div>
271
+ <div class="status-badge">
272
+ <span class="status-text">{ui.ready}</span>
273
+ </div>
274
+ </div>
275
+
276
+ <div class="timer-display">
277
+ <div class="time-input-group">
278
+ <input
279
+ type="number"
280
+ min="0"
281
+ max="999"
282
+ value="00"
283
+ class="time-input minutes"
284
+ placeholder="00"
285
+ />
286
+ <label class="time-label">{ui.minutes}</label>
287
+ </div>
288
+
289
+ <span class="time-separator">:</span>
290
+
291
+ <div class="time-input-group">
292
+ <input
293
+ type="number"
294
+ min="0"
295
+ max="59"
296
+ value="00"
297
+ class="time-input seconds"
298
+ placeholder="00"
299
+ />
300
+ <label class="time-label">{ui.seconds}</label>
301
+ </div>
302
+ </div>
303
+
304
+ <div class="timer-controls">
305
+ <div class="timer-buttons">
306
+ <button class="btn-toggle" disabled>
307
+ <span class="icon-play">
308
+ <Icon name="mdi:play" />
309
+ </span>
310
+ <span class="icon-pause" style="display: none;">
311
+ <Icon name="mdi:pause" />
312
+ </span>
313
+ <span class="btn-text">{ui.start}</span>
314
+ </button>
315
+
316
+ <button class="btn-reset">
317
+ <Icon name="mdi:refresh" />
318
+ {ui.reset}
319
+ </button>
320
+ </div>
321
+
322
+ <div class="timer-quick-buttons">
323
+ <button class="btn-add-1m">{ui.addOneMin}</button>
324
+ <button class="btn-add-5m">{ui.addFiveMin}</button>
325
+ </div>
326
+ </div>
327
+ </div>
328
+ </div>
329
+ </template>
330
+
331
+ </div>
332
+
333
+ <script>
334
+ import { initKitchenTimers } from "./init";
335
+
336
+ if (document.readyState === "loading") {
337
+ document.addEventListener("DOMContentLoaded", initKitchenTimers);
338
+ } else {
339
+ initKitchenTimers();
340
+ }
341
+ </script>