@jjlmoya/utils-drones 1.39.0 → 1.41.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 (40) hide show
  1. package/package.json +2 -2
  2. package/scripts/validate-icons.mjs +57 -0
  3. package/src/category/index.ts +2 -0
  4. package/src/entries.ts +4 -0
  5. package/src/index.ts +1 -0
  6. package/src/tests/locale_completeness.test.ts +2 -2
  7. package/src/tests/tool_validation.test.ts +2 -2
  8. package/src/tool/fpv-drone-lap-timer/audio.ts +160 -0
  9. package/src/tool/fpv-drone-lap-timer/bibliography.astro +6 -0
  10. package/src/tool/fpv-drone-lap-timer/bibliography.ts +14 -0
  11. package/src/tool/fpv-drone-lap-timer/bootstrap.ts +20 -0
  12. package/src/tool/fpv-drone-lap-timer/component.astro +136 -0
  13. package/src/tool/fpv-drone-lap-timer/contract.test.ts +24 -0
  14. package/src/tool/fpv-drone-lap-timer/controller.ts +304 -0
  15. package/src/tool/fpv-drone-lap-timer/dom-views.ts +213 -0
  16. package/src/tool/fpv-drone-lap-timer/entry.ts +27 -0
  17. package/src/tool/fpv-drone-lap-timer/export.ts +41 -0
  18. package/src/tool/fpv-drone-lap-timer/fpv-drone-lap-timer.css +705 -0
  19. package/src/tool/fpv-drone-lap-timer/i18n/de.ts +216 -0
  20. package/src/tool/fpv-drone-lap-timer/i18n/en.ts +216 -0
  21. package/src/tool/fpv-drone-lap-timer/i18n/es.ts +216 -0
  22. package/src/tool/fpv-drone-lap-timer/i18n/fr.ts +216 -0
  23. package/src/tool/fpv-drone-lap-timer/i18n/id.ts +216 -0
  24. package/src/tool/fpv-drone-lap-timer/i18n/it.ts +216 -0
  25. package/src/tool/fpv-drone-lap-timer/i18n/ja.ts +216 -0
  26. package/src/tool/fpv-drone-lap-timer/i18n/ko.ts +216 -0
  27. package/src/tool/fpv-drone-lap-timer/i18n/nl.ts +216 -0
  28. package/src/tool/fpv-drone-lap-timer/i18n/pl.ts +216 -0
  29. package/src/tool/fpv-drone-lap-timer/i18n/pt.ts +216 -0
  30. package/src/tool/fpv-drone-lap-timer/i18n/ru.ts +216 -0
  31. package/src/tool/fpv-drone-lap-timer/i18n/sv.ts +216 -0
  32. package/src/tool/fpv-drone-lap-timer/i18n/tr.ts +216 -0
  33. package/src/tool/fpv-drone-lap-timer/i18n/zh.ts +216 -0
  34. package/src/tool/fpv-drone-lap-timer/index.ts +10 -0
  35. package/src/tool/fpv-drone-lap-timer/logic.test.ts +152 -0
  36. package/src/tool/fpv-drone-lap-timer/logic.ts +228 -0
  37. package/src/tool/fpv-drone-lap-timer/seo.astro +16 -0
  38. package/src/tool/fpv-drone-lap-timer/storage.ts +52 -0
  39. package/src/tool/fpv-drone-lap-timer/ui.ts +58 -0
  40. package/src/tools.ts +3 -0
@@ -0,0 +1,705 @@
1
+ :root {
2
+ --fpv-bg-card: #fff;
3
+ --fpv-bg-subtle: #f8fafc;
4
+ --fpv-bg-inner: #f1f5f9;
5
+ --fpv-border: #cbd5e1;
6
+ --fpv-border-subtle: #e2e8f0;
7
+ --fpv-text: #0f172a;
8
+ --fpv-muted: #64748b;
9
+ --fpv-cyan: #0284c7;
10
+ --fpv-cyan-glow: rgba(2, 132, 199, 0.25);
11
+ --fpv-emerald: #059669;
12
+ --fpv-emerald-glow: rgba(5, 150, 105, 0.25);
13
+ --fpv-amber: #d97706;
14
+ --fpv-amber-glow: rgba(217, 119, 6, 0.25);
15
+ --fpv-rose: #e11d48;
16
+ --fpv-shadow: rgba(15, 23, 42, 0.08);
17
+ --fpv-active-btn: #0284c7;
18
+ }
19
+
20
+ .theme-dark .fpv-lap-timer-card {
21
+ --fpv-bg-card: #0c121e;
22
+ --fpv-bg-subtle: #111a2b;
23
+ --fpv-bg-inner: #182337;
24
+ --fpv-border: #24324a;
25
+ --fpv-border-subtle: #1b263b;
26
+ --fpv-text: #f8fafc;
27
+ --fpv-muted: #94a3b8;
28
+ --fpv-cyan: #38bdf8;
29
+ --fpv-cyan-glow: rgba(56, 189, 248, 0.35);
30
+ --fpv-emerald: #34d399;
31
+ --fpv-emerald-glow: rgba(52, 211, 153, 0.35);
32
+ --fpv-amber: #fbbf24;
33
+ --fpv-amber-glow: rgba(251, 191, 36, 0.35);
34
+ --fpv-rose: #fb7185;
35
+ --fpv-shadow: rgba(0, 0, 0, 0.45);
36
+ --fpv-active-btn: #0284c7;
37
+ }
38
+
39
+ .fpv-lap-timer-card {
40
+ display: grid;
41
+ grid-template-columns: minmax(280px, 320px) minmax(0, 1fr);
42
+ gap: 1.5rem;
43
+ align-items: start;
44
+ margin: 0 auto;
45
+ border: 1px solid var(--fpv-border);
46
+ border-radius: 1.5rem;
47
+ background: var(--fpv-bg-card);
48
+ box-shadow: 0 1rem 3rem var(--fpv-shadow);
49
+ color: var(--fpv-text);
50
+ padding: clamp(1rem, 2.5vw, 1.75rem);
51
+ box-sizing: border-box;
52
+ }
53
+
54
+ @media (max-width: 960px) {
55
+ .fpv-lap-timer-card {
56
+ grid-template-columns: 1fr;
57
+ }
58
+ }
59
+
60
+ .fpv-lap-timer-sidebar {
61
+ display: flex;
62
+ flex-direction: column;
63
+ gap: 1.25rem;
64
+ padding: 1.25rem;
65
+ border: 1px solid var(--fpv-border);
66
+ border-radius: 1rem;
67
+ background: var(--fpv-bg-subtle);
68
+ box-sizing: border-box;
69
+ }
70
+
71
+ .fpv-lap-timer-sidebar-header {
72
+ display: flex;
73
+ flex-direction: column;
74
+ gap: 0.25rem;
75
+ }
76
+
77
+ .fpv-lap-timer-kicker {
78
+ font-size: 0.68rem;
79
+ font-weight: 900;
80
+ letter-spacing: 0.14em;
81
+ text-transform: uppercase;
82
+ color: var(--fpv-cyan);
83
+ }
84
+
85
+ .fpv-lap-timer-sidebar-title {
86
+ margin: 0;
87
+ font-size: 1.05rem;
88
+ font-weight: 800;
89
+ letter-spacing: -0.01em;
90
+ }
91
+
92
+ .fpv-lap-timer-presets {
93
+ display: flex;
94
+ flex-direction: column;
95
+ gap: 0.45rem;
96
+ }
97
+
98
+ .fpv-lap-timer-preset {
99
+ padding: 0.55rem 0.85rem;
100
+ border: 1px solid var(--fpv-border);
101
+ border-radius: 0.55rem;
102
+ background: var(--fpv-bg-inner);
103
+ color: var(--fpv-text);
104
+ font-size: 0.82rem;
105
+ font-weight: 700;
106
+ text-align: left;
107
+ cursor: pointer;
108
+ transition: border-color 0.2s, background 0.2s, color 0.2s;
109
+ }
110
+
111
+ .fpv-lap-timer-preset:hover {
112
+ border-color: var(--fpv-cyan);
113
+ color: var(--fpv-cyan);
114
+ }
115
+
116
+ .fpv-lap-timer-preset.active {
117
+ border-color: var(--fpv-cyan);
118
+ background: color-mix(in srgb, var(--fpv-cyan) 14%, var(--fpv-bg-inner));
119
+ color: var(--fpv-cyan);
120
+ }
121
+
122
+ .fpv-lap-timer-fields {
123
+ display: flex;
124
+ flex-direction: column;
125
+ gap: 0.85rem;
126
+ }
127
+
128
+ .fpv-lap-timer-field {
129
+ display: flex;
130
+ flex-direction: column;
131
+ gap: 0.35rem;
132
+ }
133
+
134
+ .fpv-lap-timer-field-label {
135
+ font-size: 0.78rem;
136
+ font-weight: 700;
137
+ color: var(--fpv-muted);
138
+ }
139
+
140
+ .fpv-lap-timer-field-label small {
141
+ font-weight: 500;
142
+ opacity: 0.8;
143
+ }
144
+
145
+ .fpv-lap-timer-field input[type="number"] {
146
+ width: 100%;
147
+ padding: 0.55rem 0.75rem;
148
+ border: 1px solid var(--fpv-border);
149
+ border-radius: 0.55rem;
150
+ background: var(--fpv-bg-inner);
151
+ color: var(--fpv-text);
152
+ font-size: 0.92rem;
153
+ font-weight: 700;
154
+ box-sizing: border-box;
155
+ }
156
+
157
+ .fpv-lap-timer-checkbox {
158
+ display: flex;
159
+ align-items: center;
160
+ gap: 0.6rem;
161
+ padding: 0.35rem 0;
162
+ font-size: 0.82rem;
163
+ font-weight: 700;
164
+ cursor: pointer;
165
+ }
166
+
167
+ .fpv-lap-timer-checkbox input[type="checkbox"] {
168
+ width: 1.15rem;
169
+ height: 1.15rem;
170
+ accent-color: var(--fpv-cyan);
171
+ cursor: pointer;
172
+ }
173
+
174
+ .fpv-lap-timer-specs-card {
175
+ display: flex;
176
+ flex-direction: column;
177
+ gap: 0.6rem;
178
+ padding: 0.85rem 1rem;
179
+ border: 1px solid var(--fpv-border-subtle);
180
+ border-radius: 0.75rem;
181
+ background: var(--fpv-bg-inner);
182
+ font-size: 0.8rem;
183
+ }
184
+
185
+ .fpv-lap-timer-spec-row {
186
+ display: flex;
187
+ align-items: center;
188
+ justify-content: space-between;
189
+ gap: 0.5rem;
190
+ }
191
+
192
+ .fpv-lap-timer-spec-row span {
193
+ color: var(--fpv-muted);
194
+ font-weight: 600;
195
+ }
196
+
197
+ .fpv-lap-timer-spec-row strong {
198
+ font-weight: 800;
199
+ }
200
+
201
+ .fpv-lap-timer-stage {
202
+ display: flex;
203
+ flex-direction: column;
204
+ gap: 1.25rem;
205
+ min-width: 0;
206
+ }
207
+
208
+ .fpv-lap-timer-hud {
209
+ display: flex;
210
+ flex-direction: column;
211
+ align-items: center;
212
+ justify-content: center;
213
+ padding: clamp(1.25rem, 3vw, 2rem);
214
+ border: 1px solid var(--fpv-border);
215
+ border-radius: 1.25rem;
216
+ background: var(--fpv-bg-subtle);
217
+ box-shadow: 0 0.5rem 1.5rem var(--fpv-shadow);
218
+ text-align: center;
219
+ }
220
+
221
+ .fpv-lap-timer-hud-bar {
222
+ display: flex;
223
+ align-items: center;
224
+ justify-content: space-between;
225
+ width: 100%;
226
+ margin-bottom: 0.75rem;
227
+ }
228
+
229
+ .fpv-lap-timer-chip {
230
+ display: inline-flex;
231
+ align-items: center;
232
+ gap: 0.45rem;
233
+ padding: 0.35rem 0.75rem;
234
+ border: 1px solid var(--fpv-border);
235
+ border-radius: 9999px;
236
+ background: var(--fpv-bg-inner);
237
+ font-size: 0.78rem;
238
+ font-weight: 700;
239
+ }
240
+
241
+ .fpv-lap-timer-status-dot {
242
+ width: 0.55rem;
243
+ height: 0.55rem;
244
+ border-radius: 50%;
245
+ background: var(--fpv-muted);
246
+ }
247
+
248
+ .fpv-lap-timer-status-running .fpv-lap-timer-status-dot {
249
+ background: var(--fpv-emerald);
250
+ box-shadow: 0 0 8px var(--fpv-emerald);
251
+ }
252
+
253
+ .fpv-lap-timer-status-countdown .fpv-lap-timer-status-dot {
254
+ background: var(--fpv-amber);
255
+ box-shadow: 0 0 8px var(--fpv-amber);
256
+ }
257
+
258
+ .fpv-lap-timer-digits {
259
+ font-size: clamp(3rem, 7vw, 4.75rem);
260
+ font-weight: 900;
261
+ letter-spacing: 0.05em;
262
+ color: var(--fpv-cyan);
263
+ line-height: 1.05;
264
+ text-shadow: 0 0 24px var(--fpv-cyan-glow);
265
+ }
266
+
267
+ .fpv-lap-timer-hud-sublabel {
268
+ margin-top: 0.4rem;
269
+ font-size: 0.8rem;
270
+ font-weight: 800;
271
+ letter-spacing: 0.1em;
272
+ text-transform: uppercase;
273
+ color: var(--fpv-muted);
274
+ }
275
+
276
+ .fpv-lap-timer-trigger-box {
277
+ display: flex;
278
+ flex-direction: column;
279
+ gap: 0.65rem;
280
+ }
281
+
282
+ .fpv-lap-timer-giant-btn {
283
+ display: flex;
284
+ align-items: center;
285
+ justify-content: center;
286
+ min-height: 5.25rem;
287
+ padding: 1rem 2rem;
288
+ border: 2px solid var(--fpv-cyan);
289
+ border-radius: 1rem;
290
+ background: var(--fpv-cyan);
291
+ color: #fff;
292
+ font-size: clamp(1.3rem, 2.8vw, 1.85rem);
293
+ font-weight: 900;
294
+ letter-spacing: 0.06em;
295
+ cursor: pointer;
296
+ box-shadow: 0 0.5rem 2rem var(--fpv-cyan-glow);
297
+ transition: transform 0.1s ease, box-shadow 0.1s ease, background 0.2s ease;
298
+ user-select: none;
299
+ -webkit-tap-highlight-color: transparent;
300
+ }
301
+
302
+ .fpv-lap-timer-giant-btn:hover:not(:disabled) {
303
+ transform: translateY(-2px);
304
+ box-shadow: 0 0.75rem 2.5rem var(--fpv-cyan-glow);
305
+ }
306
+
307
+ .fpv-lap-timer-giant-btn:active:not(:disabled) {
308
+ transform: scale(0.98);
309
+ box-shadow: 0 0.2rem 1rem var(--fpv-cyan-glow);
310
+ }
311
+
312
+ .fpv-lap-timer-giant-btn:disabled {
313
+ opacity: 0.4;
314
+ cursor: not-allowed;
315
+ transform: none;
316
+ box-shadow: none;
317
+ }
318
+
319
+ .fpv-lap-timer-btn-countdown-active {
320
+ border-color: var(--fpv-amber);
321
+ background: var(--fpv-amber);
322
+ animation: fpv-lap-timer-pulse 0.5s ease infinite alternate;
323
+ }
324
+
325
+ @keyframes fpv-lap-timer-pulse {
326
+ from {
327
+ transform: scale(1);
328
+ opacity: 0.85;
329
+ }
330
+ to {
331
+ transform: scale(1.02);
332
+ opacity: 1;
333
+ }
334
+ }
335
+
336
+ .fpv-lap-timer-hint {
337
+ text-align: center;
338
+ font-size: 0.78rem;
339
+ font-weight: 600;
340
+ color: var(--fpv-muted);
341
+ }
342
+
343
+ .fpv-lap-timer-controls {
344
+ display: flex;
345
+ flex-wrap: wrap;
346
+ gap: 0.75rem;
347
+ justify-content: center;
348
+ }
349
+
350
+ .fpv-lap-timer-btn {
351
+ display: inline-flex;
352
+ align-items: center;
353
+ justify-content: center;
354
+ gap: 0.4rem;
355
+ padding: 0.65rem 1.35rem;
356
+ border: 1px solid var(--fpv-border);
357
+ border-radius: 0.65rem;
358
+ background: var(--fpv-bg-inner);
359
+ color: var(--fpv-text);
360
+ font-size: 0.88rem;
361
+ font-weight: 700;
362
+ cursor: pointer;
363
+ transition: border-color 0.2s, background 0.2s;
364
+ }
365
+
366
+ .fpv-lap-timer-btn:hover:not(:disabled) {
367
+ border-color: var(--fpv-cyan);
368
+ background: var(--fpv-bg-subtle);
369
+ }
370
+
371
+ .fpv-lap-timer-btn-primary {
372
+ border-color: var(--fpv-emerald);
373
+ background: var(--fpv-emerald);
374
+ color: #fff;
375
+ box-shadow: 0 0.35rem 1.25rem var(--fpv-emerald-glow);
376
+ }
377
+
378
+ .fpv-lap-timer-btn-primary:hover:not(:disabled) {
379
+ background: #047857;
380
+ border-color: #047857;
381
+ }
382
+
383
+ .fpv-lap-timer-btn:disabled {
384
+ opacity: 0.4;
385
+ cursor: not-allowed;
386
+ }
387
+
388
+ .fpv-lap-timer-telemetry-deck {
389
+ display: flex;
390
+ flex-direction: column;
391
+ gap: 1rem;
392
+ padding: 1.25rem;
393
+ border: 1px solid var(--fpv-border);
394
+ border-radius: 1rem;
395
+ background: var(--fpv-bg-subtle);
396
+ }
397
+
398
+ .fpv-lap-timer-telemetry-status-row {
399
+ display: flex;
400
+ align-items: center;
401
+ justify-content: flex-end;
402
+ }
403
+
404
+ .fpv-lap-timer-consistency-chip {
405
+ border-color: var(--fpv-emerald);
406
+ color: var(--fpv-emerald);
407
+ }
408
+
409
+ .fpv-lap-timer-rating-elite {
410
+ border-color: var(--fpv-emerald);
411
+ color: var(--fpv-emerald);
412
+ }
413
+
414
+ .fpv-lap-timer-rating-pro {
415
+ border-color: var(--fpv-cyan);
416
+ color: var(--fpv-cyan);
417
+ }
418
+
419
+ .fpv-lap-timer-rating-club {
420
+ border-color: var(--fpv-amber);
421
+ color: var(--fpv-amber);
422
+ }
423
+
424
+ .fpv-lap-timer-rating-novice {
425
+ border-color: var(--fpv-muted);
426
+ color: var(--fpv-muted);
427
+ }
428
+
429
+ .fpv-lap-timer-telemetry-grid {
430
+ display: grid;
431
+ grid-template-columns: 1.15fr 0.85fr;
432
+ gap: 1rem;
433
+ }
434
+
435
+ @media (max-width: 720px) {
436
+ .fpv-lap-timer-telemetry-grid {
437
+ grid-template-columns: 1fr;
438
+ }
439
+ }
440
+
441
+ .fpv-lap-timer-racetrack-box,
442
+ .fpv-lap-timer-pace-box {
443
+ border: 1px solid var(--fpv-border);
444
+ border-radius: 0.75rem;
445
+ background: var(--fpv-bg-inner);
446
+ padding: 1rem;
447
+ }
448
+
449
+ .fpv-lap-timer-racetrack-svg {
450
+ width: 100%;
451
+ height: auto;
452
+ display: block;
453
+ }
454
+
455
+ .fpv-lap-timer-track-bg {
456
+ stroke: var(--fpv-border);
457
+ stroke-width: 10px;
458
+ }
459
+
460
+ .fpv-lap-timer-track-active {
461
+ stroke-width: 10px;
462
+ stroke-linecap: round;
463
+ transition: stroke-dashoffset 0.4s ease;
464
+ }
465
+
466
+ .fpv-lap-timer-gate {
467
+ fill: var(--fpv-bg-card);
468
+ stroke-width: 3px;
469
+ }
470
+
471
+ .fpv-lap-timer-gate-sf {
472
+ stroke: var(--fpv-emerald);
473
+ fill: var(--fpv-emerald);
474
+ }
475
+
476
+ .fpv-lap-timer-gate-sector {
477
+ stroke: var(--fpv-cyan);
478
+ }
479
+
480
+ .fpv-lap-timer-gate-label {
481
+ fill: var(--fpv-muted);
482
+ font-size: 8px;
483
+ font-weight: 700;
484
+ text-anchor: middle;
485
+ }
486
+
487
+ .fpv-lap-timer-drone-center {
488
+ text-anchor: middle;
489
+ }
490
+
491
+ .fpv-lap-timer-center-time {
492
+ fill: var(--fpv-cyan);
493
+ font-size: 20px;
494
+ font-weight: 900;
495
+ letter-spacing: 0.05em;
496
+ }
497
+
498
+ .fpv-lap-timer-center-sub {
499
+ fill: var(--fpv-muted);
500
+ font-size: 9px;
501
+ font-weight: 700;
502
+ text-transform: uppercase;
503
+ }
504
+
505
+ .fpv-lap-timer-center-speed {
506
+ fill: var(--fpv-emerald);
507
+ font-size: 11px;
508
+ font-weight: 800;
509
+ }
510
+
511
+ .fpv-lap-timer-pace-header {
512
+ display: flex;
513
+ align-items: center;
514
+ justify-content: space-between;
515
+ margin-bottom: 0.75rem;
516
+ }
517
+
518
+ .fpv-lap-timer-pace-header h4 {
519
+ margin: 0;
520
+ font-size: 0.88rem;
521
+ font-weight: 700;
522
+ }
523
+
524
+ .fpv-lap-timer-fastest-pill {
525
+ font-size: 0.75rem;
526
+ font-weight: 800;
527
+ color: var(--fpv-cyan);
528
+ }
529
+
530
+ .fpv-lap-timer-pace-chart {
531
+ overflow-x: auto;
532
+ }
533
+
534
+ .fpv-lap-timer-bars-svg {
535
+ width: 100%;
536
+ height: 104px;
537
+ display: block;
538
+ }
539
+
540
+ .fpv-lap-timer-chart-axis {
541
+ stroke: var(--fpv-border);
542
+ stroke-width: 1.5px;
543
+ }
544
+
545
+ .fpv-lap-timer-bar-normal {
546
+ fill: var(--fpv-cyan);
547
+ opacity: 0.75;
548
+ transition: height 0.3s ease, y 0.3s ease;
549
+ }
550
+
551
+ .fpv-lap-timer-bar-best {
552
+ fill: var(--fpv-emerald);
553
+ opacity: 1;
554
+ }
555
+
556
+ .fpv-lap-timer-bar-label {
557
+ fill: var(--fpv-muted);
558
+ font-size: 9px;
559
+ font-weight: 700;
560
+ text-anchor: middle;
561
+ }
562
+
563
+ .fpv-lap-timer-empty-notice {
564
+ padding: 1.75rem 1rem;
565
+ text-align: center;
566
+ font-size: 0.82rem;
567
+ color: var(--fpv-muted);
568
+ }
569
+
570
+ .fpv-lap-timer-table-wrap {
571
+ overflow-x: auto;
572
+ border: 1px solid var(--fpv-border);
573
+ border-radius: 0.75rem;
574
+ }
575
+
576
+ .fpv-lap-timer-table {
577
+ width: 100%;
578
+ border-collapse: collapse;
579
+ font-size: 0.86rem;
580
+ text-align: left;
581
+ }
582
+
583
+ .fpv-lap-timer-table th {
584
+ padding: 0.65rem 0.85rem;
585
+ border-bottom: 1px solid var(--fpv-border);
586
+ background: var(--fpv-bg-inner);
587
+ font-size: 0.75rem;
588
+ font-weight: 700;
589
+ text-transform: uppercase;
590
+ letter-spacing: 0.04em;
591
+ color: var(--fpv-muted);
592
+ }
593
+
594
+ .fpv-lap-timer-table td {
595
+ padding: 0.65rem 0.85rem;
596
+ border-bottom: 1px solid var(--fpv-border-subtle);
597
+ }
598
+
599
+ .fpv-lap-timer-tr:hover {
600
+ background: var(--fpv-bg-inner);
601
+ }
602
+
603
+ .fpv-lap-timer-row-best {
604
+ background: rgba(16, 185, 129, 0.08);
605
+ }
606
+
607
+ .fpv-lap-timer-lap-tag {
608
+ font-weight: 800;
609
+ }
610
+
611
+ .fpv-lap-timer-best-mini {
612
+ display: inline-block;
613
+ margin-left: 0.4rem;
614
+ padding: 0.15rem 0.35rem;
615
+ border-radius: 4px;
616
+ background: var(--fpv-emerald);
617
+ color: #fff;
618
+ font-size: 0.65rem;
619
+ font-weight: 800;
620
+ }
621
+
622
+ .fpv-lap-timer-delta-pill {
623
+ display: inline-block;
624
+ padding: 0.2rem 0.45rem;
625
+ border-radius: 4px;
626
+ font-size: 0.8rem;
627
+ font-weight: 700;
628
+ }
629
+
630
+ .fpv-lap-timer-delta-best {
631
+ color: var(--fpv-emerald);
632
+ }
633
+
634
+ .fpv-lap-timer-delta-good {
635
+ color: var(--fpv-cyan);
636
+ }
637
+
638
+ .fpv-lap-timer-delta-slow {
639
+ color: var(--fpv-rose);
640
+ }
641
+
642
+ .fpv-lap-timer-subtle {
643
+ color: var(--fpv-muted);
644
+ }
645
+
646
+ .fpv-lap-timer-table-empty {
647
+ padding: 1.5rem;
648
+ text-align: center;
649
+ border: 1px dashed var(--fpv-border);
650
+ border-radius: 0.75rem;
651
+ color: var(--fpv-muted);
652
+ font-size: 0.84rem;
653
+ }
654
+
655
+ .fpv-lap-timer-footer {
656
+ display: flex;
657
+ flex-wrap: wrap;
658
+ gap: 0.75rem;
659
+ align-items: center;
660
+ justify-content: flex-end;
661
+ padding-top: 0.25rem;
662
+ }
663
+
664
+ .fpv-lap-timer-notice {
665
+ font-size: 0.82rem;
666
+ font-weight: 700;
667
+ color: var(--fpv-emerald);
668
+ }
669
+
670
+ .fpv-lap-timer-drone-racer {
671
+ pointer-events: none;
672
+ }
673
+
674
+ .fpv-lap-timer-drone-arm {
675
+ stroke: var(--fpv-text);
676
+ stroke-width: 1.6px;
677
+ stroke-linecap: round;
678
+ }
679
+
680
+ .fpv-lap-timer-drone-motor {
681
+ fill: var(--fpv-border);
682
+ stroke: var(--fpv-text);
683
+ stroke-width: 0.8px;
684
+ }
685
+
686
+ .fpv-lap-timer-drone-rotor-blur {
687
+ fill: var(--fpv-cyan);
688
+ opacity: 0.45;
689
+ stroke: var(--fpv-cyan);
690
+ stroke-width: 0.5px;
691
+ }
692
+
693
+ .fpv-lap-timer-drone-body {
694
+ fill: var(--fpv-bg);
695
+ stroke: var(--fpv-cyan);
696
+ stroke-width: 1.2px;
697
+ }
698
+
699
+ .fpv-lap-timer-drone-cam {
700
+ fill: #fff;
701
+ }
702
+
703
+ .fpv-lap-timer-drone-led {
704
+ fill: var(--fpv-emerald);
705
+ }