@jjlmoya/utils-nautical 1.12.0 → 1.14.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.
@@ -0,0 +1,337 @@
1
+ .endurance-calculator {
2
+ --n-bg: #fff;
3
+ --n-bg-muted: #f1f5f9;
4
+ --n-text: #0f172a;
5
+ --n-text-muted: #475569;
6
+ --n-text-dim: #64748b;
7
+ --n-border: #e2e8f0;
8
+ --n-shadow: rgba(0, 0, 0, 0.05);
9
+ --n-primary: #3b82f6;
10
+ --n-primary-on: #fff;
11
+ --n-accent: #6366f1;
12
+ --n-cyan: #0891b2;
13
+ --n-success: #10b981;
14
+ --n-warning: #f59e0b;
15
+ --n-error: #f43f5e;
16
+ --ec-hero-bg: #0f172a;
17
+ --ec-hero-label: #22d3ee;
18
+
19
+ max-width: 1000px;
20
+ margin: 0 auto;
21
+ }
22
+
23
+ :global(.theme-dark) .endurance-calculator {
24
+ --n-bg: #0f172a;
25
+ --n-bg-muted: #1e293b;
26
+ --n-text: #f8fafc;
27
+ --n-text-muted: #94a3b8;
28
+ --n-text-dim: #64748b;
29
+ --n-border: #334155;
30
+ --n-shadow: rgba(0, 0, 0, 0.3);
31
+ --n-primary: #60a5fa;
32
+ --n-primary-on: #fff;
33
+ --n-accent: #818cf8;
34
+ --n-cyan: #22d3ee;
35
+ --n-success: #34d399;
36
+ --n-warning: #fbbf24;
37
+ --n-error: #fb7185;
38
+ --ec-hero-bg: #020617;
39
+ --ec-hero-label: #22d3ee;
40
+ }
41
+
42
+ .ec-main-container {
43
+ background: var(--n-bg);
44
+ border: 1px solid var(--n-border);
45
+ border-radius: 1.5rem;
46
+ display: grid;
47
+ grid-template-columns: 360px 1fr;
48
+ overflow: hidden;
49
+ box-shadow: 0 20px 40px var(--n-shadow);
50
+ }
51
+
52
+ .ec-sidebar-inputs {
53
+ padding: 1.5rem;
54
+ border-right: 1px solid var(--n-border);
55
+ background: var(--n-bg-muted);
56
+ display: flex;
57
+ flex-direction: column;
58
+ gap: 1.2rem;
59
+ }
60
+
61
+ .ec-compact-group {
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: 0.4rem;
65
+ }
66
+
67
+ .ec-compact-group label {
68
+ font-size: 0.7rem;
69
+ font-weight: 800;
70
+ text-transform: uppercase;
71
+ color: var(--n-text-muted);
72
+ letter-spacing: 0.06em;
73
+ }
74
+
75
+ .ec-dual-row {
76
+ display: grid;
77
+ grid-template-columns: 1fr 1fr;
78
+ gap: 0.5rem;
79
+ }
80
+
81
+ .ec-sub-label {
82
+ font-size: 0.65rem;
83
+ color: var(--n-text-muted);
84
+ font-weight: 700;
85
+ margin-bottom: 0.2rem;
86
+ display: block;
87
+ }
88
+
89
+ .ec-field-wrapper {
90
+ position: relative;
91
+ display: flex;
92
+ align-items: center;
93
+ }
94
+
95
+ .ec-field-icon {
96
+ position: absolute;
97
+ left: 8px;
98
+ font-size: 0.9rem;
99
+ color: var(--n-text-muted);
100
+ pointer-events: none;
101
+ }
102
+
103
+ .ec-compact-input,
104
+ .ec-compact-select {
105
+ width: 100%;
106
+ background: var(--n-bg);
107
+ border: 1px solid var(--n-border);
108
+ border-radius: 0.5rem;
109
+ padding: 0.6rem 2.4rem 0.6rem 2.2rem;
110
+ font-size: 0.95rem;
111
+ font-weight: 700;
112
+ color: var(--n-text);
113
+ outline: none;
114
+ transition: border-color 0.2s;
115
+ }
116
+
117
+ .ec-compact-input:focus,
118
+ .ec-compact-select:focus {
119
+ border-color: var(--n-primary);
120
+ }
121
+
122
+ .ec-compact-select {
123
+ padding-right: 0.6rem;
124
+ cursor: pointer;
125
+ }
126
+
127
+ .ec-unit-tag {
128
+ position: absolute;
129
+ right: 8px;
130
+ font-size: 0.65rem;
131
+ font-weight: 800;
132
+ color: var(--n-text-muted);
133
+ pointer-events: none;
134
+ }
135
+
136
+ .ec-dashboard-panel {
137
+ padding: 2rem;
138
+ display: flex;
139
+ flex-direction: column;
140
+ gap: 2rem;
141
+ }
142
+
143
+ .ec-hero-display {
144
+ background: var(--ec-hero-bg);
145
+ border-radius: 1rem;
146
+ padding: 2rem;
147
+ color: var(--n-primary-on);
148
+ display: flex;
149
+ flex-direction: column;
150
+ gap: 1.5rem;
151
+ }
152
+
153
+ .ec-hero-top {
154
+ display: flex;
155
+ justify-content: space-between;
156
+ align-items: flex-start;
157
+ }
158
+
159
+ .ec-display-title {
160
+ font-size: 0.65rem;
161
+ font-weight: 900;
162
+ text-transform: uppercase;
163
+ color: var(--ec-hero-label);
164
+ letter-spacing: 0.1em;
165
+ }
166
+
167
+ .ec-main-value-row {
168
+ display: flex;
169
+ align-items: baseline;
170
+ gap: 0.5rem;
171
+ }
172
+
173
+ .ec-main-value {
174
+ font-size: 5rem;
175
+ font-weight: 900;
176
+ color: var(--n-primary-on);
177
+ line-height: 1;
178
+ }
179
+
180
+ .ec-main-unit {
181
+ font-size: 1.2rem;
182
+ font-weight: 700;
183
+ opacity: 0.4;
184
+ color: var(--n-primary-on);
185
+ }
186
+
187
+ .ec-fuel-badge {
188
+ font-size: 0.85rem;
189
+ font-weight: 900;
190
+ color: var(--ec-hero-label);
191
+ letter-spacing: 0.05em;
192
+ }
193
+
194
+ .ec-progress-track {
195
+ height: 10px;
196
+ background: rgba(255, 255, 255, 0.1);
197
+ border-radius: 5px;
198
+ position: relative;
199
+ overflow: hidden;
200
+ }
201
+
202
+ .ec-progress-fill {
203
+ height: 100%;
204
+ background: linear-gradient(90deg, var(--n-error) 0%, var(--n-cyan) 100%);
205
+ width: 0%;
206
+ transition: width 0.8s ease-out;
207
+ }
208
+
209
+ .ec-marker {
210
+ position: absolute;
211
+ top: 0;
212
+ bottom: 0;
213
+ width: 2px;
214
+ background: var(--n-primary-on);
215
+ z-index: 2;
216
+ }
217
+
218
+ .ec-stats-grid {
219
+ display: grid;
220
+ grid-template-columns: repeat(2, 1fr);
221
+ gap: 1rem;
222
+ }
223
+
224
+ .ec-stat-card {
225
+ background: var(--n-bg-muted);
226
+ border: 1px solid var(--n-border);
227
+ border-radius: 0.75rem;
228
+ padding: 1rem;
229
+ display: flex;
230
+ flex-direction: column;
231
+ gap: 0.2rem;
232
+ }
233
+
234
+ .ec-stat-label {
235
+ font-size: 0.6rem;
236
+ font-weight: 800;
237
+ text-transform: uppercase;
238
+ color: var(--n-text-muted);
239
+ letter-spacing: 0.06em;
240
+ }
241
+
242
+ .ec-stat-value {
243
+ font-size: 1.4rem;
244
+ font-weight: 900;
245
+ color: var(--n-text);
246
+ }
247
+
248
+ .ec-stat-value.danger {
249
+ color: var(--n-error);
250
+ }
251
+
252
+ .ec-stat-card.hidden {
253
+ display: none;
254
+ }
255
+
256
+ .ec-inverter-card {
257
+ padding: 1.5rem;
258
+ background: var(--n-bg-muted);
259
+ border: 1px dashed var(--n-border);
260
+ border-radius: 1rem;
261
+ display: flex;
262
+ flex-direction: column;
263
+ gap: 1rem;
264
+ }
265
+
266
+ .ec-inverter-header {
267
+ font-size: 0.75rem;
268
+ font-weight: 900;
269
+ text-transform: uppercase;
270
+ color: var(--n-cyan);
271
+ letter-spacing: 0.06em;
272
+ }
273
+
274
+ .ec-inverter-row {
275
+ display: grid;
276
+ grid-template-columns: 1fr 1fr;
277
+ gap: 1.5rem;
278
+ align-items: center;
279
+ }
280
+
281
+ .ec-inverter-label {
282
+ font-size: 0.65rem;
283
+ font-weight: 800;
284
+ text-transform: uppercase;
285
+ color: var(--n-text-muted);
286
+ margin-bottom: 0.3rem;
287
+ }
288
+
289
+ .ec-inverter-value {
290
+ font-size: 2rem;
291
+ font-weight: 900;
292
+ color: var(--n-cyan);
293
+ }
294
+
295
+ .ec-inverter-unit {
296
+ font-size: 0.85rem;
297
+ color: var(--n-text-muted);
298
+ font-weight: 700;
299
+ }
300
+
301
+ .ec-warning-bar {
302
+ background: color-mix(in srgb, var(--n-error), transparent 90%);
303
+ padding: 0.8rem 1.2rem;
304
+ border-radius: 0.5rem;
305
+ display: flex;
306
+ align-items: center;
307
+ gap: 0.6rem;
308
+ font-size: 0.75rem;
309
+ font-weight: 600;
310
+ color: var(--n-error);
311
+ }
312
+
313
+ .ec-warning-icon {
314
+ font-size: 1rem;
315
+ flex-shrink: 0;
316
+ }
317
+
318
+ @media (max-width: 800px) {
319
+ .ec-main-container {
320
+ grid-template-columns: 1fr;
321
+ }
322
+
323
+ .ec-sidebar-inputs {
324
+ border-right: none;
325
+ border-bottom: 1px solid var(--n-border);
326
+ }
327
+ }
328
+
329
+ @media (max-width: 480px) {
330
+ .ec-main-value {
331
+ font-size: 2.8rem;
332
+ }
333
+
334
+ .ec-stats-grid {
335
+ grid-template-columns: 1fr;
336
+ }
337
+ }
@@ -479,210 +479,3 @@ const allBeaufort = { es: beaufortEs, en: beaufortEn, fr: beaufortFr };
479
479
  new NauticalConverter();
480
480
  </script>
481
481
 
482
- <style>
483
- .nautical-converter {
484
- --n-bg: #fff;
485
- --n-bg-muted: #f1f5f9;
486
- --n-text: #0f172a;
487
- --n-text-muted: #475569;
488
- --n-text-dim: #64748b;
489
- --n-border: #e2e8f0;
490
- --n-shadow: rgba(0, 0, 0, 0.05);
491
- --n-primary: #3b82f6;
492
- --n-primary-on: #fff;
493
- --n-accent: #6366f1;
494
- --n-cyan: #0891b2;
495
- --n-success: #10b981;
496
- --n-warning: #f59e0b;
497
- --n-error: #f43f5e;
498
-
499
- display: flex;
500
- flex-direction: column;
501
- gap: 1.5rem;
502
- max-width: 900px;
503
- margin: 0 auto;
504
- }
505
-
506
- :global(.theme-dark) .nautical-converter {
507
- --n-bg: #0f172a;
508
- --n-bg-muted: #1e293b;
509
- --n-text: #f8fafc;
510
- --n-text-muted: #94a3b8;
511
- --n-text-dim: #64748b;
512
- --n-border: #334155;
513
- --n-shadow: rgba(0, 0, 0, 0.3);
514
- --n-primary: #60a5fa;
515
- --n-primary-on: #fff;
516
- --n-accent: #818cf8;
517
- --n-cyan: #22d3ee;
518
- --n-success: #34d399;
519
- --n-warning: #fbbf24;
520
- --n-error: #fb7185;
521
- }
522
-
523
- .nc-category-tabs {
524
- display: flex;
525
- gap: 0.5rem;
526
- flex-wrap: wrap;
527
- background: var(--n-bg);
528
- border: 1px solid var(--n-border);
529
- border-radius: 1rem;
530
- padding: 0.5rem;
531
- }
532
-
533
- .nc-tab-btn {
534
- flex: 1;
535
- min-width: 120px;
536
- padding: 0.7rem 1.2rem;
537
- border: none;
538
- border-radius: 0.7rem;
539
- background: transparent;
540
- color: var(--n-text-muted);
541
- font-size: 0.9rem;
542
- font-weight: 600;
543
- cursor: pointer;
544
- transition: background 0.2s, color 0.2s;
545
- }
546
-
547
- .nc-tab-btn:hover {
548
- background: var(--n-bg-muted);
549
- color: var(--n-text);
550
- }
551
-
552
- .nc-tab-btn.active {
553
- background: var(--n-primary);
554
- color: var(--n-primary-on);
555
- }
556
-
557
- .nc-tab-panel {
558
- display: none;
559
- }
560
-
561
- .nc-tab-panel.active {
562
- display: block;
563
- }
564
-
565
- .nc-converter-card {
566
- background: var(--n-bg);
567
- border: 1px solid var(--n-border);
568
- border-radius: 1.5rem;
569
- padding: 2rem;
570
- box-shadow: 0 8px 24px var(--n-shadow);
571
- }
572
-
573
- .nc-input-grid {
574
- display: grid;
575
- grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
576
- gap: 1.2rem;
577
- }
578
-
579
- .nc-input-group {
580
- display: flex;
581
- flex-direction: column;
582
- gap: 0.4rem;
583
- }
584
-
585
- .nc-input-group label {
586
- font-size: 0.8rem;
587
- font-weight: 700;
588
- color: var(--n-text-muted);
589
- text-transform: uppercase;
590
- letter-spacing: 0.05em;
591
- }
592
-
593
- .nc-input-wrapper {
594
- position: relative;
595
- display: flex;
596
- align-items: center;
597
- }
598
-
599
- .nc-elegant-input {
600
- width: 100%;
601
- background: var(--n-bg);
602
- color: var(--n-text);
603
- border: 2px solid var(--n-border);
604
- border-radius: 0.8rem;
605
- padding: 0.75rem 2.8rem 0.75rem 1rem;
606
- font-size: 1rem;
607
- outline: none;
608
- transition: border-color 0.2s;
609
- }
610
-
611
- .nc-elegant-input:focus {
612
- border-color: var(--n-cyan);
613
- }
614
-
615
- .nc-copy-btn {
616
- position: absolute;
617
- right: 0.5rem;
618
- background: none;
619
- border: none;
620
- cursor: pointer;
621
- color: var(--n-cyan);
622
- padding: 0.2rem;
623
- display: flex;
624
- align-items: center;
625
- opacity: 0.5;
626
- transition: opacity 0.2s;
627
- }
628
-
629
- .nc-copy-btn:hover {
630
- opacity: 1;
631
- }
632
-
633
- .nc-beaufort-card {
634
- margin-top: 1.5rem;
635
- background: var(--n-bg);
636
- border: 1px solid var(--n-border);
637
- border-radius: 1rem;
638
- padding: 1.2rem 1.5rem;
639
- display: none;
640
- align-items: center;
641
- gap: 1.2rem;
642
- }
643
-
644
- .nc-beaufort-card.visible {
645
- display: flex;
646
- }
647
-
648
- .nc-beaufort-badge {
649
- display: flex;
650
- align-items: center;
651
- justify-content: center;
652
- width: 56px;
653
- height: 56px;
654
- border-radius: 50%;
655
- font-size: 1.6rem;
656
- font-weight: 900;
657
- color: var(--n-primary-on);
658
- flex-shrink: 0;
659
- }
660
-
661
- .nc-beaufort-info {
662
- display: flex;
663
- flex-direction: column;
664
- gap: 0.2rem;
665
- }
666
-
667
- .nc-beaufort-name {
668
- font-size: 1.1rem;
669
- font-weight: 700;
670
- color: var(--n-text);
671
- }
672
-
673
- .nc-beaufort-sea {
674
- font-size: 0.9rem;
675
- color: var(--n-text-muted);
676
- }
677
-
678
- @media (max-width: 600px) {
679
- .nc-input-grid {
680
- grid-template-columns: 1fr 1fr;
681
- }
682
-
683
- .nc-tab-btn {
684
- font-size: 0.8rem;
685
- padding: 0.6rem 0.8rem;
686
- }
687
- }
688
- </style>
@@ -0,0 +1,57 @@
1
+ import type { NauticalToolEntry, ToolLocaleContent } from '../../types';
2
+
3
+ export interface NauticalConverterUI {
4
+ [key: string]: string;
5
+ distanceCategoryLabel: string;
6
+ speedCategoryLabel: string;
7
+ depthCategoryLabel: string;
8
+ pressureCategoryLabel: string;
9
+ nmLabel: string;
10
+ kmLabel: string;
11
+ miLabel: string;
12
+ cableLabel: string;
13
+ knLabel: string;
14
+ kmhLabel: string;
15
+ msLabel: string;
16
+ mphLabel: string;
17
+ brozaLabel: string;
18
+ mLabel: string;
19
+ ftLabel: string;
20
+ mbarLabel: string;
21
+ mmhgLabel: string;
22
+ inhgLabel: string;
23
+ atmLabel: string;
24
+ windSeaLabel: string;
25
+ forceLabel: string;
26
+ effectLabel: string;
27
+ copyLabel: string;
28
+ faqTitle: string;
29
+ bibliographyTitle: string;
30
+ }
31
+
32
+ export type NauticalConverterLocaleContent = ToolLocaleContent<NauticalConverterUI>;
33
+
34
+ export const nauticalConverter: NauticalToolEntry<NauticalConverterUI> = {
35
+ id: 'nautical-converter',
36
+ icons: {
37
+ bg: 'mdi:swap-horizontal',
38
+ fg: 'mdi:compass',
39
+ },
40
+ i18n: {
41
+ es: () => import('./i18n/es').then((m) => m.content),
42
+ en: () => import('./i18n/en').then((m) => m.content),
43
+ fr: () => import('./i18n/fr').then((m) => m.content),
44
+ de: () => import('./i18n/de').then((m) => m.content),
45
+ id: () => import('./i18n/id').then((m) => m.content),
46
+ it: () => import('./i18n/it').then((m) => m.content),
47
+ ja: () => import('./i18n/ja').then((m) => m.content),
48
+ ko: () => import('./i18n/ko').then((m) => m.content),
49
+ nl: () => import('./i18n/nl').then((m) => m.content),
50
+ pl: () => import('./i18n/pl').then((m) => m.content),
51
+ pt: () => import('./i18n/pt').then((m) => m.content),
52
+ ru: () => import('./i18n/ru').then((m) => m.content),
53
+ sv: () => import('./i18n/sv').then((m) => m.content),
54
+ tr: () => import('./i18n/tr').then((m) => m.content),
55
+ zh: () => import('./i18n/zh').then((m) => m.content),
56
+ },
57
+ };
@@ -1,62 +1,5 @@
1
- import type { NauticalToolEntry, ToolLocaleContent, ToolDefinition } from '../../types';
2
-
3
- export interface NauticalConverterUI {
4
- [key: string]: string;
5
- distanceCategoryLabel: string;
6
- speedCategoryLabel: string;
7
- depthCategoryLabel: string;
8
- pressureCategoryLabel: string;
9
- nmLabel: string;
10
- kmLabel: string;
11
- miLabel: string;
12
- cableLabel: string;
13
- knLabel: string;
14
- kmhLabel: string;
15
- msLabel: string;
16
- mphLabel: string;
17
- brozaLabel: string;
18
- mLabel: string;
19
- ftLabel: string;
20
- mbarLabel: string;
21
- mmhgLabel: string;
22
- inhgLabel: string;
23
- atmLabel: string;
24
- windSeaLabel: string;
25
- forceLabel: string;
26
- effectLabel: string;
27
- copyLabel: string;
28
- faqTitle: string;
29
- bibliographyTitle: string;
30
- }
31
-
32
- export type NauticalConverterLocaleContent = ToolLocaleContent<NauticalConverterUI>;
33
-
34
- export const nauticalConverter: NauticalToolEntry<NauticalConverterUI> = {
35
- id: 'nautical-converter',
36
- icons: {
37
- bg: 'mdi:swap-horizontal',
38
- fg: 'mdi:compass',
39
- },
40
- i18n: {
41
- es: () => import('./i18n/es').then((m) => m.content),
42
- en: () => import('./i18n/en').then((m) => m.content),
43
- fr: () => import('./i18n/fr').then((m) => m.content),
44
- de: () => import('./i18n/de').then((m) => m.content),
45
- id: () => import('./i18n/id').then((m) => m.content),
46
- it: () => import('./i18n/it').then((m) => m.content),
47
- ja: () => import('./i18n/ja').then((m) => m.content),
48
- ko: () => import('./i18n/ko').then((m) => m.content),
49
- nl: () => import('./i18n/nl').then((m) => m.content),
50
- pl: () => import('./i18n/pl').then((m) => m.content),
51
- pt: () => import('./i18n/pt').then((m) => m.content),
52
- ru: () => import('./i18n/ru').then((m) => m.content),
53
- sv: () => import('./i18n/sv').then((m) => m.content),
54
- tr: () => import('./i18n/tr').then((m) => m.content),
55
- zh: () => import('./i18n/zh').then((m) => m.content),
56
- },
57
- };
58
-
59
-
1
+ import { nauticalConverter } from './entry';
2
+ export * from './entry';
60
3
  export const NAUTICAL_CONVERTER_TOOL: ToolDefinition = {
61
4
  entry: nauticalConverter,
62
5
  Component: () => import('./component.astro'),