@jjlmoya/utils-alcohol 1.22.0 → 1.24.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.
@@ -223,488 +223,4 @@ const { ui } = Astro.props;
223
223
  customElements.define("carbonation-calculator", CarbonationCalculator);
224
224
  </script>
225
225
 
226
- <style>
227
- .carb-app {
228
- display: block;
229
- width: 100%;
230
- max-width: 72rem;
231
- margin: 0 auto;
232
- padding: 0.5rem;
233
- }
234
-
235
- .carb-card {
236
- background: #fff;
237
- border: 1px solid #e4e4e7;
238
- border-radius: 1.25rem;
239
- overflow: clip;
240
- box-shadow: 0 4px 20px rgba(0,0,0,0.06);
241
- color: #18181b;
242
- }
243
-
244
- :global(.theme-dark) .carb-card {
245
- background: #18181b;
246
- border-color: #27272a;
247
- color: #f4f4f5;
248
- }
249
-
250
- .carb-layout {
251
- display: flex;
252
- flex-direction: column;
253
- }
254
-
255
- @media (min-width: 1024px) {
256
- .carb-layout {
257
- flex-direction: row;
258
- align-items: stretch;
259
- }
260
- }
261
-
262
- .carb-left {
263
- display: flex;
264
- flex-direction: column;
265
- }
266
-
267
- @media (min-width: 1024px) {
268
- .carb-left {
269
- width: 50%;
270
- border-right: 1px solid #e4e4e7;
271
- }
272
- }
273
-
274
- :global(.theme-dark) .carb-left { border-color: #27272a; }
275
-
276
- .carb-sec {
277
- padding: 1.5rem;
278
- border-bottom: 1px solid #e4e4e7;
279
- position: relative;
280
- overflow: hidden;
281
- }
282
-
283
- :global(.theme-dark) .carb-sec { border-color: #27272a; }
284
- .carb-sec:last-child { border-bottom: none; }
285
-
286
- .carb-params-deco {
287
- position: absolute;
288
- top: 0;
289
- right: 0;
290
- padding: 1rem;
291
- opacity: 0.07;
292
- pointer-events: none;
293
- }
294
-
295
- .carb-deco-icon {
296
- width: 5rem;
297
- height: 5rem;
298
- color: #f59e0b;
299
- transform: rotate(12deg);
300
- }
301
-
302
- .carb-params-title {
303
- font-size: 1.5rem;
304
- font-weight: 900;
305
- margin: 0 0 1.25rem;
306
- display: flex;
307
- align-items: center;
308
- gap: 0.75rem;
309
- }
310
-
311
- .carb-params-title-icon {
312
- background: #f59e0b;
313
- border-radius: 0.75rem;
314
- padding: 0.5rem;
315
- color: #fff;
316
- box-shadow: 0 4px 12px rgba(245,158,11,0.3);
317
- display: flex;
318
- }
319
-
320
- .carb-title-svg {
321
- width: 1.25rem;
322
- height: 1.25rem;
323
- }
324
-
325
- .units-toggle {
326
- display: flex;
327
- background: #f4f4f5;
328
- padding: 0.25rem;
329
- border-radius: 0.75rem;
330
- width: fit-content;
331
- margin-bottom: 1.25rem;
332
- }
333
-
334
- :global(.theme-dark) .units-toggle { background: #27272a; }
335
-
336
- .unit-btn {
337
- padding: 0.4rem 1.25rem;
338
- border-radius: 0.5rem;
339
- font-size: 0.875rem;
340
- font-weight: 700;
341
- border: none;
342
- cursor: pointer;
343
- transition: all 0.2s;
344
- color: #71717a;
345
- background: transparent;
346
- }
347
-
348
- :global(.theme-dark) .unit-btn { color: #a1a1aa; }
349
- .unit-btn:hover { color: #18181b; }
350
- :global(.theme-dark) .unit-btn:hover { color: #e4e4e7; }
351
-
352
- .unit-btn-active {
353
- background: #fff;
354
- color: #18181b;
355
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
356
- }
357
-
358
- :global(.theme-dark) .unit-btn-active {
359
- background: #3f3f46;
360
- color: #fff;
361
- }
362
-
363
- .carb-inputs {
364
- display: flex;
365
- flex-direction: column;
366
- gap: 1.25rem;
367
- position: relative;
368
- z-index: 1;
369
- }
370
-
371
- .input-group {
372
- display: flex;
373
- flex-direction: column;
374
- gap: 0.5rem;
375
- }
376
-
377
- .input-label {
378
- display: flex;
379
- justify-content: space-between;
380
- align-items: center;
381
- font-size: 0.875rem;
382
- font-weight: 700;
383
- color: #71717a;
384
- text-transform: uppercase;
385
- letter-spacing: 0.05em;
386
- }
387
-
388
- :global(.theme-dark) .input-label { color: #a1a1aa; }
389
-
390
- .input-badge {
391
- padding: 0.125rem 0.5rem;
392
- border-radius: 0.25rem;
393
- font-size: 0.75rem;
394
- }
395
-
396
- .input-badge-amber {
397
- background: #fef3c7;
398
- color: #b45309;
399
- }
400
-
401
- :global(.theme-dark) .input-badge-amber {
402
- background: rgba(245,158,11,0.2);
403
- color: #fbbf24;
404
- }
405
-
406
- .input-badge-blue {
407
- background: #dbeafe;
408
- color: #1d4ed8;
409
- }
410
-
411
- :global(.theme-dark) .input-badge-blue {
412
- background: rgba(59,130,246,0.2);
413
- color: #60a5fa;
414
- }
415
-
416
- .carb-input {
417
- width: 100%;
418
- background: #fafafa;
419
- border: 2px solid #e4e4e7;
420
- border-radius: 0.75rem;
421
- padding: 0.875rem 1rem;
422
- font-size: 1.125rem;
423
- font-weight: 700;
424
- outline: none;
425
- transition: border-color 0.2s;
426
- box-sizing: border-box;
427
- }
428
-
429
- :global(.theme-dark) .carb-input {
430
- background: rgba(0,0,0,0.2);
431
- border-color: #3f3f46;
432
- color: #f4f4f5;
433
- }
434
-
435
- .carb-input:focus { border-color: #f59e0b; }
436
-
437
- .co2-section {
438
- padding-top: 1.25rem;
439
- border-top: 1px dashed #e4e4e7;
440
- }
441
-
442
- :global(.theme-dark) .co2-section { border-color: #3f3f46; }
443
-
444
- .co2-header {
445
- display: flex;
446
- justify-content: space-between;
447
- align-items: flex-end;
448
- margin-bottom: 1rem;
449
- }
450
-
451
- .co2-label {
452
- font-weight: 700;
453
- font-size: 0.875rem;
454
- color: #71717a;
455
- text-transform: uppercase;
456
- letter-spacing: 0.05em;
457
- }
458
-
459
- :global(.theme-dark) .co2-label { color: #a1a1aa; }
460
- .co2-value-wrap { text-align: right; }
461
-
462
- .co2-value {
463
- font-size: 2rem;
464
- font-weight: 900;
465
- color: #f59e0b;
466
- line-height: 1;
467
- }
468
-
469
- .co2-unit {
470
- font-size: 0.75rem;
471
- font-weight: 700;
472
- color: #a1a1aa;
473
- text-transform: uppercase;
474
- margin-left: 0.25rem;
475
- }
476
-
477
- .co2-slider {
478
- width: 100%;
479
- height: 1rem;
480
- background: #e4e4e7;
481
- border-radius: 9999px;
482
- appearance: none;
483
- cursor: pointer;
484
- accent-color: #f59e0b;
485
- }
486
-
487
- :global(.theme-dark) .co2-slider { background: #3f3f46; }
488
-
489
- .preset-row {
490
- display: flex;
491
- justify-content: space-between;
492
- margin-top: 0.75rem;
493
- padding: 0 0.25rem;
494
- }
495
-
496
- .preset-btn {
497
- display: flex;
498
- flex-direction: column;
499
- align-items: center;
500
- background: none;
501
- border: none;
502
- cursor: pointer;
503
- opacity: 0.5;
504
- transition: opacity 0.2s;
505
- padding: 0;
506
- }
507
-
508
- .preset-btn:hover { opacity: 1; }
509
-
510
- .preset-tick {
511
- width: 4px;
512
- height: 10px;
513
- background: #d4d4d8;
514
- margin-bottom: 0.25rem;
515
- }
516
-
517
- .preset-label {
518
- font-size: 0.75rem;
519
- font-weight: 700;
520
- color: #71717a;
521
- }
522
-
523
- .results-title {
524
- font-size: 1.125rem;
525
- font-weight: 700;
526
- margin: 0 0 1.25rem;
527
- display: flex;
528
- align-items: center;
529
- gap: 0.75rem;
530
- }
531
-
532
- .results-title-icon {
533
- width: 1.25rem;
534
- height: 1.25rem;
535
- color: #a1a1aa;
536
- }
537
-
538
- .results-list {
539
- display: flex;
540
- flex-direction: column;
541
- gap: 0.75rem;
542
- }
543
-
544
- .result-row {
545
- display: flex;
546
- align-items: center;
547
- justify-content: space-between;
548
- padding: 0.875rem;
549
- border-radius: 0.75rem;
550
- border: 1px solid #f4f4f5;
551
- }
552
-
553
- :global(.theme-dark) .result-row { border-color: #27272a; }
554
-
555
- .result-row-primary {
556
- background: #fafafa;
557
- border-color: #e4e4e7;
558
- }
559
-
560
- :global(.theme-dark) .result-row-primary {
561
- background: rgba(0,0,0,0.2);
562
- border-color: #3f3f46;
563
- }
564
-
565
- .result-name { font-weight: 700; }
566
-
567
- .result-name-muted {
568
- font-weight: 500;
569
- color: #71717a;
570
- }
571
-
572
- :global(.theme-dark) .result-name-muted { color: #a1a1aa; }
573
- .result-value {
574
- font-size: 1.125rem;
575
- font-weight: 700;
576
- }
577
-
578
- .result-value-primary {
579
- font-size: 1.375rem;
580
- font-weight: 900;
581
- color: #4f46e5;
582
- }
583
226
 
584
- :global(.theme-dark) .result-value-primary { color: #818cf8; }
585
-
586
- .carb-right {
587
- display: flex;
588
- flex-direction: column;
589
- align-items: center;
590
- justify-content: center;
591
- padding: 1.5rem;
592
- background: #fafafa;
593
- }
594
-
595
- @media (min-width: 1024px) {
596
- .carb-right { width: 50%; }
597
- }
598
-
599
- :global(.theme-dark) .carb-right { background: rgba(0,0,0,0.15); }
600
-
601
- .safety-box {
602
- width: 100%;
603
- margin-bottom: 1.25rem;
604
- background: #ef4444;
605
- color: #fff;
606
- padding: 0.75rem 1.25rem;
607
- border-radius: 0.75rem;
608
- box-shadow: 0 4px 12px rgba(239,68,68,0.3);
609
- display: flex;
610
- align-items: center;
611
- justify-content: center;
612
- gap: 0.75rem;
613
- font-weight: 700;
614
- text-transform: uppercase;
615
- animation: bounce 1s infinite;
616
- }
617
-
618
- .safety-icon {
619
- width: 1.25rem;
620
- height: 1.25rem;
621
- }
622
-
623
- @keyframes bounce {
624
- 0%, 100% { transform: translateY(0); }
625
- 50% { transform: translateY(-4px); }
626
- }
627
-
628
- @keyframes calc-rise {
629
- 0% {
630
- transform: translateY(100%) scale(0.5);
631
- opacity: 0;
632
- }
633
-
634
- 20% { opacity: 0.8; }
635
-
636
- 100% {
637
- transform: translateY(-120%) scale(var(--s, 1));
638
- opacity: 0;
639
- }
640
- }
641
-
642
- .calc-b {
643
- position: absolute;
644
- background: radial-gradient(circle at 30% 30%, #fff, rgba(255,255,255,0.2));
645
- border-radius: 50%;
646
- animation: calc-rise linear infinite;
647
- bottom: -20px;
648
- }
649
-
650
- .beer-visual-wrap {
651
- position: relative;
652
- width: 240px;
653
- height: 400px;
654
- }
655
-
656
- .beer-glass {
657
- position: absolute;
658
- inset: 0;
659
- background: linear-gradient(to bottom, #fbbf24, #d97706, #78350f);
660
- border-radius: 0 0 2rem 2rem;
661
- z-index: 1;
662
- clip-path: polygon(5% 0, 95% 0, 85% 100%, 15% 100%);
663
- }
664
-
665
- .glass-bubbles {
666
- position: absolute;
667
- inset: 0;
668
- opacity: 0.5;
669
- overflow: hidden;
670
- }
671
-
672
- .glass-foam {
673
- position: absolute;
674
- top: 0;
675
- width: 100%;
676
- background: #fcf5e5;
677
- transition: height 0.5s;
678
- height: 20px;
679
- }
680
-
681
- .glass-shine {
682
- position: absolute;
683
- inset: 0;
684
- border: 4px solid rgba(255,255,255,0.2);
685
- border-bottom-width: 4px;
686
- border-radius: 0 0 2rem 2rem;
687
- z-index: 2;
688
- clip-path: polygon(0 0, 100% 0, 90% 100%, 10% 100%);
689
- }
690
-
691
- .foam-info {
692
- margin-top: 1.5rem;
693
- text-align: center;
694
- }
695
-
696
- .foam-text {
697
- font-size: 1.25rem;
698
- font-weight: 900;
699
- text-transform: uppercase;
700
- letter-spacing: 0.1em;
701
- opacity: 0.8;
702
- margin: 0 0 0.5rem;
703
- }
704
-
705
- .foam-hint {
706
- color: #a1a1aa;
707
- font-size: 0.875rem;
708
- margin: 0;
709
- }
710
- </style>
@@ -0,0 +1,52 @@
1
+ import type { AlcoholToolEntry, ToolLocaleContent } from '../../types';
2
+
3
+ export interface CarbonationUI {
4
+ [key: string]: string;
5
+ parametersTitle: string;
6
+ metricBtn: string;
7
+ imperialBtn: string;
8
+ volumeLabel: string;
9
+ maxTempLabel: string;
10
+ litersUnit: string;
11
+ celsiusUnit: string;
12
+ gallonsUnit: string;
13
+ fahrenheitUnit: string;
14
+ desiredCo2Label: string;
15
+ volUnit: string;
16
+ resultsTitle: string;
17
+ tableSugarLabel: string;
18
+ cornSugarLabel: string;
19
+ dmeLabel: string;
20
+ safetyTitle: string;
21
+ lowCarbonation: string;
22
+ optimalCarbonation: string;
23
+ highEffervescence: string;
24
+ bubblingVisualizationLabel: string;
25
+ }
26
+
27
+ export type CarbonationLocaleContent = ToolLocaleContent<CarbonationUI>;
28
+
29
+ export const carbonationCalculator: AlcoholToolEntry<CarbonationUI> = {
30
+ id: 'carbonation-calculator',
31
+ icons: {
32
+ bg: 'mdi:bottle-soda-classic',
33
+ fg: 'mdi:water-opacity',
34
+ },
35
+ i18n: {
36
+ de: () => import('./i18n/de').then((m) => m.content),
37
+ en: () => import('./i18n/en').then((m) => m.content),
38
+ es: () => import('./i18n/es').then((m) => m.content),
39
+ fr: () => import('./i18n/fr').then((m) => m.content),
40
+ id: () => import('./i18n/id').then((m) => m.content),
41
+ it: () => import('./i18n/it').then((m) => m.content),
42
+ ja: () => import('./i18n/ja').then((m) => m.content),
43
+ ko: () => import('./i18n/ko').then((m) => m.content),
44
+ nl: () => import('./i18n/nl').then((m) => m.content),
45
+ pl: () => import('./i18n/pl').then((m) => m.content),
46
+ pt: () => import('./i18n/pt').then((m) => m.content),
47
+ ru: () => import('./i18n/ru').then((m) => m.content),
48
+ sv: () => import('./i18n/sv').then((m) => m.content),
49
+ tr: () => import('./i18n/tr').then((m) => m.content),
50
+ zh: () => import('./i18n/zh').then((m) => m.content),
51
+ },
52
+ };
@@ -1,57 +1,5 @@
1
- import type { AlcoholToolEntry, ToolLocaleContent, ToolDefinition } from '../../types';
2
-
3
- export interface CarbonationUI {
4
- [key: string]: string;
5
- parametersTitle: string;
6
- metricBtn: string;
7
- imperialBtn: string;
8
- volumeLabel: string;
9
- maxTempLabel: string;
10
- litersUnit: string;
11
- celsiusUnit: string;
12
- gallonsUnit: string;
13
- fahrenheitUnit: string;
14
- desiredCo2Label: string;
15
- volUnit: string;
16
- resultsTitle: string;
17
- tableSugarLabel: string;
18
- cornSugarLabel: string;
19
- dmeLabel: string;
20
- safetyTitle: string;
21
- lowCarbonation: string;
22
- optimalCarbonation: string;
23
- highEffervescence: string;
24
- bubblingVisualizationLabel: string;
25
- }
26
-
27
- export type CarbonationLocaleContent = ToolLocaleContent<CarbonationUI>;
28
-
29
- export const carbonationCalculator: AlcoholToolEntry<CarbonationUI> = {
30
- id: 'carbonation-calculator',
31
- icons: {
32
- bg: 'mdi:bottle-soda-classic',
33
- fg: 'mdi:water-opacity',
34
- },
35
- i18n: {
36
- de: () => import('./i18n/de').then((m) => m.content),
37
- en: () => import('./i18n/en').then((m) => m.content),
38
- es: () => import('./i18n/es').then((m) => m.content),
39
- fr: () => import('./i18n/fr').then((m) => m.content),
40
- id: () => import('./i18n/id').then((m) => m.content),
41
- it: () => import('./i18n/it').then((m) => m.content),
42
- ja: () => import('./i18n/ja').then((m) => m.content),
43
- ko: () => import('./i18n/ko').then((m) => m.content),
44
- nl: () => import('./i18n/nl').then((m) => m.content),
45
- pl: () => import('./i18n/pl').then((m) => m.content),
46
- pt: () => import('./i18n/pt').then((m) => m.content),
47
- ru: () => import('./i18n/ru').then((m) => m.content),
48
- sv: () => import('./i18n/sv').then((m) => m.content),
49
- tr: () => import('./i18n/tr').then((m) => m.content),
50
- zh: () => import('./i18n/zh').then((m) => m.content),
51
- },
52
- };
53
-
54
-
1
+ import { carbonationCalculator } from './entry';
2
+ export * from './entry';
55
3
  export const CARBONATION_TOOL: ToolDefinition = {
56
4
  entry: carbonationCalculator as AlcoholToolEntry<Record<string, string>>,
57
5
  Component: () => import('./component.astro'),