barua-ui 0.12.1 → 0.13.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 +2 -1
- package/css/barua.css +1 -0
- package/css/base.css +22 -12
- package/css/components/actions.css +22 -17
- package/css/components/auth.css +1 -3
- package/css/components/content.css +78 -21
- package/css/components/feedback.css +2 -2
- package/css/components/forced-colors.css +60 -0
- package/css/components/forms.css +29 -6
- package/css/components/marketing.css +8 -5
- package/css/components/media.css +66 -2
- package/css/components/nav.css +63 -13
- package/css/components/overlays.css +22 -5
- package/css/components/productivity.css +52 -12
- package/css/components/specialized.css +28 -7
- package/css/tokens.css +61 -9
- package/css/utilities.css +16 -3
- package/dist/index.cjs +37 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +769 -184
- package/dist/index.d.ts +769 -184
- package/dist/index.js +40 -15
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/css/components/nav.css
CHANGED
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
display: flex;
|
|
35
35
|
align-items: center;
|
|
36
36
|
gap: var(--b-space-2);
|
|
37
|
+
/* A brand that yields width drops its mark to nothing and wraps its name
|
|
38
|
+
onto two lines. It is the one thing in the bar that never shrinks. */
|
|
39
|
+
flex: none;
|
|
40
|
+
white-space: nowrap;
|
|
37
41
|
font-weight: var(--b-weight-bold);
|
|
38
42
|
font-size: var(--b-text-callout);
|
|
39
43
|
color: var(--b-text);
|
|
@@ -43,8 +47,14 @@
|
|
|
43
47
|
display: flex;
|
|
44
48
|
align-items: center;
|
|
45
49
|
gap: var(--b-space-1);
|
|
50
|
+
/* The rail is what gives way when the bar is short of room; without this
|
|
51
|
+
it held its content width and pushed the trailing actions off the
|
|
52
|
+
screen, where a notifications button nobody can reach is not chrome. */
|
|
53
|
+
min-width: 0;
|
|
46
54
|
}
|
|
47
55
|
.b-topnav__link {
|
|
56
|
+
flex: none;
|
|
57
|
+
white-space: nowrap;
|
|
48
58
|
padding: var(--b-space-1) var(--b-space-3);
|
|
49
59
|
font-size: var(--b-text-subheadline);
|
|
50
60
|
font-weight: var(--b-weight-medium);
|
|
@@ -54,6 +64,35 @@
|
|
|
54
64
|
}
|
|
55
65
|
.b-topnav__link:hover { color: var(--b-text); background: var(--b-fill-tertiary); text-decoration: none; }
|
|
56
66
|
.b-topnav__link.is-active { color: var(--b-color-accent-text); background: var(--b-color-accent-soft); }
|
|
67
|
+
/* Trailing controls keep their size. A button that shrinks below its touch
|
|
68
|
+
target is not a button anyone can press. */
|
|
69
|
+
.b-topnav > :is(.b-btn, .b-avatar, .b-dropdown, .b-badge, .b-input-group, .b-status) { flex: none; }
|
|
70
|
+
/* The phone way in: a menu button that only exists on a phone, for a bar
|
|
71
|
+
whose destinations live in a .b-sidebar or .b-drawer rather than on it. */
|
|
72
|
+
.b-topnav__menu { display: none; }
|
|
73
|
+
@media (max-width: 767px) {
|
|
74
|
+
.b-topnav {
|
|
75
|
+
gap: var(--b-space-2);
|
|
76
|
+
padding-inline: var(--b-space-3);
|
|
77
|
+
flex-wrap: wrap;
|
|
78
|
+
row-gap: 0;
|
|
79
|
+
height: auto;
|
|
80
|
+
min-height: var(--b-topbar-h);
|
|
81
|
+
}
|
|
82
|
+
.b-topnav__menu { display: inline-flex; }
|
|
83
|
+
/* Inline destinations drop to a full-bleed strip under the brand row that
|
|
84
|
+
scrolls sideways, the way .b-tabs does. Nothing leaves the screen. */
|
|
85
|
+
.b-topnav__links {
|
|
86
|
+
order: 1;
|
|
87
|
+
flex: 1 0 100%;
|
|
88
|
+
margin-inline: calc(var(--b-space-3) * -1);
|
|
89
|
+
padding-inline: var(--b-space-3);
|
|
90
|
+
padding-block: var(--b-space-1) var(--b-space-2);
|
|
91
|
+
overflow-x: auto;
|
|
92
|
+
scrollbar-width: none;
|
|
93
|
+
}
|
|
94
|
+
.b-topnav__links::-webkit-scrollbar { display: none; }
|
|
95
|
+
}
|
|
57
96
|
|
|
58
97
|
/* ---- Sidebar ------------------------------------------------------------ */
|
|
59
98
|
.b-sidebar {
|
|
@@ -204,7 +243,8 @@
|
|
|
204
243
|
/* ---- Tab Bar (segmented, iOS-style) ------------------------------------- */
|
|
205
244
|
.b-segmented {
|
|
206
245
|
display: inline-flex;
|
|
207
|
-
padding:
|
|
246
|
+
padding: 1px;
|
|
247
|
+
border: 1px solid transparent;
|
|
208
248
|
gap: 2px;
|
|
209
249
|
background: var(--b-fill-tertiary);
|
|
210
250
|
border-radius: var(--b-radius-md);
|
|
@@ -218,12 +258,12 @@
|
|
|
218
258
|
box-shadow: var(--b-glass-ambient);
|
|
219
259
|
}
|
|
220
260
|
.b-segmented__item {
|
|
221
|
-
padding:
|
|
261
|
+
padding: var(--b-space-1) calc(var(--b-space-4) - 1px);
|
|
222
262
|
font-size: var(--b-text-footnote);
|
|
223
263
|
font-weight: var(--b-weight-medium);
|
|
224
264
|
color: var(--b-text-secondary);
|
|
225
265
|
background: none;
|
|
226
|
-
border:
|
|
266
|
+
border: 1px solid transparent;
|
|
227
267
|
border-radius: calc(var(--b-radius-md) - 2px);
|
|
228
268
|
cursor: pointer;
|
|
229
269
|
transition: background var(--b-duration-fast), color var(--b-duration-fast),
|
|
@@ -300,7 +340,7 @@
|
|
|
300
340
|
color: var(--b-text-quaternary);
|
|
301
341
|
padding-inline: var(--b-space-1);
|
|
302
342
|
}
|
|
303
|
-
.b-breadcrumbs a { color: var(--b-text-secondary); }
|
|
343
|
+
.b-breadcrumbs a:not(.b-btn) { color: var(--b-text-secondary); }
|
|
304
344
|
.b-breadcrumbs a:hover { color: var(--b-text); text-decoration: none; }
|
|
305
345
|
.b-breadcrumbs [aria-current="page"] { color: var(--b-text); font-weight: var(--b-weight-medium); }
|
|
306
346
|
|
|
@@ -332,7 +372,7 @@
|
|
|
332
372
|
.b-pagination__item:hover { background: var(--b-fill-tertiary); color: var(--b-text); text-decoration: none; }
|
|
333
373
|
.b-pagination__item.is-active, .b-pagination__item[aria-current="page"] {
|
|
334
374
|
color: var(--b-color-on-accent);
|
|
335
|
-
background: var(--b-color-accent);
|
|
375
|
+
background: var(--b-color-accent-fill);
|
|
336
376
|
}
|
|
337
377
|
.b-pagination__ellipsis { color: var(--b-text-quaternary); padding-inline: var(--b-space-1); }
|
|
338
378
|
|
|
@@ -381,7 +421,7 @@
|
|
|
381
421
|
.b-steps li.is-complete::before {
|
|
382
422
|
content: "✓";
|
|
383
423
|
color: var(--b-color-on-accent);
|
|
384
|
-
background: var(--b-color-accent);
|
|
424
|
+
background: var(--b-color-accent-fill);
|
|
385
425
|
}
|
|
386
426
|
.b-steps li.is-complete:not(:last-child)::after { background: var(--b-color-accent); }
|
|
387
427
|
.b-steps li.is-active { color: var(--b-text); font-weight: var(--b-weight-semibold); }
|
|
@@ -413,7 +453,7 @@
|
|
|
413
453
|
}
|
|
414
454
|
.b-menubar__item:hover, .b-menubar__item.is-active,
|
|
415
455
|
.b-menubar__item[aria-expanded="true"] {
|
|
416
|
-
background: var(--b-color-accent);
|
|
456
|
+
background: var(--b-color-accent-fill);
|
|
417
457
|
color: var(--b-color-on-accent);
|
|
418
458
|
}
|
|
419
459
|
|
|
@@ -468,7 +508,7 @@
|
|
|
468
508
|
white-space: nowrap;
|
|
469
509
|
}
|
|
470
510
|
.b-menu__item:hover, .b-menu__item.is-active {
|
|
471
|
-
background: var(--b-color-accent);
|
|
511
|
+
background: var(--b-color-accent-fill);
|
|
472
512
|
color: var(--b-color-on-accent);
|
|
473
513
|
text-decoration: none;
|
|
474
514
|
}
|
|
@@ -478,7 +518,7 @@
|
|
|
478
518
|
background: none;
|
|
479
519
|
cursor: not-allowed;
|
|
480
520
|
}
|
|
481
|
-
.b-menu__item--danger { color: var(--b-color-danger); }
|
|
521
|
+
.b-menu__item--danger { color: var(--b-color-danger-text); }
|
|
482
522
|
.b-menu__item--danger:hover { background: var(--b-color-danger); color: #fff; }
|
|
483
523
|
.b-menu__item svg { width: 1rem; height: 1rem; flex: none; opacity: 0.85; }
|
|
484
524
|
.b-menu__shortcut {
|
|
@@ -504,7 +544,7 @@
|
|
|
504
544
|
}
|
|
505
545
|
.b-menu__sub:hover > .b-menu,
|
|
506
546
|
.b-menu__sub:focus-within > .b-menu { display: block; }
|
|
507
|
-
.b-menu__sub:hover > .b-menu__item { background: var(--b-color-accent); color: var(--b-color-on-accent); }
|
|
547
|
+
.b-menu__sub:hover > .b-menu__item { background: var(--b-color-accent-fill); color: var(--b-color-on-accent); }
|
|
508
548
|
|
|
509
549
|
.b-menu__separator {
|
|
510
550
|
height: 1px;
|
|
@@ -546,7 +586,13 @@
|
|
|
546
586
|
}
|
|
547
587
|
|
|
548
588
|
/* ---- Command Menu / Command Palette ---------------------------------------- */
|
|
549
|
-
.b-cmdk
|
|
589
|
+
/* .b-cmdk is composed onto the platform dialog (<dialog class="b-modal b-cmdk">).
|
|
590
|
+
.b-modal sits later in the import order at equal specificity, so without
|
|
591
|
+
the composed form the palette rendered as a 448px opaque modal instead of
|
|
592
|
+
the 600px heavy glass documented here. The surface wins by specificity;
|
|
593
|
+
.b-modal still supplies the open/close transition and ::backdrop. */
|
|
594
|
+
.b-cmdk,
|
|
595
|
+
.b-modal.b-cmdk {
|
|
550
596
|
width: min(37.5rem, calc(100vw - 2rem));
|
|
551
597
|
padding: 0;
|
|
552
598
|
user-select: none;
|
|
@@ -577,7 +623,6 @@
|
|
|
577
623
|
outline: none;
|
|
578
624
|
user-select: text;
|
|
579
625
|
}
|
|
580
|
-
.b-cmdk__input:focus-visible { box-shadow: none; }
|
|
581
626
|
.b-cmdk__list {
|
|
582
627
|
max-height: min(20rem, 50vh);
|
|
583
628
|
overflow: auto;
|
|
@@ -638,6 +683,10 @@
|
|
|
638
683
|
max-height: none;
|
|
639
684
|
height: 100dvh;
|
|
640
685
|
overflow: hidden;
|
|
686
|
+
/* A column, so a long body scrolls inside the drawer instead of being
|
|
687
|
+
clipped by it: the header keeps its height and the body takes the rest. */
|
|
688
|
+
display: flex;
|
|
689
|
+
flex-direction: column;
|
|
641
690
|
transition: translate var(--b-duration-slow) var(--b-ease-spring),
|
|
642
691
|
display var(--b-duration-slow) allow-discrete,
|
|
643
692
|
overlay var(--b-duration-slow) allow-discrete;
|
|
@@ -676,6 +725,7 @@
|
|
|
676
725
|
backdrop-filter: blur(var(--b-blur-xs));
|
|
677
726
|
}
|
|
678
727
|
.b-drawer__header {
|
|
728
|
+
flex: none;
|
|
679
729
|
display: flex;
|
|
680
730
|
align-items: center;
|
|
681
731
|
justify-content: space-between;
|
|
@@ -683,5 +733,5 @@
|
|
|
683
733
|
border-bottom: 1px solid var(--b-separator);
|
|
684
734
|
font-weight: var(--b-weight-semibold);
|
|
685
735
|
}
|
|
686
|
-
.b-drawer__body { padding: var(--b-space-3); overflow-y: auto; }
|
|
736
|
+
.b-drawer__body { padding: var(--b-space-3); flex: 1 1 auto; min-height: 0; overflow-y: auto; }
|
|
687
737
|
}
|
|
@@ -98,7 +98,9 @@
|
|
|
98
98
|
.b-modal__close:hover { background: var(--b-fill-secondary); color: var(--b-text); }
|
|
99
99
|
|
|
100
100
|
/* ---- Alert Dialog (centered, compact) --------------------------------------- */
|
|
101
|
-
.b-
|
|
101
|
+
/* Composed onto .b-modal like .b-cmdk; explicit so a reorder cannot break it. */
|
|
102
|
+
.b-alert-dialog,
|
|
103
|
+
.b-modal.b-alert-dialog { width: min(18.5rem, calc(100vw - 2rem)); text-align: center; }
|
|
102
104
|
.b-alert-dialog .b-modal__body {
|
|
103
105
|
padding: var(--b-space-6) var(--b-space-5) var(--b-space-4);
|
|
104
106
|
}
|
|
@@ -124,7 +126,7 @@
|
|
|
124
126
|
}
|
|
125
127
|
.b-alert-dialog__actions button:hover { background: var(--b-fill-quaternary); }
|
|
126
128
|
.b-alert-dialog__actions button + button { border-top: 1px solid var(--b-separator); }
|
|
127
|
-
.b-alert-dialog__actions .is-destructive { color: var(--b-color-danger); }
|
|
129
|
+
.b-alert-dialog__actions .is-destructive { color: var(--b-color-danger-text); }
|
|
128
130
|
.b-alert-dialog__actions .is-primary { font-weight: var(--b-weight-semibold); }
|
|
129
131
|
.b-alert-dialog__actions--row { flex-direction: row; }
|
|
130
132
|
.b-alert-dialog__actions--row button { flex: 1; }
|
|
@@ -144,6 +146,12 @@
|
|
|
144
146
|
max-height: none;
|
|
145
147
|
height: 100dvh;
|
|
146
148
|
padding: 0;
|
|
149
|
+
/* A column: the header keeps its height and the body is the one pane that
|
|
150
|
+
scrolls. With the body at height:100% under a clipped dialog, a long
|
|
151
|
+
sheet simply could not be scrolled to its end. */
|
|
152
|
+
display: flex;
|
|
153
|
+
flex-direction: column;
|
|
154
|
+
overflow: hidden;
|
|
147
155
|
background: var(--b-elevated);
|
|
148
156
|
border: none;
|
|
149
157
|
border-inline-start: 1px solid var(--b-hairline);
|
|
@@ -176,13 +184,14 @@
|
|
|
176
184
|
transition: opacity var(--b-duration-normal) var(--b-ease-out);
|
|
177
185
|
}
|
|
178
186
|
.b-sheet__header {
|
|
187
|
+
flex: none;
|
|
179
188
|
display: flex;
|
|
180
189
|
align-items: center;
|
|
181
190
|
justify-content: space-between;
|
|
182
191
|
padding: var(--b-space-4) var(--b-space-5);
|
|
183
192
|
border-bottom: 1px solid var(--b-separator);
|
|
184
193
|
}
|
|
185
|
-
.b-sheet__body { padding: var(--b-space-5);
|
|
194
|
+
.b-sheet__body { padding: var(--b-space-5); flex: 1 1 auto; min-height: 0; overflow-y: auto; }
|
|
186
195
|
|
|
187
196
|
/* ---- Bottom Sheet --------------------------------------------------------------- */
|
|
188
197
|
.b-bottom-sheet {
|
|
@@ -194,6 +203,8 @@
|
|
|
194
203
|
width: min(34rem, 100vw);
|
|
195
204
|
max-height: 85dvh;
|
|
196
205
|
padding: 0;
|
|
206
|
+
display: flex;
|
|
207
|
+
flex-direction: column;
|
|
197
208
|
background: var(--b-material-thick-bg);
|
|
198
209
|
-webkit-backdrop-filter: var(--b-glass-heavy);
|
|
199
210
|
backdrop-filter: var(--b-glass-heavy);
|
|
@@ -223,6 +234,7 @@
|
|
|
223
234
|
}
|
|
224
235
|
.b-bottom-sheet::backdrop { background: var(--b-scrim); }
|
|
225
236
|
.b-bottom-sheet__grabber {
|
|
237
|
+
flex: none;
|
|
226
238
|
width: 2.25rem;
|
|
227
239
|
height: 0.3rem;
|
|
228
240
|
margin: var(--b-space-2) auto 0;
|
|
@@ -232,6 +244,8 @@
|
|
|
232
244
|
.b-bottom-sheet__body {
|
|
233
245
|
padding: var(--b-space-4) var(--b-space-5);
|
|
234
246
|
padding-bottom: max(var(--b-space-5), env(safe-area-inset-bottom));
|
|
247
|
+
flex: 1 1 auto;
|
|
248
|
+
min-height: 0;
|
|
235
249
|
overflow-y: auto;
|
|
236
250
|
}
|
|
237
251
|
|
|
@@ -292,7 +306,7 @@
|
|
|
292
306
|
}
|
|
293
307
|
.b-action-sheet__group button:first-child { border-top: none; }
|
|
294
308
|
.b-action-sheet__group button:hover { background: var(--b-fill-quaternary); }
|
|
295
|
-
.b-action-sheet__group button.is-destructive { color: var(--b-color-danger); }
|
|
309
|
+
.b-action-sheet__group button.is-destructive { color: var(--b-color-danger-text); }
|
|
296
310
|
.b-action-sheet__cancel {
|
|
297
311
|
margin-block-start: var(--b-space-2);
|
|
298
312
|
font-weight: var(--b-weight-semibold);
|
|
@@ -569,6 +583,8 @@
|
|
|
569
583
|
max-height: none;
|
|
570
584
|
margin: 0;
|
|
571
585
|
padding: 0;
|
|
586
|
+
display: flex;
|
|
587
|
+
flex-direction: column;
|
|
572
588
|
background: var(--b-bg);
|
|
573
589
|
border: none;
|
|
574
590
|
transition: opacity var(--b-duration-normal) var(--b-ease-out),
|
|
@@ -581,11 +597,12 @@
|
|
|
581
597
|
.b-fullscreen[open] { opacity: 0; }
|
|
582
598
|
}
|
|
583
599
|
.b-fullscreen__bar {
|
|
600
|
+
flex: none;
|
|
584
601
|
display: flex;
|
|
585
602
|
align-items: center;
|
|
586
603
|
justify-content: space-between;
|
|
587
604
|
padding: var(--b-space-3) var(--b-space-5);
|
|
588
605
|
border-bottom: 1px solid var(--b-separator);
|
|
589
606
|
}
|
|
590
|
-
.b-fullscreen__body { padding: var(--b-space-6);
|
|
607
|
+
.b-fullscreen__body { padding: var(--b-space-6); flex: 1 1 auto; min-height: 0; overflow: auto; }
|
|
591
608
|
}
|
|
@@ -25,21 +25,56 @@
|
|
|
25
25
|
.b-workspace__main {
|
|
26
26
|
grid-area: main;
|
|
27
27
|
overflow: auto;
|
|
28
|
-
padding: var(--b-space-6);
|
|
29
|
-
|
|
28
|
+
padding-block: var(--b-space-6);
|
|
29
|
+
/* The pane's margin, and the only one: 16px on a phone, 24px on a desktop.
|
|
30
|
+
A container inside it does not repeat it, the same rule as
|
|
31
|
+
.b-chapter > .b-container: at 390 the shell, the container and a tip each
|
|
32
|
+
took a gutter and the tip's words were left 200px. */
|
|
33
|
+
padding-inline: clamp(var(--b-space-4), 3vw, var(--b-space-6));
|
|
34
|
+
}
|
|
35
|
+
.b-workspace__main > .b-container { padding-inline: 0; }
|
|
30
36
|
.b-workspace > .b-inspector { grid-area: inspector; }
|
|
31
37
|
.b-workspace > .b-statusbar { grid-area: statusbar; }
|
|
38
|
+
/* On a phone the shell is one column: chrome above, the work surface below.
|
|
39
|
+
Side panes leave the grid and a .b-topnav__menu button opens the sidebar
|
|
40
|
+
as a .b-drawer instead. Without this every page had to remember
|
|
41
|
+
.b-hide-mobile itself, and the ones that forgot left main a 150px slit
|
|
42
|
+
beside a full-width sidebar. The screen still ends at the screen: the
|
|
43
|
+
shell keeps 100dvh and main stays the one scroller. */
|
|
44
|
+
@media (max-width: 767px) {
|
|
45
|
+
.b-workspace {
|
|
46
|
+
grid-template-columns: minmax(0, 1fr);
|
|
47
|
+
grid-template-areas:
|
|
48
|
+
"topbar"
|
|
49
|
+
"main"
|
|
50
|
+
"statusbar";
|
|
51
|
+
}
|
|
52
|
+
.b-workspace > .b-sidebar,
|
|
53
|
+
.b-workspace > .b-rail,
|
|
54
|
+
.b-workspace > .b-inspector { display: none; }
|
|
55
|
+
.b-workspace__main { padding-block: var(--b-space-4); }
|
|
56
|
+
}
|
|
32
57
|
|
|
33
58
|
/* Dashboard grid */
|
|
34
59
|
.b-dashboard {
|
|
35
60
|
display: grid;
|
|
36
61
|
gap: var(--b-space-4);
|
|
37
62
|
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
63
|
+
/* Spans answer to the grid's own width, not the viewport. Inside a
|
|
64
|
+
workspace the main pane is the viewport minus a rail, a sidebar and an
|
|
65
|
+
inspector, and a viewport query handed a 12-column layout to a 392px
|
|
66
|
+
pane at exactly the width the side panes were still docked. Same
|
|
67
|
+
sm/md ladder as .b-cq, so one set of breakpoints means one thing. */
|
|
68
|
+
container-type: inline-size;
|
|
38
69
|
}
|
|
39
70
|
.b-dashboard > * { grid-column: span 12; }
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
71
|
+
/* sm: anything up to a half becomes a half; wider spans stay full. */
|
|
72
|
+
@container (min-width: 24rem) {
|
|
73
|
+
.b-dashboard > :is(.b-span-2, .b-span-3, .b-span-4, .b-span-5, .b-span-6) { grid-column: span 6; }
|
|
74
|
+
}
|
|
75
|
+
/* md: the full scale. A twelve-column grid that only answers to five of the
|
|
76
|
+
twelve is a trap; b-span-7 silently did nothing. */
|
|
77
|
+
@container (min-width: 40rem) {
|
|
43
78
|
.b-dashboard > .b-span-2 { grid-column: span 2; }
|
|
44
79
|
.b-dashboard > .b-span-3 { grid-column: span 3; }
|
|
45
80
|
.b-dashboard > .b-span-4 { grid-column: span 4; }
|
|
@@ -153,12 +188,16 @@
|
|
|
153
188
|
color: var(--b-text-tertiary);
|
|
154
189
|
font-variant-numeric: tabular-nums;
|
|
155
190
|
}
|
|
156
|
-
.b-task-row__due.is-overdue { color: var(--b-color-danger); font-weight: var(--b-weight-medium); }
|
|
191
|
+
.b-task-row__due.is-overdue { color: var(--b-color-danger-text); font-weight: var(--b-weight-medium); }
|
|
157
192
|
|
|
158
193
|
/* ---- Calendar View (month grid) -------------------------------------------------- */
|
|
159
194
|
.b-calview {
|
|
160
195
|
display: grid;
|
|
161
|
-
|
|
196
|
+
/* A bare 1fr is minmax(auto, 1fr): a nowrap .b-event set the column's
|
|
197
|
+
minimum, the seven of them overflowed the clipped grid on a phone and
|
|
198
|
+
Friday to Sunday were simply gone. minmax(0, 1fr) lets a column be
|
|
199
|
+
narrower than its longest event, which then ellipsises as designed. */
|
|
200
|
+
grid-template-columns: repeat(7, minmax(0, 1fr));
|
|
162
201
|
background: var(--b-surface);
|
|
163
202
|
border: 1px solid var(--b-separator);
|
|
164
203
|
border-radius: var(--b-radius-xl);
|
|
@@ -176,6 +215,7 @@
|
|
|
176
215
|
border-bottom: 1px solid var(--b-separator);
|
|
177
216
|
}
|
|
178
217
|
.b-calview__cell {
|
|
218
|
+
min-width: 0;
|
|
179
219
|
min-height: 6rem;
|
|
180
220
|
padding: var(--b-space-1);
|
|
181
221
|
border-bottom: 1px solid var(--b-separator);
|
|
@@ -192,12 +232,12 @@
|
|
|
192
232
|
color: var(--b-text-secondary);
|
|
193
233
|
}
|
|
194
234
|
.b-calview__cell.is-today .b-calview__date {
|
|
195
|
-
background: var(--b-color-accent);
|
|
235
|
+
background: var(--b-color-accent-fill);
|
|
196
236
|
color: var(--b-color-on-accent);
|
|
197
237
|
font-weight: var(--b-weight-semibold);
|
|
198
238
|
}
|
|
199
239
|
.b-calview__cell.is-other-month { background: var(--b-fill-quaternary); }
|
|
200
|
-
.b-calview__cell.is-other-month .b-calview__date { color: var(--b-text-
|
|
240
|
+
.b-calview__cell.is-other-month .b-calview__date { color: var(--b-text-tertiary); }
|
|
201
241
|
.b-event {
|
|
202
242
|
display: block;
|
|
203
243
|
margin-block-start: 2px;
|
|
@@ -213,9 +253,9 @@
|
|
|
213
253
|
white-space: nowrap;
|
|
214
254
|
cursor: pointer;
|
|
215
255
|
}
|
|
216
|
-
.b-event--green { color: var(--b-color-success); background: var(--b-color-success-soft); border-color: var(--b-color-success); }
|
|
217
|
-
.b-event--orange { color:
|
|
218
|
-
.b-event--purple { color: var(--b-color-purple); background: var(--b-color-purple-soft); border-color: var(--b-color-purple); }
|
|
256
|
+
.b-event--green { color: var(--b-color-success-text); background: var(--b-color-success-soft); border-color: var(--b-color-success-text); }
|
|
257
|
+
.b-event--orange { color: var(--b-color-warning-text); background: var(--b-color-warning-soft); border-color: var(--b-color-warning); }
|
|
258
|
+
.b-event--purple { color: var(--b-color-purple-text); background: var(--b-color-purple-soft); border-color: var(--b-color-purple-text); }
|
|
219
259
|
|
|
220
260
|
/* ---- Gantt View --------------------------------------------------------------------- */
|
|
221
261
|
.b-gantt {
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
@layer components {
|
|
10
10
|
/* ---- Calendar ------------------------------------------------------------- */
|
|
11
11
|
.b-calendar {
|
|
12
|
+
/* The cell, named once, so a coarse pointer can grow it to the touch
|
|
13
|
+
target and the selected day stays a circle. */
|
|
14
|
+
--b-calendar-cell: 2.25rem;
|
|
12
15
|
display: inline-flex;
|
|
13
16
|
flex-direction: column;
|
|
14
17
|
gap: var(--b-space-2);
|
|
@@ -27,7 +30,7 @@
|
|
|
27
30
|
.b-calendar__month { font-weight: var(--b-weight-semibold); font-size: var(--b-text-subheadline); }
|
|
28
31
|
.b-calendar__grid {
|
|
29
32
|
display: grid;
|
|
30
|
-
grid-template-columns: repeat(7,
|
|
33
|
+
grid-template-columns: repeat(7, var(--b-calendar-cell));
|
|
31
34
|
gap: 2px;
|
|
32
35
|
}
|
|
33
36
|
.b-calendar__weekday {
|
|
@@ -42,7 +45,7 @@
|
|
|
42
45
|
.b-calendar__day {
|
|
43
46
|
display: grid;
|
|
44
47
|
place-items: center;
|
|
45
|
-
height:
|
|
48
|
+
height: var(--b-calendar-cell);
|
|
46
49
|
font-size: var(--b-text-footnote);
|
|
47
50
|
font-variant-numeric: tabular-nums;
|
|
48
51
|
color: var(--b-text);
|
|
@@ -53,14 +56,14 @@
|
|
|
53
56
|
transition: background var(--b-duration-fast);
|
|
54
57
|
}
|
|
55
58
|
.b-calendar__day:hover { background: var(--b-fill-tertiary); }
|
|
56
|
-
.b-calendar__day.is-muted { color: var(--b-text-
|
|
59
|
+
.b-calendar__day.is-muted { color: var(--b-text-tertiary); }
|
|
57
60
|
.b-calendar__day.is-today {
|
|
58
61
|
color: var(--b-color-accent-text);
|
|
59
62
|
font-weight: var(--b-weight-bold);
|
|
60
63
|
}
|
|
61
64
|
.b-calendar__day.is-selected {
|
|
62
65
|
color: var(--b-color-on-accent);
|
|
63
|
-
background: var(--b-color-accent);
|
|
66
|
+
background: var(--b-color-accent-fill);
|
|
64
67
|
font-weight: var(--b-weight-semibold);
|
|
65
68
|
}
|
|
66
69
|
.b-calendar__day.is-in-range { background: var(--b-color-accent-soft); border-radius: 0; }
|
|
@@ -270,7 +273,8 @@
|
|
|
270
273
|
}
|
|
271
274
|
.b-multiselect:focus-within {
|
|
272
275
|
border-color: var(--b-color-accent);
|
|
273
|
-
|
|
276
|
+
outline: var(--b-focus-ring);
|
|
277
|
+
outline-offset: var(--b-focus-ring-offset);
|
|
274
278
|
}
|
|
275
279
|
.b-multiselect input {
|
|
276
280
|
flex: 1;
|
|
@@ -281,7 +285,6 @@
|
|
|
281
285
|
font-size: var(--b-text-subheadline);
|
|
282
286
|
padding: var(--b-space-1);
|
|
283
287
|
}
|
|
284
|
-
.b-multiselect input:focus-visible { box-shadow: none; }
|
|
285
288
|
.b-multiselect .b-chip { height: 1.5rem; font-size: var(--b-text-caption); }
|
|
286
289
|
|
|
287
290
|
/* ---- File Browser / Folder Tree ------------------------------------------------------- */
|
|
@@ -324,7 +327,7 @@
|
|
|
324
327
|
.b-file-tile:hover { background: var(--b-fill-quaternary); }
|
|
325
328
|
.b-file-tile.is-selected { background: var(--b-color-accent-soft); }
|
|
326
329
|
.b-file-tile.is-selected .b-file-tile__name {
|
|
327
|
-
background: var(--b-color-accent);
|
|
330
|
+
background: var(--b-color-accent-fill);
|
|
328
331
|
color: var(--b-color-on-accent);
|
|
329
332
|
border-radius: var(--b-radius-xs);
|
|
330
333
|
padding-inline: 0.25rem;
|
|
@@ -363,5 +366,23 @@
|
|
|
363
366
|
white-space: nowrap;
|
|
364
367
|
}
|
|
365
368
|
.b-log--audit .b-log__entry { grid-template-columns: 7.5rem max-content 1fr max-content; }
|
|
369
|
+
/* Four fixed columns are a desktop shape: at 390 they overflowed the page
|
|
370
|
+
by 11px and were clipped inside a card with nothing to scroll. On a phone
|
|
371
|
+
the entry becomes three rows: who and when, what, and where from. */
|
|
372
|
+
@media (max-width: 40rem) {
|
|
373
|
+
.b-log--audit .b-log__entry {
|
|
374
|
+
grid-template-columns: max-content 1fr;
|
|
375
|
+
grid-template-areas:
|
|
376
|
+
"actor time"
|
|
377
|
+
"action action"
|
|
378
|
+
"ip ip";
|
|
379
|
+
row-gap: var(--b-space-1);
|
|
380
|
+
align-items: baseline;
|
|
381
|
+
}
|
|
382
|
+
.b-log--audit .b-log__actor { grid-area: actor; }
|
|
383
|
+
.b-log--audit .b-log__time { grid-area: time; justify-self: end; }
|
|
384
|
+
.b-log--audit .b-log__action { grid-area: action; }
|
|
385
|
+
.b-log--audit .b-log__ip { grid-area: ip; }
|
|
386
|
+
}
|
|
366
387
|
.b-log__ip { font-family: var(--b-font-mono); font-size: var(--b-text-caption); color: var(--b-text-tertiary); }
|
|
367
388
|
}
|
package/css/tokens.css
CHANGED
|
@@ -38,8 +38,16 @@
|
|
|
38
38
|
--b-color-accent-hover: light-dark(#0066e0, #3395ff);
|
|
39
39
|
--b-color-accent-active: light-dark(#0052b4, #66afff);
|
|
40
40
|
--b-color-accent-soft: light-dark(rgba(10, 122, 255, 0.12), rgba(10, 132, 255, 0.18));
|
|
41
|
-
--b-color-accent-text: light-dark(#
|
|
41
|
+
--b-color-accent-text: light-dark(#0064dc, #6cb2ff); /* 4.63:1 on the darkest light surface */
|
|
42
42
|
--b-color-on-accent: #ffffff;
|
|
43
|
+
/* Fills that carry --b-color-on-accent text. One step darker than the
|
|
44
|
+
accent so white holds 4.5:1 in both schemes (5.28 light, 4.76 dark;
|
|
45
|
+
the accent itself was 4.01 and 3.65). States go darker, never lighter:
|
|
46
|
+
a lighter fill under white ink loses contrast. The accent stays what it
|
|
47
|
+
was for strokes, rings, links and tinted text, where 3:1 is the bar. */
|
|
48
|
+
--b-color-accent-fill: light-dark(#0066e0, #0a6cf0);
|
|
49
|
+
--b-color-accent-fill-hover: light-dark(#0052b4, #0066e0);
|
|
50
|
+
--b-color-accent-fill-active: light-dark(#003d87, #0052b4);
|
|
43
51
|
|
|
44
52
|
/* ------------------------------------------------------------------ *
|
|
45
53
|
* Color — Apple system palette
|
|
@@ -57,6 +65,17 @@
|
|
|
57
65
|
--b-color-pink: light-dark(#ff2d55, #ff375f);
|
|
58
66
|
--b-color-brown: light-dark(#a2845e, #ac8e68);
|
|
59
67
|
|
|
68
|
+
/* Inks. The hues above are fills; text set in a hue needs a darker cousin
|
|
69
|
+
in light and a lighter one in dark, exactly as --b-color-accent-text
|
|
70
|
+
does for the blue. Green as text was 2.22:1, red 3.55:1, and the retints
|
|
71
|
+
handed the raw hue to every link. Each pair clears 4.5:1 on white, the
|
|
72
|
+
canvas, the elevated card and its own -soft fill. */
|
|
73
|
+
--b-color-green-text: light-dark(#1a7a38, #4cd964);
|
|
74
|
+
--b-color-teal-text: light-dark(#0a6f82, #5fd6ea);
|
|
75
|
+
--b-color-pink-text: light-dark(#d1173f, #ff6b85);
|
|
76
|
+
--b-color-indigo-text: light-dark(#4a48c4, #9d9bff);
|
|
77
|
+
--b-color-purple-text: light-dark(#8a2fb8, #d18cff);
|
|
78
|
+
|
|
60
79
|
--b-color-red-soft: light-dark(rgba(255, 59, 48, 0.12), rgba(255, 69, 58, 0.18));
|
|
61
80
|
--b-color-orange-soft: light-dark(rgba(255, 149, 0, 0.14), rgba(255, 159, 10, 0.18));
|
|
62
81
|
--b-color-yellow-soft: light-dark(rgba(255, 204, 0, 0.18), rgba(255, 214, 10, 0.18));
|
|
@@ -64,6 +83,7 @@
|
|
|
64
83
|
--b-color-indigo-soft: light-dark(rgba(88, 86, 214, 0.12), rgba(94, 92, 230, 0.18));
|
|
65
84
|
--b-color-purple-soft: light-dark(rgba(175, 82, 222, 0.12), rgba(191, 90, 242, 0.18));
|
|
66
85
|
--b-color-pink-soft: light-dark(rgba(255, 45, 85, 0.12), rgba(255, 55, 95, 0.18));
|
|
86
|
+
--b-color-teal-soft: light-dark(rgba(48, 176, 199, 0.14), rgba(64, 203, 224, 0.18));
|
|
67
87
|
|
|
68
88
|
/* Semantic aliases */
|
|
69
89
|
--b-color-success: var(--b-color-green);
|
|
@@ -74,6 +94,14 @@
|
|
|
74
94
|
--b-color-warning-soft: var(--b-color-orange-soft);
|
|
75
95
|
--b-color-danger-soft: var(--b-color-red-soft);
|
|
76
96
|
--b-color-info-soft: var(--b-color-accent-soft);
|
|
97
|
+
--b-color-success-text: var(--b-color-green-text);
|
|
98
|
+
--b-color-warning-text: light-dark(#8a4b00, #ffb340);
|
|
99
|
+
--b-color-danger-text: light-dark(#c9241a, #ff6961);
|
|
100
|
+
/* Solid status fills that carry white text: the raw hues were 2.22 (green)
|
|
101
|
+
and 3.55 (red) under white. */
|
|
102
|
+
--b-color-success-fill: light-dark(#1a8438, #1f8839);
|
|
103
|
+
--b-color-danger-fill: light-dark(#d70015, #e0261c);
|
|
104
|
+
--b-color-warning-fill: light-dark(#995900, #a66100);
|
|
77
105
|
|
|
78
106
|
/* ------------------------------------------------------------------ *
|
|
79
107
|
* Color — grays (Apple systemGray 1–6)
|
|
@@ -100,8 +128,13 @@
|
|
|
100
128
|
* Color — text (Apple label hierarchy)
|
|
101
129
|
* ------------------------------------------------------------------ */
|
|
102
130
|
--b-text: light-dark(rgba(10, 12, 20, 0.92), rgba(245, 246, 250, 0.96));
|
|
103
|
-
|
|
104
|
-
|
|
131
|
+
/* The ladder is tuned so tertiary still clears 4.5:1 on the darkest
|
|
132
|
+
light surface (#ececf2) and the darkest dark one (#303038): at 0.40 it
|
|
133
|
+
rendered at 2.53:1 and was the ink of every placeholder, timestamp and
|
|
134
|
+
hint in the system. Quaternary is for glyphs and watermarks, never for
|
|
135
|
+
something a person has to read. */
|
|
136
|
+
--b-text-secondary: light-dark(rgba(20, 24, 38, 0.74), rgba(235, 235, 245, 0.76));
|
|
137
|
+
--b-text-tertiary: light-dark(rgba(20, 24, 38, 0.62), rgba(235, 235, 245, 0.58));
|
|
105
138
|
--b-text-quaternary: light-dark(rgba(20, 24, 38, 0.22), rgba(235, 235, 245, 0.24));
|
|
106
139
|
|
|
107
140
|
/* ------------------------------------------------------------------ *
|
|
@@ -317,7 +350,17 @@
|
|
|
317
350
|
--b-control-h-lg: 2.75rem; /* 44 — default touch target */
|
|
318
351
|
--b-control-h-xl: 3.25rem; /* 52 */
|
|
319
352
|
--b-touch-target: 44px;
|
|
320
|
-
|
|
353
|
+
/* The focus ring is an outline, not a shadow. A shadow ring lost to every
|
|
354
|
+
component that owns box-shadow for its material, which is most of them,
|
|
355
|
+
so the primary button, the FAB and every button in liquid mode never
|
|
356
|
+
showed focus at all; an outline competes with nothing. It is opaque
|
|
357
|
+
(2px of the accent, 2px off the control) because the old 30% halo sat at
|
|
358
|
+
1.46:1 against the page, below the 3:1 an indicator needs. Components
|
|
359
|
+
flush inside a clipping container pull it inward with the offset. */
|
|
360
|
+
--b-focus-ring-color: var(--b-color-accent);
|
|
361
|
+
--b-focus-ring-width: 2px;
|
|
362
|
+
--b-focus-ring-offset: 2px;
|
|
363
|
+
--b-focus-ring: var(--b-focus-ring-width) solid var(--b-focus-ring-color);
|
|
321
364
|
--b-container-sm: 40rem;
|
|
322
365
|
--b-container-md: 48rem;
|
|
323
366
|
--b-container-lg: 64rem;
|
|
@@ -339,6 +382,11 @@
|
|
|
339
382
|
/* Explicit theme overrides — win over system preference */
|
|
340
383
|
[data-theme="light"] { color-scheme: light; }
|
|
341
384
|
[data-theme="dark"] { color-scheme: dark; }
|
|
385
|
+
/* Re-anchor the ink inside a themed subtree. `color` arrives from the page
|
|
386
|
+
around it as an already-resolved colour, so redeclaring the tokens flipped
|
|
387
|
+
the surfaces but not the words on them: a light island in a dark page kept
|
|
388
|
+
white text on its new white cards. Same rule the wallpaper scopes carry. */
|
|
389
|
+
[data-theme], .b-chapter--dark { color: var(--b-text); }
|
|
342
390
|
|
|
343
391
|
/* ---- Baked glass -------------------------------------------------------
|
|
344
392
|
*
|
|
@@ -427,11 +475,15 @@
|
|
|
427
475
|
}
|
|
428
476
|
|
|
429
477
|
/* Accent re-tinting: <html data-accent="purple"> etc. */
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
[data-accent="
|
|
478
|
+
/* Each retint hands the ink jobs to the -text pair and the fill jobs to a
|
|
479
|
+
darker mix, so a green accent does not put 2.2:1 links and 2.2:1 buttons
|
|
480
|
+
on the page. Teal and green are too light to carry the focus ring; they
|
|
481
|
+
supply a darker ring colour. */
|
|
482
|
+
[data-accent="indigo"] { --b-color-accent: var(--b-color-indigo); --b-color-accent-hover: color-mix(in srgb, var(--b-color-indigo) 85%, black); --b-color-accent-soft: var(--b-color-indigo-soft); --b-color-accent-text: var(--b-color-indigo-text); --b-color-accent-fill: var(--b-color-indigo); --b-color-accent-fill-hover: color-mix(in srgb, var(--b-color-indigo) 85%, black); --b-color-accent-fill-active: color-mix(in srgb, var(--b-color-indigo) 75%, black); }
|
|
483
|
+
[data-accent="purple"] { --b-color-accent: var(--b-color-purple); --b-color-accent-hover: color-mix(in srgb, var(--b-color-purple) 85%, black); --b-color-accent-soft: var(--b-color-purple-soft); --b-color-accent-text: var(--b-color-purple-text); --b-color-accent-fill: color-mix(in srgb, var(--b-color-purple) 85%, black); --b-color-accent-fill-hover: color-mix(in srgb, var(--b-color-purple) 75%, black); --b-color-accent-fill-active: color-mix(in srgb, var(--b-color-purple) 65%, black); }
|
|
484
|
+
[data-accent="pink"] { --b-color-accent: var(--b-color-pink); --b-color-accent-hover: color-mix(in srgb, var(--b-color-pink) 85%, black); --b-color-accent-soft: var(--b-color-pink-soft); --b-color-accent-text: var(--b-color-pink-text); --b-color-accent-fill: color-mix(in srgb, var(--b-color-pink) 85%, black); --b-color-accent-fill-hover: color-mix(in srgb, var(--b-color-pink) 75%, black); --b-color-accent-fill-active: color-mix(in srgb, var(--b-color-pink) 65%, black); }
|
|
485
|
+
[data-accent="teal"] { --b-color-accent: var(--b-color-teal); --b-color-accent-hover: color-mix(in srgb, var(--b-color-teal) 85%, black); --b-color-accent-soft: var(--b-color-teal-soft); --b-color-accent-text: var(--b-color-teal-text); --b-color-accent-fill: color-mix(in srgb, var(--b-color-teal) 60%, black); --b-color-accent-fill-hover: color-mix(in srgb, var(--b-color-teal) 50%, black); --b-color-accent-fill-active: color-mix(in srgb, var(--b-color-teal) 40%, black); --b-focus-ring-color: var(--b-color-accent-hover); }
|
|
486
|
+
[data-accent="green"] { --b-color-accent: var(--b-color-green); --b-color-accent-hover: color-mix(in srgb, var(--b-color-green) 85%, black); --b-color-accent-soft: var(--b-color-green-soft); --b-color-accent-text: var(--b-color-green-text); --b-color-accent-fill: color-mix(in srgb, var(--b-color-green) 65%, black); --b-color-accent-fill-hover: color-mix(in srgb, var(--b-color-green) 55%, black); --b-color-accent-fill-active: color-mix(in srgb, var(--b-color-green) 45%, black); --b-focus-ring-color: light-dark(color-mix(in srgb, var(--b-color-green) 70%, black), var(--b-color-green)); }
|
|
435
487
|
|
|
436
488
|
/* ---- Glass keyframes (Liquid Glass) ----------------------------------- */
|
|
437
489
|
/* Shimmer — light flash sweeping across on press/interaction */
|
package/css/utilities.css
CHANGED
|
@@ -442,9 +442,9 @@
|
|
|
442
442
|
.b-text-secondary { color: var(--b-text-secondary); }
|
|
443
443
|
.b-text-tertiary { color: var(--b-text-tertiary); }
|
|
444
444
|
.b-text-accent { color: var(--b-color-accent-text); }
|
|
445
|
-
.b-text-success { color: var(--b-color-success); }
|
|
446
|
-
.b-text-warning { color: var(--b-color-warning); }
|
|
447
|
-
.b-text-danger { color: var(--b-color-danger); }
|
|
445
|
+
.b-text-success { color: var(--b-color-success-text); }
|
|
446
|
+
.b-text-warning { color: var(--b-color-warning-text); }
|
|
447
|
+
.b-text-danger { color: var(--b-color-danger-text); }
|
|
448
448
|
.b-text-start { text-align: start; }
|
|
449
449
|
.b-text-center { text-align: center; }
|
|
450
450
|
.b-text-end { text-align: end; }
|
|
@@ -628,6 +628,19 @@
|
|
|
628
628
|
width: max(100%, var(--b-touch-target));
|
|
629
629
|
height: max(100%, var(--b-touch-target));
|
|
630
630
|
}
|
|
631
|
+
/* ---- Coarse pointer: the primitives meet the touch target ----------------
|
|
632
|
+
A segmented item at 30px, a chip at 30px, a menu row at 39px are fine
|
|
633
|
+
under a cursor and misses under a thumb. On a coarse pointer they grow to
|
|
634
|
+
the target without changing shape; a 44px calendar cell keeps its circle
|
|
635
|
+
and the dropdown that holds it may not push off a 390 screen. */
|
|
636
|
+
@media (pointer: coarse) {
|
|
637
|
+
:is(.b-segmented__item, .b-chip, .b-menu__item, .b-sidebar__item,
|
|
638
|
+
.b-topnav__link, .b-pagination__item) {
|
|
639
|
+
min-block-size: var(--b-touch-target);
|
|
640
|
+
}
|
|
641
|
+
.b-calendar { --b-calendar-cell: var(--b-touch-target); }
|
|
642
|
+
.b-dropdown > .b-menu { max-inline-size: calc(100vw - 2 * var(--b-space-4)); }
|
|
643
|
+
}
|
|
631
644
|
|
|
632
645
|
/* ---- Responsive visibility --------------------------------------------- */
|
|
633
646
|
@media (max-width: 767px) {
|