@jjlmoya/utils-nautical 1.13.0 → 1.15.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-nautical",
3
- "version": "1.13.0",
3
+ "version": "1.15.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -10,7 +10,8 @@
10
10
  "./entries": "./src/entries.ts"
11
11
  },
12
12
  "files": [
13
- "src"
13
+ "src",
14
+ "scripts"
14
15
  ],
15
16
  "publishConfig": {
16
17
  "access": "public"
@@ -29,7 +30,8 @@
29
30
  "postversion": "git push && git push --tags",
30
31
  "patch": "npm version patch",
31
32
  "minor": "npm version minor",
32
- "major": "npm version major"
33
+ "major": "npm version major",
34
+ "postinstall": "node scripts/postinstall.mjs"
33
35
  },
34
36
  "lint-staged": {
35
37
  "*.{ts,tsx,astro}": [
@@ -0,0 +1,27 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const libDir = dirname(fileURLToPath(import.meta.url));
6
+ const toolsDir = join(libDir, '../src/tool');
7
+
8
+ const inNodeModules = libDir.includes('node_modules');
9
+ if (!inNodeModules) process.exit(0);
10
+
11
+ const projectRoot = join(libDir, '../../../..');
12
+ const categoryKey = JSON.parse(readFileSync(join(libDir, '../package.json'), 'utf8')).name.replace('@jjlmoya/utils-', '');
13
+ const destDir = join(projectRoot, `public/styles/lib/${categoryKey}`);
14
+
15
+ mkdirSync(destDir, { recursive: true });
16
+
17
+ const tools = readdirSync(toolsDir, { withFileTypes: true }).filter(d => d.isDirectory());
18
+ for (const tool of tools) {
19
+ const toolDir = join(toolsDir, tool.name);
20
+ let files;
21
+ try { files = readdirSync(toolDir).filter(f => f.endsWith('.css')); }
22
+ catch { continue; }
23
+ for (const file of files) {
24
+ writeFileSync(join(destDir, file), readFileSync(join(toolDir, file)));
25
+ console.log(`[@jjlmoya/utils-${categoryKey}] copied ${file}`);
26
+ }
27
+ }
@@ -308,342 +308,3 @@ const { ui } = Astro.props;
308
308
  new EnduranceCalculator();
309
309
  </script>
310
310
 
311
- <style>
312
- .endurance-calculator {
313
- --n-bg: #fff;
314
- --n-bg-muted: #f1f5f9;
315
- --n-text: #0f172a;
316
- --n-text-muted: #475569;
317
- --n-text-dim: #64748b;
318
- --n-border: #e2e8f0;
319
- --n-shadow: rgba(0, 0, 0, 0.05);
320
- --n-primary: #3b82f6;
321
- --n-primary-on: #fff;
322
- --n-accent: #6366f1;
323
- --n-cyan: #0891b2;
324
- --n-success: #10b981;
325
- --n-warning: #f59e0b;
326
- --n-error: #f43f5e;
327
- --ec-hero-bg: #0f172a;
328
- --ec-hero-label: #22d3ee;
329
-
330
- max-width: 1000px;
331
- margin: 0 auto;
332
- }
333
-
334
- :global(.theme-dark) .endurance-calculator {
335
- --n-bg: #0f172a;
336
- --n-bg-muted: #1e293b;
337
- --n-text: #f8fafc;
338
- --n-text-muted: #94a3b8;
339
- --n-text-dim: #64748b;
340
- --n-border: #334155;
341
- --n-shadow: rgba(0, 0, 0, 0.3);
342
- --n-primary: #60a5fa;
343
- --n-primary-on: #fff;
344
- --n-accent: #818cf8;
345
- --n-cyan: #22d3ee;
346
- --n-success: #34d399;
347
- --n-warning: #fbbf24;
348
- --n-error: #fb7185;
349
- --ec-hero-bg: #020617;
350
- --ec-hero-label: #22d3ee;
351
- }
352
-
353
- .ec-main-container {
354
- background: var(--n-bg);
355
- border: 1px solid var(--n-border);
356
- border-radius: 1.5rem;
357
- display: grid;
358
- grid-template-columns: 360px 1fr;
359
- overflow: hidden;
360
- box-shadow: 0 20px 40px var(--n-shadow);
361
- }
362
-
363
- .ec-sidebar-inputs {
364
- padding: 1.5rem;
365
- border-right: 1px solid var(--n-border);
366
- background: var(--n-bg-muted);
367
- display: flex;
368
- flex-direction: column;
369
- gap: 1.2rem;
370
- }
371
-
372
- .ec-compact-group {
373
- display: flex;
374
- flex-direction: column;
375
- gap: 0.4rem;
376
- }
377
-
378
- .ec-compact-group label {
379
- font-size: 0.7rem;
380
- font-weight: 800;
381
- text-transform: uppercase;
382
- color: var(--n-text-muted);
383
- letter-spacing: 0.06em;
384
- }
385
-
386
- .ec-dual-row {
387
- display: grid;
388
- grid-template-columns: 1fr 1fr;
389
- gap: 0.5rem;
390
- }
391
-
392
- .ec-sub-label {
393
- font-size: 0.65rem;
394
- color: var(--n-text-muted);
395
- font-weight: 700;
396
- margin-bottom: 0.2rem;
397
- display: block;
398
- }
399
-
400
- .ec-field-wrapper {
401
- position: relative;
402
- display: flex;
403
- align-items: center;
404
- }
405
-
406
- .ec-field-icon {
407
- position: absolute;
408
- left: 8px;
409
- font-size: 0.9rem;
410
- color: var(--n-text-muted);
411
- pointer-events: none;
412
- }
413
-
414
- .ec-compact-input,
415
- .ec-compact-select {
416
- width: 100%;
417
- background: var(--n-bg);
418
- border: 1px solid var(--n-border);
419
- border-radius: 0.5rem;
420
- padding: 0.6rem 2.4rem 0.6rem 2.2rem;
421
- font-size: 0.95rem;
422
- font-weight: 700;
423
- color: var(--n-text);
424
- outline: none;
425
- transition: border-color 0.2s;
426
- }
427
-
428
- .ec-compact-input:focus,
429
- .ec-compact-select:focus {
430
- border-color: var(--n-primary);
431
- }
432
-
433
- .ec-compact-select {
434
- padding-right: 0.6rem;
435
- cursor: pointer;
436
- }
437
-
438
- .ec-unit-tag {
439
- position: absolute;
440
- right: 8px;
441
- font-size: 0.65rem;
442
- font-weight: 800;
443
- color: var(--n-text-muted);
444
- pointer-events: none;
445
- }
446
-
447
- .ec-dashboard-panel {
448
- padding: 2rem;
449
- display: flex;
450
- flex-direction: column;
451
- gap: 2rem;
452
- }
453
-
454
- .ec-hero-display {
455
- background: var(--ec-hero-bg);
456
- border-radius: 1rem;
457
- padding: 2rem;
458
- color: var(--n-primary-on);
459
- display: flex;
460
- flex-direction: column;
461
- gap: 1.5rem;
462
- }
463
-
464
- .ec-hero-top {
465
- display: flex;
466
- justify-content: space-between;
467
- align-items: flex-start;
468
- }
469
-
470
- .ec-display-title {
471
- font-size: 0.65rem;
472
- font-weight: 900;
473
- text-transform: uppercase;
474
- color: var(--ec-hero-label);
475
- letter-spacing: 0.1em;
476
- }
477
-
478
- .ec-main-value-row {
479
- display: flex;
480
- align-items: baseline;
481
- gap: 0.5rem;
482
- }
483
-
484
- .ec-main-value {
485
- font-size: 5rem;
486
- font-weight: 900;
487
- color: var(--n-primary-on);
488
- line-height: 1;
489
- }
490
-
491
- .ec-main-unit {
492
- font-size: 1.2rem;
493
- font-weight: 700;
494
- opacity: 0.4;
495
- color: var(--n-primary-on);
496
- }
497
-
498
- .ec-fuel-badge {
499
- font-size: 0.85rem;
500
- font-weight: 900;
501
- color: var(--ec-hero-label);
502
- letter-spacing: 0.05em;
503
- }
504
-
505
- .ec-progress-track {
506
- height: 10px;
507
- background: rgba(255, 255, 255, 0.1);
508
- border-radius: 5px;
509
- position: relative;
510
- overflow: hidden;
511
- }
512
-
513
- .ec-progress-fill {
514
- height: 100%;
515
- background: linear-gradient(90deg, var(--n-error) 0%, var(--n-cyan) 100%);
516
- width: 0%;
517
- transition: width 0.8s ease-out;
518
- }
519
-
520
- .ec-marker {
521
- position: absolute;
522
- top: 0;
523
- bottom: 0;
524
- width: 2px;
525
- background: var(--n-primary-on);
526
- z-index: 2;
527
- }
528
-
529
- .ec-stats-grid {
530
- display: grid;
531
- grid-template-columns: repeat(2, 1fr);
532
- gap: 1rem;
533
- }
534
-
535
- .ec-stat-card {
536
- background: var(--n-bg-muted);
537
- border: 1px solid var(--n-border);
538
- border-radius: 0.75rem;
539
- padding: 1rem;
540
- display: flex;
541
- flex-direction: column;
542
- gap: 0.2rem;
543
- }
544
-
545
- .ec-stat-label {
546
- font-size: 0.6rem;
547
- font-weight: 800;
548
- text-transform: uppercase;
549
- color: var(--n-text-muted);
550
- letter-spacing: 0.06em;
551
- }
552
-
553
- .ec-stat-value {
554
- font-size: 1.4rem;
555
- font-weight: 900;
556
- color: var(--n-text);
557
- }
558
-
559
- .ec-stat-value.danger {
560
- color: var(--n-error);
561
- }
562
-
563
- .ec-stat-card.hidden {
564
- display: none;
565
- }
566
-
567
- .ec-inverter-card {
568
- padding: 1.5rem;
569
- background: var(--n-bg-muted);
570
- border: 1px dashed var(--n-border);
571
- border-radius: 1rem;
572
- display: flex;
573
- flex-direction: column;
574
- gap: 1rem;
575
- }
576
-
577
- .ec-inverter-header {
578
- font-size: 0.75rem;
579
- font-weight: 900;
580
- text-transform: uppercase;
581
- color: var(--n-cyan);
582
- letter-spacing: 0.06em;
583
- }
584
-
585
- .ec-inverter-row {
586
- display: grid;
587
- grid-template-columns: 1fr 1fr;
588
- gap: 1.5rem;
589
- align-items: center;
590
- }
591
-
592
- .ec-inverter-label {
593
- font-size: 0.65rem;
594
- font-weight: 800;
595
- text-transform: uppercase;
596
- color: var(--n-text-muted);
597
- margin-bottom: 0.3rem;
598
- }
599
-
600
- .ec-inverter-value {
601
- font-size: 2rem;
602
- font-weight: 900;
603
- color: var(--n-cyan);
604
- }
605
-
606
- .ec-inverter-unit {
607
- font-size: 0.85rem;
608
- color: var(--n-text-muted);
609
- font-weight: 700;
610
- }
611
-
612
- .ec-warning-bar {
613
- background: color-mix(in srgb, var(--n-error), transparent 90%);
614
- padding: 0.8rem 1.2rem;
615
- border-radius: 0.5rem;
616
- display: flex;
617
- align-items: center;
618
- gap: 0.6rem;
619
- font-size: 0.75rem;
620
- font-weight: 600;
621
- color: var(--n-error);
622
- }
623
-
624
- .ec-warning-icon {
625
- font-size: 1rem;
626
- flex-shrink: 0;
627
- }
628
-
629
- @media (max-width: 800px) {
630
- .ec-main-container {
631
- grid-template-columns: 1fr;
632
- }
633
-
634
- .ec-sidebar-inputs {
635
- border-right: none;
636
- border-bottom: 1px solid var(--n-border);
637
- }
638
- }
639
-
640
- @media (max-width: 480px) {
641
- .ec-main-value {
642
- font-size: 2.8rem;
643
- }
644
-
645
- .ec-stats-grid {
646
- grid-template-columns: 1fr;
647
- }
648
- }
649
- </style>
@@ -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
+ .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
+ }