@mp-consulting/homebridge-ui-kit 1.2.2 → 1.3.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/README.md +294 -37
- package/dist/ai.css +63 -16
- package/dist/ai.min.css +3 -0
- package/dist/ai.min.css.map +1 -0
- package/dist/kit.css +689 -21
- package/dist/kit.d.mts +37 -0
- package/dist/kit.d.ts +513 -0
- package/dist/kit.js +1978 -485
- package/dist/kit.min.css +3 -0
- package/dist/kit.min.css.map +1 -0
- package/dist/kit.min.js +13 -0
- package/dist/kit.min.js.map +1 -0
- package/dist/kit.mjs +2315 -0
- package/dist/theme-boot.js +2 -0
- package/package.json +39 -3
- package/scripts/copy-assets.js +81 -15
package/dist/kit.css
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
/* @mp-consulting/homebridge-ui-kit v1.
|
|
1
|
+
/* @mp-consulting/homebridge-ui-kit v1.3.0 */
|
|
2
2
|
|
|
3
3
|
/* ── Design tokens ──────────────────────────────────────────────────────────
|
|
4
4
|
CSS custom properties used throughout the design system.
|
|
5
5
|
Override these in your plugin's styles.css to customize per-plugin.
|
|
6
|
-
Light values live on :root
|
|
6
|
+
Light values live on :root. Dark values apply under Bootstrap's
|
|
7
|
+
[data-bs-theme="dark"] or under the selector-agnostic .mp-theme-dark class,
|
|
8
|
+
for hosts whose dark mode does not use Bootstrap's attribute (e.g. a
|
|
9
|
+
`body.dark-mode` app): add .mp-theme-dark next to your own class instead of
|
|
10
|
+
copying these values.
|
|
11
|
+
|
|
12
|
+
The kit's rules are deliberately NOT wrapped in a cascade layer:
|
|
13
|
+
unlayered styles beat every layered style regardless of specificity or
|
|
14
|
+
order, so unlayered Bootstrap would then override the kit's Bootstrap
|
|
15
|
+
remaps (primary button, tabs, spinner) and break them.
|
|
7
16
|
────────────────────────────────────────────────────────────────────────── */
|
|
8
17
|
|
|
9
18
|
:root {
|
|
@@ -19,10 +28,19 @@
|
|
|
19
28
|
--mp-status-offline: #ef4444;
|
|
20
29
|
--mp-status-checking: #94a3b8;
|
|
21
30
|
|
|
31
|
+
/* Accessible text and focus colours (plain values, so they hold contrast
|
|
32
|
+
whether or not the host switches Bootstrap's variables) */
|
|
33
|
+
--mp-text-subtle: #5c636a; /* secondary hints; 6.1:1 on white */
|
|
34
|
+
--mp-focus-ring: #4f46e5; /* focus outlines; 6.3:1 on white */
|
|
35
|
+
|
|
22
36
|
/* Surfaces */
|
|
23
37
|
--mp-surface: rgba(0, 0, 0, 0.02);
|
|
24
38
|
--mp-border: rgba(0, 0, 0, 0.1);
|
|
25
39
|
|
|
40
|
+
/* Skeleton shimmer */
|
|
41
|
+
--mp-skeleton-base: rgba(0, 0, 0, 0.08);
|
|
42
|
+
--mp-skeleton-shine: rgba(0, 0, 0, 0.03);
|
|
43
|
+
|
|
26
44
|
/* Shape */
|
|
27
45
|
--mp-radius: 0.5rem;
|
|
28
46
|
--mp-shadow-hover: 0 0.5rem 1rem rgba(0, 0, 0, 0.12);
|
|
@@ -75,12 +93,42 @@
|
|
|
75
93
|
initial-value: 0deg;
|
|
76
94
|
}
|
|
77
95
|
|
|
78
|
-
|
|
96
|
+
/* Dark values that do not depend on Bootstrap. */
|
|
97
|
+
[data-bs-theme="dark"],
|
|
98
|
+
.mp-theme-dark {
|
|
79
99
|
--mp-primary-text: #818cf8;
|
|
100
|
+
--mp-text-subtle: #a3a9b0; /* 6.5:1 on #212529 */
|
|
101
|
+
--mp-focus-ring: #818cf8; /* 5.2:1 on #212529 (the brand indigo is 2.5:1) */
|
|
80
102
|
--mp-surface: rgba(255, 255, 255, 0.03);
|
|
81
103
|
--mp-border: rgba(255, 255, 255, 0.08);
|
|
82
104
|
--mp-shadow-hover: 0 0.5rem 1rem rgba(0, 0, 0, 0.3);
|
|
105
|
+
--mp-skeleton-base: rgba(255, 255, 255, 0.08);
|
|
106
|
+
--mp-skeleton-shine: rgba(255, 255, 255, 0.16);
|
|
83
107
|
--mp-ai-text: #d8b4fe; /* 9.6:1 on #212529 */
|
|
108
|
+
--mp-ai-glow-opacity: 0.7;
|
|
109
|
+
--mp-ai-edge-glow-opacity: 0.8;
|
|
110
|
+
--mp-ai-diff-add-bg: rgba(34, 197, 94, 0.16);
|
|
111
|
+
--mp-ai-diff-add-text: #bbf7d0;
|
|
112
|
+
--mp-ai-diff-del-bg: rgba(239, 68, 68, 0.18);
|
|
113
|
+
--mp-ai-diff-del-text: #fecaca;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* .mp-theme-dark alone: the host does not switch Bootstrap's variables, so
|
|
117
|
+
the host colours are plain values (Bootstrap's dark palette). */
|
|
118
|
+
.mp-theme-dark {
|
|
119
|
+
--mp-ai-surface: #212529;
|
|
120
|
+
--mp-ai-fg: #dee2e6;
|
|
121
|
+
--mp-ai-fg-muted: rgba(222, 226, 230, 0.75);
|
|
122
|
+
--mp-ai-bg: transparent;
|
|
123
|
+
--mp-ai-border-color: #495057;
|
|
124
|
+
--mp-ai-success-text: #75b798;
|
|
125
|
+
--mp-ai-danger-text: #ea868f;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Bootstrap's dark theme: follow its variables, so a plugin that customises
|
|
129
|
+
them is respected. Declared after .mp-theme-dark so it wins when an element
|
|
130
|
+
has both. */
|
|
131
|
+
[data-bs-theme="dark"] {
|
|
84
132
|
--mp-ai-surface: var(--bs-body-bg, #212529);
|
|
85
133
|
--mp-ai-fg: var(--bs-body-color, #dee2e6);
|
|
86
134
|
--mp-ai-fg-muted: var(--bs-secondary-color, rgba(222, 226, 230, 0.75));
|
|
@@ -88,12 +136,6 @@
|
|
|
88
136
|
--mp-ai-border-color: var(--bs-border-color, #495057);
|
|
89
137
|
--mp-ai-success-text: var(--bs-success-text-emphasis, #75b798);
|
|
90
138
|
--mp-ai-danger-text: var(--bs-danger-text-emphasis, #ea868f);
|
|
91
|
-
--mp-ai-glow-opacity: 0.7;
|
|
92
|
-
--mp-ai-edge-glow-opacity: 0.8;
|
|
93
|
-
--mp-ai-diff-add-bg: rgba(34, 197, 94, 0.16);
|
|
94
|
-
--mp-ai-diff-add-text: #bbf7d0;
|
|
95
|
-
--mp-ai-diff-del-bg: rgba(239, 68, 68, 0.18);
|
|
96
|
-
--mp-ai-diff-del-text: #fecaca;
|
|
97
139
|
}
|
|
98
140
|
|
|
99
141
|
/* ── Bootstrap 5 overrides ──────────────────────────────────────────────────
|
|
@@ -119,6 +161,12 @@
|
|
|
119
161
|
color: var(--mp-primary) !important;
|
|
120
162
|
}
|
|
121
163
|
|
|
164
|
+
/* Outline secondary button: Bootstrap's #6c757d text is 4.49:1 on a light
|
|
165
|
+
surface and 3:1 on the dark background; use the contrast-safe token. */
|
|
166
|
+
.btn-outline-secondary {
|
|
167
|
+
--bs-btn-color: var(--mp-text-subtle);
|
|
168
|
+
}
|
|
169
|
+
|
|
122
170
|
/* ── Components ─────────────────────────────────────────────────────────────
|
|
123
171
|
Reusable UI components used across all Homebridge plugins.
|
|
124
172
|
────────────────────────────────────────────────────────────────────────── */
|
|
@@ -162,6 +210,12 @@
|
|
|
162
210
|
vertical-align: middle;
|
|
163
211
|
}
|
|
164
212
|
|
|
213
|
+
/* Spacing between a status dot and its badge label (logical, so RTL works
|
|
214
|
+
without Bootstrap's RTL build). */
|
|
215
|
+
.badge > .mp-status {
|
|
216
|
+
margin-inline-end: 0.25rem;
|
|
217
|
+
}
|
|
218
|
+
|
|
165
219
|
.mp-status-online {
|
|
166
220
|
background-color: var(--mp-status-online);
|
|
167
221
|
box-shadow: 0 0 5px var(--mp-status-online-glow);
|
|
@@ -194,10 +248,152 @@
|
|
|
194
248
|
}
|
|
195
249
|
|
|
196
250
|
.mp-device-card:focus-visible {
|
|
197
|
-
outline: 2px solid var(--mp-
|
|
251
|
+
outline: 2px solid var(--mp-focus-ring);
|
|
252
|
+
outline-offset: 2px;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/* Default card content rendered by MpKit.DeviceList */
|
|
256
|
+
.mp-device-card-body {
|
|
257
|
+
display: flex;
|
|
258
|
+
align-items: center;
|
|
259
|
+
gap: 0.75rem;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.mp-device-card-icon {
|
|
263
|
+
flex: none;
|
|
264
|
+
font-size: 1.5rem;
|
|
265
|
+
line-height: 1;
|
|
266
|
+
color: var(--mp-primary-text);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.mp-device-card-text {
|
|
270
|
+
flex: 1;
|
|
271
|
+
min-width: 0;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.mp-device-card-name {
|
|
275
|
+
font-weight: 600;
|
|
276
|
+
overflow: hidden;
|
|
277
|
+
text-overflow: ellipsis;
|
|
278
|
+
white-space: nowrap;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.mp-device-card-subtitle {
|
|
282
|
+
font-size: 0.8125rem;
|
|
283
|
+
color: var(--bs-secondary-color);
|
|
284
|
+
overflow: hidden;
|
|
285
|
+
text-overflow: ellipsis;
|
|
286
|
+
white-space: nowrap;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/* ── Device list ────────────────────────────────────────── */
|
|
290
|
+
|
|
291
|
+
.mp-device-list-search {
|
|
292
|
+
margin-bottom: 0.75rem;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.mp-device-list-items {
|
|
296
|
+
display: grid;
|
|
297
|
+
gap: 0.5rem;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.mp-device-card-skeleton {
|
|
301
|
+
cursor: default;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.mp-device-card-skeleton:hover {
|
|
305
|
+
transform: none;
|
|
306
|
+
box-shadow: none !important;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* ── Skeleton shimmer ───────────────────────────────────── */
|
|
310
|
+
|
|
311
|
+
.mp-skeleton {
|
|
312
|
+
display: block;
|
|
313
|
+
border-radius: 0.25rem;
|
|
314
|
+
background: linear-gradient(90deg, var(--mp-skeleton-base) 25%, var(--mp-skeleton-shine) 50%, var(--mp-skeleton-base) 75%);
|
|
315
|
+
background-size: 200% 100%;
|
|
316
|
+
animation: mp-shimmer 1.4s ease-in-out infinite;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.mp-skeleton-text {
|
|
320
|
+
height: 0.75rem;
|
|
321
|
+
width: 100%;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.mp-skeleton-text + .mp-skeleton-text {
|
|
325
|
+
margin-top: 0.5rem;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.mp-skeleton-circle {
|
|
329
|
+
flex: none;
|
|
330
|
+
width: 2rem;
|
|
331
|
+
height: 2rem;
|
|
332
|
+
border-radius: 50%;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.mp-skeleton-group {
|
|
336
|
+
display: flex;
|
|
337
|
+
align-items: center;
|
|
338
|
+
gap: 0.75rem;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.mp-skeleton-lines {
|
|
342
|
+
flex: 1;
|
|
343
|
+
min-width: 0;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
@keyframes mp-shimmer {
|
|
347
|
+
from { background-position: 200% 0; }
|
|
348
|
+
to { background-position: -200% 0; }
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/* RTL: shimmer travels the other way */
|
|
352
|
+
[dir="rtl"] .mp-skeleton {
|
|
353
|
+
animation-direction: reverse;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/* ── Log viewer ─────────────────────────────────────────── */
|
|
357
|
+
|
|
358
|
+
.mp-log {
|
|
359
|
+
position: relative;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.mp-log-body {
|
|
363
|
+
direction: ltr;
|
|
364
|
+
unicode-bidi: isolate;
|
|
365
|
+
max-height: var(--mp-log-height, 20rem);
|
|
366
|
+
overflow: auto;
|
|
367
|
+
padding: 0.5rem 0.75rem;
|
|
368
|
+
border: 1px solid var(--mp-border);
|
|
369
|
+
border-radius: var(--mp-radius);
|
|
370
|
+
background: var(--mp-surface);
|
|
371
|
+
font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
372
|
+
font-size: 0.8125rem;
|
|
373
|
+
line-height: 1.5;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.mp-log-body:focus-visible {
|
|
377
|
+
outline: 2px solid var(--mp-focus-ring);
|
|
198
378
|
outline-offset: 2px;
|
|
199
379
|
}
|
|
200
380
|
|
|
381
|
+
.mp-log-line {
|
|
382
|
+
min-height: 1.5em;
|
|
383
|
+
white-space: pre;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.mp-log-wrap .mp-log-line {
|
|
387
|
+
white-space: pre-wrap;
|
|
388
|
+
overflow-wrap: anywhere;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.mp-log-jump {
|
|
392
|
+
position: absolute;
|
|
393
|
+
inset-block-end: 0.75rem;
|
|
394
|
+
inset-inline-end: 1.25rem;
|
|
395
|
+
}
|
|
396
|
+
|
|
201
397
|
/* ── Settings surface card ──────────────────────────────── */
|
|
202
398
|
|
|
203
399
|
.mp-settings-card {
|
|
@@ -231,11 +427,11 @@
|
|
|
231
427
|
margin: 0 0 0.25rem;
|
|
232
428
|
}
|
|
233
429
|
|
|
430
|
+
/* A token instead of opacity: the old 0.7 opacity dropped it to 3.3:1. */
|
|
234
431
|
.mp-empty-state-hint {
|
|
235
432
|
font-size: 0.8125rem;
|
|
236
|
-
color: var(--
|
|
433
|
+
color: var(--mp-text-subtle);
|
|
237
434
|
margin: 0;
|
|
238
|
-
opacity: 0.7;
|
|
239
435
|
}
|
|
240
436
|
|
|
241
437
|
/* ── Loading state ──────────────────────────────────────── */
|
|
@@ -270,12 +466,19 @@
|
|
|
270
466
|
border-color: transparent;
|
|
271
467
|
}
|
|
272
468
|
|
|
273
|
-
.mp-tabs .nav-link.active
|
|
469
|
+
.mp-tabs .nav-link.active,
|
|
470
|
+
.mp-tabs .nav-link[aria-selected="true"] {
|
|
274
471
|
color: var(--mp-primary-text);
|
|
275
472
|
background: transparent;
|
|
276
473
|
border-bottom-color: var(--mp-primary);
|
|
277
474
|
}
|
|
278
475
|
|
|
476
|
+
.mp-tabs .nav-link:focus-visible {
|
|
477
|
+
outline: 2px solid var(--mp-focus-ring);
|
|
478
|
+
outline-offset: -2px;
|
|
479
|
+
box-shadow: none;
|
|
480
|
+
}
|
|
481
|
+
|
|
279
482
|
/* ── Metadata label ─────────────────────────────────────── */
|
|
280
483
|
|
|
281
484
|
.mp-label {
|
|
@@ -295,6 +498,26 @@
|
|
|
295
498
|
display: block;
|
|
296
499
|
}
|
|
297
500
|
|
|
501
|
+
/* View.show() moves focus to the view's heading (tabindex="-1"); a
|
|
502
|
+
programmatic focus target needs no ring. */
|
|
503
|
+
.mp-focus-target:focus:not(:focus-visible) {
|
|
504
|
+
outline: none;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/* ── Screen-reader only ─────────────────────────────────── */
|
|
508
|
+
|
|
509
|
+
.mp-sr-only {
|
|
510
|
+
position: absolute !important;
|
|
511
|
+
width: 1px !important;
|
|
512
|
+
height: 1px !important;
|
|
513
|
+
padding: 0 !important;
|
|
514
|
+
margin: -1px !important;
|
|
515
|
+
overflow: hidden !important;
|
|
516
|
+
clip: rect(0, 0, 0, 0) !important;
|
|
517
|
+
white-space: nowrap !important;
|
|
518
|
+
border: 0 !important;
|
|
519
|
+
}
|
|
520
|
+
|
|
298
521
|
/* ── Support footer ─────────────────────────────────────── */
|
|
299
522
|
|
|
300
523
|
.mp-footer {
|
|
@@ -335,10 +558,450 @@
|
|
|
335
558
|
user-select: none;
|
|
336
559
|
}
|
|
337
560
|
|
|
561
|
+
/* ── Forms ──────────────────────────────────────────────── */
|
|
562
|
+
|
|
563
|
+
/* Bootstrap's invalid colour (#dc3545) is 4.3:1 on light surfaces. */
|
|
564
|
+
.mp-field .invalid-feedback {
|
|
565
|
+
color: var(--bs-danger-text-emphasis, #b02a37);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.mp-required {
|
|
569
|
+
color: var(--bs-danger-text-emphasis, #b02a37);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
.mp-secret-input {
|
|
573
|
+
font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
.mp-copy-btn.is-copied {
|
|
577
|
+
color: var(--bs-success-text-emphasis, #0a3622);
|
|
578
|
+
border-color: var(--bs-success, #198754);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/* Sticky Save bar shown by MpKit.Form.track() while there are unsaved changes */
|
|
582
|
+
.mp-savebar {
|
|
583
|
+
position: sticky;
|
|
584
|
+
inset-block-end: 0;
|
|
585
|
+
z-index: 1020;
|
|
586
|
+
display: flex;
|
|
587
|
+
flex-wrap: wrap;
|
|
588
|
+
align-items: center;
|
|
589
|
+
justify-content: space-between;
|
|
590
|
+
gap: 0.5rem 1rem;
|
|
591
|
+
margin-top: 1rem;
|
|
592
|
+
padding: 0.625rem 0.875rem;
|
|
593
|
+
border: 1px solid var(--mp-border);
|
|
594
|
+
border-radius: var(--mp-radius);
|
|
595
|
+
background: var(--bs-body-bg, #fff);
|
|
596
|
+
box-shadow: 0 -0.25rem 1rem rgba(0, 0, 0, 0.08);
|
|
597
|
+
font-size: 0.875rem;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
.mp-savebar[hidden] {
|
|
601
|
+
display: none;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.mp-savebar-actions {
|
|
605
|
+
display: inline-flex;
|
|
606
|
+
gap: 0.5rem;
|
|
607
|
+
margin-inline-start: auto;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/* ── HomeKit setup code ─────────────────────────────────── */
|
|
611
|
+
|
|
612
|
+
.mp-pin {
|
|
613
|
+
display: inline-flex;
|
|
614
|
+
flex-wrap: wrap;
|
|
615
|
+
align-items: center;
|
|
616
|
+
gap: 1rem;
|
|
617
|
+
margin: 0;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
.mp-pin-label-box {
|
|
621
|
+
display: inline-flex;
|
|
622
|
+
flex-direction: column;
|
|
623
|
+
align-items: center;
|
|
624
|
+
gap: 0.25rem;
|
|
625
|
+
padding: 0.5rem 1rem 0.625rem;
|
|
626
|
+
border: 2px solid currentColor;
|
|
627
|
+
border-radius: 0.5rem;
|
|
628
|
+
color: var(--bs-body-color, #212529);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
.mp-pin-label {
|
|
632
|
+
font-size: 0.6875rem;
|
|
633
|
+
font-weight: 600;
|
|
634
|
+
letter-spacing: 0.04em;
|
|
635
|
+
text-transform: uppercase;
|
|
636
|
+
color: var(--bs-secondary-color, #6c757d);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
.mp-pin-code {
|
|
640
|
+
direction: ltr;
|
|
641
|
+
font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
642
|
+
font-size: 1.75rem;
|
|
643
|
+
font-weight: 600;
|
|
644
|
+
letter-spacing: 0.08em;
|
|
645
|
+
line-height: 1.1;
|
|
646
|
+
white-space: nowrap;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
.mp-pin-qr {
|
|
650
|
+
display: block;
|
|
651
|
+
width: var(--mp-pin-qr-size, 8rem);
|
|
652
|
+
height: var(--mp-pin-qr-size, 8rem);
|
|
653
|
+
padding: 0.375rem;
|
|
654
|
+
border-radius: 0.375rem;
|
|
655
|
+
background: #fff; /* QR codes need a light quiet zone, also in dark mode */
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
.mp-pin-qr-slot:empty {
|
|
659
|
+
display: none;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
.mp-pin-actions {
|
|
663
|
+
flex-basis: 100%;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/* ── Sign-in (OAuth / device code) card ─────────────────── */
|
|
667
|
+
|
|
668
|
+
.mp-auth-card {
|
|
669
|
+
border-color: var(--mp-border);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
.mp-auth-title {
|
|
673
|
+
margin: 0 0 0.5rem;
|
|
674
|
+
font-size: 1.0625rem;
|
|
675
|
+
font-weight: 600;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
.mp-auth-instructions {
|
|
679
|
+
color: var(--bs-secondary-color);
|
|
680
|
+
font-size: 0.875rem;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
.mp-auth-steps {
|
|
684
|
+
display: grid;
|
|
685
|
+
gap: 0.75rem;
|
|
686
|
+
margin: 0 0 1rem;
|
|
687
|
+
padding-inline-start: 1.25rem;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.mp-auth-steps > li {
|
|
691
|
+
padding-inline-start: 0.25rem;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
.mp-auth-step-text {
|
|
695
|
+
display: block;
|
|
696
|
+
margin-bottom: 0.375rem;
|
|
697
|
+
font-size: 0.875rem;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
.mp-auth-code-row {
|
|
701
|
+
display: inline-flex;
|
|
702
|
+
flex-wrap: wrap;
|
|
703
|
+
align-items: center;
|
|
704
|
+
gap: 0.5rem;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
.mp-auth-code {
|
|
708
|
+
direction: ltr;
|
|
709
|
+
padding: 0.25rem 0.75rem;
|
|
710
|
+
border: 1px dashed var(--mp-border);
|
|
711
|
+
border-radius: 0.375rem;
|
|
712
|
+
background: var(--mp-surface);
|
|
713
|
+
color: var(--bs-body-color, #212529);
|
|
714
|
+
font-size: 1.375rem;
|
|
715
|
+
font-weight: 600;
|
|
716
|
+
letter-spacing: 0.12em;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.mp-auth-status {
|
|
720
|
+
display: flex;
|
|
721
|
+
align-items: center;
|
|
722
|
+
gap: 0.5rem;
|
|
723
|
+
margin: 0;
|
|
724
|
+
font-size: 0.875rem;
|
|
725
|
+
color: var(--bs-secondary-color);
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.mp-auth-status-icon {
|
|
729
|
+
display: none;
|
|
730
|
+
flex: none;
|
|
731
|
+
width: 1rem;
|
|
732
|
+
height: 1rem;
|
|
733
|
+
border-radius: 50%;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
.mp-auth-card.is-polling .mp-auth-status-icon {
|
|
737
|
+
display: inline-block;
|
|
738
|
+
border: 2px solid currentColor;
|
|
739
|
+
border-inline-end-color: transparent;
|
|
740
|
+
animation: mp-spin 0.75s linear infinite;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
.mp-auth-card.is-success .mp-auth-status {
|
|
744
|
+
color: var(--bs-success-text-emphasis, #0a3622);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
.mp-auth-card.is-success .mp-auth-status-icon {
|
|
748
|
+
display: inline-block;
|
|
749
|
+
background: var(--bs-success, #198754);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
.mp-auth-card.is-error .mp-auth-status,
|
|
753
|
+
.mp-auth-card.is-expired .mp-auth-status {
|
|
754
|
+
color: var(--bs-danger-text-emphasis, #b02a37);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
.mp-auth-retry {
|
|
758
|
+
margin-top: 0.75rem;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
@keyframes mp-spin {
|
|
762
|
+
to { transform: rotate(360deg); }
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/* ── Steps (wizard progress) ────────────────────────────── */
|
|
766
|
+
|
|
767
|
+
.mp-steps {
|
|
768
|
+
display: flex;
|
|
769
|
+
gap: 0.5rem;
|
|
770
|
+
margin: 0 0 1.5rem;
|
|
771
|
+
padding: 0;
|
|
772
|
+
list-style: none;
|
|
773
|
+
counter-reset: none;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
.mp-step {
|
|
777
|
+
position: relative;
|
|
778
|
+
display: flex;
|
|
779
|
+
flex: 1 1 0;
|
|
780
|
+
flex-direction: column;
|
|
781
|
+
align-items: center;
|
|
782
|
+
gap: 0.375rem;
|
|
783
|
+
min-width: 0;
|
|
784
|
+
color: var(--bs-secondary-color);
|
|
785
|
+
font-size: 0.8125rem;
|
|
786
|
+
text-align: center;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/* Connector line to the previous step */
|
|
790
|
+
.mp-step + .mp-step::before {
|
|
791
|
+
content: '';
|
|
792
|
+
position: absolute;
|
|
793
|
+
inset-block-start: 0.875rem;
|
|
794
|
+
inset-inline-end: calc(50% + 1.125rem);
|
|
795
|
+
width: calc(100% - 2.25rem + 0.5rem);
|
|
796
|
+
height: 2px;
|
|
797
|
+
background: var(--mp-border);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
.mp-step.is-complete::before,
|
|
801
|
+
.mp-step.is-current::before {
|
|
802
|
+
background: var(--mp-primary);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.mp-step-marker {
|
|
806
|
+
display: inline-flex;
|
|
807
|
+
align-items: center;
|
|
808
|
+
justify-content: center;
|
|
809
|
+
width: 1.75rem;
|
|
810
|
+
height: 1.75rem;
|
|
811
|
+
border: 2px solid var(--mp-border);
|
|
812
|
+
border-radius: 50%;
|
|
813
|
+
background: var(--bs-body-bg, #fff);
|
|
814
|
+
font-weight: 600;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
.mp-step.is-current {
|
|
818
|
+
color: var(--mp-primary-text);
|
|
819
|
+
font-weight: 600;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
.mp-step.is-current .mp-step-marker {
|
|
823
|
+
border-color: var(--mp-primary);
|
|
824
|
+
color: var(--mp-primary-text);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
.mp-step.is-complete .mp-step-marker {
|
|
828
|
+
border-color: var(--mp-primary);
|
|
829
|
+
background: var(--mp-primary);
|
|
830
|
+
color: #fff;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
.mp-step-title {
|
|
834
|
+
max-width: 100%;
|
|
835
|
+
overflow-wrap: anywhere;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/* Narrow: keep markers, hide titles except the current one */
|
|
839
|
+
@media (max-width: 30rem) {
|
|
840
|
+
.mp-step:not(.is-current) .mp-step-title {
|
|
841
|
+
position: absolute;
|
|
842
|
+
width: 1px;
|
|
843
|
+
height: 1px;
|
|
844
|
+
overflow: hidden;
|
|
845
|
+
clip: rect(0, 0, 0, 0);
|
|
846
|
+
white-space: nowrap;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/* ── Toasts (fallback outside Homebridge) ───────────────── */
|
|
851
|
+
|
|
852
|
+
.mp-toast-container {
|
|
853
|
+
position: fixed;
|
|
854
|
+
inset-block-end: 1rem;
|
|
855
|
+
inset-inline-end: 1rem;
|
|
856
|
+
z-index: 1095;
|
|
857
|
+
display: flex;
|
|
858
|
+
flex-direction: column;
|
|
859
|
+
gap: 0.5rem;
|
|
860
|
+
width: min(22rem, calc(100vw - 2rem));
|
|
861
|
+
pointer-events: none;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.mp-toast {
|
|
865
|
+
display: flex;
|
|
866
|
+
align-items: flex-start;
|
|
867
|
+
gap: 0.625rem;
|
|
868
|
+
padding: 0.75rem 0.875rem;
|
|
869
|
+
border: 1px solid var(--bs-border-color, #dee2e6);
|
|
870
|
+
border-inline-start: 4px solid var(--mp-toast-accent, var(--mp-primary));
|
|
871
|
+
border-radius: var(--mp-radius);
|
|
872
|
+
background: var(--bs-body-bg, #fff);
|
|
873
|
+
color: var(--bs-body-color, #212529);
|
|
874
|
+
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
875
|
+
font-size: 0.875rem;
|
|
876
|
+
pointer-events: auto;
|
|
877
|
+
animation: mp-toast-in 0.2s ease-out;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
.mp-toast-success { --mp-toast-accent: var(--bs-success, #198754); }
|
|
881
|
+
.mp-toast-error { --mp-toast-accent: var(--bs-danger, #dc3545); }
|
|
882
|
+
.mp-toast-warning { --mp-toast-accent: var(--bs-warning, #ffc107); }
|
|
883
|
+
.mp-toast-info { --mp-toast-accent: var(--mp-primary); }
|
|
884
|
+
|
|
885
|
+
.mp-toast-icon {
|
|
886
|
+
display: inline-flex;
|
|
887
|
+
align-items: center;
|
|
888
|
+
justify-content: center;
|
|
889
|
+
flex: none;
|
|
890
|
+
width: 1.25rem;
|
|
891
|
+
height: 1.25rem;
|
|
892
|
+
border-radius: 50%;
|
|
893
|
+
background: var(--mp-toast-accent);
|
|
894
|
+
color: #fff;
|
|
895
|
+
font-size: 0.75rem;
|
|
896
|
+
font-weight: 700;
|
|
897
|
+
line-height: 1;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
.mp-toast-warning .mp-toast-icon {
|
|
901
|
+
color: #000;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
.mp-toast-body {
|
|
905
|
+
flex: 1;
|
|
906
|
+
min-width: 0;
|
|
907
|
+
overflow-wrap: anywhere;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.mp-toast-title {
|
|
911
|
+
margin: 0 0 0.125rem;
|
|
912
|
+
font-weight: 600;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
.mp-toast-message {
|
|
916
|
+
margin: 0;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
.mp-toast-close,
|
|
920
|
+
.mp-icon-button {
|
|
921
|
+
flex: none;
|
|
922
|
+
padding: 0 0.25rem;
|
|
923
|
+
border: 0;
|
|
924
|
+
border-radius: 0.25rem;
|
|
925
|
+
background: transparent;
|
|
926
|
+
color: var(--bs-secondary-color, #6c757d);
|
|
927
|
+
font-size: 1.25rem;
|
|
928
|
+
line-height: 1;
|
|
929
|
+
cursor: pointer;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
.mp-toast-close:hover {
|
|
933
|
+
color: var(--bs-body-color, #212529);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
.mp-toast-close:focus-visible,
|
|
937
|
+
.mp-icon-button:focus-visible {
|
|
938
|
+
outline: 2px solid var(--mp-focus-ring);
|
|
939
|
+
outline-offset: 1px;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
@keyframes mp-toast-in {
|
|
943
|
+
from { opacity: 0; transform: translateY(0.5rem); }
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
/* ── Confirm dialog ─────────────────────────────────────── */
|
|
947
|
+
|
|
948
|
+
.mp-dialog-backdrop {
|
|
949
|
+
position: fixed;
|
|
950
|
+
inset: 0;
|
|
951
|
+
z-index: 1100;
|
|
952
|
+
display: flex;
|
|
953
|
+
align-items: center;
|
|
954
|
+
justify-content: center;
|
|
955
|
+
padding: 1rem;
|
|
956
|
+
background: rgba(0, 0, 0, 0.5);
|
|
957
|
+
animation: mp-fade-in 0.15s ease-out;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
.mp-dialog {
|
|
961
|
+
width: min(28rem, 100%);
|
|
962
|
+
padding: 1.25rem;
|
|
963
|
+
border: 1px solid var(--bs-border-color, #dee2e6);
|
|
964
|
+
border-radius: var(--mp-radius);
|
|
965
|
+
background: var(--bs-body-bg, #fff);
|
|
966
|
+
color: var(--bs-body-color, #212529);
|
|
967
|
+
box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.3);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
.mp-dialog-title {
|
|
971
|
+
margin: 0 0 0.5rem;
|
|
972
|
+
font-size: 1.125rem;
|
|
973
|
+
font-weight: 600;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
.mp-dialog-message {
|
|
977
|
+
margin: 0;
|
|
978
|
+
color: var(--bs-secondary-color, #6c757d);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
.mp-dialog-actions {
|
|
982
|
+
display: flex;
|
|
983
|
+
flex-wrap: wrap;
|
|
984
|
+
justify-content: flex-end;
|
|
985
|
+
gap: 0.5rem;
|
|
986
|
+
margin-top: 1.25rem;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
.mp-dialog-open {
|
|
990
|
+
overflow: hidden;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
@keyframes mp-fade-in {
|
|
994
|
+
from { opacity: 0; }
|
|
995
|
+
}
|
|
996
|
+
|
|
338
997
|
/* ── Reduced motion ─────────────────────────────────────── */
|
|
339
998
|
|
|
340
999
|
@media (prefers-reduced-motion: reduce) {
|
|
341
|
-
.mp-
|
|
1000
|
+
.mp-skeleton,
|
|
1001
|
+
.mp-auth-card.is-polling .mp-auth-status-icon,
|
|
1002
|
+
.mp-status-checking,
|
|
1003
|
+
.mp-toast,
|
|
1004
|
+
.mp-dialog-backdrop {
|
|
342
1005
|
animation: none;
|
|
343
1006
|
}
|
|
344
1007
|
|
|
@@ -629,7 +1292,7 @@
|
|
|
629
1292
|
display: inline-block;
|
|
630
1293
|
width: 0.5em;
|
|
631
1294
|
height: 1.1em;
|
|
632
|
-
margin-
|
|
1295
|
+
margin-inline-start: 2px;
|
|
633
1296
|
vertical-align: text-bottom;
|
|
634
1297
|
border-radius: 1px;
|
|
635
1298
|
background: var(--mp-ai-text);
|
|
@@ -655,7 +1318,7 @@
|
|
|
655
1318
|
|
|
656
1319
|
.mp-ai-prose ul,
|
|
657
1320
|
.mp-ai-prose ol {
|
|
658
|
-
padding-
|
|
1321
|
+
padding-inline-start: 1.25rem;
|
|
659
1322
|
}
|
|
660
1323
|
|
|
661
1324
|
.mp-ai-prose code {
|
|
@@ -668,7 +1331,10 @@
|
|
|
668
1331
|
font-size: 0.85em;
|
|
669
1332
|
}
|
|
670
1333
|
|
|
1334
|
+
/* Code reads left to right even on an RTL page. */
|
|
671
1335
|
.mp-ai-prose pre {
|
|
1336
|
+
direction: ltr;
|
|
1337
|
+
unicode-bidi: isolate;
|
|
672
1338
|
padding: 0.625rem 0.75rem;
|
|
673
1339
|
overflow-x: auto;
|
|
674
1340
|
border-radius: 0.375rem;
|
|
@@ -739,14 +1405,14 @@
|
|
|
739
1405
|
}
|
|
740
1406
|
|
|
741
1407
|
.is-user > .mp-ai-chat-bubble {
|
|
742
|
-
border-
|
|
1408
|
+
border-end-end-radius: 0.25rem;
|
|
743
1409
|
background: var(--mp-primary, #4f46e5);
|
|
744
1410
|
color: #fff;
|
|
745
1411
|
}
|
|
746
1412
|
|
|
747
1413
|
.is-assistant > .mp-ai-chat-bubble {
|
|
748
1414
|
border: 1px solid var(--mp-border, rgba(0, 0, 0, 0.1));
|
|
749
|
-
border-
|
|
1415
|
+
border-end-start-radius: 0.25rem;
|
|
750
1416
|
background: var(--mp-surface, rgba(0, 0, 0, 0.02));
|
|
751
1417
|
}
|
|
752
1418
|
|
|
@@ -816,7 +1482,7 @@
|
|
|
816
1482
|
.mp-ai-diff-stats {
|
|
817
1483
|
flex: none;
|
|
818
1484
|
display: inline-flex;
|
|
819
|
-
margin-
|
|
1485
|
+
margin-inline-start: auto;
|
|
820
1486
|
gap: 0.5rem;
|
|
821
1487
|
font-family: var(--bs-font-monospace, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
|
|
822
1488
|
}
|
|
@@ -830,6 +1496,8 @@
|
|
|
830
1496
|
}
|
|
831
1497
|
|
|
832
1498
|
.mp-ai-diff-body {
|
|
1499
|
+
direction: ltr;
|
|
1500
|
+
unicode-bidi: isolate;
|
|
833
1501
|
max-height: 24rem;
|
|
834
1502
|
margin: 0;
|
|
835
1503
|
padding: 0.375rem 0;
|
|
@@ -842,7 +1510,7 @@
|
|
|
842
1510
|
.mp-ai-diff-line {
|
|
843
1511
|
display: block;
|
|
844
1512
|
min-width: max-content;
|
|
845
|
-
padding-
|
|
1513
|
+
padding-inline-end: 0.75rem;
|
|
846
1514
|
white-space: pre;
|
|
847
1515
|
}
|
|
848
1516
|
|
|
@@ -879,7 +1547,7 @@
|
|
|
879
1547
|
}
|
|
880
1548
|
|
|
881
1549
|
.mp-ai-diff-status {
|
|
882
|
-
margin-
|
|
1550
|
+
margin-inline-end: auto;
|
|
883
1551
|
color: var(--mp-ai-fg-muted);
|
|
884
1552
|
font-size: 0.8125rem;
|
|
885
1553
|
}
|