@jjlmoya/utils-cooking 1.38.0 → 1.40.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 (63) hide show
  1. package/package.json +1 -1
  2. package/scripts/fix-translations.js +51 -0
  3. package/src/category/index.ts +5 -0
  4. package/src/entries.ts +6 -1
  5. package/src/index.ts +3 -0
  6. package/src/tests/i18n-titles.test.ts +2 -2
  7. package/src/tests/locale_completeness.test.ts +2 -2
  8. package/src/tests/sous-vide-pasteurization-curves.test.ts +66 -0
  9. package/src/tests/tool_validation.test.ts +2 -2
  10. package/src/tool/pectin-jam-setting-calculator/bibliography.astro +6 -0
  11. package/src/tool/pectin-jam-setting-calculator/bibliography.ts +10 -0
  12. package/src/tool/pectin-jam-setting-calculator/component.astro +170 -0
  13. package/src/tool/pectin-jam-setting-calculator/components/CalculatorInputs.astro +44 -0
  14. package/src/tool/pectin-jam-setting-calculator/components/DropTestVisualizer.astro +40 -0
  15. package/src/tool/pectin-jam-setting-calculator/components/FruitSelector.astro +38 -0
  16. package/src/tool/pectin-jam-setting-calculator/components/RecipeResults.astro +72 -0
  17. package/src/tool/pectin-jam-setting-calculator/entry.ts +26 -0
  18. package/src/tool/pectin-jam-setting-calculator/i18n/de.ts +248 -0
  19. package/src/tool/pectin-jam-setting-calculator/i18n/en.ts +248 -0
  20. package/src/tool/pectin-jam-setting-calculator/i18n/es.ts +248 -0
  21. package/src/tool/pectin-jam-setting-calculator/i18n/fr.ts +248 -0
  22. package/src/tool/pectin-jam-setting-calculator/i18n/id.ts +248 -0
  23. package/src/tool/pectin-jam-setting-calculator/i18n/it.ts +248 -0
  24. package/src/tool/pectin-jam-setting-calculator/i18n/ja.ts +248 -0
  25. package/src/tool/pectin-jam-setting-calculator/i18n/ko.ts +248 -0
  26. package/src/tool/pectin-jam-setting-calculator/i18n/nl.ts +248 -0
  27. package/src/tool/pectin-jam-setting-calculator/i18n/pl.ts +248 -0
  28. package/src/tool/pectin-jam-setting-calculator/i18n/pt.ts +248 -0
  29. package/src/tool/pectin-jam-setting-calculator/i18n/ru.ts +248 -0
  30. package/src/tool/pectin-jam-setting-calculator/i18n/sv.ts +248 -0
  31. package/src/tool/pectin-jam-setting-calculator/i18n/tr.ts +248 -0
  32. package/src/tool/pectin-jam-setting-calculator/i18n/zh.ts +248 -0
  33. package/src/tool/pectin-jam-setting-calculator/index.ts +11 -0
  34. package/src/tool/pectin-jam-setting-calculator/logic.ts +96 -0
  35. package/src/tool/pectin-jam-setting-calculator/pectin-jam-setting-calculator.css +730 -0
  36. package/src/tool/pectin-jam-setting-calculator/seo.astro +15 -0
  37. package/src/tool/sous-vide-pasteurization-curves/bibliography.astro +6 -0
  38. package/src/tool/sous-vide-pasteurization-curves/bibliography.ts +10 -0
  39. package/src/tool/sous-vide-pasteurization-curves/component.astro +275 -0
  40. package/src/tool/sous-vide-pasteurization-curves/components/Controls.astro +90 -0
  41. package/src/tool/sous-vide-pasteurization-curves/components/LethalityChart.astro +28 -0
  42. package/src/tool/sous-vide-pasteurization-curves/components/ResultsDisplay.astro +36 -0
  43. package/src/tool/sous-vide-pasteurization-curves/entry.ts +26 -0
  44. package/src/tool/sous-vide-pasteurization-curves/i18n/de.ts +323 -0
  45. package/src/tool/sous-vide-pasteurization-curves/i18n/en.ts +323 -0
  46. package/src/tool/sous-vide-pasteurization-curves/i18n/es.ts +323 -0
  47. package/src/tool/sous-vide-pasteurization-curves/i18n/fr.ts +323 -0
  48. package/src/tool/sous-vide-pasteurization-curves/i18n/id.ts +323 -0
  49. package/src/tool/sous-vide-pasteurization-curves/i18n/it.ts +323 -0
  50. package/src/tool/sous-vide-pasteurization-curves/i18n/ja.ts +323 -0
  51. package/src/tool/sous-vide-pasteurization-curves/i18n/ko.ts +323 -0
  52. package/src/tool/sous-vide-pasteurization-curves/i18n/nl.ts +323 -0
  53. package/src/tool/sous-vide-pasteurization-curves/i18n/pl.ts +154 -0
  54. package/src/tool/sous-vide-pasteurization-curves/i18n/pt.ts +323 -0
  55. package/src/tool/sous-vide-pasteurization-curves/i18n/ru.ts +154 -0
  56. package/src/tool/sous-vide-pasteurization-curves/i18n/sv.ts +154 -0
  57. package/src/tool/sous-vide-pasteurization-curves/i18n/tr.ts +154 -0
  58. package/src/tool/sous-vide-pasteurization-curves/i18n/zh.ts +323 -0
  59. package/src/tool/sous-vide-pasteurization-curves/index.ts +11 -0
  60. package/src/tool/sous-vide-pasteurization-curves/logic.ts +89 -0
  61. package/src/tool/sous-vide-pasteurization-curves/seo.astro +15 -0
  62. package/src/tool/sous-vide-pasteurization-curves/sous-vide-pasteurization-curves.css +456 -0
  63. package/src/tools.ts +5 -0
@@ -0,0 +1,730 @@
1
+ .jam-container {
2
+ --color-ruby: #e11d48;
3
+ --color-ruby-dark: #be123c;
4
+ --color-ruby-light: #fda4af;
5
+ --color-garnet: #9f1239;
6
+ --color-amber: #d97706;
7
+ --color-amber-dark: #b45309;
8
+ --color-amber-light: #fcd34d;
9
+ --color-topaz: #ea580c;
10
+ --color-amethyst: #7c3aed;
11
+ --color-amethyst-dark: #6d28d9;
12
+ --color-amethyst-light: #c4b5fd;
13
+ --color-sapphire: #4f46e5;
14
+ --color-emerald: #059669;
15
+ --color-emerald-dark: #047857;
16
+ --color-emerald-bright: #34d399;
17
+ --color-peridot: #65a30d;
18
+ --color-ivory: #fef3c7;
19
+ --color-cream: #fef9ef;
20
+ --color-white: #fff;
21
+ --color-slate-900: #1e1b2e;
22
+ --color-slate-800: #2d2a3e;
23
+ --color-slate-700: #3d3a4e;
24
+ --color-slate-500: #6b6880;
25
+ --color-slate-400: #8b88a0;
26
+ --color-slate-300: #b8b5c8;
27
+ --color-slate-200: #d4d1e0;
28
+ --color-slate-100: #eae7f2;
29
+ --color-slate-50: #f7f5fb;
30
+ --jam-radius-sm: 16px;
31
+ --jam-radius-md: 24px;
32
+ --jam-radius-lg: 32px;
33
+ --jam-radius-xl: 40px;
34
+
35
+ display: flex;
36
+ flex-direction: column;
37
+ align-items: center;
38
+ justify-content: center;
39
+ width: 100%;
40
+ max-width: 100%;
41
+ overflow: hidden;
42
+ box-sizing: border-box;
43
+ }
44
+
45
+ .jam-card {
46
+ position: relative;
47
+ width: 100%;
48
+ max-width: 720px;
49
+ background: rgba(255, 255, 255, 0.7);
50
+ backdrop-filter: blur(24px);
51
+ -webkit-backdrop-filter: blur(24px);
52
+ border: 1px solid rgba(0, 0, 0, 0.06);
53
+ border-radius: var(--jam-radius-xl);
54
+ padding: 2.25rem;
55
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.04), 0 2px 8px rgba(0, 0, 0, 0.02);
56
+ overflow: hidden;
57
+ box-sizing: border-box;
58
+ }
59
+
60
+ .theme-dark .jam-card {
61
+ background: rgba(30, 27, 46, 0.55);
62
+ border: 1px solid rgba(255, 255, 255, 0.06);
63
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
64
+ }
65
+
66
+ .jam-glow-1,
67
+ .jam-glow-2,
68
+ .jam-glow-3 {
69
+ position: absolute;
70
+ border-radius: 50%;
71
+ z-index: 0;
72
+ pointer-events: none;
73
+ }
74
+
75
+ .jam-glow-1 {
76
+ top: -60px;
77
+ right: -60px;
78
+ width: 220px;
79
+ height: 220px;
80
+ background: radial-gradient(circle, rgba(225, 29, 72, 0.08) 0%, transparent 70%);
81
+ }
82
+
83
+ .jam-glow-2 {
84
+ bottom: -40px;
85
+ left: -40px;
86
+ width: 200px;
87
+ height: 200px;
88
+ background: radial-gradient(circle, rgba(217, 119, 6, 0.08) 0%, transparent 70%);
89
+ }
90
+
91
+ .jam-glow-3 {
92
+ top: 40%;
93
+ left: 50%;
94
+ transform: translate(-50%, -50%);
95
+ width: 280px;
96
+ height: 280px;
97
+ background: radial-gradient(circle, rgba(124, 58, 237, 0.05) 0%, transparent 70%);
98
+ }
99
+
100
+ .theme-dark .jam-glow-1 {
101
+ background: radial-gradient(circle, rgba(225, 29, 72, 0.12) 0%, transparent 70%);
102
+ }
103
+
104
+ .theme-dark .jam-glow-2 {
105
+ background: radial-gradient(circle, rgba(217, 119, 6, 0.12) 0%, transparent 70%);
106
+ }
107
+
108
+ .theme-dark .jam-glow-3 {
109
+ background: radial-gradient(circle, rgba(124, 58, 237, 0.08) 0%, transparent 70%);
110
+ }
111
+
112
+ .jam-main-grid {
113
+ position: relative;
114
+ z-index: 1;
115
+ display: flex;
116
+ flex-direction: column;
117
+ gap: 2.25rem;
118
+ width: 100%;
119
+ }
120
+
121
+ .jam-section-label {
122
+ font-size: 1.35rem;
123
+ font-weight: 700;
124
+ text-transform: uppercase;
125
+ letter-spacing: 0.12em;
126
+ color: var(--color-slate-500);
127
+ margin-bottom: 1.1rem;
128
+ }
129
+
130
+ .theme-dark .jam-section-label {
131
+ color: var(--color-slate-300);
132
+ }
133
+
134
+ .jam-fruit-scroll {
135
+ display: flex;
136
+ gap: 1.25rem;
137
+ overflow-x: auto;
138
+ padding: 0.6rem 0 1.25rem;
139
+ -webkit-overflow-scrolling: touch;
140
+ scrollbar-width: none;
141
+ -ms-overflow-style: none;
142
+ width: 100%;
143
+ max-width: 100%;
144
+ box-sizing: border-box;
145
+ }
146
+
147
+ .jam-fruit-scroll::-webkit-scrollbar {
148
+ display: none;
149
+ }
150
+
151
+ .jam-fruit-pill {
152
+ --fruit-color: #e11d48;
153
+
154
+ display: flex;
155
+ align-items: center;
156
+ gap: 0.95rem;
157
+ background: var(--color-white);
158
+ border: 2px solid rgba(0, 0, 0, 0.08);
159
+ border-radius: 999px;
160
+ padding: 1.15rem 1.85rem;
161
+ cursor: pointer;
162
+ transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
163
+ flex-shrink: 0;
164
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
165
+ }
166
+
167
+ .theme-dark .jam-fruit-pill {
168
+ background: rgba(30, 27, 46, 0.6);
169
+ border: 2px solid rgba(255, 255, 255, 0.08);
170
+ }
171
+
172
+ .jam-fruit-pill.active {
173
+ border-color: var(--fruit-color);
174
+ background: var(--fruit-color);
175
+ box-shadow: 0 6px 20px rgba(var(--fruit-color-rgb, 225, 29, 72), 0.35);
176
+ transform: translateY(-2px);
177
+ }
178
+
179
+ .jam-fruit-pill.active .jam-fruit-name {
180
+ color: var(--color-white);
181
+ }
182
+
183
+ .jam-fruit-pill.active .jam-fruit-dot {
184
+ background: rgba(255, 255, 255, 0.4);
185
+ }
186
+
187
+ .jam-fruit-dot {
188
+ width: 20px;
189
+ height: 20px;
190
+ border-radius: 50%;
191
+ flex-shrink: 0;
192
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
193
+ }
194
+
195
+ .jam-fruit-name {
196
+ font-size: 1.45rem;
197
+ font-weight: 700;
198
+ color: var(--color-slate-700);
199
+ white-space: nowrap;
200
+ }
201
+
202
+ .theme-dark .jam-fruit-name {
203
+ color: var(--color-slate-200);
204
+ }
205
+
206
+ .jam-filter-pills {
207
+ display: flex;
208
+ gap: 1rem;
209
+ margin-top: 1.25rem;
210
+ flex-wrap: wrap;
211
+ width: 100%;
212
+ max-width: 100%;
213
+ }
214
+
215
+ .jam-filter-pill {
216
+ background: transparent;
217
+ border: 1px solid rgba(0, 0, 0, 0.08);
218
+ border-radius: 999px;
219
+ padding: 0.75rem 1.45rem;
220
+ font-size: 1.25rem;
221
+ font-weight: 600;
222
+ color: var(--color-slate-500);
223
+ cursor: pointer;
224
+ transition: all 0.2s;
225
+ white-space: normal;
226
+ text-align: center;
227
+ }
228
+
229
+ .theme-dark .jam-filter-pill {
230
+ border: 1px solid rgba(255, 255, 255, 0.08);
231
+ color: var(--color-slate-400);
232
+ }
233
+
234
+ .jam-filter-pill.active {
235
+ background: var(--color-slate-100);
236
+ color: var(--color-slate-900);
237
+ border-color: var(--color-slate-300);
238
+ }
239
+
240
+ .theme-dark .jam-filter-pill.active {
241
+ background: rgba(255, 255, 255, 0.08);
242
+ color: var(--color-slate-100);
243
+ border-color: rgba(255, 255, 255, 0.15);
244
+ }
245
+
246
+ .jam-inputs-section {
247
+ display: flex;
248
+ flex-direction: column;
249
+ gap: 1.85rem;
250
+ }
251
+
252
+ .jam-input-row {
253
+ display: flex;
254
+ flex-direction: column;
255
+ gap: 0.85rem;
256
+ position: relative;
257
+ }
258
+
259
+ .jam-input-row.jam-hidden {
260
+ display: none;
261
+ }
262
+
263
+ .jam-input-label {
264
+ font-size: 1.35rem;
265
+ font-weight: 700;
266
+ color: var(--color-slate-700);
267
+ text-transform: uppercase;
268
+ letter-spacing: 0.06em;
269
+ }
270
+
271
+ .theme-dark .jam-input-label {
272
+ color: var(--color-slate-200);
273
+ }
274
+
275
+ .jam-weight-input-wrap {
276
+ display: flex;
277
+ align-items: center;
278
+ background: rgba(247, 245, 251, 0.6);
279
+ border: 1px solid rgba(0, 0, 0, 0.08);
280
+ border-radius: var(--jam-radius-md);
281
+ padding: 0.8rem;
282
+ transition: border-color 0.2s;
283
+ }
284
+
285
+ .theme-dark .jam-weight-input-wrap {
286
+ background: rgba(45, 42, 62, 0.4);
287
+ border: 1px solid rgba(255, 255, 255, 0.08);
288
+ }
289
+
290
+ .jam-weight-input-wrap:focus-within {
291
+ border-color: var(--color-amethyst);
292
+ box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.15);
293
+ }
294
+
295
+ .jam-weight-input {
296
+ flex: 1;
297
+ background: transparent;
298
+ border: none;
299
+ outline: none;
300
+ font-size: 2.8rem;
301
+ font-weight: 800;
302
+ color: var(--color-slate-900);
303
+ padding: 1rem 1.3rem;
304
+ min-width: 0;
305
+ -moz-appearance: textfield;
306
+ }
307
+
308
+ .jam-weight-input::-webkit-inner-spin-button,
309
+ .jam-weight-input::-webkit-outer-spin-button {
310
+ -webkit-appearance: none;
311
+ margin: 0;
312
+ }
313
+
314
+ .theme-dark .jam-weight-input {
315
+ color: var(--color-white);
316
+ }
317
+
318
+ .jam-weight-unit {
319
+ font-size: 1.6rem;
320
+ font-weight: 700;
321
+ color: var(--color-slate-500);
322
+ padding-right: 1.45rem;
323
+ flex-shrink: 0;
324
+ }
325
+
326
+ .theme-dark .jam-weight-unit {
327
+ color: var(--color-slate-300);
328
+ }
329
+
330
+ .jam-sugar-auto-hint {
331
+ font-size: 1.1rem;
332
+ font-weight: 600;
333
+ color: var(--color-slate-400);
334
+ text-transform: uppercase;
335
+ letter-spacing: 0.05em;
336
+ margin-top: -0.25rem;
337
+ }
338
+
339
+ .jam-toggle-wrap {
340
+ display: grid;
341
+ grid-template-columns: 1fr 1fr;
342
+ background: rgba(234, 231, 242, 0.5);
343
+ border: 1px solid rgba(0, 0, 0, 0.05);
344
+ border-radius: var(--jam-radius-sm);
345
+ padding: 0.6rem;
346
+ }
347
+
348
+ .theme-dark .jam-toggle-wrap {
349
+ background: rgba(45, 42, 62, 0.4);
350
+ border: 1px solid rgba(255, 255, 255, 0.06);
351
+ }
352
+
353
+ .jam-toggle-btn {
354
+ background: transparent;
355
+ border: none;
356
+ padding: 1.3rem;
357
+ border-radius: calc(var(--jam-radius-sm) - 2px);
358
+ font-size: 1.35rem;
359
+ font-weight: 700;
360
+ color: var(--color-slate-500);
361
+ cursor: pointer;
362
+ transition: all 0.2s;
363
+ white-space: normal;
364
+ overflow-wrap: break-word;
365
+ }
366
+
367
+ .theme-dark .jam-toggle-btn {
368
+ color: var(--color-slate-300);
369
+ }
370
+
371
+ .jam-toggle-btn.active {
372
+ background: var(--color-white);
373
+ color: var(--color-slate-900);
374
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
375
+ }
376
+
377
+ .theme-dark .jam-toggle-btn.active {
378
+ background: rgba(255, 255, 255, 0.1);
379
+ color: var(--color-white);
380
+ box-shadow: none;
381
+ }
382
+
383
+ .jam-visual-section {
384
+ display: flex;
385
+ flex-direction: column;
386
+ align-items: center;
387
+ }
388
+
389
+ .jam-drop-hint {
390
+ font-size: 1.25rem;
391
+ color: var(--color-slate-500);
392
+ text-align: center;
393
+ margin-bottom: 1.25rem;
394
+ margin-top: -0.5rem;
395
+ }
396
+
397
+ .theme-dark .jam-drop-hint {
398
+ color: var(--color-slate-400);
399
+ }
400
+
401
+ .jam-plate-stage {
402
+ position: relative;
403
+ width: 100%;
404
+ max-width: 380px;
405
+ display: flex;
406
+ flex-direction: column;
407
+ align-items: center;
408
+ gap: 1.25rem;
409
+
410
+ --jam-fruit-color: #e11d48;
411
+ --jam-fruit-color-light: #fda4af;
412
+ --jam-fruit-color-dark: #be123c;
413
+ }
414
+
415
+ .jam-plate-svg {
416
+ width: 100%;
417
+ max-width: 300px;
418
+ height: auto;
419
+ color: var(--color-slate-300);
420
+ }
421
+
422
+ .theme-dark .jam-plate-svg {
423
+ color: var(--color-slate-400);
424
+ }
425
+
426
+ .jam-drop {
427
+ transition: cy 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
428
+ }
429
+
430
+ .jam-drop-highlight {
431
+ transition: cy 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
432
+ }
433
+
434
+ .jam-drop-status {
435
+ display: flex;
436
+ align-items: center;
437
+ gap: 0.95rem;
438
+ opacity: 0;
439
+ font-size: 1.5rem;
440
+ font-weight: 700;
441
+ text-align: left;
442
+ padding: 0.95rem 0;
443
+ transition: opacity 0.3s;
444
+ }
445
+
446
+ .jam-drop-status.visible {
447
+ opacity: 1;
448
+ }
449
+
450
+ .jam-drop-status-icon {
451
+ flex-shrink: 0;
452
+ display: flex;
453
+ align-items: center;
454
+ }
455
+
456
+ .jam-drop-status.perfect {
457
+ color: var(--color-emerald);
458
+ }
459
+
460
+ .jam-drop-status.slightly-thin {
461
+ color: var(--color-amber);
462
+ }
463
+
464
+ .jam-drop-status.too-thin {
465
+ color: var(--color-ruby);
466
+ }
467
+
468
+ .jam-drop-status.too-stiff {
469
+ color: var(--color-sapphire);
470
+ }
471
+
472
+ .theme-dark .jam-drop-status.perfect {
473
+ color: var(--color-emerald-bright);
474
+ }
475
+
476
+ .theme-dark .jam-drop-status.too-thin {
477
+ color: var(--color-ruby-light);
478
+ }
479
+
480
+ .jam-recipe-section {
481
+ --fruit-color: #e11d48;
482
+ --fruit-color-rgb: 225, 29, 72;
483
+ }
484
+
485
+ .jam-recipe-grid {
486
+ display: grid;
487
+ grid-template-columns: 1fr;
488
+ gap: 1.25rem;
489
+ margin-bottom: 1.45rem;
490
+ }
491
+
492
+ @media (min-width: 600px) {
493
+ .jam-recipe-grid {
494
+ grid-template-columns: 1fr 1fr;
495
+ }
496
+ }
497
+
498
+ @media (min-width: 768px) {
499
+ .jam-recipe-grid {
500
+ grid-template-columns: repeat(4, 1fr);
501
+ }
502
+ }
503
+
504
+ .jam-recipe-item {
505
+ display: flex;
506
+ align-items: center;
507
+ gap: 1.1rem;
508
+ background: rgba(247, 245, 251, 0.5);
509
+ border: 1px solid rgba(0, 0, 0, 0.04);
510
+ border-radius: var(--jam-radius-md);
511
+ padding: 1.45rem;
512
+ }
513
+
514
+ .theme-dark .jam-recipe-item {
515
+ background: rgba(45, 42, 62, 0.3);
516
+ border: 1px solid rgba(255, 255, 255, 0.04);
517
+ }
518
+
519
+ .jam-recipe-icon {
520
+ flex-shrink: 0;
521
+ color: var(--color-slate-400);
522
+ display: flex;
523
+ align-items: center;
524
+ }
525
+
526
+ .theme-dark .jam-recipe-icon {
527
+ color: var(--color-slate-300);
528
+ }
529
+
530
+ .jam-recipe-info {
531
+ min-width: 0;
532
+ }
533
+
534
+ .jam-recipe-val {
535
+ font-size: 2.2rem;
536
+ font-weight: 800;
537
+ color: var(--color-slate-900);
538
+ line-height: 1.2;
539
+ display: flex;
540
+ align-items: baseline;
541
+ }
542
+
543
+ .theme-dark .jam-recipe-val {
544
+ color: var(--color-white);
545
+ }
546
+
547
+ .jam-recipe-unit {
548
+ font-size: 1.3rem;
549
+ font-weight: 600;
550
+ color: var(--color-slate-400);
551
+ margin-left: 0.35rem;
552
+ }
553
+
554
+ .jam-recipe-label {
555
+ font-size: 1.15rem;
556
+ font-weight: 700;
557
+ color: var(--color-slate-500);
558
+ text-transform: uppercase;
559
+ letter-spacing: 0.04em;
560
+ margin-top: 0.25rem;
561
+ }
562
+
563
+ .theme-dark .jam-recipe-label {
564
+ color: var(--color-slate-400);
565
+ }
566
+
567
+ .jam-sugar-hint {
568
+ font-weight: 400;
569
+ text-transform: none;
570
+ opacity: 0.6;
571
+ }
572
+
573
+ .jam-recipe-sub {
574
+ font-size: 1.1rem;
575
+ color: var(--color-slate-400);
576
+ margin-top: 0.25rem;
577
+ }
578
+
579
+ .theme-dark .jam-recipe-sub {
580
+ color: var(--color-slate-500);
581
+ }
582
+
583
+ .jam-sugar-bar-wrap {
584
+ background: rgba(247, 245, 251, 0.5);
585
+ border: 1px solid rgba(0, 0, 0, 0.04);
586
+ border-radius: var(--jam-radius-md);
587
+ padding: 1.45rem;
588
+ }
589
+
590
+ .theme-dark .jam-sugar-bar-wrap {
591
+ background: rgba(45, 42, 62, 0.3);
592
+ border: 1px solid rgba(255, 255, 255, 0.04);
593
+ }
594
+
595
+ .jam-sugar-bar-header {
596
+ display: flex;
597
+ justify-content: space-between;
598
+ align-items: baseline;
599
+ font-size: 1.15rem;
600
+ font-weight: 700;
601
+ text-transform: uppercase;
602
+ letter-spacing: 0.05em;
603
+ color: var(--color-slate-500);
604
+ margin-bottom: 0.95rem;
605
+ flex-wrap: wrap;
606
+ gap: 0.8rem;
607
+ }
608
+
609
+ .jam-sugar-bar-val {
610
+ font-size: 1.45rem;
611
+ color: var(--color-slate-900);
612
+ display: flex;
613
+ align-items: baseline;
614
+ gap: 0.6rem;
615
+ flex-wrap: wrap;
616
+ }
617
+
618
+ .theme-dark .jam-sugar-bar-val {
619
+ color: var(--color-white);
620
+ }
621
+
622
+ #sugar-pct-context {
623
+ font-size: 1rem;
624
+ font-weight: 400;
625
+ text-transform: none;
626
+ letter-spacing: 0;
627
+ color: var(--color-slate-400);
628
+ }
629
+
630
+ .jam-sugar-bar {
631
+ position: relative;
632
+ width: 100%;
633
+ height: 16px;
634
+ background: rgba(0, 0, 0, 0.05);
635
+ border-radius: 8px;
636
+ overflow: visible;
637
+ margin-bottom: 0.8rem;
638
+ }
639
+
640
+ .theme-dark .jam-sugar-bar {
641
+ background: rgba(255, 255, 255, 0.06);
642
+ }
643
+
644
+ .jam-sugar-bar-fill {
645
+ height: 100%;
646
+ border-radius: 8px;
647
+ background: linear-gradient(90deg, var(--fruit-color), var(--color-amber));
648
+ transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
649
+ }
650
+
651
+ .jam-sugar-bar-fill.good {
652
+ background: linear-gradient(90deg, var(--color-emerald), var(--color-emerald-bright));
653
+ }
654
+
655
+ .jam-sugar-bar-fill.warn {
656
+ background: linear-gradient(90deg, var(--color-amber), var(--color-ruby));
657
+ }
658
+
659
+ .jam-sugar-bar-marker {
660
+ position: absolute;
661
+ top: -2px;
662
+ bottom: -2px;
663
+ width: 2px;
664
+ background: var(--color-slate-400);
665
+ border-radius: 1px;
666
+ opacity: 0.3;
667
+ }
668
+
669
+ .jam-sugar-bar-labels {
670
+ display: flex;
671
+ justify-content: space-between;
672
+ font-size: 1rem;
673
+ font-weight: 600;
674
+ color: var(--color-slate-400);
675
+ }
676
+
677
+ .jam-sugar-bar-ideal {
678
+ color: var(--color-emerald);
679
+ font-weight: 700;
680
+ }
681
+
682
+ @media (max-width: 480px) {
683
+ .jam-card {
684
+ padding: 1.75rem;
685
+ border-radius: var(--jam-radius-lg);
686
+ }
687
+
688
+ .jam-weight-input {
689
+ font-size: 2.2rem;
690
+ }
691
+
692
+ .jam-recipe-val {
693
+ font-size: 1.8rem;
694
+ }
695
+
696
+ .jam-fruit-pill {
697
+ padding: 0.95rem 1.45rem;
698
+ }
699
+
700
+ .jam-fruit-name {
701
+ font-size: 1.25rem;
702
+ }
703
+
704
+ .jam-fruit-dot {
705
+ width: 18px;
706
+ height: 18px;
707
+ }
708
+
709
+ .jam-toggle-wrap {
710
+ display: flex;
711
+ flex-direction: column;
712
+ gap: 0.6rem;
713
+ padding: 0.6rem;
714
+ }
715
+
716
+ .jam-toggle-btn {
717
+ padding: 1.1rem;
718
+ font-size: 1.25rem;
719
+ }
720
+
721
+ .jam-sugar-bar-header {
722
+ flex-direction: column;
723
+ align-items: flex-start;
724
+ gap: 0.6rem;
725
+ }
726
+
727
+ .jam-sugar-bar-val {
728
+ font-size: 1.25rem;
729
+ }
730
+ }
@@ -0,0 +1,15 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { pectinJam } from './entry';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'en' } = Astro.props;
11
+ const content = await pectinJam.i18n[locale]?.();
12
+ if (!content) return null;
13
+ ---
14
+
15
+ {content.seo?.length > 0 && <SEORenderer content={{ locale, sections: content.seo }} />}