@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.
- package/package.json +60 -0
- package/src/category/i18n/en.ts +24 -0
- package/src/category/i18n/es.ts +208 -0
- package/src/category/i18n/fr.ts +24 -0
- package/src/category/index.ts +37 -0
- package/src/category/seo.astro +15 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +11 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +32 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +146 -0
- package/src/pages/[locale].astro +251 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/faq_count.test.ts +19 -0
- package/src/tests/i18n-titles.test.ts +66 -0
- package/src/tests/locale_completeness.test.ts +42 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/no_h1_in_components.test.ts +48 -0
- package/src/tests/seo_length.test.ts +22 -0
- package/src/tests/tool_validation.test.ts +17 -0
- package/src/tool/american-kitchen-converter/AmericanKitchenEngine.ts +259 -0
- package/src/tool/american-kitchen-converter/bibliography.astro +6 -0
- package/src/tool/american-kitchen-converter/component.astro +838 -0
- package/src/tool/american-kitchen-converter/i18n/en.ts +282 -0
- package/src/tool/american-kitchen-converter/i18n/es.ts +281 -0
- package/src/tool/american-kitchen-converter/i18n/fr.ts +292 -0
- package/src/tool/american-kitchen-converter/index.ts +24 -0
- package/src/tool/american-kitchen-converter/seo.astro +8 -0
- package/src/tool/banana-ripeness/BananaCare.css +587 -0
- package/src/tool/banana-ripeness/BananaEngine.ts +79 -0
- package/src/tool/banana-ripeness/bibliography.astro +6 -0
- package/src/tool/banana-ripeness/component.astro +285 -0
- package/src/tool/banana-ripeness/i18n/en.ts +177 -0
- package/src/tool/banana-ripeness/i18n/es.ts +177 -0
- package/src/tool/banana-ripeness/i18n/fr.ts +177 -0
- package/src/tool/banana-ripeness/index.ts +24 -0
- package/src/tool/banana-ripeness/seo.astro +8 -0
- package/src/tool/brine/bibliography.astro +6 -0
- package/src/tool/brine/component.astro +884 -0
- package/src/tool/brine/i18n/en.ts +221 -0
- package/src/tool/brine/i18n/es.ts +222 -0
- package/src/tool/brine/i18n/fr.ts +221 -0
- package/src/tool/brine/index.ts +26 -0
- package/src/tool/brine/seo.astro +8 -0
- package/src/tool/cookware-guide/CookwareGuide.css +487 -0
- package/src/tool/cookware-guide/bibliography.astro +6 -0
- package/src/tool/cookware-guide/component.astro +164 -0
- package/src/tool/cookware-guide/i18n/en.ts +163 -0
- package/src/tool/cookware-guide/i18n/es.ts +163 -0
- package/src/tool/cookware-guide/i18n/fr.ts +164 -0
- package/src/tool/cookware-guide/index.ts +24 -0
- package/src/tool/cookware-guide/init.ts +174 -0
- package/src/tool/cookware-guide/seo.astro +8 -0
- package/src/tool/egg-timer/EggTimer.css +503 -0
- package/src/tool/egg-timer/bibliography.astro +14 -0
- package/src/tool/egg-timer/component.astro +281 -0
- package/src/tool/egg-timer/i18n/en.ts +230 -0
- package/src/tool/egg-timer/i18n/es.ts +222 -0
- package/src/tool/egg-timer/i18n/fr.ts +121 -0
- package/src/tool/egg-timer/index.ts +27 -0
- package/src/tool/egg-timer/seo.astro +39 -0
- package/src/tool/ingredient-rescaler/IngredientRescaler.css +308 -0
- package/src/tool/ingredient-rescaler/bibliography.astro +6 -0
- package/src/tool/ingredient-rescaler/component.astro +107 -0
- package/src/tool/ingredient-rescaler/i18n/en.ts +265 -0
- package/src/tool/ingredient-rescaler/i18n/es.ts +268 -0
- package/src/tool/ingredient-rescaler/i18n/fr.ts +207 -0
- package/src/tool/ingredient-rescaler/index.ts +24 -0
- package/src/tool/ingredient-rescaler/init.ts +200 -0
- package/src/tool/ingredient-rescaler/seo.astro +8 -0
- package/src/tool/kitchen-timer/KitchenTimer.css +325 -0
- package/src/tool/kitchen-timer/bibliography.astro +6 -0
- package/src/tool/kitchen-timer/component.astro +341 -0
- package/src/tool/kitchen-timer/i18n/en.ts +154 -0
- package/src/tool/kitchen-timer/i18n/es.ts +154 -0
- package/src/tool/kitchen-timer/i18n/fr.ts +154 -0
- package/src/tool/kitchen-timer/index.ts +26 -0
- package/src/tool/kitchen-timer/init.ts +55 -0
- package/src/tool/kitchen-timer/lib/AudioHelper.ts +27 -0
- package/src/tool/kitchen-timer/lib/DockManager.ts +97 -0
- package/src/tool/kitchen-timer/lib/KitchenTimer.ts +264 -0
- package/src/tool/kitchen-timer/seo.astro +8 -0
- package/src/tool/meringue-peak/MeringueCalculator.css +298 -0
- package/src/tool/meringue-peak/bibliography.astro +6 -0
- package/src/tool/meringue-peak/component.astro +169 -0
- package/src/tool/meringue-peak/i18n/en.ts +257 -0
- package/src/tool/meringue-peak/i18n/es.ts +234 -0
- package/src/tool/meringue-peak/i18n/fr.ts +234 -0
- package/src/tool/meringue-peak/index.ts +24 -0
- package/src/tool/meringue-peak/seo.astro +8 -0
- package/src/tool/mold-scaler/MoldScaler.css +406 -0
- package/src/tool/mold-scaler/bibliography.astro +6 -0
- package/src/tool/mold-scaler/component.astro +126 -0
- package/src/tool/mold-scaler/i18n/en.ts +268 -0
- package/src/tool/mold-scaler/i18n/es.ts +269 -0
- package/src/tool/mold-scaler/i18n/fr.ts +276 -0
- package/src/tool/mold-scaler/index.ts +26 -0
- package/src/tool/mold-scaler/init.ts +264 -0
- package/src/tool/mold-scaler/seo.astro +8 -0
- package/src/tool/pizza/Pizza.css +569 -0
- package/src/tool/pizza/bibliography.astro +6 -0
- package/src/tool/pizza/calculator.ts +143 -0
- package/src/tool/pizza/component.astro +237 -0
- package/src/tool/pizza/i18n/en.ts +288 -0
- package/src/tool/pizza/i18n/es.ts +289 -0
- package/src/tool/pizza/i18n/fr.ts +288 -0
- package/src/tool/pizza/index.ts +27 -0
- package/src/tool/pizza/seo.astro +8 -0
- package/src/tool/roux-guide/RouxGuide.css +483 -0
- package/src/tool/roux-guide/bibliography.astro +6 -0
- package/src/tool/roux-guide/component.astro +194 -0
- package/src/tool/roux-guide/i18n/en.ts +233 -0
- package/src/tool/roux-guide/i18n/es.ts +225 -0
- package/src/tool/roux-guide/i18n/fr.ts +225 -0
- package/src/tool/roux-guide/index.ts +24 -0
- package/src/tool/roux-guide/init.ts +187 -0
- package/src/tool/roux-guide/seo.astro +8 -0
- package/src/tool/sourdough-calculator/SourdoughCalculator.css +369 -0
- package/src/tool/sourdough-calculator/bibliography.astro +6 -0
- package/src/tool/sourdough-calculator/component.astro +198 -0
- package/src/tool/sourdough-calculator/i18n/en.ts +242 -0
- package/src/tool/sourdough-calculator/i18n/es.ts +243 -0
- package/src/tool/sourdough-calculator/i18n/fr.ts +248 -0
- package/src/tool/sourdough-calculator/index.ts +24 -0
- package/src/tool/sourdough-calculator/init.ts +131 -0
- package/src/tool/sourdough-calculator/seo.astro +8 -0
- package/src/tools.ts +29 -0
- package/src/types.ts +73 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--ir-primary: hsl(220deg, 90%, 56%);
|
|
3
|
+
--ir-primary-light: hsl(220deg, 90%, 92%);
|
|
4
|
+
--ir-primary-dark: hsl(220deg, 85%, 45%);
|
|
5
|
+
--ir-success: hsl(142deg, 72%, 45%);
|
|
6
|
+
--ir-danger: hsl(0deg, 84%, 60%);
|
|
7
|
+
--ir-bg-card: hsl(0deg, 0%, 100%);
|
|
8
|
+
--ir-bg-app: hsl(210deg, 20%, 98%);
|
|
9
|
+
--ir-border: hsl(210deg, 20%, 90%);
|
|
10
|
+
--ir-text-main: hsl(210deg, 30%, 20%);
|
|
11
|
+
--ir-text-muted: hsl(210deg, 15%, 50%);
|
|
12
|
+
--ir-text-disabled: hsl(210deg, 15%, 75%);
|
|
13
|
+
--ir-shadow-sm: 0 1px 2px 0 rgb(0, 0, 0, 0.05);
|
|
14
|
+
--ir-shadow-md: 0 4px 6px -1px rgb(0, 0, 0, 0.1), 0 2px 4px -2px rgb(0, 0, 0, 0.1);
|
|
15
|
+
--ir-shadow-lg: 0 10px 15px -3px rgb(0, 0, 0, 0.1), 0 4px 6px -4px rgb(0, 0, 0, 0.1);
|
|
16
|
+
--ir-radius: 1rem;
|
|
17
|
+
--ir-transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.theme-dark {
|
|
21
|
+
--ir-bg-card: hsl(220deg, 25%, 12%);
|
|
22
|
+
--ir-bg-app: hsl(220deg, 30%, 7%);
|
|
23
|
+
--ir-border: hsl(220deg, 20%, 20%);
|
|
24
|
+
--ir-text-main: hsl(210deg, 20%, 95%);
|
|
25
|
+
--ir-text-muted: hsl(210deg, 15%, 70%);
|
|
26
|
+
--ir-text-disabled: hsl(210deg, 15%, 50%);
|
|
27
|
+
--ir-primary-light: hsl(220deg, 90%, 12%);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.ingredient-rescaler-container {
|
|
31
|
+
max-width: 100%;
|
|
32
|
+
padding: 1.5rem;
|
|
33
|
+
background: var(--ir-bg-card);
|
|
34
|
+
border: 1px solid var(--ir-border);
|
|
35
|
+
border-radius: var(--ir-radius);
|
|
36
|
+
box-shadow: var(--ir-shadow-lg);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.ir-grid {
|
|
40
|
+
display: grid;
|
|
41
|
+
grid-template-columns: 1fr;
|
|
42
|
+
gap: 2rem;
|
|
43
|
+
margin-bottom: 2rem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@media (min-width: 768px) {
|
|
47
|
+
.ir-grid {
|
|
48
|
+
grid-template-columns: 1fr 1fr;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.ir-section {
|
|
53
|
+
background: var(--ir-bg-app);
|
|
54
|
+
padding: 1.5rem;
|
|
55
|
+
border-radius: 1.25rem;
|
|
56
|
+
border: 1px solid var(--ir-border);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.ir-section-primary {
|
|
60
|
+
background: var(--ir-bg-card);
|
|
61
|
+
border: 2px solid var(--ir-primary);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.ir-section-title {
|
|
65
|
+
font-size: 1.125rem;
|
|
66
|
+
font-weight: 700;
|
|
67
|
+
color: var(--ir-text-main);
|
|
68
|
+
margin-bottom: 1rem;
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
gap: 0.5rem;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.ir-section-primary .ir-section-title {
|
|
75
|
+
color: var(--ir-primary);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.ir-fields {
|
|
79
|
+
display: grid;
|
|
80
|
+
grid-template-columns: 1fr 1fr;
|
|
81
|
+
gap: 1rem;
|
|
82
|
+
margin-bottom: 1.5rem;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.ir-field {
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: column;
|
|
88
|
+
gap: 0.5rem;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.ir-label {
|
|
92
|
+
font-size: 0.75rem;
|
|
93
|
+
font-weight: 700;
|
|
94
|
+
color: var(--ir-text-muted);
|
|
95
|
+
text-transform: uppercase;
|
|
96
|
+
letter-spacing: 0.05em;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.ir-input {
|
|
100
|
+
width: 100%;
|
|
101
|
+
padding: 0.75rem 1rem;
|
|
102
|
+
border-radius: 0.75rem;
|
|
103
|
+
border: 1px solid var(--ir-border);
|
|
104
|
+
background: var(--ir-bg-card);
|
|
105
|
+
color: var(--ir-text-main);
|
|
106
|
+
font-weight: 600;
|
|
107
|
+
font-size: 1.125rem;
|
|
108
|
+
text-align: center;
|
|
109
|
+
transition: var(--ir-transition);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.ir-input:focus {
|
|
113
|
+
outline: none;
|
|
114
|
+
border-color: var(--ir-primary);
|
|
115
|
+
box-shadow: 0 0 0 3px hsl(25deg, 95%, 53%, 0.1);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.ir-factor-display {
|
|
119
|
+
margin-top: 1rem;
|
|
120
|
+
padding: 1rem;
|
|
121
|
+
background: var(--ir-primary-light);
|
|
122
|
+
border-radius: 0.75rem;
|
|
123
|
+
border: 1px solid var(--ir-primary);
|
|
124
|
+
display: flex;
|
|
125
|
+
justify-content: space-between;
|
|
126
|
+
align-items: center;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.ir-factor-label {
|
|
130
|
+
font-size: 0.875rem;
|
|
131
|
+
font-weight: 600;
|
|
132
|
+
color: var(--ir-text-muted);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.ir-factor-value {
|
|
136
|
+
font-size: 2rem;
|
|
137
|
+
font-weight: 800;
|
|
138
|
+
color: var(--ir-primary);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.ir-textarea-container {
|
|
142
|
+
display: flex;
|
|
143
|
+
flex-direction: column;
|
|
144
|
+
height: 100%;
|
|
145
|
+
gap: 0.5rem;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.ir-textarea {
|
|
149
|
+
width: 100%;
|
|
150
|
+
flex: 1;
|
|
151
|
+
min-height: 200px;
|
|
152
|
+
padding: 1rem;
|
|
153
|
+
border-radius: 0.75rem;
|
|
154
|
+
border: 1px solid var(--ir-border);
|
|
155
|
+
background: var(--ir-bg-card);
|
|
156
|
+
color: var(--ir-text-main);
|
|
157
|
+
font-size: 0.875rem;
|
|
158
|
+
resize: none;
|
|
159
|
+
line-height: 1.6;
|
|
160
|
+
transition: var(--ir-transition);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.ir-textarea:focus {
|
|
164
|
+
outline: none;
|
|
165
|
+
border-color: var(--ir-primary);
|
|
166
|
+
box-shadow: 0 0 0 3px hsl(25deg, 95%, 53%, 0.1);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.ir-textarea::placeholder {
|
|
170
|
+
color: var(--ir-text-disabled);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.ir-results-card {
|
|
174
|
+
background: var(--ir-text-main);
|
|
175
|
+
border-radius: 1.25rem;
|
|
176
|
+
border: 1px solid var(--ir-border);
|
|
177
|
+
overflow: hidden;
|
|
178
|
+
box-shadow: var(--ir-shadow-md);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.ir-results-header {
|
|
182
|
+
padding: 1rem 1.5rem;
|
|
183
|
+
background: hsl(210deg, 30%, 15%);
|
|
184
|
+
border-bottom: 1px solid hsl(210deg, 30%, 25%);
|
|
185
|
+
display: flex;
|
|
186
|
+
justify-content: space-between;
|
|
187
|
+
align-items: center;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.theme-dark .ir-results-header {
|
|
191
|
+
background: hsl(220deg, 25%, 8%);
|
|
192
|
+
border-bottom-color: hsl(220deg, 25%, 20%);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.ir-results-title {
|
|
196
|
+
color: var(--ir-bg-card);
|
|
197
|
+
font-weight: 700;
|
|
198
|
+
display: flex;
|
|
199
|
+
align-items: center;
|
|
200
|
+
gap: 0.5rem;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.ir-copy-btn {
|
|
204
|
+
font-size: 0.75rem;
|
|
205
|
+
background: hsl(210deg, 30%, 35%);
|
|
206
|
+
color: var(--ir-bg-card);
|
|
207
|
+
padding: 0.5rem 1rem;
|
|
208
|
+
border-radius: 0.5rem;
|
|
209
|
+
border: none;
|
|
210
|
+
cursor: pointer;
|
|
211
|
+
transition: var(--ir-transition);
|
|
212
|
+
font-weight: 600;
|
|
213
|
+
display: flex;
|
|
214
|
+
align-items: center;
|
|
215
|
+
gap: 0.5rem;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.theme-dark .ir-copy-btn {
|
|
219
|
+
background: hsl(220deg, 25%, 30%);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.ir-copy-btn:hover {
|
|
223
|
+
background: hsl(210deg, 30%, 45%);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.theme-dark .ir-copy-btn:hover {
|
|
227
|
+
background: hsl(220deg, 25%, 40%);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.ir-copy-btn.ir-copied {
|
|
231
|
+
background: var(--ir-success);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.ir-copy-btn.ir-copied:hover {
|
|
235
|
+
background: hsl(142deg, 72%, 35%);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.ir-results-container {
|
|
239
|
+
padding: 2rem;
|
|
240
|
+
font-size: 1rem;
|
|
241
|
+
display: flex;
|
|
242
|
+
flex-direction: column;
|
|
243
|
+
gap: 0.75rem;
|
|
244
|
+
min-height: 200px;
|
|
245
|
+
background: var(--ir-bg-card);
|
|
246
|
+
color: var(--ir-text-main);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.ir-empty-state {
|
|
250
|
+
height: 100%;
|
|
251
|
+
display: flex;
|
|
252
|
+
flex-direction: column;
|
|
253
|
+
align-items: center;
|
|
254
|
+
justify-content: center;
|
|
255
|
+
gap: 1rem;
|
|
256
|
+
opacity: 0.5;
|
|
257
|
+
color: var(--ir-text-muted);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.ir-empty-icon {
|
|
261
|
+
width: 3rem;
|
|
262
|
+
height: 3rem;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.ir-result-row {
|
|
266
|
+
display: flex;
|
|
267
|
+
justify-content: space-between;
|
|
268
|
+
align-items: center;
|
|
269
|
+
background: var(--ir-bg-app);
|
|
270
|
+
padding: 0.75rem;
|
|
271
|
+
border-radius: 0.5rem;
|
|
272
|
+
border-left: 4px solid transparent;
|
|
273
|
+
transition: var(--ir-transition);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.ir-result-row:hover {
|
|
277
|
+
background: var(--ir-primary-light);
|
|
278
|
+
border-left-color: var(--ir-primary);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.ir-original-amount {
|
|
282
|
+
color: var(--ir-text-disabled);
|
|
283
|
+
font-size: 0.75rem;
|
|
284
|
+
text-decoration: line-through;
|
|
285
|
+
opacity: 0.75;
|
|
286
|
+
max-width: 30%;
|
|
287
|
+
overflow: hidden;
|
|
288
|
+
text-overflow: ellipsis;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.ir-new-amount {
|
|
292
|
+
font-weight: 500;
|
|
293
|
+
color: var(--ir-text-main);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.ir-new-value {
|
|
297
|
+
color: var(--ir-primary);
|
|
298
|
+
font-weight: 800;
|
|
299
|
+
font-size: 1.125rem;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.ir-no-amount-row {
|
|
303
|
+
color: var(--ir-text-muted);
|
|
304
|
+
font-style: italic;
|
|
305
|
+
font-size: 0.875rem;
|
|
306
|
+
padding: 0.5rem;
|
|
307
|
+
background: transparent;
|
|
308
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Icon } from 'astro-icon/components';
|
|
3
|
+
import './IngredientRescaler.css';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
ui: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { ui } = Astro.props;
|
|
10
|
+
const placeholderText = `${ui.pasteHere}
|
|
11
|
+
${ui.exampleLine1}
|
|
12
|
+
${ui.exampleLine2}
|
|
13
|
+
${ui.exampleLine3}
|
|
14
|
+
${ui.exampleLine4}`;
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<div class="ingredient-rescaler-container">
|
|
18
|
+
<div class="ir-grid" id="calculator-interface">
|
|
19
|
+
<div>
|
|
20
|
+
<section class="ir-section ir-section-primary">
|
|
21
|
+
<h3 class="ir-section-title">
|
|
22
|
+
<span>1.</span> {ui.servings}
|
|
23
|
+
</h3>
|
|
24
|
+
|
|
25
|
+
<div class="ir-fields">
|
|
26
|
+
<div class="ir-field">
|
|
27
|
+
<label for="original-servings" class="ir-label">{ui.original}</label>
|
|
28
|
+
<input
|
|
29
|
+
type="number"
|
|
30
|
+
id="original-servings"
|
|
31
|
+
value="4"
|
|
32
|
+
min="1"
|
|
33
|
+
class="ir-input"
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="ir-field">
|
|
37
|
+
<label for="target-servings" class="ir-label">{ui.desired}</label>
|
|
38
|
+
<input
|
|
39
|
+
type="number"
|
|
40
|
+
id="target-servings"
|
|
41
|
+
value="7"
|
|
42
|
+
min="1"
|
|
43
|
+
class="ir-input"
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div class="ir-factor-display">
|
|
49
|
+
<span class="ir-factor-label">{ui.multiplyingFactor}</span>
|
|
50
|
+
<span id="multiplier-display" class="ir-factor-value">1.75x</span>
|
|
51
|
+
</div>
|
|
52
|
+
</section>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div class="ir-textarea-container">
|
|
56
|
+
<section class="ir-section">
|
|
57
|
+
<h3 class="ir-section-title">
|
|
58
|
+
<span>2.</span> {ui.ingredientsList}
|
|
59
|
+
</h3>
|
|
60
|
+
|
|
61
|
+
<textarea
|
|
62
|
+
id="ingredients-input"
|
|
63
|
+
placeholder={placeholderText}
|
|
64
|
+
class="ir-textarea"
|
|
65
|
+
spellcheck="false"
|
|
66
|
+
></textarea>
|
|
67
|
+
</section>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div class="ir-results-card">
|
|
72
|
+
<div class="ir-results-header">
|
|
73
|
+
<h3 class="ir-results-title">
|
|
74
|
+
<Icon name="mdi:chef-hat" /> {ui.result}
|
|
75
|
+
</h3>
|
|
76
|
+
<button id="copy-btn" class="ir-copy-btn ir-default">
|
|
77
|
+
<Icon name="mdi:content-copy" /> {ui.copy}
|
|
78
|
+
</button>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div id="results-container" class="ir-results-container">
|
|
82
|
+
<div class="ir-empty-state">
|
|
83
|
+
<Icon name="mdi:pot-steam" class="ir-empty-icon" />
|
|
84
|
+
<p>{ui.emptyState}</p>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<script>
|
|
91
|
+
import { initIngredientRescaler } from './init';
|
|
92
|
+
window.__initIngredientRescaler = initIngredientRescaler;
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<script define:vars={{ ui }}>
|
|
96
|
+
const init = () => {
|
|
97
|
+
if (window.__initIngredientRescaler) {
|
|
98
|
+
window.__initIngredientRescaler(ui);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
if (document.readyState === 'loading') {
|
|
103
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
104
|
+
} else {
|
|
105
|
+
init();
|
|
106
|
+
}
|
|
107
|
+
</script>
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
2
|
+
|
|
3
|
+
export const content: ToolLocaleContent = {
|
|
4
|
+
slug: "recipe-ingredient-scaler-converter-servings",
|
|
5
|
+
title: "Professional Recipe Ingredient Scaler",
|
|
6
|
+
description:
|
|
7
|
+
"Automatically scale your recipes based on serving count. Calculate exact ingredient amounts to multiply or reduce any recipe with professional precision.",
|
|
8
|
+
ui: {
|
|
9
|
+
servings: "Servings",
|
|
10
|
+
original: "Original",
|
|
11
|
+
desired: "Desired",
|
|
12
|
+
multiplyingFactor: "Conversion Factor",
|
|
13
|
+
ingredientsList: "Ingredient List",
|
|
14
|
+
pasteHere: "Paste your ingredients here.",
|
|
15
|
+
exampleLine1: "Ex:",
|
|
16
|
+
exampleLine2: "500g Flour",
|
|
17
|
+
exampleLine3: "300ml Water",
|
|
18
|
+
exampleLine4: "10g Salt",
|
|
19
|
+
result: "Result",
|
|
20
|
+
copy: "Copy",
|
|
21
|
+
copied: "Copied!",
|
|
22
|
+
emptyState: "Your adjusted ingredients will appear here...",
|
|
23
|
+
defaultIngredient1: "200g Flour",
|
|
24
|
+
defaultIngredient2: "100ml Milk",
|
|
25
|
+
defaultIngredient3: "2 Eggs",
|
|
26
|
+
},
|
|
27
|
+
faqTitle: "Frequently Asked Questions",
|
|
28
|
+
faq: [
|
|
29
|
+
{
|
|
30
|
+
question: "Why does my conversion factor include decimals?",
|
|
31
|
+
answer: "Because culinary proportions aren't always whole numbers. If you scale a 4-person recipe for 7 people, the factor is exactly 1.75. Multiplying by this specific ratio is more accurate than arbitrary rounding.",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
question: "How do I handle fractions like '1/2 tsp'?",
|
|
35
|
+
answer: "The parser automatically identifies numbers. It will read '1/2' as '0.5' and scale it accordingly. For maximum clarity, you can also enter decimals directly.",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
question: "Should I round the final results?",
|
|
39
|
+
answer: "It depends on the ingredient. For flours and liquids, yes. For potent spices or yeast, we recommend scaling to about 75% of the calculated total to avoid overpowering the dish.",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
question: "Does it work with cups and ounces?",
|
|
43
|
+
answer: "Yes, the tool scales any numerical value. However, we strongly recommend converting to grams first for professional-grade consistency across larger batches.",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
bibliographyTitle: "Bibliography & Resources",
|
|
47
|
+
bibliography: [
|
|
48
|
+
{
|
|
49
|
+
name: "Harold McGee - On Food and Cooking",
|
|
50
|
+
url: "https://en.wikipedia.org/wiki/Harold_McGee",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "The Flavor Bible - Page & Dornenburg",
|
|
54
|
+
url: "https://www.flavorprints.com/",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "Modernist Cuisine - Scaling Techniques",
|
|
58
|
+
url: "https://www.modernistcuisine.com/",
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
howTo: [
|
|
62
|
+
{
|
|
63
|
+
name: "Enter your servings count",
|
|
64
|
+
text: "Define how many people the recipe was originally for, and how many you want to cook for now.",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "Paste your ingredient list",
|
|
68
|
+
text: "Copy and paste your entire list. Our tool recognizes numbers at the start of each line (e.g., 500g, 1/2, 2.5) and scales them instantly.",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "Apply professional adjustments",
|
|
72
|
+
text: "Math is exact, but cooking is situational. Scale spices to 75%. Don't scale cooking times. Use your chef's intuition for the final touch.",
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
seo: [
|
|
76
|
+
{
|
|
77
|
+
type: "title",
|
|
78
|
+
text: "Master Guide for Recipe Scaling and Converter Logic",
|
|
79
|
+
level: 2,
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
type: "paragraph",
|
|
83
|
+
html: "<strong>Ingredient scaling</strong> is one of the most critical yet error-prone tasks in professional kitchens. It's not just about multiplying numbers; it's about understanding how food chemistry and physics react to changes in volume and surface area.",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: "stats",
|
|
87
|
+
columns: 4,
|
|
88
|
+
items: [
|
|
89
|
+
{
|
|
90
|
+
value: "x1.75",
|
|
91
|
+
label: "Factor 4 to 7 per.",
|
|
92
|
+
icon: "mdi:calculator",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
value: "75%",
|
|
96
|
+
label: "Spice Adjustment",
|
|
97
|
+
icon: "mdi:shaker-outline",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
value: "0%",
|
|
101
|
+
label: "Time Scaling",
|
|
102
|
+
icon: "mdi:timer-off",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
value: "100g",
|
|
106
|
+
label: "Reference Base",
|
|
107
|
+
icon: "mdi:weight-gram",
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
type: "title",
|
|
113
|
+
text: "Differences Between Linear and Contextual Scaling",
|
|
114
|
+
level: 3,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: "comparative",
|
|
118
|
+
columns: 2,
|
|
119
|
+
items: [
|
|
120
|
+
{
|
|
121
|
+
title: "Mathematical Linear Scaling",
|
|
122
|
+
icon: "mdi:math-log",
|
|
123
|
+
description: "Direct multiplication of all values by the calculated conversion factor.",
|
|
124
|
+
points: [
|
|
125
|
+
"Perfect for flour and base liquids",
|
|
126
|
+
"Ideal for cold precision pastry",
|
|
127
|
+
"Works well for small shifts (x2, x0.5)",
|
|
128
|
+
"Easy to calculate automatically",
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
title: "Chef's Contextual Scaling",
|
|
133
|
+
icon: "mdi:chef-hat",
|
|
134
|
+
description: "Adjusting proportions based on flavor saturation and evaporation.",
|
|
135
|
+
highlight: true,
|
|
136
|
+
points: [
|
|
137
|
+
"Prevents excess salt and spice levels",
|
|
138
|
+
"Considers evaporation surface area",
|
|
139
|
+
"Adjusts yeast based on friction heat",
|
|
140
|
+
"Requires professional culinary judgment",
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
type: "title",
|
|
147
|
+
text: "Common Conversion Factors by Serving Size",
|
|
148
|
+
level: 3,
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
type: "table",
|
|
152
|
+
headers: ["From Servings", "To Servings", "Factor (CF)", "Adjustment Difficulty"],
|
|
153
|
+
rows: [
|
|
154
|
+
["2 persons", "4 persons", "x 2.0", "Low (Linear)"],
|
|
155
|
+
["4 persons", "6 persons", "x 1.5", "Low (Linear)"],
|
|
156
|
+
["4 persons", "10 persons", "x 2.5", "Medium (Watch spices)"],
|
|
157
|
+
["4 persons", "25 persons", "x 6.25", "High (Contextual)"],
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: "diagnostic",
|
|
162
|
+
variant: "warning",
|
|
163
|
+
title: "Common Pitfalls When Doubling a Recipe",
|
|
164
|
+
html: "If you notice flavors becoming too intense after scaling—especially with chili or salt—reduce the specific scale for those ingredients to 75%. Never double the cooking time; internal temperature is reached based on thickness, not total batch weight.",
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
type: "title",
|
|
168
|
+
text: "Standardization Terminology Glossary",
|
|
169
|
+
level: 3,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
type: "glossary",
|
|
173
|
+
items: [
|
|
174
|
+
{
|
|
175
|
+
term: "Conversion Factor",
|
|
176
|
+
definition: "The number used to multiply ingredients: Desired Quantity / Original Quantity.",
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
term: "Cooking Shrinkage",
|
|
180
|
+
definition: "Weight loss due to evaporation or fat loss. This does not scale linearly with batch size.",
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
term: "Gross vs Net Weight",
|
|
184
|
+
definition: "Weight before and after cleaning. Always scale based on the recipe's specified net weight.",
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
term: "Batch Yield",
|
|
188
|
+
definition: "The total amount of finished product after scaling and cooking processes.",
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
type: "tip",
|
|
194
|
+
title: "The Beaten Egg Trick",
|
|
195
|
+
html: "If the calculator asks for 2.3 eggs, beat one whole egg, weigh it, and use only 30% of that weight. This is the only way to maintain precision in fine pâtisserie.",
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
type: "paragraph",
|
|
199
|
+
html: "Our tool simplifies the math so you can focus on what truly matters: creativity and flavor.",
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
|
|
203
|
+
schemas: [
|
|
204
|
+
{
|
|
205
|
+
'@context': 'https://schema.org',
|
|
206
|
+
'@type': 'WebApplication',
|
|
207
|
+
name: 'Ingredient Rescaler',
|
|
208
|
+
description: 'Scale recipes automatically based on the number of servings. Calculate exact ingredient quantities by multiplying or reducing your recipe without complications.',
|
|
209
|
+
url: 'https://jjlmoya.es/en/ingredient-rescaler',
|
|
210
|
+
applicationCategory: 'Utilities',
|
|
211
|
+
inLanguage: 'en-US',
|
|
212
|
+
offers: {
|
|
213
|
+
'@type': 'Offer',
|
|
214
|
+
price: '0',
|
|
215
|
+
priceCurrency: 'EUR',
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
'@context': 'https://schema.org',
|
|
220
|
+
'@type': 'Article',
|
|
221
|
+
headline: 'Ingredient Rescaler - Scale Your Recipes Easily',
|
|
222
|
+
description: 'Scale recipes automatically based on the number of servings. Calculate exact ingredient quantities by multiplying or reducing your recipe without complications.',
|
|
223
|
+
author: {
|
|
224
|
+
'@type': 'Person',
|
|
225
|
+
name: 'jjlmoya',
|
|
226
|
+
},
|
|
227
|
+
inLanguage: 'en-US',
|
|
228
|
+
isPartOf: {
|
|
229
|
+
'@type': 'WebSite',
|
|
230
|
+
name: 'jjlmoya Utilities',
|
|
231
|
+
url: 'https://jjlmoya.es',
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
'@context': 'https://schema.org',
|
|
236
|
+
'@type': 'BreadcrumbList',
|
|
237
|
+
itemListElement: [
|
|
238
|
+
{
|
|
239
|
+
'@type': 'ListItem',
|
|
240
|
+
position: 1,
|
|
241
|
+
name: 'Home',
|
|
242
|
+
item: 'https://jjlmoya.es/en',
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
'@type': 'ListItem',
|
|
246
|
+
position: 2,
|
|
247
|
+
name: 'Utilities',
|
|
248
|
+
item: 'https://jjlmoya.es/en/utilities',
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
'@type': 'ListItem',
|
|
252
|
+
position: 3,
|
|
253
|
+
name: 'Cooking',
|
|
254
|
+
item: 'https://jjlmoya.es/en/cooking',
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
'@type': 'ListItem',
|
|
258
|
+
position: 4,
|
|
259
|
+
name: 'Ingredient Rescaler',
|
|
260
|
+
item: 'https://jjlmoya.es/en/ingredient-rescaler',
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
};
|