@lcars-gui/federation 0.0.0-stage → 0.1.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/dist/ui.css ADDED
@@ -0,0 +1,959 @@
1
+ /* AUTO-GENERATED FROM tokens/ + css/*.css — DO NOT EDIT */
2
+
3
+ :root {
4
+ --colors-text1: #000000;
5
+ --colors-text2: #FFFFFF;
6
+ --colors-background: #000000;
7
+ --padding-btn-std: 0em 1em;
8
+ --width-xs: 2em;
9
+ --width-s: 3em;
10
+ --width-m: 6em;
11
+ --width-l: 8em;
12
+ --width-xl: 10em;
13
+ --height-btn-std: 1.5em;
14
+ --fontSize-xs: 0.75vw;
15
+ --fontSize-s: 1.0vw;
16
+ --fontSize-m: 1.25vw;
17
+ --fontSize-l: 1.75vw;
18
+ --fontSize-xl: 2.5vw;
19
+ --radius-btn-std: 10rem;
20
+ --frame-gap: 0.3rem;
21
+ --frame-sidebar-width: 9rem;
22
+ --frame-bar-height: 1.5rem;
23
+ --frame-segment-height: 3.5rem;
24
+ --frame-elbow-height: 5rem;
25
+ --frame-elbow-radius: 4rem;
26
+ --frame-elbow-inner-radius: 1.75rem;
27
+ --frame-label-size: 1.1rem;
28
+ --frame-title-size: 2.2rem;
29
+ --status-ok: #99CC66;
30
+ --status-warn: #FFCC33;
31
+ --status-error: #FF4444;
32
+ --status-off: #555555;
33
+ --alert-red: #FF3333;
34
+ --alert-yellow: #FFCC00;
35
+ --colors-color1: #EA9D3C;
36
+ --colors-color1hover: #EFB46B;
37
+ --colors-color2: #B96C69;
38
+ --colors-color2hover: #C98F8D;
39
+ --colors-color3: #EA9D6F;
40
+ --colors-color3hover: #F4CB9A;
41
+ --colors-color4: #F1CC9F;
42
+ --colors-color4hover: #F7E3C9;
43
+ --colors-color5: #FDFEE3;
44
+ --colors-color5hover: #FFFFFF;
45
+ --colors-color6: #9C9DF7;
46
+ --colors-color6hover: #CBCCFB;
47
+ --colors-color7: #C29DC9;
48
+ --colors-color7hover: #D6BDDB;
49
+ }
50
+
51
+ /* Colors */
52
+ [data-color="1"] { --lcar-bg: var(--colors-color1); --lcar-bg-hover: var(--colors-color1hover); }
53
+ [data-color="2"] { --lcar-bg: var(--colors-color2); --lcar-bg-hover: var(--colors-color2hover); }
54
+ [data-color="3"] { --lcar-bg: var(--colors-color3); --lcar-bg-hover: var(--colors-color3hover); }
55
+ [data-color="4"] { --lcar-bg: var(--colors-color4); --lcar-bg-hover: var(--colors-color4hover); }
56
+ [data-color="5"] { --lcar-bg: var(--colors-color5); --lcar-bg-hover: var(--colors-color5hover); }
57
+ [data-color="6"] { --lcar-bg: var(--colors-color6); --lcar-bg-hover: var(--colors-color6hover); }
58
+ [data-color="7"] { --lcar-bg: var(--colors-color7); --lcar-bg-hover: var(--colors-color7hover); }
59
+
60
+ /* Themes */
61
+ [data-theme="ds9"] {
62
+ --colors-color1: #5B8DD9;
63
+ --colors-color1hover: color-mix(in srgb, #5B8DD9 65%, white);
64
+ --colors-color2: #8FAADC;
65
+ --colors-color2hover: color-mix(in srgb, #8FAADC 65%, white);
66
+ --colors-color3: #C9A86A;
67
+ --colors-color3hover: color-mix(in srgb, #C9A86A 65%, white);
68
+ --colors-color4: #E3C38F;
69
+ --colors-color4hover: color-mix(in srgb, #E3C38F 65%, white);
70
+ --colors-color5: #DDE6F5;
71
+ --colors-color5hover: color-mix(in srgb, #DDE6F5 65%, white);
72
+ --colors-color6: #6E6EC4;
73
+ --colors-color6hover: color-mix(in srgb, #6E6EC4 65%, white);
74
+ --colors-color7: #A88BC7;
75
+ --colors-color7hover: color-mix(in srgb, #A88BC7 65%, white);
76
+ }
77
+ [data-theme="picard"] {
78
+ --colors-color1: #FF9900;
79
+ --colors-color1hover: color-mix(in srgb, #FF9900 65%, white);
80
+ --colors-color2: #CC6666;
81
+ --colors-color2hover: color-mix(in srgb, #CC6666 65%, white);
82
+ --colors-color3: #FFAA90;
83
+ --colors-color3hover: color-mix(in srgb, #FFAA90 65%, white);
84
+ --colors-color4: #FFCC99;
85
+ --colors-color4hover: color-mix(in srgb, #FFCC99 65%, white);
86
+ --colors-color5: #FFF1D9;
87
+ --colors-color5hover: color-mix(in srgb, #FFF1D9 65%, white);
88
+ --colors-color6: #5599FF;
89
+ --colors-color6hover: color-mix(in srgb, #5599FF 65%, white);
90
+ --colors-color7: #CC88FF;
91
+ --colors-color7hover: color-mix(in srgb, #CC88FF 65%, white);
92
+ }
93
+ [data-theme="tng"] {
94
+ --colors-color1: #EA9D3C;
95
+ --colors-color1hover: #EFB46B;
96
+ --colors-color2: #B96C69;
97
+ --colors-color2hover: #C98F8D;
98
+ --colors-color3: #EA9D6F;
99
+ --colors-color3hover: #F4CB9A;
100
+ --colors-color4: #F1CC9F;
101
+ --colors-color4hover: #F7E3C9;
102
+ --colors-color5: #FDFEE3;
103
+ --colors-color5hover: #FFFFFF;
104
+ --colors-color6: #9C9DF7;
105
+ --colors-color6hover: #CBCCFB;
106
+ --colors-color7: #C29DC9;
107
+ --colors-color7hover: #D6BDDB;
108
+ }
109
+
110
+ /* Alert palettes */
111
+ [data-alert="red"] {
112
+ --colors-color1: #CC3333;
113
+ --colors-color1hover: color-mix(in srgb, #CC3333 65%, white);
114
+ --colors-color2: #FF5555;
115
+ --colors-color2hover: color-mix(in srgb, #FF5555 65%, white);
116
+ --colors-color3: #E06666;
117
+ --colors-color3hover: color-mix(in srgb, #E06666 65%, white);
118
+ --colors-color4: #FF8080;
119
+ --colors-color4hover: color-mix(in srgb, #FF8080 65%, white);
120
+ --colors-color5: #FFC0C0;
121
+ --colors-color5hover: color-mix(in srgb, #FFC0C0 65%, white);
122
+ --colors-color6: #B32020;
123
+ --colors-color6hover: color-mix(in srgb, #B32020 65%, white);
124
+ --colors-color7: #FF3B3B;
125
+ --colors-color7hover: color-mix(in srgb, #FF3B3B 65%, white);
126
+ }
127
+ [data-alert="yellow"] {
128
+ --colors-color1: #E6B800;
129
+ --colors-color1hover: color-mix(in srgb, #E6B800 65%, white);
130
+ --colors-color2: #FFCC33;
131
+ --colors-color2hover: color-mix(in srgb, #FFCC33 65%, white);
132
+ --colors-color3: #F2C14E;
133
+ --colors-color3hover: color-mix(in srgb, #F2C14E 65%, white);
134
+ --colors-color4: #FFE08A;
135
+ --colors-color4hover: color-mix(in srgb, #FFE08A 65%, white);
136
+ --colors-color5: #FFF4CC;
137
+ --colors-color5hover: color-mix(in srgb, #FFF4CC 65%, white);
138
+ --colors-color6: #CC9900;
139
+ --colors-color6hover: color-mix(in srgb, #CC9900 65%, white);
140
+ --colors-color7: #FFD24D;
141
+ --colors-color7hover: color-mix(in srgb, #FFD24D 65%, white);
142
+ }
143
+
144
+ /* ==================== 00-base.css ==================== */
145
+
146
+ /* Antonio (SIL Open Font License 1.1, siehe fonts/Antonio/OFL.txt) – variable Schrift 100–700 */
147
+ @font-face {
148
+ font-family: 'Antonio';
149
+ src: url('./fonts/Antonio/Antonio-latin.woff2') format('woff2');
150
+ font-weight: 100 700;
151
+ font-style: normal;
152
+ font-display: swap;
153
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
154
+ }
155
+
156
+ @font-face {
157
+ font-family: 'Antonio';
158
+ src: url('./fonts/Antonio/Antonio-latin-ext.woff2') format('woff2');
159
+ font-weight: 100 700;
160
+ font-style: normal;
161
+ font-display: swap;
162
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
163
+ }
164
+
165
+ [class*="lcar-"] {
166
+ box-sizing: border-box;
167
+ }
168
+
169
+ .lcar-btn-std, .lcar-elbow, .lcar-bar, .lcar-block, .lcar-title, .lcar-number,
170
+ .lcar-tab, .lcar-field, .lcar-input, .lcar-keypad-display, .lcar-cascade,
171
+ .lcar-readout, .lcar-gauge, .lcar-status, .lcar-alert {
172
+ font-family: 'Antonio', 'Arial Narrow', sans-serif;
173
+ text-transform: uppercase;
174
+ line-height: 1;
175
+ }
176
+
177
+ @keyframes lcar-pulse {
178
+ from { opacity: 1; }
179
+ to { opacity: 0.45; }
180
+ }
181
+
182
+ @keyframes lcar-blink {
183
+ 0%, 49% { opacity: 1; }
184
+ 50%, 100% { opacity: 0.15; }
185
+ }
186
+
187
+ @media (prefers-reduced-motion: reduce) {
188
+ [class*="lcar-"], [class*="lcar-"]::before, [class*="lcar-"]::after {
189
+ animation: none !important;
190
+ }
191
+ }
192
+
193
+ /* ==================== 10-button.css ==================== */
194
+
195
+ /* #################### CAPSULE #################### */
196
+
197
+ /* Base style */
198
+ .lcar-btn-std {
199
+ background: var(--lcar-bg, var(--colors-color1));
200
+ border-radius: var(--radius-btn-std);
201
+ border: none;
202
+ cursor: pointer;
203
+ display: inline-flex;
204
+ transition: background 0.2s ease;
205
+ color: var(--colors-text1);
206
+ align-items: center;
207
+ justify-content: center;
208
+ overflow: hidden;
209
+ text-overflow: ellipsis;
210
+ text-decoration: none;
211
+ }
212
+
213
+ .lcar-btn-std:hover {
214
+ background: var(--lcar-bg-hover, var(--colors-color1hover));
215
+ }
216
+
217
+ .lcar-btn-std:focus-visible {
218
+ outline: 2px solid var(--colors-color5);
219
+ outline-offset: 2px;
220
+ }
221
+
222
+ .lcar-btn-std:disabled {
223
+ cursor: default;
224
+ opacity: 0.4;
225
+ background: var(--lcar-bg, var(--colors-color1));
226
+ }
227
+
228
+ /* Size Variants */
229
+ .lcar-btn-std[data-size="xs"] { height: var(--height-btn-std); padding: var(--padding-btn-std); font-size: var(--fontSize-xs); }
230
+ .lcar-btn-std[data-size="s"] { height: var(--height-btn-std); padding: var(--padding-btn-std); font-size: var(--fontSize-s); }
231
+ .lcar-btn-std[data-size="m"] { height: var(--height-btn-std); padding: var(--padding-btn-std); font-size: var(--fontSize-m); }
232
+ .lcar-btn-std[data-size="l"] { height: var(--height-btn-std); padding: var(--padding-btn-std); font-size: var(--fontSize-l); }
233
+ .lcar-btn-std[data-size="xl"] { height: var(--height-btn-std); padding: var(--padding-btn-std); font-size: var(--fontSize-xl); }
234
+
235
+ /* Length Variants */
236
+ .lcar-btn-std[data-length="xs"] { width: var(--width-xs); }
237
+ .lcar-btn-std[data-length="s"] { width: var(--width-s); }
238
+ .lcar-btn-std[data-length="m"] { width: var(--width-m); }
239
+ .lcar-btn-std[data-length="l"] { width: var(--width-l); }
240
+ .lcar-btn-std[data-length="xl"] { width: var(--width-xl); }
241
+
242
+ /* Shape Variants (default: capsule) */
243
+ .lcar-btn-std[data-shape="rect"] { border-radius: 0; }
244
+ .lcar-btn-std[data-shape="cap-left"] { border-radius: var(--radius-btn-std) 0 0 var(--radius-btn-std); }
245
+ .lcar-btn-std[data-shape="cap-right"] { border-radius: 0 var(--radius-btn-std) var(--radius-btn-std) 0; }
246
+
247
+ /* Label bottom-right (TNG style) */
248
+ .lcar-btn-std[data-align="br"] {
249
+ align-items: flex-end;
250
+ justify-content: flex-end;
251
+ padding: 0 0.5em 0.3em;
252
+ }
253
+
254
+ /* Toggle: aria-pressed */
255
+ .lcar-btn-std[aria-pressed="false"] {
256
+ background: color-mix(in srgb, var(--lcar-bg, var(--colors-color1)) 45%, black);
257
+ }
258
+ .lcar-btn-std[aria-pressed="false"]:hover {
259
+ background: color-mix(in srgb, var(--lcar-bg, var(--colors-color1)) 70%, black);
260
+ }
261
+ .lcar-btn-std[aria-pressed="true"] {
262
+ background: var(--lcar-bg-hover, var(--colors-color1hover));
263
+ box-shadow: inset 0.5em 0 0 var(--colors-color5);
264
+ }
265
+
266
+ /* ==================== 20-frame.css ==================== */
267
+
268
+ /* #################### ELBOW #################### */
269
+
270
+ .lcar-elbow {
271
+ position: relative;
272
+ flex: none;
273
+ display: flex;
274
+ width: calc(var(--frame-sidebar-width) + var(--frame-elbow-inner-radius));
275
+ height: var(--frame-elbow-height);
276
+ background: var(--lcar-bg, var(--colors-color1));
277
+ color: var(--colors-text1);
278
+ font-size: var(--frame-label-size);
279
+ }
280
+
281
+ /* Inner curve: a quarter circle in surface color */
282
+ .lcar-elbow::after {
283
+ content: "";
284
+ position: absolute;
285
+ width: var(--frame-elbow-inner-radius);
286
+ height: calc(100% - var(--frame-bar-height));
287
+ background: var(--lcar-surface, var(--colors-background));
288
+ }
289
+
290
+ .lcar-elbow[data-corner="tl"], .lcar-elbow:not([data-corner]) {
291
+ border-top-left-radius: var(--frame-elbow-radius);
292
+ align-items: flex-end;
293
+ justify-content: flex-end;
294
+ padding: 0.3em calc(var(--frame-elbow-inner-radius) + 0.5em) 0.3em 0.5em;
295
+ }
296
+ .lcar-elbow[data-corner="tl"]::after, .lcar-elbow:not([data-corner])::after {
297
+ right: 0; bottom: 0;
298
+ border-top-left-radius: var(--frame-elbow-inner-radius);
299
+ }
300
+
301
+ .lcar-elbow[data-corner="tr"] {
302
+ border-top-right-radius: var(--frame-elbow-radius);
303
+ align-items: flex-end;
304
+ justify-content: flex-start;
305
+ padding: 0.3em 0.5em 0.3em calc(var(--frame-elbow-inner-radius) + 0.5em);
306
+ }
307
+ .lcar-elbow[data-corner="tr"]::after {
308
+ left: 0; bottom: 0;
309
+ border-top-right-radius: var(--frame-elbow-inner-radius);
310
+ }
311
+
312
+ .lcar-elbow[data-corner="bl"] {
313
+ border-bottom-left-radius: var(--frame-elbow-radius);
314
+ align-items: flex-start;
315
+ justify-content: flex-end;
316
+ padding: 0.3em calc(var(--frame-elbow-inner-radius) + 0.5em) 0.3em 0.5em;
317
+ }
318
+ .lcar-elbow[data-corner="bl"]::after {
319
+ right: 0; top: 0;
320
+ border-bottom-left-radius: var(--frame-elbow-inner-radius);
321
+ }
322
+
323
+ .lcar-elbow[data-corner="br"] {
324
+ border-bottom-right-radius: var(--frame-elbow-radius);
325
+ align-items: flex-start;
326
+ justify-content: flex-start;
327
+ padding: 0.3em 0.5em 0.3em calc(var(--frame-elbow-inner-radius) + 0.5em);
328
+ }
329
+ .lcar-elbow[data-corner="br"]::after {
330
+ left: 0; top: 0;
331
+ border-bottom-right-radius: var(--frame-elbow-inner-radius);
332
+ }
333
+
334
+ /* #################### BAR / END CAP #################### */
335
+
336
+ .lcar-bar {
337
+ flex: 1 1 0;
338
+ height: var(--frame-bar-height);
339
+ background: var(--lcar-bg, var(--colors-color1));
340
+ }
341
+
342
+ .lcar-bar[data-length="xs"] { flex: none; width: var(--width-xs); }
343
+ .lcar-bar[data-length="s"] { flex: none; width: var(--width-s); }
344
+ .lcar-bar[data-length="m"] { flex: none; width: var(--width-m); }
345
+ .lcar-bar[data-length="l"] { flex: none; width: var(--width-l); }
346
+ .lcar-bar[data-length="xl"] { flex: none; width: var(--width-xl); }
347
+
348
+ .lcar-bar[data-cap="left"] { border-radius: var(--frame-bar-height) 0 0 var(--frame-bar-height); }
349
+ .lcar-bar[data-cap="right"] { border-radius: 0 var(--frame-bar-height) var(--frame-bar-height) 0; }
350
+ .lcar-bar[data-cap="both"] { border-radius: var(--frame-bar-height); }
351
+
352
+ /* #################### TITLE / NUMBER #################### */
353
+
354
+ .lcar-title {
355
+ flex: none;
356
+ color: var(--lcar-bg, var(--colors-color1));
357
+ font-size: var(--frame-title-size);
358
+ height: var(--frame-bar-height);
359
+ line-height: var(--frame-bar-height);
360
+ white-space: nowrap;
361
+ margin: 0;
362
+ font-weight: normal;
363
+ }
364
+
365
+ .lcar-number {
366
+ color: var(--lcar-bg, var(--colors-color4));
367
+ font-size: var(--frame-label-size);
368
+ letter-spacing: 0.05em;
369
+ white-space: nowrap;
370
+ font-variant-numeric: tabular-nums;
371
+ }
372
+
373
+ /* #################### DIVIDER #################### */
374
+
375
+ .lcar-divider {
376
+ height: 0.35rem;
377
+ margin: 1rem 0;
378
+ border: none;
379
+ background: linear-gradient(90deg,
380
+ var(--colors-color1) 0 18%, transparent 0 calc(18% + var(--frame-gap)),
381
+ var(--colors-color4) 0 55%, transparent 0 calc(55% + var(--frame-gap)),
382
+ var(--colors-color6) 0 80%, transparent 0 calc(80% + var(--frame-gap)),
383
+ var(--colors-color2) 0);
384
+ }
385
+
386
+ .lcar-divider[data-color] { background: var(--lcar-bg); }
387
+
388
+ /* #################### BLOCK / STACK / GRID #################### */
389
+
390
+ .lcar-block {
391
+ display: flex;
392
+ align-items: flex-end;
393
+ justify-content: flex-end;
394
+ min-height: var(--frame-segment-height);
395
+ padding: 0 0.5em 0.3em;
396
+ background: var(--lcar-bg, var(--colors-color1));
397
+ color: var(--colors-text1);
398
+ font-size: var(--frame-label-size);
399
+ }
400
+
401
+ .lcar-block[data-fill] { flex: 1 1 auto; }
402
+
403
+ .lcar-stack {
404
+ display: flex;
405
+ flex-direction: column;
406
+ gap: var(--frame-gap);
407
+ width: var(--frame-sidebar-width);
408
+ }
409
+
410
+ .lcar-stack > * { width: 100%; }
411
+
412
+ .lcar-stack > .lcar-btn-std {
413
+ height: var(--frame-segment-height);
414
+ font-size: var(--frame-label-size);
415
+ }
416
+
417
+ /* Button grid: like a bridge console */
418
+ .lcar-grid {
419
+ display: grid;
420
+ grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr));
421
+ gap: var(--frame-gap);
422
+ }
423
+
424
+ .lcar-grid > .lcar-btn-std {
425
+ width: 100%;
426
+ height: var(--frame-segment-height);
427
+ font-size: var(--frame-label-size);
428
+ }
429
+
430
+ /* #################### FRAME #################### */
431
+
432
+ .lcar-frame {
433
+ display: grid;
434
+ grid-template-columns: var(--frame-sidebar-width) minmax(0, 1fr);
435
+ grid-template-rows: auto 1fr auto;
436
+ gap: var(--frame-gap);
437
+ min-height: 100%;
438
+ }
439
+
440
+ .lcar-frame-top, .lcar-frame-bottom {
441
+ grid-column: 1 / -1;
442
+ display: flex;
443
+ gap: var(--frame-gap);
444
+ }
445
+ .lcar-frame-top { align-items: flex-start; }
446
+ .lcar-frame-bottom { align-items: flex-end; }
447
+
448
+ .lcar-frame-content {
449
+ min-width: 0;
450
+ padding: 0.5rem calc(var(--frame-elbow-inner-radius) + 0.5rem);
451
+ color: var(--colors-text2);
452
+ }
453
+
454
+ /* Split layout (TNG main screen): upper panel, divider elbows, lower panel.
455
+ Order: stack, content, frame-bottom, frame-top, stack, content */
456
+ .lcar-frame[data-layout="split"] {
457
+ grid-template-rows: auto auto auto 1fr;
458
+ }
459
+
460
+ .lcar-frame[data-layout="split"] > .lcar-frame-top {
461
+ margin-top: calc(var(--frame-gap) * 2);
462
+ }
463
+
464
+ .lcar-frame-header {
465
+ display: flex;
466
+ align-items: flex-start;
467
+ justify-content: space-between;
468
+ gap: 1.5rem;
469
+ flex-wrap: wrap;
470
+ }
471
+
472
+ .lcar-frame-header > .lcar-title {
473
+ height: auto;
474
+ line-height: 1;
475
+ }
476
+
477
+ /* ==================== 30-controls.css ==================== */
478
+
479
+ /* #################### TABS #################### */
480
+
481
+ .lcar-tabs {
482
+ display: flex;
483
+ flex-direction: column;
484
+ }
485
+
486
+ .lcar-tabs > .lcar-bar {
487
+ flex: none;
488
+ width: 100%;
489
+ }
490
+
491
+ .lcar-tablist {
492
+ display: flex;
493
+ gap: var(--frame-gap);
494
+ }
495
+
496
+ .lcar-tab {
497
+ display: flex;
498
+ align-items: flex-end;
499
+ justify-content: flex-end;
500
+ min-width: 7rem;
501
+ height: 2.5rem;
502
+ margin-bottom: var(--frame-gap);
503
+ padding: 0 0.6em 0.3em;
504
+ border: none;
505
+ cursor: pointer;
506
+ font-size: var(--frame-label-size);
507
+ color: var(--colors-text1);
508
+ background: color-mix(in srgb, var(--lcar-bg, var(--colors-color1)) 45%, black);
509
+ }
510
+
511
+ .lcar-tab:first-child { border-top-left-radius: 1.25rem; }
512
+
513
+ .lcar-tab:hover {
514
+ background: color-mix(in srgb, var(--lcar-bg, var(--colors-color1)) 70%, black);
515
+ }
516
+
517
+ /* Active tab flows into the bar below */
518
+ .lcar-tab[aria-selected="true"] {
519
+ background: var(--lcar-bg, var(--colors-color1));
520
+ margin-bottom: 0;
521
+ height: calc(2.5rem + var(--frame-gap));
522
+ }
523
+
524
+ .lcar-tab:focus-visible {
525
+ outline: 2px solid var(--colors-color5);
526
+ outline-offset: 2px;
527
+ }
528
+
529
+ .lcar-tabpanel {
530
+ padding: 1rem 0;
531
+ color: var(--colors-text2);
532
+ }
533
+
534
+ /* #################### INPUT #################### */
535
+
536
+ .lcar-field {
537
+ display: flex;
538
+ gap: var(--frame-gap);
539
+ height: 2.4rem;
540
+ font-size: var(--frame-label-size);
541
+ }
542
+
543
+ .lcar-field-label {
544
+ display: flex;
545
+ align-items: flex-end;
546
+ justify-content: flex-end;
547
+ min-width: 6rem;
548
+ padding: 0 0.6em 0.3em 1.2em;
549
+ border-radius: 1.2rem 0 0 1.2rem;
550
+ background: var(--lcar-bg, var(--colors-color1));
551
+ color: var(--colors-text1);
552
+ }
553
+
554
+ .lcar-input {
555
+ flex: 1 1 auto;
556
+ min-width: 0;
557
+ padding: 0 1.2em 0 0.6em;
558
+ border: 0.2rem solid var(--lcar-bg, var(--colors-color1));
559
+ border-radius: 0 1.2rem 1.2rem 0;
560
+ background: transparent;
561
+ color: var(--lcar-bg-hover, var(--colors-color1hover));
562
+ font-size: 1.4em;
563
+ outline: none;
564
+ }
565
+
566
+ .lcar-input::placeholder {
567
+ color: color-mix(in srgb, var(--lcar-bg, var(--colors-color1)) 50%, black);
568
+ }
569
+
570
+ .lcar-input:focus {
571
+ border-color: var(--lcar-bg-hover, var(--colors-color1hover));
572
+ box-shadow: 0 0 0.6rem color-mix(in srgb, var(--lcar-bg, var(--colors-color1)) 50%, transparent);
573
+ }
574
+
575
+ /* #################### SLIDER (native range) #################### */
576
+
577
+ .lcar-range {
578
+ -webkit-appearance: none;
579
+ appearance: none;
580
+ width: 100%;
581
+ height: calc(var(--frame-bar-height) * 1.6);
582
+ margin: 0;
583
+ background: transparent;
584
+ cursor: pointer;
585
+ }
586
+
587
+ .lcar-range::-webkit-slider-runnable-track {
588
+ height: var(--frame-bar-height);
589
+ border-radius: var(--frame-bar-height);
590
+ background: color-mix(in srgb, var(--lcar-bg, var(--colors-color1)) 35%, black);
591
+ }
592
+ .lcar-range::-moz-range-track {
593
+ height: var(--frame-bar-height);
594
+ border-radius: var(--frame-bar-height);
595
+ background: color-mix(in srgb, var(--lcar-bg, var(--colors-color1)) 35%, black);
596
+ }
597
+ .lcar-range::-moz-range-progress {
598
+ height: var(--frame-bar-height);
599
+ border-radius: var(--frame-bar-height) 0 0 var(--frame-bar-height);
600
+ background: var(--lcar-bg, var(--colors-color1));
601
+ }
602
+
603
+ .lcar-range::-webkit-slider-thumb {
604
+ -webkit-appearance: none;
605
+ width: 2.5rem;
606
+ height: calc(var(--frame-bar-height) * 1.6);
607
+ margin-top: calc(var(--frame-bar-height) * -0.3);
608
+ border: 0.25rem solid var(--colors-background);
609
+ border-radius: 0.4rem;
610
+ background: var(--lcar-bg-hover, var(--colors-color1hover));
611
+ }
612
+ .lcar-range::-moz-range-thumb {
613
+ width: 2.5rem;
614
+ height: calc(var(--frame-bar-height) * 1.6);
615
+ border: 0.25rem solid var(--colors-background);
616
+ border-radius: 0.4rem;
617
+ background: var(--lcar-bg-hover, var(--colors-color1hover));
618
+ }
619
+
620
+ .lcar-range:focus-visible {
621
+ outline: 2px solid var(--colors-color5);
622
+ outline-offset: 2px;
623
+ }
624
+
625
+ /* #################### KEYPAD #################### */
626
+
627
+ .lcar-keypad {
628
+ display: grid;
629
+ grid-template-columns: repeat(3, minmax(0, 1fr));
630
+ gap: var(--frame-gap);
631
+ width: 15rem;
632
+ }
633
+
634
+ .lcar-keypad > .lcar-btn-std {
635
+ width: 100%;
636
+ height: 3rem;
637
+ font-size: calc(var(--frame-label-size) * 1.3);
638
+ }
639
+
640
+ .lcar-keypad-display {
641
+ grid-column: 1 / -1;
642
+ display: flex;
643
+ align-items: center;
644
+ justify-content: flex-end;
645
+ height: 3rem;
646
+ margin-bottom: var(--frame-gap);
647
+ padding: 0 1.2rem;
648
+ border: 0.2rem solid var(--lcar-bg, var(--colors-color1));
649
+ border-radius: 1.5rem;
650
+ color: var(--colors-color5);
651
+ font-size: 1.8rem;
652
+ letter-spacing: 0.25em;
653
+ }
654
+
655
+ .lcar-keypad-display[data-state="ok"] { border-color: var(--status-ok); color: var(--status-ok); }
656
+ .lcar-keypad-display[data-state="error"] { border-color: var(--status-error); color: var(--status-error); }
657
+
658
+ /* ==================== 40-display.css ==================== */
659
+
660
+ /* #################### DATA CASCADE #################### */
661
+
662
+ .lcar-cascade {
663
+ display: flex;
664
+ max-width: 100%;
665
+ overflow: hidden;
666
+ gap: 1.2em;
667
+ font-size: var(--frame-label-size);
668
+ font-variant-numeric: tabular-nums;
669
+ color: var(--colors-color4);
670
+ }
671
+
672
+ .lcar-cascade-col {
673
+ display: flex;
674
+ flex-direction: column;
675
+ gap: 0.3em;
676
+ text-align: right;
677
+ }
678
+
679
+ .lcar-cascade-col:nth-child(3n + 2) { color: var(--colors-color6); }
680
+ .lcar-cascade-col:nth-child(3n + 3) { color: var(--colors-color3); }
681
+
682
+ /* each cell sets --i (stagger index) */
683
+ .lcar-cascade-col > span {
684
+ animation: lcar-cascade 4s steps(1) infinite;
685
+ animation-delay: calc(var(--i, 0) * 110ms);
686
+ }
687
+
688
+ @keyframes lcar-cascade {
689
+ 0% { color: var(--colors-color5); }
690
+ 6% { color: var(--colors-color1); }
691
+ 45% { color: inherit; }
692
+ }
693
+
694
+ /* #################### READOUT #################### */
695
+
696
+ .lcar-readout {
697
+ display: grid;
698
+ grid-template-columns: auto auto;
699
+ justify-content: start;
700
+ gap: 0.35em 2em;
701
+ margin: 0;
702
+ font-size: var(--frame-label-size);
703
+ }
704
+
705
+ .lcar-readout dt {
706
+ color: var(--lcar-bg, var(--colors-color3));
707
+ }
708
+
709
+ .lcar-readout dd {
710
+ margin: 0;
711
+ text-align: right;
712
+ color: var(--colors-color5);
713
+ font-variant-numeric: tabular-nums;
714
+ }
715
+
716
+ /* #################### LEVEL BAR #################### */
717
+
718
+ .lcar-level {
719
+ display: flex;
720
+ gap: 0.2rem;
721
+ height: var(--frame-bar-height);
722
+ }
723
+
724
+ .lcar-level > span {
725
+ flex: 1 1 0;
726
+ background: color-mix(in srgb, var(--lcar-bg, var(--colors-color1)) 25%, black);
727
+ }
728
+
729
+ .lcar-level > span[data-on] {
730
+ background: var(--lcar-bg, var(--colors-color1));
731
+ }
732
+
733
+ .lcar-level > span:first-child { border-radius: var(--frame-bar-height) 0 0 var(--frame-bar-height); }
734
+ .lcar-level > span:last-child { border-radius: 0 var(--frame-bar-height) var(--frame-bar-height) 0; }
735
+
736
+ .lcar-level[data-orientation="vertical"] {
737
+ flex-direction: column-reverse;
738
+ width: calc(var(--frame-bar-height) * 1.5);
739
+ height: 9rem;
740
+ }
741
+ .lcar-level[data-orientation="vertical"] > span:first-child { border-radius: 0 0 0.75rem 0.75rem; }
742
+ .lcar-level[data-orientation="vertical"] > span:last-child { border-radius: 0.75rem 0.75rem 0 0; }
743
+
744
+ /* #################### GAUGE (set --value 0–100) #################### */
745
+
746
+ .lcar-gauge {
747
+ --value: 0;
748
+ --segments: 12;
749
+ position: relative;
750
+ display: inline-flex;
751
+ flex-direction: column;
752
+ align-items: center;
753
+ justify-content: flex-end;
754
+ width: 12rem;
755
+ aspect-ratio: 2;
756
+ font-size: 2.4rem;
757
+ color: var(--colors-color5);
758
+ }
759
+
760
+ .lcar-gauge::before {
761
+ content: "";
762
+ position: absolute;
763
+ inset: 0;
764
+ background: conic-gradient(from -90deg at 50% 100%,
765
+ var(--lcar-bg, var(--colors-color1)) calc(var(--value) * 1.8deg),
766
+ color-mix(in srgb, var(--lcar-bg, var(--colors-color1)) 22%, black) 0 180deg,
767
+ transparent 0);
768
+ -webkit-mask:
769
+ radial-gradient(circle farthest-side at 50% 100%, transparent 58%, #000 calc(58% + 1px) 100%, transparent 0),
770
+ repeating-conic-gradient(from -90deg at 50% 100%, #000 0 calc(180deg / var(--segments) - 2deg), transparent 0 calc(180deg / var(--segments)));
771
+ -webkit-mask-composite: source-in;
772
+ mask:
773
+ radial-gradient(circle farthest-side at 50% 100%, transparent 58%, #000 calc(58% + 1px) 100%, transparent 0),
774
+ repeating-conic-gradient(from -90deg at 50% 100%, #000 0 calc(180deg / var(--segments) - 2deg), transparent 0 calc(180deg / var(--segments)));
775
+ mask-composite: intersect;
776
+ }
777
+
778
+ .lcar-gauge > * { position: relative; }
779
+
780
+ .lcar-gauge > small {
781
+ font-size: 0.4em;
782
+ color: var(--lcar-bg, var(--colors-color1));
783
+ }
784
+
785
+ /* #################### SENSOR / BLIP / SCAN #################### */
786
+
787
+ .lcar-sensor {
788
+ --lcar-line: var(--lcar-bg, var(--colors-color6));
789
+ position: relative;
790
+ overflow: hidden;
791
+ aspect-ratio: 16 / 9;
792
+ border: 0.2rem solid var(--lcar-line);
793
+ border-radius: 1.5rem;
794
+ background:
795
+ linear-gradient(var(--lcar-line), var(--lcar-line)) center / 1px 100% no-repeat,
796
+ linear-gradient(var(--lcar-line), var(--lcar-line)) center / 100% 1px no-repeat,
797
+ repeating-linear-gradient(0deg, color-mix(in srgb, var(--lcar-line) 25%, transparent) 0 1px, transparent 1px 2rem),
798
+ repeating-linear-gradient(90deg, color-mix(in srgb, var(--lcar-line) 25%, transparent) 0 1px, transparent 1px 2rem);
799
+ }
800
+
801
+ /* --x / --y: position in percent (0–100) */
802
+ .lcar-blip {
803
+ position: absolute;
804
+ left: calc(var(--x, 50) * 1%);
805
+ top: calc(var(--y, 50) * 1%);
806
+ width: 0.7rem;
807
+ height: 0.7rem;
808
+ translate: -50% -50%;
809
+ border-radius: 50%;
810
+ background: var(--lcar-bg);
811
+ box-shadow: 0 0 0.6rem var(--lcar-bg);
812
+ animation: lcar-pulse 0.9s ease-in-out infinite alternate;
813
+ }
814
+
815
+ .lcar-blip:not([data-color]) { --lcar-bg: var(--colors-color5); }
816
+
817
+ .lcar-scan {
818
+ position: relative;
819
+ overflow: hidden;
820
+ }
821
+
822
+ .lcar-scan::after {
823
+ content: "";
824
+ position: absolute;
825
+ top: 0;
826
+ bottom: 0;
827
+ left: -4rem;
828
+ width: 4rem;
829
+ background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--colors-color5) 45%, transparent));
830
+ animation: lcar-scan 3s linear infinite;
831
+ pointer-events: none;
832
+ }
833
+
834
+ @keyframes lcar-scan {
835
+ to { left: 100%; }
836
+ }
837
+
838
+ /* #################### STATUS INDICATOR #################### */
839
+
840
+ .lcar-status {
841
+ --lcar-status: var(--status-off);
842
+ display: inline-flex;
843
+ align-items: center;
844
+ gap: 0.5em;
845
+ font-size: var(--frame-label-size);
846
+ color: var(--colors-color5);
847
+ }
848
+
849
+ .lcar-status::before {
850
+ content: "";
851
+ width: 0.8em;
852
+ height: 0.8em;
853
+ border-radius: 50%;
854
+ background: var(--lcar-status);
855
+ box-shadow: 0 0 0.5em var(--lcar-status);
856
+ }
857
+
858
+ .lcar-status[data-status="ok"] { --lcar-status: var(--status-ok); }
859
+ .lcar-status[data-status="warn"] { --lcar-status: var(--status-warn); }
860
+ .lcar-status[data-status="error"] { --lcar-status: var(--status-error); }
861
+ .lcar-status[data-status="off"] { --lcar-status: var(--status-off); }
862
+ .lcar-status[data-status="off"]::before { box-shadow: none; }
863
+
864
+ .lcar-status[data-blink]::before {
865
+ animation: lcar-blink 1s infinite;
866
+ }
867
+
868
+ /* #################### ALERT #################### */
869
+
870
+ .lcar-alert {
871
+ --lcar-bg: var(--alert-red);
872
+ display: inline-flex;
873
+ flex-direction: column;
874
+ align-items: center;
875
+ gap: 0.4rem;
876
+ padding: 1rem 3rem;
877
+ border: 0.45rem solid var(--lcar-bg);
878
+ border-radius: 3rem;
879
+ outline: 0.45rem solid var(--lcar-bg);
880
+ outline-offset: 0.45rem;
881
+ color: var(--lcar-bg);
882
+ animation: lcar-blink 1.2s infinite;
883
+ }
884
+
885
+ .lcar-alert[data-level="yellow"] { --lcar-bg: var(--alert-yellow); }
886
+
887
+ .lcar-alert-title {
888
+ font-size: 4rem;
889
+ letter-spacing: 0.15em;
890
+ }
891
+
892
+ .lcar-alert-text {
893
+ font-size: 1.4rem;
894
+ letter-spacing: 0.1em;
895
+ }
896
+
897
+ /* Alert mode on any container: palette comes from the theme section,
898
+ frame elements pulse */
899
+ [data-alert] :is(.lcar-bar, .lcar-elbow, .lcar-block) {
900
+ animation: lcar-pulse 1.4s ease-in-out infinite alternate;
901
+ }
902
+
903
+ [data-alert="red"] :is(.lcar-bar, .lcar-elbow, .lcar-block) {
904
+ animation-duration: 0.7s;
905
+ }
906
+
907
+ /* ==================== 90-responsive.css ==================== */
908
+
909
+ /* #################### RESPONSIVE #################### */
910
+
911
+ /* Narrow screens: sidebar becomes a row of buttons above the content */
912
+ @media (max-width: 720px) {
913
+ .lcar-frame {
914
+ grid-template-columns: minmax(0, 1fr);
915
+ }
916
+
917
+ .lcar-stack {
918
+ flex-direction: row;
919
+ flex-wrap: wrap;
920
+ width: auto;
921
+ }
922
+
923
+ .lcar-stack > * {
924
+ width: auto;
925
+ flex: 1 1 5rem;
926
+ }
927
+
928
+ .lcar-stack > .lcar-btn-std,
929
+ .lcar-stack > .lcar-block {
930
+ height: calc(var(--frame-segment-height) * 0.7);
931
+ min-height: 0;
932
+ }
933
+
934
+ .lcar-stack > .lcar-block[data-fill] {
935
+ display: none;
936
+ }
937
+
938
+ .lcar-elbow {
939
+ width: calc(var(--frame-elbow-radius) + var(--frame-elbow-inner-radius));
940
+ height: calc(var(--frame-bar-height) + var(--frame-elbow-inner-radius) * 1.5);
941
+ font-size: 0;
942
+ }
943
+
944
+ .lcar-frame-content {
945
+ padding: 0.5rem 0;
946
+ }
947
+
948
+ .lcar-title {
949
+ font-size: calc(var(--frame-title-size) * 0.7);
950
+ }
951
+
952
+ .lcar-grid {
953
+ grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
954
+ }
955
+
956
+ .lcar-alert-title {
957
+ font-size: 2.5rem;
958
+ }
959
+ }