@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,587 @@
1
+ .banana-care-container {
2
+ --bc-yellow: #fbbf24;
3
+ --bc-yellow-dark: #eab308;
4
+ --bc-orange: #b45309;
5
+ --bc-text-dark: #18181b;
6
+ --bc-text-light: #fff;
7
+ --bc-text-muted: #a1a1aa;
8
+ --bc-text-gray: #71717a;
9
+ --bc-text-gray-dark: #52525b;
10
+ --bc-blue-light: #4f8cee;
11
+ --bc-blue: #3b82f6;
12
+ --bc-blue-dark: #2563eb;
13
+ --bc-blue-lighter: #60a5fa;
14
+ --bc-green: #10b981;
15
+ --bc-gray-light: #d4d4d8;
16
+ --bc-slate-dark: #1e293b;
17
+
18
+ max-width: 100%;
19
+ margin: 2rem auto;
20
+ padding: 1rem;
21
+ display: flex;
22
+ flex-direction: column;
23
+ gap: 2rem;
24
+ }
25
+
26
+ .banana-card {
27
+ background: #fafafa;
28
+ backdrop-filter: blur(24px);
29
+ border: 1px solid #e4e4e7;
30
+ border-radius: 2.5rem;
31
+ padding: 2.5rem;
32
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
33
+ overflow: hidden;
34
+ position: relative;
35
+ }
36
+
37
+ .theme-dark .banana-card {
38
+ background: rgba(24, 24, 27, 0.4);
39
+ border-color: rgba(113, 113, 122, 0.5);
40
+ box-shadow: 0 32px 64px 0 rgba(0, 0, 0, 0.3);
41
+ }
42
+
43
+ .glow-bg {
44
+ position: absolute;
45
+ top: -96px;
46
+ right: -96px;
47
+ width: 256px;
48
+ height: 256px;
49
+ background: rgba(250, 204, 21, 0.2);
50
+ border-radius: 9999px;
51
+ filter: blur(96px);
52
+ pointer-events: none;
53
+ transition: all 700ms;
54
+ }
55
+
56
+ .glow-bg-2 {
57
+ position: absolute;
58
+ bottom: -96px;
59
+ left: -96px;
60
+ width: 256px;
61
+ height: 256px;
62
+ background: rgba(52, 211, 153, 0.1);
63
+ border-radius: 9999px;
64
+ filter: blur(96px);
65
+ pointer-events: none;
66
+ transition: all 700ms;
67
+ }
68
+
69
+ .banana-grid {
70
+ position: relative;
71
+ z-index: 10;
72
+ max-width: 80rem;
73
+ margin: 0 auto;
74
+ display: grid;
75
+ grid-template-columns: 1fr 1fr;
76
+ gap: 2rem;
77
+ align-items: center;
78
+ }
79
+
80
+ @media (max-width: 1024px) {
81
+ .banana-grid {
82
+ grid-template-columns: 1fr;
83
+ }
84
+ }
85
+
86
+ .banana-visual-section {
87
+ display: flex;
88
+ flex-direction: column;
89
+ align-items: center;
90
+ justify-content: center;
91
+ gap: 1rem;
92
+ }
93
+
94
+ .status-card {
95
+ position: relative;
96
+ width: 100%;
97
+ max-width: 340px;
98
+ aspect-ratio: 1;
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ }
103
+
104
+ .glow-indicator {
105
+ position: absolute;
106
+ inset: -100px;
107
+ border-radius: 9999px;
108
+ filter: blur(80px);
109
+ opacity: 0.3;
110
+ transition: all 1000ms;
111
+ }
112
+
113
+ .status-visual {
114
+ position: relative;
115
+ z-index: 10;
116
+ transition: all 700ms ease-out;
117
+ }
118
+
119
+ .banana-svg {
120
+ width: 100%;
121
+ height: 100%;
122
+ filter: drop-shadow(0 25px 50px rgba(0, 0, 0, 0.3));
123
+ }
124
+
125
+ .banana-group {
126
+ transition: all 700ms;
127
+ transform-origin: center;
128
+ }
129
+
130
+ .banana-body {
131
+ transition: color 500ms;
132
+ color: var(--bc-yellow);
133
+ }
134
+
135
+ .banana-dot {
136
+ transition: opacity 500ms cubic-bezier(0.4, 0, 0.2, 1);
137
+ opacity: 0;
138
+ }
139
+
140
+ .status-info {
141
+ display: flex;
142
+ flex-direction: column;
143
+ align-items: center;
144
+ gap: 1rem;
145
+ }
146
+
147
+ .status-badge {
148
+ display: inline-flex;
149
+ align-items: center;
150
+ gap: 0.5rem;
151
+ padding: 0.375rem 1rem;
152
+ border-radius: 9999px;
153
+ background: rgba(255, 255, 255, 0.1);
154
+ border: 1px solid rgba(255, 255, 255, 0.2);
155
+ backdrop-filter: blur(12px);
156
+ }
157
+
158
+ .theme-dark .status-badge {
159
+ background: rgba(0, 0, 0, 0.2);
160
+ border-color: rgba(255, 255, 255, 0.05);
161
+ }
162
+
163
+ .status-dot {
164
+ width: 0.625rem;
165
+ height: 0.625rem;
166
+ border-radius: 50%;
167
+ box-shadow: 0 0 15px currentcolor;
168
+ }
169
+
170
+ .status-name {
171
+ font-size: 0.875rem;
172
+ font-weight: 900;
173
+ text-transform: uppercase;
174
+ letter-spacing: 0.05em;
175
+ color: var(--bc-text-dark);
176
+ }
177
+
178
+ .theme-dark .status-name {
179
+ color: var(--bc-text-light);
180
+ }
181
+
182
+ .status-description {
183
+ font-size: 0.75rem;
184
+ color: var(--bc-text-gray);
185
+ font-weight: 700;
186
+ max-width: 280px;
187
+ text-align: center;
188
+ min-height: 3em;
189
+ }
190
+
191
+ .theme-dark .status-description {
192
+ color: var(--bc-text-muted);
193
+ }
194
+
195
+ .banana-controls {
196
+ display: flex;
197
+ flex-direction: column;
198
+ }
199
+
200
+ .controls-panel {
201
+ padding: 2rem;
202
+ border-radius: 2rem;
203
+ background: #fff;
204
+ border: 1px solid #e4e4e7;
205
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
206
+ backdrop-filter: blur(12px);
207
+ display: flex;
208
+ flex-direction: column;
209
+ gap: 2rem;
210
+ }
211
+
212
+ .theme-dark .controls-panel {
213
+ background: rgba(0, 0, 0, 0.2);
214
+ border-color: rgba(255, 255, 255, 0.05);
215
+ }
216
+
217
+ .control-group {
218
+ display: flex;
219
+ flex-direction: column;
220
+ gap: 1rem;
221
+ }
222
+
223
+ .ripeness-header {
224
+ display: flex;
225
+ justify-content: space-between;
226
+ align-items: flex-end;
227
+ }
228
+
229
+ .ripeness-label {
230
+ font-size: 0.625rem;
231
+ font-weight: 900;
232
+ text-transform: uppercase;
233
+ letter-spacing: 0.075em;
234
+ color: var(--bc-text-muted);
235
+ }
236
+
237
+ .level-value {
238
+ font-size: 1.875rem;
239
+ font-weight: 900;
240
+ color: var(--bc-yellow-dark);
241
+ font-variant-numeric: tabular-nums;
242
+ }
243
+
244
+ .ripeness-slider {
245
+ width: 100%;
246
+ height: 0.75rem;
247
+ border-radius: 9999px;
248
+ background: #e4e4e7;
249
+ border: none;
250
+ outline: none;
251
+ cursor: pointer;
252
+ accent-color: var(--bc-yellow-dark);
253
+ appearance: none;
254
+ }
255
+
256
+ .theme-dark .ripeness-slider {
257
+ background: #27272a;
258
+ }
259
+
260
+ .ripeness-slider::-webkit-slider-thumb {
261
+ appearance: none;
262
+ width: 36px;
263
+ height: 36px;
264
+ background: var(--bc-yellow);
265
+ cursor: pointer;
266
+ border-radius: 50%;
267
+ border: 4px solid white;
268
+ box-shadow: 0 10px 25px rgba(251, 191, 36, 0.4);
269
+ transition: all 0.2s;
270
+ }
271
+
272
+ .theme-dark .ripeness-slider::-webkit-slider-thumb {
273
+ border-color: var(--bc-text-dark);
274
+ }
275
+
276
+ .ripeness-slider:active::-webkit-slider-thumb {
277
+ transform: scale(0.9);
278
+ }
279
+
280
+ .grid-2-cols {
281
+ display: grid;
282
+ grid-template-columns: 1fr 1fr;
283
+ gap: 1.5rem;
284
+ }
285
+
286
+ @media (max-width: 768px) {
287
+ .grid-2-cols {
288
+ grid-template-columns: 1fr;
289
+ }
290
+ }
291
+
292
+ .prediction-box {
293
+ padding: 1.5rem;
294
+ border-radius: 1.875rem;
295
+ background: #fafafa;
296
+ border: 1px solid #e4e4e7;
297
+ text-align: center;
298
+ display: flex;
299
+ flex-direction: column;
300
+ justify-content: center;
301
+ }
302
+
303
+ .prediction-label {
304
+ font-size: 0.625rem;
305
+ font-weight: 900;
306
+ text-transform: uppercase;
307
+ letter-spacing: 0.05em;
308
+ color: var(--bc-orange);
309
+ margin-bottom: 0.5rem;
310
+ }
311
+
312
+ :root[class~="dark"] .prediction-label {
313
+ color: var(--bc-yellow);
314
+ }
315
+
316
+ .prediction-value {
317
+ display: flex;
318
+ align-items: baseline;
319
+ justify-content: center;
320
+ gap: 0.25rem;
321
+ }
322
+
323
+ .days-number {
324
+ font-size: 3.75rem;
325
+ font-weight: 900;
326
+ color: var(--bc-text-dark);
327
+ font-variant-numeric: tabular-nums;
328
+ }
329
+
330
+ :root[class~="dark"] .days-number {
331
+ color: var(--bc-text-light);
332
+ }
333
+
334
+ .days-unit {
335
+ font-size: 0.75rem;
336
+ font-weight: 900;
337
+ color: var(--bc-text-muted);
338
+ text-transform: uppercase;
339
+ }
340
+
341
+ .settings-column {
342
+ display: flex;
343
+ flex-direction: column;
344
+ gap: 1rem;
345
+ }
346
+
347
+ .setting-item {
348
+ padding: 1rem;
349
+ border-radius: 0.5rem;
350
+ border: 1px solid transparent;
351
+ transition: all 0.2s;
352
+ }
353
+
354
+ .setting-item.temp {
355
+ background: rgba(79, 172, 254, 0.05);
356
+ border-color: rgba(79, 172, 254, 0.1);
357
+ }
358
+
359
+ .setting-item.humidity {
360
+ background: rgba(59, 130, 246, 0.05);
361
+ border-color: rgba(59, 130, 246, 0.1);
362
+ }
363
+
364
+ .setting-item:hover {
365
+ background-color: rgba(79, 172, 254, 0.1);
366
+ }
367
+
368
+ .setting-header {
369
+ display: flex;
370
+ justify-content: space-between;
371
+ align-items: center;
372
+ margin-bottom: 0.5rem;
373
+ }
374
+
375
+ .setting-label {
376
+ font-size: 0.5625rem;
377
+ font-weight: 900;
378
+ text-transform: uppercase;
379
+ color: var(--bc-blue-light);
380
+ }
381
+
382
+ .setting-item.humidity .setting-label {
383
+ color: var(--bc-blue);
384
+ }
385
+
386
+ .setting-value {
387
+ font-size: 0.75rem;
388
+ font-weight: 700;
389
+ color: var(--bc-blue-dark);
390
+ }
391
+
392
+ .theme-dark .setting-value {
393
+ color: var(--bc-blue-lighter);
394
+ }
395
+
396
+ .setting-slider {
397
+ width: 100%;
398
+ height: 0.25rem;
399
+ border-radius: 9999px;
400
+ background: #dbeafe;
401
+ border: none;
402
+ outline: none;
403
+ cursor: pointer;
404
+ accent-color: var(--bc-blue-light);
405
+ appearance: none;
406
+ }
407
+
408
+ .theme-dark .setting-slider {
409
+ background: rgba(59, 130, 246, 0.5);
410
+ }
411
+
412
+ .partner-btn {
413
+ width: 100%;
414
+ padding: 1.25rem;
415
+ border-radius: 0.5rem;
416
+ border: 1px solid rgba(16, 185, 129, 0.2);
417
+ background: rgba(16, 185, 129, 0.05);
418
+ display: flex;
419
+ align-items: center;
420
+ justify-content: space-between;
421
+ cursor: pointer;
422
+ transition: all 0.2s;
423
+ }
424
+
425
+ .partner-btn:hover {
426
+ background: rgba(16, 185, 129, 0.1);
427
+ }
428
+
429
+ .partner-btn.active {
430
+ background: var(--bc-green);
431
+ }
432
+
433
+ .theme-dark .partner-btn.active {
434
+ background: var(--bc-green);
435
+ }
436
+
437
+ .partner-content {
438
+ display: flex;
439
+ align-items: center;
440
+ gap: 1rem;
441
+ text-align: left;
442
+ }
443
+
444
+ .partner-icon {
445
+ padding: 0.75rem;
446
+ border-radius: 0.5rem;
447
+ background: rgba(16, 185, 129, 0.2);
448
+ width: 2.5rem;
449
+ height: 2.5rem;
450
+ display: flex;
451
+ align-items: center;
452
+ justify-content: center;
453
+ color: var(--bc-green);
454
+ transition: transform 0.2s;
455
+ }
456
+
457
+ .partner-btn.active .partner-icon {
458
+ transform: scale(1.1);
459
+ }
460
+
461
+ .partner-title {
462
+ font-size: 0.75rem;
463
+ font-weight: 900;
464
+ color: var(--bc-text-dark);
465
+ text-transform: uppercase;
466
+ }
467
+
468
+ .theme-dark .partner-title {
469
+ color: var(--bc-text-light);
470
+ }
471
+
472
+ .partner-btn.active .partner-title {
473
+ color: var(--bc-text-light);
474
+ }
475
+
476
+ .partner-subtitle {
477
+ font-size: 0.625rem;
478
+ color: var(--bc-text-muted);
479
+ font-weight: 700;
480
+ text-transform: uppercase;
481
+ letter-spacing: 0.05em;
482
+ }
483
+
484
+ .partner-btn.active .partner-subtitle {
485
+ color: rgba(255, 255, 255, 0.8);
486
+ }
487
+
488
+ .toggle-switch {
489
+ width: 3rem;
490
+ height: 1.5rem;
491
+ border-radius: 9999px;
492
+ background: #e4e4e7;
493
+ position: relative;
494
+ border: 1px solid var(--bc-gray-light);
495
+ }
496
+
497
+ .theme-dark .toggle-switch {
498
+ background: #27272a;
499
+ border-color: #3f3f46;
500
+ }
501
+
502
+ .toggle-circle {
503
+ position: absolute;
504
+ left: 0.25rem;
505
+ top: 0.25rem;
506
+ width: 1rem;
507
+ height: 1rem;
508
+ border-radius: 50%;
509
+ background: white;
510
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
511
+ transition: transform 300ms;
512
+ }
513
+
514
+ .toggle-circle.active {
515
+ transform: translateX(1.5rem);
516
+ }
517
+
518
+ .info-grid {
519
+ gap: 1rem;
520
+ }
521
+
522
+ .info-box {
523
+ padding: 1.5rem;
524
+ border-radius: 1.875rem;
525
+ border: 1px solid #e4e4e7;
526
+ }
527
+
528
+ .theme-dark .info-box {
529
+ background: rgba(113, 113, 122, 0.4);
530
+ border-color: rgba(113, 113, 122, 0.5);
531
+ }
532
+
533
+ .info-box.conservation {
534
+ background: #fafafa;
535
+ }
536
+
537
+ .info-box.conservation .info-title {
538
+ color: var(--bc-text-dark);
539
+ }
540
+
541
+ .info-box.conservation .info-text {
542
+ color: var(--bc-slate-dark);
543
+ }
544
+
545
+ .info-box.acceleration {
546
+ background: rgba(250, 204, 21, 0.05);
547
+ border-color: rgba(250, 204, 21, 0.2);
548
+ }
549
+
550
+ .info-title {
551
+ font-size: 0.5625rem;
552
+ font-weight: 900;
553
+ text-transform: uppercase;
554
+ letter-spacing: 0.05em;
555
+ color: var(--bc-text-gray-dark);
556
+ margin-bottom: 0.5rem;
557
+ }
558
+
559
+ .info-text {
560
+ font-size: 0.75rem;
561
+ color: var(--bc-text-dark);
562
+ line-height: 1.5;
563
+ font-weight: 700;
564
+ margin: 0;
565
+ }
566
+
567
+ .theme-dark .info-text {
568
+ color: var(--bc-gray-light);
569
+ }
570
+
571
+ .info-box.acceleration .info-title {
572
+ color: var(--bc-orange);
573
+ }
574
+
575
+ .theme-dark .info-box.acceleration .info-title {
576
+ color: var(--bc-yellow);
577
+ }
578
+
579
+ .info-box.acceleration .info-text {
580
+ font-style: italic;
581
+ color: var(--bc-text-dark);
582
+ font-weight: 900;
583
+ }
584
+
585
+ .theme-dark .info-box.acceleration .info-text {
586
+ color: var(--bc-text-light);
587
+ }
@@ -0,0 +1,79 @@
1
+ export interface RipenessState {
2
+ level: number;
3
+ name: string;
4
+ description: string;
5
+ conservation: string;
6
+ acceleration: string;
7
+ suggestedUse: string;
8
+ color: string;
9
+ }
10
+
11
+ export const RIPENESS_STAGES: Record<number, RipenessState> = {
12
+ 1: {
13
+ level: 1,
14
+ name: "Verde Esmeralda",
15
+ description: "Contenido máximo de almidón resistente. Firmeza total.",
16
+ conservation: "Ambiente (18-20°C). Evitar frío (<12°C).",
17
+ acceleration: "Bolsa de papel con una manzana o tomate maduro.",
18
+ suggestedUse: "Cocinar (tostones) o madurar.",
19
+ color: "#059669",
20
+ },
21
+ 2: {
22
+ level: 2,
23
+ name: "Amarillo Radiante",
24
+ description: "Equilibrio perfecto entre firmeza y dulzor inicial.",
25
+ conservation: "Lugar fresco, separar del racimo para frenar etileno.",
26
+ acceleration: "Mantener en el racimo y envolver en plástico.",
27
+ suggestedUse: "Consumo directo, ensaladas de frutas.",
28
+ color: "#fbbf24",
29
+ },
30
+ 3: {
31
+ level: 3,
32
+ name: "Moteado Dulce",
33
+ description: "Pico de antioxidantes. Dulzor intenso y textura cremosa.",
34
+ conservation: "Refrigerar para conservar pulpa (aunque la piel se oscurezca).",
35
+ acceleration: "Calor suave (cerca de una fuente de calor, no directa).",
36
+ suggestedUse: "Postres rápidos, batidos, snacks.",
37
+ color: "#f59e0b",
38
+ },
39
+ 4: {
40
+ level: 4,
41
+ name: "Maduro Canela",
42
+ description: "Textura muy blanda. Ideal para repostería sin azúcar.",
43
+ conservation: "Pelar y congelar inmediatamente.",
44
+ acceleration: "Ya ha alcanzado su máximo.",
45
+ suggestedUse: "Banana bread, tortitas, helados.",
46
+ color: "#b45309",
47
+ },
48
+ 5: {
49
+ level: 5,
50
+ name: "Pasado / Fermentado",
51
+ description: "Proceso de degradación avanzado.",
52
+ conservation: "No recomendable para consumo directo.",
53
+ acceleration: "N/A",
54
+ suggestedUse: "Compost o abono orgánico.",
55
+ color: "#451a03",
56
+ },
57
+ };
58
+
59
+ export class BananaEngine {
60
+ static getStatus(level: number): RipenessState {
61
+ const stage = Math.max(1, Math.min(5, Math.round(level)));
62
+ return RIPENESS_STAGES[stage];
63
+ }
64
+
65
+ static calculateDays(
66
+ level: number,
67
+ temperature: number,
68
+ humidity: number,
69
+ hasPartners: boolean
70
+ ): number {
71
+ const baseDaysPerStage = 3;
72
+ const tempFactor = 20 / temperature;
73
+ const humidityFactor = 1 + (humidity - 50) / 200;
74
+ const partnerFactor = hasPartners ? 0.6 : 1.0;
75
+
76
+ const remainingInStage = (1 - (level % 1 || 0.1)) * baseDaysPerStage;
77
+ return Number((remainingInStage * tempFactor * humidityFactor * partnerFactor).toFixed(1));
78
+ }
79
+ }
@@ -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} />