@jjlmoya/utils-alcohol 1.24.0 → 1.26.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 (144) hide show
  1. package/package.json +1 -1
  2. package/src/entries.ts +7 -1
  3. package/src/index.ts +1 -0
  4. package/src/pages/[locale]/[slug].astro +7 -3
  5. package/src/tests/locale_completeness.test.ts +4 -9
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/alcoholClearance/alcohol-clearance-calculator.css +23 -23
  8. package/src/tool/alcoholClearance/bibliography.ts +6 -0
  9. package/src/tool/alcoholClearance/entry.ts +1 -0
  10. package/src/tool/alcoholClearance/i18n/de.ts +1 -12
  11. package/src/tool/alcoholClearance/i18n/en.ts +1 -12
  12. package/src/tool/alcoholClearance/i18n/es.ts +1 -12
  13. package/src/tool/alcoholClearance/i18n/fr.ts +1 -12
  14. package/src/tool/alcoholClearance/i18n/id.ts +1 -12
  15. package/src/tool/alcoholClearance/i18n/it.ts +1 -12
  16. package/src/tool/alcoholClearance/i18n/ja.ts +1 -12
  17. package/src/tool/alcoholClearance/i18n/ko.ts +1 -12
  18. package/src/tool/alcoholClearance/i18n/nl.ts +1 -12
  19. package/src/tool/alcoholClearance/i18n/pl.ts +1 -12
  20. package/src/tool/alcoholClearance/i18n/pt.ts +1 -12
  21. package/src/tool/alcoholClearance/i18n/ru.ts +1 -12
  22. package/src/tool/alcoholClearance/i18n/sv.ts +1 -12
  23. package/src/tool/alcoholClearance/i18n/tr.ts +1 -12
  24. package/src/tool/alcoholClearance/i18n/zh.ts +1 -12
  25. package/src/tool/beerCooler/beer-cooler.css +22 -22
  26. package/src/tool/beerCooler/bibliography.ts +6 -0
  27. package/src/tool/beerCooler/entry.ts +1 -0
  28. package/src/tool/beerCooler/i18n/de.ts +1 -12
  29. package/src/tool/beerCooler/i18n/en.ts +1 -12
  30. package/src/tool/beerCooler/i18n/es.ts +1 -12
  31. package/src/tool/beerCooler/i18n/fr.ts +1 -12
  32. package/src/tool/beerCooler/i18n/id.ts +1 -12
  33. package/src/tool/beerCooler/i18n/it.ts +1 -12
  34. package/src/tool/beerCooler/i18n/ja.ts +1 -12
  35. package/src/tool/beerCooler/i18n/ko.ts +1 -12
  36. package/src/tool/beerCooler/i18n/nl.ts +1 -12
  37. package/src/tool/beerCooler/i18n/pl.ts +1 -12
  38. package/src/tool/beerCooler/i18n/pt.ts +1 -12
  39. package/src/tool/beerCooler/i18n/ru.ts +1 -12
  40. package/src/tool/beerCooler/i18n/sv.ts +1 -12
  41. package/src/tool/beerCooler/i18n/tr.ts +1 -12
  42. package/src/tool/beerCooler/i18n/zh.ts +1 -12
  43. package/src/tool/carbonationCalculator/beer-carbonation-calculator.css +19 -19
  44. package/src/tool/carbonationCalculator/bibliography.ts +6 -0
  45. package/src/tool/carbonationCalculator/entry.ts +1 -0
  46. package/src/tool/carbonationCalculator/i18n/de.ts +1 -12
  47. package/src/tool/carbonationCalculator/i18n/en.ts +1 -12
  48. package/src/tool/carbonationCalculator/i18n/es.ts +1 -12
  49. package/src/tool/carbonationCalculator/i18n/fr.ts +1 -12
  50. package/src/tool/carbonationCalculator/i18n/id.ts +1 -12
  51. package/src/tool/carbonationCalculator/i18n/it.ts +1 -12
  52. package/src/tool/carbonationCalculator/i18n/ja.ts +1 -12
  53. package/src/tool/carbonationCalculator/i18n/ko.ts +1 -12
  54. package/src/tool/carbonationCalculator/i18n/nl.ts +1 -12
  55. package/src/tool/carbonationCalculator/i18n/pl.ts +1 -12
  56. package/src/tool/carbonationCalculator/i18n/pt.ts +1 -12
  57. package/src/tool/carbonationCalculator/i18n/ru.ts +1 -12
  58. package/src/tool/carbonationCalculator/i18n/sv.ts +1 -12
  59. package/src/tool/carbonationCalculator/i18n/tr.ts +1 -12
  60. package/src/tool/carbonationCalculator/i18n/zh.ts +1 -12
  61. package/src/tool/cocktailBalancer/bibliography.ts +7 -0
  62. package/src/tool/cocktailBalancer/cocktail-balancer.css +59 -59
  63. package/src/tool/cocktailBalancer/entry.ts +1 -0
  64. package/src/tool/cocktailBalancer/i18n/de.ts +1 -16
  65. package/src/tool/cocktailBalancer/i18n/en.ts +1 -16
  66. package/src/tool/cocktailBalancer/i18n/es.ts +1 -16
  67. package/src/tool/cocktailBalancer/i18n/fr.ts +1 -16
  68. package/src/tool/cocktailBalancer/i18n/id.ts +1 -16
  69. package/src/tool/cocktailBalancer/i18n/it.ts +1 -16
  70. package/src/tool/cocktailBalancer/i18n/ja.ts +1 -16
  71. package/src/tool/cocktailBalancer/i18n/ko.ts +1 -16
  72. package/src/tool/cocktailBalancer/i18n/nl.ts +1 -16
  73. package/src/tool/cocktailBalancer/i18n/pl.ts +1 -16
  74. package/src/tool/cocktailBalancer/i18n/pt.ts +1 -16
  75. package/src/tool/cocktailBalancer/i18n/ru.ts +1 -16
  76. package/src/tool/cocktailBalancer/i18n/sv.ts +1 -16
  77. package/src/tool/cocktailBalancer/i18n/tr.ts +1 -16
  78. package/src/tool/cocktailBalancer/i18n/zh.ts +1 -16
  79. package/src/tool/fortifiedWine/bibliography.astro +14 -0
  80. package/src/tool/fortifiedWine/bibliography.ts +7 -0
  81. package/src/tool/fortifiedWine/component.astro +331 -0
  82. package/src/tool/fortifiedWine/entry.ts +62 -0
  83. package/src/tool/fortifiedWine/fortified-wine-builder.css +534 -0
  84. package/src/tool/fortifiedWine/i18n/de.ts +66 -0
  85. package/src/tool/fortifiedWine/i18n/en.ts +140 -0
  86. package/src/tool/fortifiedWine/i18n/es.ts +140 -0
  87. package/src/tool/fortifiedWine/i18n/fr.ts +91 -0
  88. package/src/tool/fortifiedWine/i18n/id.ts +91 -0
  89. package/src/tool/fortifiedWine/i18n/it.ts +91 -0
  90. package/src/tool/fortifiedWine/i18n/ja.ts +91 -0
  91. package/src/tool/fortifiedWine/i18n/ko.ts +91 -0
  92. package/src/tool/fortifiedWine/i18n/nl.ts +91 -0
  93. package/src/tool/fortifiedWine/i18n/pl.ts +91 -0
  94. package/src/tool/fortifiedWine/i18n/pt.ts +91 -0
  95. package/src/tool/fortifiedWine/i18n/ru.ts +91 -0
  96. package/src/tool/fortifiedWine/i18n/sv.ts +91 -0
  97. package/src/tool/fortifiedWine/i18n/tr.ts +91 -0
  98. package/src/tool/fortifiedWine/i18n/zh.ts +91 -0
  99. package/src/tool/fortifiedWine/index.ts +8 -0
  100. package/src/tool/fortifiedWine/logic.ts +46 -0
  101. package/src/tool/fortifiedWine/seo.astro +41 -0
  102. package/src/tool/jelloShotLab/bibliography.astro +14 -0
  103. package/src/tool/jelloShotLab/bibliography.ts +8 -0
  104. package/src/tool/jelloShotLab/component.astro +183 -0
  105. package/src/tool/jelloShotLab/entry.ts +62 -0
  106. package/src/tool/jelloShotLab/i18n/de.ts +156 -0
  107. package/src/tool/jelloShotLab/i18n/en.ts +156 -0
  108. package/src/tool/jelloShotLab/i18n/es.ts +156 -0
  109. package/src/tool/jelloShotLab/i18n/fr.ts +156 -0
  110. package/src/tool/jelloShotLab/i18n/id.ts +156 -0
  111. package/src/tool/jelloShotLab/i18n/it.ts +156 -0
  112. package/src/tool/jelloShotLab/i18n/ja.ts +156 -0
  113. package/src/tool/jelloShotLab/i18n/ko.ts +156 -0
  114. package/src/tool/jelloShotLab/i18n/nl.ts +156 -0
  115. package/src/tool/jelloShotLab/i18n/pl.ts +156 -0
  116. package/src/tool/jelloShotLab/i18n/pt.ts +156 -0
  117. package/src/tool/jelloShotLab/i18n/ru.ts +156 -0
  118. package/src/tool/jelloShotLab/i18n/sv.ts +156 -0
  119. package/src/tool/jelloShotLab/i18n/tr.ts +156 -0
  120. package/src/tool/jelloShotLab/i18n/zh.ts +156 -0
  121. package/src/tool/jelloShotLab/index.ts +11 -0
  122. package/src/tool/jelloShotLab/jello-shot-lab.css +229 -0
  123. package/src/tool/jelloShotLab/logic.ts +29 -0
  124. package/src/tool/jelloShotLab/seo.astro +53 -0
  125. package/src/tool/partyKeg/bibliography.ts +6 -0
  126. package/src/tool/partyKeg/entry.ts +1 -0
  127. package/src/tool/partyKeg/i18n/de.ts +1 -12
  128. package/src/tool/partyKeg/i18n/en.ts +1 -12
  129. package/src/tool/partyKeg/i18n/es.ts +1 -12
  130. package/src/tool/partyKeg/i18n/fr.ts +1 -12
  131. package/src/tool/partyKeg/i18n/id.ts +1 -12
  132. package/src/tool/partyKeg/i18n/it.ts +1 -12
  133. package/src/tool/partyKeg/i18n/ja.ts +1 -12
  134. package/src/tool/partyKeg/i18n/ko.ts +1 -12
  135. package/src/tool/partyKeg/i18n/nl.ts +1 -12
  136. package/src/tool/partyKeg/i18n/pl.ts +1 -12
  137. package/src/tool/partyKeg/i18n/pt.ts +1 -12
  138. package/src/tool/partyKeg/i18n/ru.ts +1 -12
  139. package/src/tool/partyKeg/i18n/sv.ts +1 -12
  140. package/src/tool/partyKeg/i18n/tr.ts +1 -12
  141. package/src/tool/partyKeg/i18n/zh.ts +1 -12
  142. package/src/tool/partyKeg/party-stock-calculator.css +23 -23
  143. package/src/tools.ts +5 -0
  144. package/src/types.ts +1 -1
@@ -0,0 +1,534 @@
1
+ .fw-app {
2
+ width: 100%;
3
+ max-width: 72rem;
4
+ margin: 0 auto;
5
+ padding: 0.5rem;
6
+ }
7
+
8
+ .fw-card {
9
+ background: #fff;
10
+ border: 1px solid #e2e8f0;
11
+ border-radius: 1.25rem;
12
+ overflow: clip;
13
+ box-shadow: 0 4px 20px rgba(0,0,0,0.06);
14
+ color: #1e293b;
15
+ }
16
+
17
+ .theme-dark .fw-card {
18
+ background: #0f172a;
19
+ border-color: #1e293b;
20
+ color: #f1f5f9;
21
+ }
22
+
23
+ .fw-intention {
24
+ padding: 1.25rem 1.5rem;
25
+ border-bottom: 1px solid #e2e8f0;
26
+ background: linear-gradient(135deg, #7f1d1d08, #78181808);
27
+ }
28
+
29
+ .theme-dark .fw-intention {
30
+ border-color: #1e293b;
31
+ background: linear-gradient(135deg, #7f1d1d18, #78181818);
32
+ }
33
+
34
+ .fw-section-label {
35
+ font-size: 0.75rem;
36
+ font-weight: 700;
37
+ text-transform: uppercase;
38
+ letter-spacing: 0.08em;
39
+ color: #7f1d1d;
40
+ margin: 0 0 0.75rem;
41
+ }
42
+
43
+ .theme-dark .fw-section-label { color: #fca5a5; }
44
+
45
+ .fw-intention-btns {
46
+ display: flex;
47
+ gap: 0.5rem;
48
+ flex-wrap: wrap;
49
+ }
50
+
51
+ .fw-intention-btn {
52
+ padding: 0.5rem 1rem;
53
+ border-radius: 2rem;
54
+ border: 1.5px solid #e2e8f0;
55
+ background: transparent;
56
+ color: #475569;
57
+ font-size: 0.875rem;
58
+ font-weight: 600;
59
+ cursor: pointer;
60
+ transition: all 0.15s;
61
+ }
62
+
63
+ .theme-dark .fw-intention-btn {
64
+ border-color: #334155;
65
+ color: #94a3b8;
66
+ }
67
+
68
+ .fw-intention-btn:hover {
69
+ border-color: #7f1d1d;
70
+ color: #7f1d1d;
71
+ }
72
+
73
+ .theme-dark .fw-intention-btn:hover {
74
+ border-color: #fca5a5;
75
+ color: #fca5a5;
76
+ }
77
+
78
+ .fw-intention-btn.active {
79
+ background: #7f1d1d;
80
+ border-color: #7f1d1d;
81
+ color: #fff;
82
+ }
83
+
84
+ .theme-dark .fw-intention-btn.active {
85
+ background: #991b1b;
86
+ border-color: #991b1b;
87
+ }
88
+
89
+ .fw-mode {
90
+ display: flex;
91
+ border-bottom: 1px solid #e2e8f0;
92
+ }
93
+
94
+ .theme-dark .fw-mode { border-color: #1e293b; }
95
+
96
+ .fw-mode-btn {
97
+ flex: 1;
98
+ padding: 0.875rem 1rem;
99
+ border: none;
100
+ background: transparent;
101
+ color: #64748b;
102
+ font-size: 0.875rem;
103
+ font-weight: 600;
104
+ cursor: pointer;
105
+ transition: all 0.15s;
106
+ border-bottom: 2.5px solid transparent;
107
+ }
108
+
109
+ .theme-dark .fw-mode-btn { color: #64748b; }
110
+
111
+ .fw-mode-btn.active {
112
+ color: #7f1d1d;
113
+ border-bottom-color: #7f1d1d;
114
+ background: #7f1d1d08;
115
+ }
116
+
117
+ .theme-dark .fw-mode-btn.active {
118
+ color: #fca5a5;
119
+ border-bottom-color: #fca5a5;
120
+ background: #fca5a518;
121
+ }
122
+
123
+ .fw-grid { display: grid; }
124
+
125
+ @media (min-width: 1024px) {
126
+ .fw-grid {
127
+ grid-template-columns: 1fr 1fr;
128
+ align-items: start;
129
+ }
130
+ }
131
+
132
+ .fw-left {
133
+ display: flex;
134
+ flex-direction: column;
135
+ border-right: 0;
136
+ }
137
+
138
+ @media (min-width: 1024px) {
139
+ .fw-left { border-right: 1px solid #e2e8f0; }
140
+
141
+ .theme-dark .fw-left { border-right-color: #1e293b; }
142
+ }
143
+
144
+ .fw-sec {
145
+ padding: 1.25rem 1.5rem;
146
+ border-bottom: 1px solid #e2e8f0;
147
+ }
148
+
149
+ .theme-dark .fw-sec { border-color: #1e293b; }
150
+
151
+ .fw-sec:last-child { border-bottom: none; }
152
+
153
+ .fw-sec-title {
154
+ font-size: 0.875rem;
155
+ font-weight: 700;
156
+ color: #1e293b;
157
+ margin: 0 0 1rem;
158
+ display: flex;
159
+ align-items: center;
160
+ gap: 0.5rem;
161
+ }
162
+
163
+ .theme-dark .fw-sec-title { color: #f1f5f9; }
164
+
165
+ .fw-sec-title::before {
166
+ content: '';
167
+ width: 3px;
168
+ height: 1em;
169
+ background: #7f1d1d;
170
+ border-radius: 2px;
171
+ }
172
+
173
+ .theme-dark .fw-sec-title::before { background: #fca5a5; }
174
+
175
+ .fw-input-row {
176
+ display: flex;
177
+ flex-direction: column;
178
+ gap: 0.75rem;
179
+ }
180
+
181
+ .fw-field {
182
+ display: flex;
183
+ flex-direction: column;
184
+ gap: 0.375rem;
185
+ }
186
+
187
+ .fw-label {
188
+ font-size: 0.75rem;
189
+ font-weight: 600;
190
+ color: #64748b;
191
+ }
192
+
193
+ .theme-dark .fw-label { color: #94a3b8; }
194
+
195
+ .fw-slider-row {
196
+ display: flex;
197
+ align-items: center;
198
+ gap: 0.75rem;
199
+ }
200
+
201
+ .fw-slider {
202
+ flex: 1;
203
+ -webkit-appearance: none;
204
+ height: 4px;
205
+ border-radius: 2px;
206
+ background: linear-gradient(to right, #7f1d1d var(--val, 50%), #e2e8f0 var(--val, 50%));
207
+ outline: none;
208
+ cursor: pointer;
209
+ }
210
+
211
+ .theme-dark .fw-slider {
212
+ background: linear-gradient(to right, #991b1b var(--val, 50%), #1e293b var(--val, 50%));
213
+ }
214
+
215
+ .fw-slider::-webkit-slider-thumb {
216
+ -webkit-appearance: none;
217
+ width: 16px;
218
+ height: 16px;
219
+ border-radius: 50%;
220
+ background: #7f1d1d;
221
+ cursor: pointer;
222
+ box-shadow: 0 1px 4px rgba(0,0,0,0.2);
223
+ }
224
+
225
+ .theme-dark .fw-slider::-webkit-slider-thumb { background: #fca5a5; }
226
+
227
+ .fw-num-input {
228
+ width: 4.5rem;
229
+ padding: 0.375rem 0.5rem;
230
+ border-radius: 0.5rem;
231
+ border: 1.5px solid #e2e8f0;
232
+ background: #f8fafc;
233
+ color: #1e293b;
234
+ font-size: 0.875rem;
235
+ font-weight: 700;
236
+ text-align: center;
237
+ }
238
+
239
+ .theme-dark .fw-num-input {
240
+ border-color: #334155;
241
+ background: #1e293b;
242
+ color: #f1f5f9;
243
+ }
244
+
245
+ .fw-num-input:focus {
246
+ outline: none;
247
+ border-color: #7f1d1d;
248
+ }
249
+
250
+ .theme-dark .fw-num-input:focus { border-color: #fca5a5; }
251
+
252
+ .fw-presets {
253
+ display: flex;
254
+ gap: 0.4rem;
255
+ flex-wrap: wrap;
256
+ margin-bottom: 0.75rem;
257
+ }
258
+
259
+ .fw-preset-btn {
260
+ padding: 0.3rem 0.65rem;
261
+ border-radius: 0.375rem;
262
+ border: 1.5px solid #e2e8f0;
263
+ background: transparent;
264
+ color: #475569;
265
+ font-size: 0.75rem;
266
+ font-weight: 600;
267
+ cursor: pointer;
268
+ transition: all 0.12s;
269
+ }
270
+
271
+ .theme-dark .fw-preset-btn {
272
+ border-color: #334155;
273
+ color: #94a3b8;
274
+ }
275
+
276
+ .fw-preset-btn:hover {
277
+ border-color: #b45309;
278
+ color: #b45309;
279
+ }
280
+
281
+ .theme-dark .fw-preset-btn:hover {
282
+ border-color: #fcd34d;
283
+ color: #fcd34d;
284
+ }
285
+
286
+ .fw-right {
287
+ display: flex;
288
+ flex-direction: column;
289
+ }
290
+
291
+ .fw-pearson-wrap {
292
+ padding: 1.25rem 1.5rem;
293
+ border-bottom: 1px solid #e2e8f0;
294
+ }
295
+
296
+ .theme-dark .fw-pearson-wrap { border-color: #1e293b; }
297
+
298
+ .fw-pearson-title {
299
+ font-size: 0.75rem;
300
+ font-weight: 700;
301
+ text-transform: uppercase;
302
+ letter-spacing: 0.08em;
303
+ color: #7f1d1d;
304
+ margin: 0 0 1rem;
305
+ }
306
+
307
+ .theme-dark .fw-pearson-title { color: #fca5a5; }
308
+
309
+ .fw-pearson-svg {
310
+ width: 100%;
311
+ max-width: 340px;
312
+ display: block;
313
+ margin: 0 auto;
314
+ }
315
+
316
+ .fw-empty-state {
317
+ text-align: center;
318
+ color: #94a3b8;
319
+ font-size: 0.875rem;
320
+ padding: 2rem 0;
321
+ }
322
+
323
+ .fw-error {
324
+ color: #dc2626;
325
+ font-size: 0.8rem;
326
+ padding: 0.75rem 1rem;
327
+ background: #fef2f2;
328
+ border-radius: 0.5rem;
329
+ margin-top: 0.5rem;
330
+ }
331
+
332
+ .theme-dark .fw-error {
333
+ background: #7f1d1d30;
334
+ color: #fca5a5;
335
+ }
336
+
337
+ .fw-results {
338
+ padding: 1.25rem 1.5rem;
339
+ border-bottom: 1px solid #e2e8f0;
340
+ }
341
+
342
+ .theme-dark .fw-results { border-color: #1e293b; }
343
+
344
+ .fw-results-title {
345
+ font-size: 0.875rem;
346
+ font-weight: 700;
347
+ color: #1e293b;
348
+ margin: 0 0 1rem;
349
+ display: flex;
350
+ align-items: center;
351
+ gap: 0.5rem;
352
+ }
353
+
354
+ .theme-dark .fw-results-title { color: #f1f5f9; }
355
+
356
+ .fw-results-title::before {
357
+ content: '';
358
+ width: 3px;
359
+ height: 1em;
360
+ background: #7f1d1d;
361
+ border-radius: 2px;
362
+ }
363
+
364
+ .theme-dark .fw-results-title::before { background: #fca5a5; }
365
+
366
+ .fw-result-grid {
367
+ display: grid;
368
+ grid-template-columns: 1fr 1fr;
369
+ gap: 0.75rem;
370
+ }
371
+
372
+ .fw-result-card {
373
+ background: #f8fafc;
374
+ border-radius: 0.75rem;
375
+ padding: 0.875rem;
376
+ border: 1px solid #e2e8f0;
377
+ }
378
+
379
+ .theme-dark .fw-result-card {
380
+ background: #1e293b;
381
+ border-color: #334155;
382
+ }
383
+
384
+ .fw-result-card.accent {
385
+ background: linear-gradient(135deg, #7f1d1d, #991b1b);
386
+ border-color: transparent;
387
+ color: #fff;
388
+ }
389
+
390
+ .fw-result-label {
391
+ font-size: 0.7rem;
392
+ font-weight: 600;
393
+ text-transform: uppercase;
394
+ letter-spacing: 0.06em;
395
+ color: #64748b;
396
+ margin-bottom: 0.25rem;
397
+ }
398
+
399
+ .theme-dark .fw-result-label { color: #94a3b8; }
400
+
401
+ .fw-result-card.accent .fw-result-label { color: #fecaca; }
402
+
403
+ .fw-result-value {
404
+ font-size: 1.5rem;
405
+ font-weight: 800;
406
+ color: #1e293b;
407
+ line-height: 1;
408
+ }
409
+
410
+ .theme-dark .fw-result-value { color: #f1f5f9; }
411
+
412
+ .fw-result-card.accent .fw-result-value { color: #fff; }
413
+
414
+ .fw-result-unit {
415
+ font-size: 0.8rem;
416
+ font-weight: 600;
417
+ color: #64748b;
418
+ margin-left: 0.2rem;
419
+ }
420
+
421
+ .theme-dark .fw-result-unit { color: #94a3b8; }
422
+
423
+ .fw-result-card.accent .fw-result-unit { color: #fecaca; }
424
+
425
+ .fw-bottles {
426
+ padding: 1rem 1.5rem;
427
+ border-bottom: 1px solid #e2e8f0;
428
+ display: flex;
429
+ gap: 0.75rem;
430
+ align-items: center;
431
+ flex-wrap: wrap;
432
+ }
433
+
434
+ .theme-dark .fw-bottles { border-color: #1e293b; }
435
+
436
+ .fw-bottles-label {
437
+ font-size: 0.75rem;
438
+ font-weight: 700;
439
+ color: #64748b;
440
+ flex-shrink: 0;
441
+ }
442
+
443
+ .theme-dark .fw-bottles-label { color: #94a3b8; }
444
+
445
+ .fw-bottle-badge {
446
+ display: flex;
447
+ align-items: center;
448
+ gap: 0.35rem;
449
+ background: #f1f5f9;
450
+ border-radius: 0.5rem;
451
+ padding: 0.35rem 0.65rem;
452
+ font-size: 0.8rem;
453
+ font-weight: 700;
454
+ color: #334155;
455
+ }
456
+
457
+ .theme-dark .fw-bottle-badge {
458
+ background: #1e293b;
459
+ color: #cbd5e1;
460
+ }
461
+
462
+ .fw-bottle-icon {
463
+ width: 1rem;
464
+ height: 1rem;
465
+ opacity: 0.5;
466
+ }
467
+
468
+ .fw-copy-wrap { padding: 1rem 1.5rem; }
469
+
470
+ .fw-copy-btn {
471
+ width: 100%;
472
+ padding: 0.75rem;
473
+ border-radius: 0.75rem;
474
+ border: none;
475
+ background: #7f1d1d;
476
+ color: #fff;
477
+ font-size: 0.875rem;
478
+ font-weight: 700;
479
+ cursor: pointer;
480
+ transition: background 0.15s;
481
+ display: flex;
482
+ align-items: center;
483
+ justify-content: center;
484
+ gap: 0.5rem;
485
+ }
486
+
487
+ .fw-copy-btn:hover { background: #991b1b; }
488
+
489
+ .fw-copy-btn.copied { background: #15803d; }
490
+
491
+ .fw-prop-bar {
492
+ height: 8px;
493
+ border-radius: 4px;
494
+ overflow: hidden;
495
+ background: #e2e8f0;
496
+ margin-top: 0.75rem;
497
+ display: flex;
498
+ }
499
+
500
+ .theme-dark .fw-prop-bar { background: #1e293b; }
501
+
502
+ .fw-prop-wine {
503
+ background: #7f1d1d;
504
+ transition: width 0.3s;
505
+ }
506
+
507
+ .fw-prop-spirit {
508
+ background: #b45309;
509
+ transition: width 0.3s;
510
+ }
511
+
512
+ .fw-prop-labels {
513
+ display: flex;
514
+ justify-content: space-between;
515
+ margin-top: 0.35rem;
516
+ font-size: 0.7rem;
517
+ color: #64748b;
518
+ }
519
+
520
+ .theme-dark .fw-prop-labels { color: #94a3b8; }
521
+
522
+ .fw-prop-wine-pct {
523
+ color: #7f1d1d;
524
+ font-weight: 700;
525
+ }
526
+
527
+ .theme-dark .fw-prop-wine-pct { color: #fca5a5; }
528
+
529
+ .fw-prop-spirit-pct {
530
+ color: #b45309;
531
+ font-weight: 700;
532
+ }
533
+
534
+ .theme-dark .fw-prop-spirit-pct { color: #fcd34d; }
@@ -0,0 +1,66 @@
1
+ import { bibliography } from '../bibliography';
2
+ import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
3
+ import type { FortifiedWineBuilderUI, FortifiedWineBuilderLocaleContent } from '../index';
4
+
5
+ const slug = 'wein-aufspritung-rechner';
6
+ const title = 'Weinaufspritung und Wermut Rechner: Pearson Quadrat Kalkulator';
7
+ const description = 'Berechne genau, wie viel Alkohol du deinem Wein hinzufügen musst, um den gewünschten Alkoholgehalt zu erreichen. Stelle perfekten Wermut, Port und Sherry mit der Pearson Quadrat Methode her.';
8
+
9
+ const ui: FortifiedWineBuilderUI = {
10
+ intentionTitle: 'Was möchtest du herstellen?',
11
+ intentionVermouth: 'Wermut',
12
+ intentionPort: 'Portwein',
13
+ intentionSherry: 'Sherry',
14
+ intentionCustom: 'Benutzerdefiniert',
15
+ modeALabel: 'Aus vorhandenem Wein',
16
+ modeBLabel: 'Zielvolumen am Ende',
17
+ wineSection: 'Basiswein',
18
+ wineVolumeLabel: 'Weinmenge (L)',
19
+ wineAbvLabel: 'Alkoholgehalt Wein (%)',
20
+ spiritSection: 'Aufspritung',
21
+ spiritAbvLabel: 'Alkoholgehalt Sprit (%)',
22
+ brandyPreset: 'Weinbrand (38°)',
23
+ neutralPreset: 'Neutralalkohol (96°)',
24
+ aguardientePreset: 'Aguardiente (42°)',
25
+ targetAbvLabel: 'Ziel Alkoholgehalt (%)',
26
+ targetVolumeLabel: 'Zielvolumen gesamt (L)',
27
+ resultsTitle: 'Dein Rezept',
28
+ addLabel: 'Hinzufügen',
29
+ finalVolumeLabel: 'Endvolumen',
30
+ bottlesSection: 'Benötigte Flaschen',
31
+ copyBtn: 'Rezept kopieren',
32
+ copiedBtn: 'Kopiert!',
33
+ pearsonTitle: 'Pearson Quadrat',
34
+ wineCornerLabel: 'Wein',
35
+ spiritCornerLabel: 'Sprit',
36
+ emptyState: 'Gib deine Werte ein, um das Pearson Quadrat zu sehen',
37
+ errorAbv: 'Der Alkoholgehalt des Sprits muss höher als der Zielwert sein, und der Zielwert muss höher als der Weinalkohol sein.',
38
+ errorMode: 'Gib ein gültiges Volumen ein, um zu berechnen.',
39
+ };
40
+
41
+ const faqTitle = 'Häufig gestellte Fragen';
42
+
43
+ const faq: FortifiedWineBuilderLocaleContent['faq'] = [
44
+ {
45
+ question: 'Was ist die Pearson Quadrat Methode?',
46
+ answer: 'Das Pearson Quadrat ist eine einfache grafische Methode in der Weinherstellung zur Berechnung von Mischverhältnissen.',
47
+ }
48
+ ];
49
+
50
+ const howTo: FortifiedWineBuilderLocaleContent['howTo'] = [
51
+ { name: 'Stil wählen', text: 'Wähle Wermut, Portwein, Sherry oder Benutzerdefiniert.' },
52
+ ];
53
+
54
+
55
+ const seo: FortifiedWineBuilderLocaleContent['seo'] = [
56
+ { type: 'title', text: 'Das Pearson Quadrat: Alte Mathematik, perfekter Wein', level: 2 },
57
+ { type: 'tip', title: 'Profi Tipp: Bei 20 Grad messen', html: 'Die Alkoholdichte verändert sich mit der Temperatur.' },
58
+ ];
59
+
60
+ const schemas: FortifiedWineBuilderLocaleContent['schemas'] = [
61
+ { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) } as WithContext<FAQPage>,
62
+ { '@context': 'https://schema.org', '@type': 'HowTo', name: title, description, step: howTo.map((step, i) => ({ '@type': 'HowToStep', position: i + 1, name: step.name, text: step.text })) } as WithContext<HowTo>,
63
+ { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: title, description, applicationCategory: 'UtilityApplication', operatingSystem: 'Web', offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' } } as WithContext<SoftwareApplication>,
64
+ ];
65
+
66
+ export const content: FortifiedWineBuilderLocaleContent = { slug, title, description, ui, seo, faqTitle, faq, bibliography, howTo, schemas };