@aortl/admin-css 0.16.1 → 0.16.2
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/CHANGELOG.md +54 -0
- package/dist/admin.css +0 -4
- package/dist/admin.min.css +1 -1
- package/dist/admin.scoped.css +0 -4
- package/dist/admin.scoped.min.css +0 -1
- package/package.json +3 -2
- package/src/components/accordion.css +4 -13
- package/src/components/alert.css +6 -21
- package/src/components/app-shell.css +2 -4
- package/src/components/badge.css +1 -5
- package/src/components/breadcrumbs.css +2 -11
- package/src/components/button-group.css +7 -19
- package/src/components/button.css +7 -23
- package/src/components/card.css +10 -26
- package/src/components/chart.css +26 -83
- package/src/components/checkbox.css +3 -9
- package/src/components/code-block.css +2 -4
- package/src/components/container.css +3 -7
- package/src/components/dialog.css +11 -18
- package/src/components/field.css +3 -7
- package/src/components/footer.css +2 -3
- package/src/components/indicator.css +9 -28
- package/src/components/input-group.css +3 -6
- package/src/components/input.css +2 -5
- package/src/components/kbd.css +7 -13
- package/src/components/link.css +2 -8
- package/src/components/menu.css +9 -24
- package/src/components/navbar.css +3 -7
- package/src/components/pagination.css +1 -4
- package/src/components/progress.css +3 -7
- package/src/components/property-list.css +5 -14
- package/src/components/prose.css +6 -24
- package/src/components/radio.css +3 -7
- package/src/components/select.css +4 -11
- package/src/components/sidebar.css +2 -7
- package/src/components/spinner.css +1 -4
- package/src/components/stat-card.css +5 -16
- package/src/components/switch.css +3 -5
- package/src/components/table.css +15 -34
- package/src/components/tabs.css +14 -32
- package/src/components/textarea.css +3 -7
- package/src/components/tooltip.css +6 -16
- package/src/fonts.css +8 -28
- package/src/theme.css +32 -100
- package/src/utilities.css +11 -37
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
/*
|
|
3
|
-
|
|
4
|
-
`.app-shell-main` (which has no padding of its own). Width presets just
|
|
5
|
-
set `--container-max`; override the var per-instance to deviate. */
|
|
2
|
+
/* Goes inside the bare `.app-shell-main` (no padding of its own); override
|
|
3
|
+
`--container-max` per-instance to deviate from the presets. */
|
|
6
4
|
.container {
|
|
7
5
|
@apply flex flex-col gap-6 w-full mx-auto px-6 py-6;
|
|
8
6
|
max-width: var(--container-max, 90rem);
|
|
@@ -16,17 +14,15 @@
|
|
|
16
14
|
--container-max: 115rem;
|
|
17
15
|
}
|
|
18
16
|
|
|
19
|
-
/* Full-bleed: edge-to-edge within `main`, padding retained. */
|
|
20
17
|
.container-fluid {
|
|
21
18
|
--container-max: none;
|
|
22
19
|
}
|
|
23
20
|
|
|
24
|
-
/* Denser vertical rhythm + tighter block padding for packed screens. */
|
|
25
21
|
.container-compact {
|
|
26
22
|
@apply gap-4 py-4;
|
|
27
23
|
}
|
|
28
24
|
|
|
29
|
-
/*
|
|
25
|
+
/* Reuses the shell breakpoint. */
|
|
30
26
|
@media (max-width: 48rem) {
|
|
31
27
|
.container {
|
|
32
28
|
@apply px-4;
|
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
width: calc(100% - 2rem);
|
|
10
10
|
max-width: 32rem;
|
|
11
11
|
max-height: calc(100dvh - 2rem);
|
|
12
|
-
/* Long
|
|
13
|
-
|
|
14
|
-
additionally needs `min-width: 0` below since it's a flex item. */
|
|
12
|
+
/* Long tokens (filenames, IDs) break instead of pushing past max-width;
|
|
13
|
+
inherited by title + description. */
|
|
15
14
|
overflow-wrap: break-word;
|
|
16
15
|
opacity: 1;
|
|
17
16
|
transform: translateY(0) scale(1);
|
|
@@ -22,9 +21,8 @@
|
|
|
22
21
|
transform 150ms ease-out;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
/*
|
|
26
|
-
|
|
27
|
-
would render in-flow before showModal() was ever called. */
|
|
24
|
+
/* Gate on [open] — an unconditional flex would override the UA's
|
|
25
|
+
`dialog:not([open]) { display: none }` and render the dialog in-flow. */
|
|
28
26
|
.dialog[open] {
|
|
29
27
|
display: flex;
|
|
30
28
|
}
|
|
@@ -37,7 +35,6 @@
|
|
|
37
35
|
background 150ms ease-out;
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
/* Entry — animate from these values up to the open state. */
|
|
41
38
|
@starting-style {
|
|
42
39
|
.dialog[open] {
|
|
43
40
|
opacity: 0;
|
|
@@ -64,8 +61,7 @@
|
|
|
64
61
|
|
|
65
62
|
.dialog-title {
|
|
66
63
|
@apply flex-1 flex items-center gap-2 text-lg font-semibold leading-tight m-0;
|
|
67
|
-
/*
|
|
68
|
-
blowing the header past the dialog's max-width. */
|
|
64
|
+
/* Let a long title shrink and wrap rather than widen the header. */
|
|
69
65
|
min-width: 0;
|
|
70
66
|
}
|
|
71
67
|
|
|
@@ -73,16 +69,14 @@
|
|
|
73
69
|
@apply px-5 -mt-2 mb-3 text-sm text-text-muted;
|
|
74
70
|
}
|
|
75
71
|
|
|
76
|
-
/*
|
|
77
|
-
|
|
78
|
-
tall content scrolls here while the header/footer stay pinned. */
|
|
72
|
+
/* min-h-0 beats the flex default `min-height: auto` so tall content scrolls
|
|
73
|
+
here while the header/footer stay pinned. */
|
|
79
74
|
.dialog-body {
|
|
80
75
|
@apply flex-1 min-h-0 px-5 py-3 overflow-y-auto flex flex-col gap-3;
|
|
81
76
|
}
|
|
82
77
|
|
|
83
|
-
/*
|
|
84
|
-
|
|
85
|
-
`flex-1 min-h-0` still resolves and scrolls. */
|
|
78
|
+
/* In the form-dialog pattern the form is the sole flex child; it must carry
|
|
79
|
+
the flex column so the body's `flex-1 min-h-0` still scrolls. */
|
|
86
80
|
.dialog > form {
|
|
87
81
|
@apply flex flex-col min-h-0 flex-1;
|
|
88
82
|
}
|
|
@@ -92,9 +86,8 @@
|
|
|
92
86
|
px-5 py-3
|
|
93
87
|
border-t border-border
|
|
94
88
|
bg-surface-muted;
|
|
95
|
-
/*
|
|
96
|
-
|
|
97
|
-
handled by `overflow: hidden` on `.dialog`, which clipped popups. */
|
|
89
|
+
/* Keep the muted background inside the parent's rounded corners — don't
|
|
90
|
+
use `overflow: hidden` on `.dialog` for this; it clips popups. */
|
|
98
91
|
border-bottom-left-radius: inherit;
|
|
99
92
|
border-bottom-right-radius: inherit;
|
|
100
93
|
}
|
package/src/components/field.css
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
@layer components {
|
|
2
2
|
.field {
|
|
3
3
|
@apply flex flex-col gap-1.5;
|
|
4
|
-
/*
|
|
5
|
-
|
|
6
|
-
by all three. Mirrors `.alert`. */
|
|
4
|
+
/* Long operator-/validation-supplied tokens break instead of overflowing;
|
|
5
|
+
inherited by label, description, and error. */
|
|
7
6
|
overflow-wrap: break-word;
|
|
8
7
|
}
|
|
9
8
|
|
|
10
|
-
/* Horizontal layout — pairs a control (typically a switch) with its label
|
|
11
|
-
on one row. Use when the label belongs beside the control, not above it. */
|
|
12
9
|
.field-row {
|
|
13
10
|
@apply flex-row items-center gap-3;
|
|
14
11
|
}
|
|
@@ -34,8 +31,7 @@
|
|
|
34
31
|
@apply text-xs text-danger leading-relaxed;
|
|
35
32
|
}
|
|
36
33
|
|
|
37
|
-
/*
|
|
38
|
-
Base UI applies data-invalid on the Field root once validation fails. */
|
|
34
|
+
/* Base UI sets data-invalid on the Field root when validation fails. */
|
|
39
35
|
.field[data-invalid] .input,
|
|
40
36
|
.field[data-invalid] .textarea,
|
|
41
37
|
.field[data-invalid] .select,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
/*
|
|
3
|
-
|
|
4
|
-
when the consuming app overrides that variable at :root. */
|
|
2
|
+
/* The top stripe mirrors the navbar's bottom stripe; both brand-shift
|
|
3
|
+
together when the app overrides `--color-system-accent` at :root. */
|
|
5
4
|
.footer {
|
|
6
5
|
@apply flex flex-wrap items-center justify-between gap-3 px-4 py-3
|
|
7
6
|
bg-surface-muted text-text-muted
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
/*
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* buttons, status dots on avatars, "new" markers on tiles.
|
|
6
|
-
*
|
|
7
|
-
* Composition is driven by CSS custom properties so a horizontal modifier
|
|
8
|
-
* (start/center/end) and a vertical modifier (top/middle/bottom) compose
|
|
9
|
-
* naturally without needing a 3×3 grid of explicit selectors.
|
|
10
|
-
*/
|
|
2
|
+
/* Floats a small element (badge, dot) at a corner/edge of an anchor.
|
|
3
|
+
Placement is var-driven so a horizontal and a vertical modifier compose
|
|
4
|
+
without a 3×3 grid of selectors. */
|
|
11
5
|
.indicator {
|
|
12
6
|
@apply relative inline-flex w-max;
|
|
13
7
|
}
|
|
14
8
|
|
|
15
|
-
/*
|
|
16
|
-
|
|
17
|
-
* visual corner instead of the geometric box corner. Roughly half the
|
|
18
|
-
* anchor's border-radius. Override per-instance by passing the `offset`
|
|
19
|
-
* prop or setting `--indicator-offset` inline.
|
|
20
|
-
*/
|
|
9
|
+
/* Auto-offset (~half the anchor's border-radius) aligns with the visual
|
|
10
|
+
corner of rounded anchors; override `--indicator-offset` inline. */
|
|
21
11
|
.indicator:has(> .btn),
|
|
22
12
|
.indicator:has(> .input) {
|
|
23
13
|
--indicator-offset: 2px;
|
|
@@ -32,14 +22,9 @@
|
|
|
32
22
|
bottom: var(--indicator-bottom, auto);
|
|
33
23
|
inset-inline-start: var(--indicator-start, auto);
|
|
34
24
|
inset-inline-end: var(--indicator-end, 0);
|
|
35
|
-
/*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* (default 0). The pull direction is set per-modifier so it tracks the
|
|
39
|
-
* placement automatically — e.g. `top-end` pulls left-and-down. Useful
|
|
40
|
-
* for anchors with rounded corners: try `--indicator-offset: 4px` for a
|
|
41
|
-
* `rounded-md` button.
|
|
42
|
-
*/
|
|
25
|
+
/* The first translate half-overlaps the corner; the second pulls back
|
|
26
|
+
toward the anchor centre by `--indicator-offset`, direction set
|
|
27
|
+
per-modifier. */
|
|
43
28
|
transform: translate(var(--indicator-tx, 50%), var(--indicator-ty, -50%))
|
|
44
29
|
translate(
|
|
45
30
|
var(--indicator-offset-x, calc(-1 * var(--indicator-offset, 0px))),
|
|
@@ -87,11 +72,7 @@
|
|
|
87
72
|
--indicator-offset-y: calc(-1 * var(--indicator-offset, 0px));
|
|
88
73
|
}
|
|
89
74
|
|
|
90
|
-
/*
|
|
91
|
-
* Status dot — a small saturated circle for label-less presence/status.
|
|
92
|
-
* A `.badge` with no content is still a pill (fixed height, horizontal
|
|
93
|
-
* padding); a dot needs to actually be round.
|
|
94
|
-
*/
|
|
75
|
+
/* Status dot — an empty `.badge` is still a pill; a dot must be round. */
|
|
95
76
|
.indicator-dot {
|
|
96
77
|
@apply inline-block w-2 h-2 rounded-full bg-text-muted;
|
|
97
78
|
}
|
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
@apply inline-flex w-full;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
/*
|
|
7
|
-
|
|
8
|
-
after input.css. */
|
|
6
|
+
/* Equal-specificity override of `.input`'s radius — works only because
|
|
7
|
+
input-group.css imports after input.css. */
|
|
9
8
|
.input-group > * {
|
|
10
9
|
@apply rounded-none;
|
|
11
10
|
}
|
|
@@ -18,13 +17,11 @@
|
|
|
18
17
|
@apply rounded-r-lg;
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
/* Collapse the shared edge between adjacent children. */
|
|
22
20
|
.input-group > :not(:first-child) {
|
|
23
21
|
margin-left: -1px;
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
/*
|
|
27
|
-
can't be clipped by its neighbour's overlapping edge. */
|
|
24
|
+
/* Lift above the neighbour's overlapping edge so the focus ring isn't clipped. */
|
|
28
25
|
.input-group > :focus,
|
|
29
26
|
.input-group > :focus-within {
|
|
30
27
|
@apply relative z-10;
|
package/src/components/input.css
CHANGED
|
@@ -18,8 +18,7 @@
|
|
|
18
18
|
@apply border-danger hover:border-danger focus-visible:outline-danger;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
/* Status variants
|
|
22
|
-
warning's yellow accent (which fails AA as text) is fine here. */
|
|
21
|
+
/* Status variants tint border + outline only — warning's yellow fails AA as text. */
|
|
23
22
|
.input-info {
|
|
24
23
|
@apply border-info hover:border-info focus-visible:outline-info;
|
|
25
24
|
}
|
|
@@ -41,9 +40,7 @@
|
|
|
41
40
|
@apply text-base px-4 py-2.5;
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
/*
|
|
45
|
-
via the inherited `color-scheme` set on [data-theme]; we just tone the
|
|
46
|
-
glyph down at rest and brighten it on hover so it reads as interactive. */
|
|
43
|
+
/* Dark-mode glyph coloring comes free via the inherited `color-scheme`. */
|
|
47
44
|
.input::-webkit-calendar-picker-indicator {
|
|
48
45
|
@apply opacity-60 cursor-pointer hover:opacity-100;
|
|
49
46
|
}
|
package/src/components/kbd.css
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
/*
|
|
3
|
-
for multi-key chords. */
|
|
2
|
+
/* One key per chip; stack inside `.kbd-group` for chords. */
|
|
4
3
|
.kbd {
|
|
5
4
|
@apply inline-flex items-center justify-center
|
|
6
5
|
min-w-[1.25em] h-[1.4em] px-[0.35em]
|
|
@@ -10,15 +9,12 @@
|
|
|
10
9
|
whitespace-nowrap tabular-nums;
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
/*
|
|
14
|
-
selectors can target the whole binding as a unit. */
|
|
12
|
+
/* Always emitted by the React `<Kbd>` so selectors can target the whole binding. */
|
|
15
13
|
.kbd-group {
|
|
16
14
|
@apply inline-flex items-center gap-1 align-middle;
|
|
17
15
|
}
|
|
18
16
|
|
|
19
|
-
/*
|
|
20
|
-
colour from the host so it stays legible on any variant without
|
|
21
|
-
fighting the surrounding chrome. */
|
|
17
|
+
/* Derive the chip colour from the host so it stays legible on any variant. */
|
|
22
18
|
.btn .kbd,
|
|
23
19
|
.menu-item .kbd {
|
|
24
20
|
color: currentColor;
|
|
@@ -26,20 +22,18 @@
|
|
|
26
22
|
border-color: color-mix(in srgb, currentColor 22%, transparent);
|
|
27
23
|
}
|
|
28
24
|
|
|
29
|
-
/*
|
|
30
|
-
visual priority.
|
|
31
|
-
a single unit. */
|
|
25
|
+
/* Dim the cluster (not each chip, so the chord reads as one unit) to keep
|
|
26
|
+
the label's visual priority. */
|
|
32
27
|
.btn > .kbd-group {
|
|
33
28
|
opacity: 0.85;
|
|
34
29
|
}
|
|
35
30
|
|
|
36
|
-
/*
|
|
31
|
+
/* Matches native menu convention. */
|
|
37
32
|
.menu-item > .kbd-group {
|
|
38
33
|
margin-inline-start: auto;
|
|
39
34
|
}
|
|
40
35
|
|
|
41
|
-
/*
|
|
42
|
-
inline-trailing layout (chip sits next to the label). */
|
|
36
|
+
/* Vertical groups only — standalone buttons keep the chip beside the label. */
|
|
43
37
|
.btn-group-vertical > .btn > .kbd-group {
|
|
44
38
|
margin-inline-start: auto;
|
|
45
39
|
}
|
package/src/components/link.css
CHANGED
|
@@ -5,21 +5,15 @@
|
|
|
5
5
|
rounded-sm transition-colors duration-150
|
|
6
6
|
hover:text-link-hover
|
|
7
7
|
focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus;
|
|
8
|
-
/* Links are often the URL itself —
|
|
9
|
-
instead of overflowing a narrow row, sidebar, or table cell. The leading
|
|
10
|
-
icon stays `flex-shrink: 0` below. */
|
|
8
|
+
/* Links are often the URL itself — break instead of overflowing a narrow cell. */
|
|
11
9
|
overflow-wrap: break-word;
|
|
12
10
|
}
|
|
13
11
|
|
|
14
|
-
/* Keep a leading icon from squishing when the link text wraps. The trailing
|
|
15
|
-
external arrow is already `flex: none` below. */
|
|
16
12
|
.link > :is(i, svg) {
|
|
17
13
|
flex-shrink: 0;
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
/*
|
|
21
|
-
in both bundles — no JS, no icon-font dependency. The arrow is a masked box
|
|
22
|
-
tinted with `currentColor`, so it tracks the link's color (incl. hover). */
|
|
16
|
+
/* Trailing ↗ drawn in CSS — no JS or icon-font dependency in either bundle. */
|
|
23
17
|
.link-external {
|
|
24
18
|
--link-external-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17 7 7 17'/%3E%3Cpath d='M8 7h9v9'/%3E%3C/svg%3E");
|
|
25
19
|
}
|
package/src/components/menu.css
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
/* Native <details> drives open state — no JS
|
|
3
|
-
position: absolute child of the relative .menu root. */
|
|
2
|
+
/* Native <details> drives open state — no JS. */
|
|
4
3
|
.menu {
|
|
5
4
|
@apply relative inline-block;
|
|
6
5
|
}
|
|
7
6
|
|
|
8
|
-
/* Behaviour —
|
|
9
|
-
additional visual classes (e.g. `btn btn-primary` for a split button). */
|
|
7
|
+
/* Behaviour only — visual classes (e.g. `btn btn-primary`) may stack on top. */
|
|
10
8
|
.menu-trigger {
|
|
11
9
|
@apply inline-flex items-center gap-1.5
|
|
12
10
|
cursor-pointer select-none
|
|
@@ -19,17 +17,14 @@
|
|
|
19
17
|
display: none;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
/* Default appearance — bows out when `.btn`
|
|
23
|
-
button classes (bg, hover, padding, text colour) take over cleanly. */
|
|
20
|
+
/* Default appearance — bows out when `.btn` supplies its own. */
|
|
24
21
|
.menu-trigger:not(.btn) {
|
|
25
22
|
@apply px-2.5 py-1.5 rounded-md text-sm leading-none
|
|
26
23
|
text-text bg-transparent
|
|
27
24
|
hover:bg-surface-strong;
|
|
28
25
|
}
|
|
29
26
|
|
|
30
|
-
/*
|
|
31
|
-
muted text on the default trigger, content colour on a btn-primary
|
|
32
|
-
split button, etc. Sized in em so it scales with btn-sm / btn-lg. */
|
|
27
|
+
/* em-sized so the chevron scales with btn-sm / btn-lg. */
|
|
33
28
|
.menu-trigger::after {
|
|
34
29
|
content: "";
|
|
35
30
|
width: 0.5em;
|
|
@@ -41,8 +36,7 @@
|
|
|
41
36
|
flex-shrink: 0;
|
|
42
37
|
}
|
|
43
38
|
|
|
44
|
-
/*
|
|
45
|
-
their chevron instead of letting it sit at the start. */
|
|
39
|
+
/* A text-less trigger (split-button dropdown half) centers its chevron. */
|
|
46
40
|
.menu-trigger:empty {
|
|
47
41
|
@apply justify-center;
|
|
48
42
|
}
|
|
@@ -59,15 +53,9 @@
|
|
|
59
53
|
border border-border rounded-lg shadow-md;
|
|
60
54
|
}
|
|
61
55
|
|
|
62
|
-
/*
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
scroll-clipped surface like a card body. `anchor-scope` keeps each
|
|
66
|
-
menu's anchor lookups isolated so multiple menus on the page don't
|
|
67
|
-
cross-target, and `position-try-fallbacks` flips the popup above the
|
|
68
|
-
trigger when there isn't room below. Browsers without anchor
|
|
69
|
-
positioning (Firefox, as of early 2026) fall back to the absolute
|
|
70
|
-
rules above and clip as before. */
|
|
56
|
+
/* Anchor positioning makes the popup fixed so it escapes ancestor overflow
|
|
57
|
+
clipping (e.g. inside a <dialog>); browsers without it (Firefox, early
|
|
58
|
+
2026) fall back to the absolute rules above and clip as before. */
|
|
71
59
|
@supports (anchor-name: --x) {
|
|
72
60
|
.menu {
|
|
73
61
|
anchor-scope: --menu-trigger;
|
|
@@ -100,9 +88,7 @@
|
|
|
100
88
|
hover:bg-surface-muted
|
|
101
89
|
focus-visible:bg-surface-muted focus-visible:outline-none
|
|
102
90
|
disabled:opacity-50 disabled:cursor-not-allowed;
|
|
103
|
-
/* The popup has no max-width
|
|
104
|
-
break and shrink rather than grow the popup horizontally. Item icons stay
|
|
105
|
-
`flex-shrink: 0` below. */
|
|
91
|
+
/* The popup has no max-width — break long labels instead of growing it. */
|
|
106
92
|
overflow-wrap: break-word;
|
|
107
93
|
min-width: 0;
|
|
108
94
|
}
|
|
@@ -111,7 +97,6 @@
|
|
|
111
97
|
@apply opacity-50 cursor-not-allowed;
|
|
112
98
|
}
|
|
113
99
|
|
|
114
|
-
/* Don't let a constrained menu width squish a leading/trailing icon. */
|
|
115
100
|
.menu-trigger > :is(i, svg),
|
|
116
101
|
.menu-item > :is(i, svg) {
|
|
117
102
|
flex-shrink: 0;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
/*
|
|
3
|
-
`--color-system-accent`
|
|
4
|
-
that variable at :root (see also `.footer` and `.brand-tile`). */
|
|
2
|
+
/* The bottom stripe brand-shifts when the consuming app overrides
|
|
3
|
+
`--color-system-accent` at :root (see also `.footer` and `.brand-tile`). */
|
|
5
4
|
.navbar {
|
|
6
5
|
@apply flex items-center gap-3 px-4 h-12
|
|
7
6
|
bg-surface-muted text-text
|
|
@@ -31,19 +30,16 @@
|
|
|
31
30
|
@apply bg-primary-muted text-primary;
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
/* Keep brand/item icons at their intrinsic size in a crowded bar. */
|
|
35
33
|
.navbar-brand > :is(i, svg),
|
|
36
34
|
.navbar-item > :is(i, svg) {
|
|
37
35
|
flex-shrink: 0;
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
/* Right-aligned slot for actions: shop selector, user menu, etc. */
|
|
41
38
|
.navbar-actions {
|
|
42
39
|
@apply flex items-center gap-2 ml-auto;
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
/* Hamburger
|
|
46
|
-
with one element + two box-shadow strokes — no SVG needed. */
|
|
42
|
+
/* Hamburger — three lines from one element + two box-shadow strokes. */
|
|
47
43
|
.navbar-mobile-toggle {
|
|
48
44
|
@apply inline-flex items-center justify-center size-9 -ml-2
|
|
49
45
|
rounded-md text-text bg-transparent
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
@apply inline-flex;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
/* Square button shared by number, prev/next, and ellipsis containers. */
|
|
12
11
|
.page-link {
|
|
13
12
|
@apply inline-flex items-center justify-center
|
|
14
13
|
min-w-8 h-8 px-2
|
|
@@ -23,8 +22,7 @@
|
|
|
23
22
|
disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
/*
|
|
27
|
-
metaphor is consistent. */
|
|
25
|
+
/* Same surface as a sidebar's active item. */
|
|
28
26
|
.page-link.active,
|
|
29
27
|
.page-link[aria-current="page"] {
|
|
30
28
|
@apply bg-primary-muted text-primary border-primary-muted;
|
|
@@ -34,7 +32,6 @@
|
|
|
34
32
|
@apply opacity-50 cursor-not-allowed pointer-events-none;
|
|
35
33
|
}
|
|
36
34
|
|
|
37
|
-
/* Ellipsis — non-interactive placeholder between groups of pages. */
|
|
38
35
|
.page-ellipsis {
|
|
39
36
|
@apply inline-flex items-center justify-center
|
|
40
37
|
min-w-8 h-8 px-2
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
/*
|
|
3
|
-
platform default; the track is the element itself, the fill comes from
|
|
4
|
-
::-webkit-progress-value / ::-moz-progress-bar. */
|
|
2
|
+
/* The track is the element itself; the fill is the engine-specific value pseudo. */
|
|
5
3
|
.progress {
|
|
6
4
|
appearance: none;
|
|
7
5
|
-webkit-appearance: none;
|
|
@@ -32,7 +30,6 @@
|
|
|
32
30
|
transition: inline-size 200ms ease;
|
|
33
31
|
}
|
|
34
32
|
|
|
35
|
-
/* Sizes */
|
|
36
33
|
.progress-sm {
|
|
37
34
|
height: 0.25rem;
|
|
38
35
|
}
|
|
@@ -54,9 +51,8 @@
|
|
|
54
51
|
color: var(--color-danger);
|
|
55
52
|
}
|
|
56
53
|
|
|
57
|
-
/*
|
|
58
|
-
|
|
59
|
-
bar itself. */
|
|
54
|
+
/* When indeterminate, WebKit hides the value pseudo and Firefox draws it
|
|
55
|
+
full-width — blank both and animate a gradient on the bar itself. */
|
|
60
56
|
.progress:indeterminate {
|
|
61
57
|
background-image: linear-gradient(
|
|
62
58
|
90deg,
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
/* Outer section — owns striped, hide-if-empty modifiers. Title
|
|
3
|
-
(optional) and the items grid stack vertically. */
|
|
4
2
|
.property-list {
|
|
5
3
|
@apply flex flex-col text-sm text-text;
|
|
6
4
|
}
|
|
@@ -9,8 +7,7 @@
|
|
|
9
7
|
@apply text-sm font-bold text-text mb-2;
|
|
10
8
|
}
|
|
11
9
|
|
|
12
|
-
/* The <dl>
|
|
13
|
-
and <dd> into column 2. */
|
|
10
|
+
/* The <dl> is the grid; <dt>/<dd> auto-flow into the two tracks. */
|
|
14
11
|
.property-list-items {
|
|
15
12
|
display: grid;
|
|
16
13
|
grid-template-columns: max-content 1fr;
|
|
@@ -25,15 +22,12 @@
|
|
|
25
22
|
@apply text-text-muted;
|
|
26
23
|
}
|
|
27
24
|
|
|
28
|
-
/* `min-w-0` lets the
|
|
29
|
-
|
|
30
|
-
file paths) break instead of overflowing the column. */
|
|
25
|
+
/* `min-w-0` lets the track shrink below its content so long unbreakable
|
|
26
|
+
values break instead of overflowing the column. */
|
|
31
27
|
.property-list-value {
|
|
32
28
|
@apply gap-2 min-w-0 break-words;
|
|
33
29
|
}
|
|
34
30
|
|
|
35
|
-
/* Compact density — tighter rows for sidebar info blocks or very many
|
|
36
|
-
short attributes. */
|
|
37
31
|
.property-list-compact .property-list-title {
|
|
38
32
|
@apply mb-1;
|
|
39
33
|
}
|
|
@@ -43,7 +37,6 @@
|
|
|
43
37
|
@apply px-2 py-0.5 min-h-6;
|
|
44
38
|
}
|
|
45
39
|
|
|
46
|
-
/* Numeric — right-align + tabular-nums on the value. */
|
|
47
40
|
.property-list-value-numeric {
|
|
48
41
|
justify-content: flex-end;
|
|
49
42
|
@apply tabular-nums;
|
|
@@ -60,8 +53,7 @@
|
|
|
60
53
|
display: none;
|
|
61
54
|
}
|
|
62
55
|
|
|
63
|
-
/*
|
|
64
|
-
unless this specific value opts in. */
|
|
56
|
+
/* Always emitted by the Value; kept out of layout unless the value opts in. */
|
|
65
57
|
.property-list-copy {
|
|
66
58
|
@apply inline-flex items-center justify-center
|
|
67
59
|
ml-auto rounded
|
|
@@ -82,8 +74,7 @@
|
|
|
82
74
|
pointer-events: none;
|
|
83
75
|
}
|
|
84
76
|
|
|
85
|
-
/* Reveal on hover of
|
|
86
|
-
button focus, or while feedback is active. */
|
|
77
|
+
/* Reveal on hover of the row's label or value, on focus, or during feedback. */
|
|
87
78
|
.property-list-label:has(+ .property-list-value-copyable):hover
|
|
88
79
|
+ .property-list-value
|
|
89
80
|
.property-list-copy,
|
package/src/components/prose.css
CHANGED
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
@layer components {
|
|
2
|
-
/*
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* margins, list markers, and link styling from bare elements (so admin chrome
|
|
6
|
-
* stays neutral); `.prose` re-establishes them for its descendants only, using
|
|
7
|
-
* the semantic tokens so it follows dark mode and `--color-*` overrides.
|
|
8
|
-
*
|
|
9
|
-
* Descendant rules use `:where()` to stay at specificity 0 — a consumer's own
|
|
10
|
-
* `.prose a { … }` wins without `!important`.
|
|
11
|
-
*/
|
|
2
|
+
/* Styles rendered HTML (markdown, CMS bodies) that can't carry the system's
|
|
3
|
+
class names — re-establishes what the global reset strips. Descendant rules
|
|
4
|
+
use `:where()` so a consumer's own `.prose a { … }` wins without `!important`. */
|
|
12
5
|
.prose {
|
|
13
6
|
@apply text-sm leading-normal text-text;
|
|
14
|
-
/*
|
|
15
|
-
column. Inherited by p/li/a/td/blockquote; the deliberately-scrolling
|
|
16
|
-
`<pre>` keeps its own `white-space: pre` + `overflow-x: auto`. */
|
|
7
|
+
/* Break long URLs/tokens; the scrolling `<pre>` keeps its own `white-space: pre`. */
|
|
17
8
|
overflow-wrap: break-word;
|
|
18
9
|
}
|
|
19
10
|
|
|
20
|
-
/* Vertical rhythm — space between flow blocks, none at the container edges. */
|
|
21
11
|
.prose :where(p, ul, ol, blockquote, pre, table, figure) {
|
|
22
12
|
@apply my-3;
|
|
23
13
|
}
|
|
@@ -28,8 +18,7 @@
|
|
|
28
18
|
margin-bottom: 0;
|
|
29
19
|
}
|
|
30
20
|
|
|
31
|
-
/*
|
|
32
|
-
sectioning rhythm. The edge reset above zeroes a leading heading's margin. */
|
|
21
|
+
/* base.css already sizes h1–h3; add h4–h6 and the sectioning rhythm. */
|
|
33
22
|
.prose :where(h1, h2, h3, h4, h5, h6) {
|
|
34
23
|
@apply mt-6 mb-2 font-semibold leading-tight;
|
|
35
24
|
}
|
|
@@ -40,7 +29,6 @@
|
|
|
40
29
|
@apply text-xs uppercase tracking-wide text-text-muted;
|
|
41
30
|
}
|
|
42
31
|
|
|
43
|
-
/* Lists — restore the markers the reset removes. */
|
|
44
32
|
.prose :where(ul) {
|
|
45
33
|
@apply list-disc ps-5;
|
|
46
34
|
}
|
|
@@ -54,7 +42,6 @@
|
|
|
54
42
|
.prose :where(li) :where(p) {
|
|
55
43
|
@apply my-1;
|
|
56
44
|
}
|
|
57
|
-
/* Nested lists hug their parent item rather than taking full block spacing. */
|
|
58
45
|
.prose :where(li > ul, li > ol) {
|
|
59
46
|
@apply my-1;
|
|
60
47
|
}
|
|
@@ -66,15 +53,13 @@
|
|
|
66
53
|
focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus;
|
|
67
54
|
}
|
|
68
55
|
|
|
69
|
-
/* Inline code — a tinted chip. */
|
|
70
56
|
.prose :where(code) {
|
|
71
57
|
@apply rounded border border-border bg-code-surface px-1 py-0.5
|
|
72
58
|
font-mono text-code-text;
|
|
73
59
|
font-size: 0.85em;
|
|
74
60
|
}
|
|
75
61
|
|
|
76
|
-
/*
|
|
77
|
-
<code> so a highlighter's own tokens show through. */
|
|
62
|
+
/* Mirrors .code-block; nested <code> sheds the chip so highlighter tokens show. */
|
|
78
63
|
.prose :where(pre) {
|
|
79
64
|
@apply rounded-lg bg-code-surface p-3 font-mono text-sm text-code-text;
|
|
80
65
|
white-space: pre;
|
|
@@ -85,12 +70,10 @@
|
|
|
85
70
|
font-size: inherit;
|
|
86
71
|
}
|
|
87
72
|
|
|
88
|
-
/* Blockquote — a quiet inline-start rule. */
|
|
89
73
|
.prose :where(blockquote) {
|
|
90
74
|
@apply border-s-2 border-border-strong ps-3 text-text-muted;
|
|
91
75
|
}
|
|
92
76
|
|
|
93
|
-
/* Thematic break. */
|
|
94
77
|
.prose :where(hr) {
|
|
95
78
|
@apply my-6 border-0 border-t border-border;
|
|
96
79
|
}
|
|
@@ -106,7 +89,6 @@
|
|
|
106
89
|
@apply font-semibold text-text-muted;
|
|
107
90
|
}
|
|
108
91
|
|
|
109
|
-
/* Media + emphasis. */
|
|
110
92
|
.prose :where(img) {
|
|
111
93
|
@apply h-auto max-w-full rounded-md;
|
|
112
94
|
}
|