@ponchia/ui 0.6.0 → 0.6.3
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 +64 -4
- package/README.md +1 -1
- package/annotations/index.d.ts.map +1 -1
- package/annotations/index.js +36 -33
- package/behaviors/carousel.d.ts +28 -0
- package/behaviors/carousel.d.ts.map +1 -0
- package/behaviors/carousel.js +3 -0
- package/behaviors/combobox.d.ts +40 -0
- package/behaviors/combobox.d.ts.map +1 -0
- package/behaviors/combobox.js +71 -20
- package/behaviors/command.d.ts +41 -0
- package/behaviors/command.d.ts.map +1 -0
- package/behaviors/command.js +9 -0
- package/behaviors/connectors.d.ts +17 -0
- package/behaviors/connectors.d.ts.map +1 -0
- package/behaviors/connectors.js +3 -0
- package/behaviors/crosshair.d.ts +42 -0
- package/behaviors/crosshair.d.ts.map +1 -0
- package/behaviors/crosshair.js +19 -1
- package/behaviors/dialog.d.ts +20 -0
- package/behaviors/dialog.d.ts.map +1 -0
- package/behaviors/dialog.js +3 -0
- package/behaviors/disclosure.d.ts +10 -0
- package/behaviors/disclosure.d.ts.map +1 -0
- package/behaviors/disclosure.js +3 -0
- package/behaviors/dismissible.d.ts +10 -0
- package/behaviors/dismissible.d.ts.map +1 -0
- package/behaviors/dismissible.js +3 -0
- package/behaviors/forms.d.ts +27 -0
- package/behaviors/forms.d.ts.map +1 -0
- package/behaviors/forms.js +18 -5
- package/behaviors/glyph.d.ts +14 -0
- package/behaviors/glyph.d.ts.map +1 -0
- package/behaviors/glyph.js +24 -0
- package/behaviors/index.d.ts +31 -237
- package/behaviors/index.d.ts.map +1 -0
- package/behaviors/index.js +17 -0
- package/behaviors/inert.d.ts +20 -0
- package/behaviors/inert.d.ts.map +1 -0
- package/behaviors/inert.js +46 -0
- package/behaviors/internal.d.ts +25 -0
- package/behaviors/internal.d.ts.map +1 -0
- package/behaviors/internal.js +30 -1
- package/behaviors/legend.d.ts +35 -0
- package/behaviors/legend.d.ts.map +1 -0
- package/behaviors/legend.js +9 -0
- package/behaviors/menu.d.ts +16 -0
- package/behaviors/menu.d.ts.map +1 -0
- package/behaviors/menu.js +3 -0
- package/behaviors/modal.d.ts +41 -0
- package/behaviors/modal.d.ts.map +1 -0
- package/behaviors/modal.js +124 -0
- package/behaviors/popover.d.ts +28 -0
- package/behaviors/popover.d.ts.map +1 -0
- package/behaviors/popover.js +17 -17
- package/behaviors/spotlight.d.ts +17 -0
- package/behaviors/spotlight.d.ts.map +1 -0
- package/behaviors/spotlight.js +3 -0
- package/behaviors/table.d.ts +36 -0
- package/behaviors/table.d.ts.map +1 -0
- package/behaviors/table.js +48 -8
- package/behaviors/tabs.d.ts +20 -0
- package/behaviors/tabs.d.ts.map +1 -0
- package/behaviors/tabs.js +3 -0
- package/behaviors/theme.d.ts +54 -0
- package/behaviors/theme.d.ts.map +1 -0
- package/behaviors/theme.js +17 -0
- package/behaviors/toast.d.ts +49 -0
- package/behaviors/toast.d.ts.map +1 -0
- package/behaviors/toast.js +34 -2
- package/classes/classes.json +683 -13
- package/classes/index.d.ts +106 -2
- package/classes/index.js +249 -65
- package/connectors/index.d.ts +12 -0
- package/connectors/index.d.ts.map +1 -1
- package/connectors/index.js +23 -2
- package/css/app.css +26 -0
- package/css/bullet.css +108 -0
- package/css/code.css +98 -0
- package/css/content.css +15 -2
- package/css/crosshair.css +7 -7
- package/css/diff.css +153 -0
- package/css/disclosure.css +18 -4
- package/css/dots.css +37 -7
- package/css/feedback.css +39 -7
- package/css/forms.css +71 -3
- package/css/legend.css +5 -2
- package/css/motion.css +79 -14
- package/css/overlay.css +59 -2
- package/css/primitives.css +67 -8
- package/css/report.css +40 -0
- package/css/sidenote.css +67 -0
- package/css/spark.css +62 -0
- package/css/table.css +9 -2
- package/css/term.css +110 -0
- package/css/textref.css +63 -0
- package/css/toc.css +91 -0
- package/css/tokens.css +14 -1
- package/css/tree.css +134 -0
- package/dist/bronto.css +1 -1
- package/dist/css/analytical.css +1 -1
- package/dist/css/app.css +1 -1
- package/dist/css/bullet.css +1 -0
- package/dist/css/code.css +1 -0
- package/dist/css/content.css +1 -1
- package/dist/css/crosshair.css +1 -1
- package/dist/css/diff.css +1 -0
- package/dist/css/disclosure.css +1 -1
- package/dist/css/dots.css +1 -1
- package/dist/css/feedback.css +1 -1
- package/dist/css/forms.css +1 -1
- package/dist/css/legend.css +1 -1
- package/dist/css/motion.css +1 -1
- package/dist/css/overlay.css +1 -1
- package/dist/css/primitives.css +1 -1
- package/dist/css/report.css +1 -1
- package/dist/css/sidenote.css +1 -0
- package/dist/css/spark.css +1 -0
- package/dist/css/table.css +1 -1
- package/dist/css/term.css +1 -0
- package/dist/css/textref.css +1 -0
- package/dist/css/toc.css +1 -0
- package/dist/css/tokens.css +1 -1
- package/dist/css/tree.css +1 -0
- package/docs/annotations.md +39 -0
- package/docs/architecture.md +2 -3
- package/docs/bullet.md +78 -0
- package/docs/code.md +76 -0
- package/docs/d2.md +4 -3
- package/docs/diff.md +146 -0
- package/docs/legends.md +8 -4
- package/docs/mermaid.md +21 -4
- package/docs/reference.md +127 -8
- package/docs/reporting.md +35 -14
- package/docs/sidenote.md +64 -0
- package/docs/spark.md +78 -0
- package/docs/stability.md +1 -0
- package/docs/term.md +81 -0
- package/docs/textref.md +78 -0
- package/docs/theming.md +44 -5
- package/docs/toc.md +83 -0
- package/docs/tree.md +74 -0
- package/docs/usage.md +264 -23
- package/docs/vega.md +22 -3
- package/glyphs/glyphs.js +7 -1
- package/llms.txt +159 -13
- package/package.json +47 -7
- package/qwik/index.d.ts +4 -2
- package/qwik/index.d.ts.map +1 -1
- package/qwik/index.js +10 -0
- package/react/index.d.ts +4 -2
- package/react/index.d.ts.map +1 -1
- package/react/index.js +6 -0
- package/solid/index.d.ts +6 -2
- package/solid/index.d.ts.map +1 -1
- package/solid/index.js +6 -0
package/css/spark.css
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
spark — opt-in inline datawords (word-sized microcharts).
|
|
3
|
+
|
|
4
|
+
A trend-in-a-sentence for generated reports and dense tables — the inline
|
|
5
|
+
counterpart to the scalar `ui-delta` / `ui-num` / `ui-stat`. Pure CSS, no
|
|
6
|
+
measurement, SSR-static, print-survivable. Not imported by core.css.
|
|
7
|
+
|
|
8
|
+
Boundary: the HOST normalises each point to 0..1 and sets it as `--v` on a
|
|
9
|
+
`.ui-spark__bar`; Bronto only paints the geometry. It refuses raw values and
|
|
10
|
+
min/max/scale computation. A bare spark is opaque to assistive tech, so the
|
|
11
|
+
container MUST carry a host-written `role="img"` + `aria-label` text
|
|
12
|
+
equivalent (e.g. "weekly signups, trending up"). Colour is never the only
|
|
13
|
+
channel — pair it with that label.
|
|
14
|
+
========================================================================== */
|
|
15
|
+
|
|
16
|
+
.ui-spark {
|
|
17
|
+
align-items: flex-end;
|
|
18
|
+
block-size: 1em;
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
gap: 1px;
|
|
21
|
+
inline-size: max-content;
|
|
22
|
+
vertical-align: -0.15em;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.ui-spark__bar {
|
|
26
|
+
background: currentColor;
|
|
27
|
+
block-size: max(1px, calc(var(--v, 0) * 100%));
|
|
28
|
+
border-radius: 0.5px;
|
|
29
|
+
flex: 0 0 0.25em;
|
|
30
|
+
min-inline-size: 2px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* Emphasise / tone a single bar — the rationed accent or a status tone. The
|
|
34
|
+
meaning still has to be in the aria-label (WCAG 1.4.1). */
|
|
35
|
+
.ui-spark__bar--accent {
|
|
36
|
+
background: var(--accent);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.ui-spark__bar--pos {
|
|
40
|
+
background: var(--success);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.ui-spark__bar--neg {
|
|
44
|
+
background: var(--danger);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Forced colours would force the bar backgrounds to the system surface and the
|
|
48
|
+
chart would vanish — repaint the bars in the system text colour so the shape
|
|
49
|
+
survives (the tone distinction is carried by the required aria-label). */
|
|
50
|
+
@media (forced-colors: active) {
|
|
51
|
+
.ui-spark__bar {
|
|
52
|
+
background: CanvasText;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Print: the bars are currentColor fills the print economy would drop. */
|
|
57
|
+
@media print {
|
|
58
|
+
.ui-spark__bar {
|
|
59
|
+
-webkit-print-color-adjust: exact;
|
|
60
|
+
print-color-adjust: exact;
|
|
61
|
+
}
|
|
62
|
+
}
|
package/css/table.css
CHANGED
|
@@ -35,6 +35,11 @@
|
|
|
35
35
|
position: sticky;
|
|
36
36
|
text-transform: uppercase;
|
|
37
37
|
inset-block-start: 0;
|
|
38
|
+
|
|
39
|
+
/* Keep the sticky header above body cells — cheap insurance for the
|
|
40
|
+
sticky-header + pinned/positioned-column combo, where an un-z-indexed th
|
|
41
|
+
scrolls under a positioned cell. (audit C30.) */
|
|
42
|
+
z-index: 1;
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
.ui-table td {
|
|
@@ -154,8 +159,10 @@
|
|
|
154
159
|
padding: var(--space-sm) var(--space-md);
|
|
155
160
|
}
|
|
156
161
|
|
|
157
|
-
/* --- Loading state: set aria-busy + .ui-table--loading on the wrap
|
|
158
|
-
|
|
162
|
+
/* --- Loading state: set aria-busy + .ui-table-wrap--loading on the wrap. The
|
|
163
|
+
modifier is named for the element it goes ON (the wrap), not `.ui-table`, so
|
|
164
|
+
the BEM host matches the documented placement. (component audit C19.) --- */
|
|
165
|
+
.ui-table-wrap--loading {
|
|
159
166
|
opacity: 0.6;
|
|
160
167
|
pointer-events: none;
|
|
161
168
|
}
|
package/css/term.css
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
term — opt-in inline glossary term + definition, and an end-of-report glossary.
|
|
3
|
+
|
|
4
|
+
The accessible upgrade of the famously touch/keyboard-broken `abbr[title]`: a
|
|
5
|
+
dotted-underline term whose definition lives in real, reachable DOM via the
|
|
6
|
+
native `[popover]` + `popovertarget` pairing, plus a `ui-glossary` `<dl>` block
|
|
7
|
+
that collects every term at the end of a document. Jargon that explains itself
|
|
8
|
+
inline and gathers into a reference — dead-centre on the explanation pillar.
|
|
9
|
+
Pure CSS over native popover, no kernel. Not imported by core.css.
|
|
10
|
+
|
|
11
|
+
Boundary: the HOST owns the wiring. The term is a `<button class="ui-term"
|
|
12
|
+
popovertarget="…">`; the definition is `<div class="ui-def" popover id="…">`.
|
|
13
|
+
That native pairing gives keyboard + touch + light-dismiss for free — no JS.
|
|
14
|
+
The glossary is a plain `<dl>`; the printed document leans on it because
|
|
15
|
+
popovers don't print (see docs/term.md). Anchor positioning is a gated
|
|
16
|
+
enhancement; without it the definition opens centred in the top layer.
|
|
17
|
+
========================================================================== */
|
|
18
|
+
|
|
19
|
+
/* The inline term marker — a real <button> so it is keyboard- and touch-
|
|
20
|
+
reachable (the abbr[title] failure). Reset to inline text, keep a dotted
|
|
21
|
+
underline as the "has a definition" cue. */
|
|
22
|
+
.ui-term {
|
|
23
|
+
background: none;
|
|
24
|
+
border: 0;
|
|
25
|
+
color: inherit;
|
|
26
|
+
cursor: help;
|
|
27
|
+
font: inherit;
|
|
28
|
+
padding: 0;
|
|
29
|
+
text-decoration: underline;
|
|
30
|
+
text-decoration-color: var(--line-strong);
|
|
31
|
+
text-decoration-style: dotted;
|
|
32
|
+
text-underline-offset: 0.2em;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@media (hover: hover) {
|
|
36
|
+
.ui-term:hover {
|
|
37
|
+
text-decoration-color: var(--accent);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.ui-term:focus-visible {
|
|
42
|
+
outline: 2px solid var(--focus-ring);
|
|
43
|
+
outline-offset: 2px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* The definition — a native popover. Reset the UA popover chrome to the Bronto
|
|
47
|
+
raised-surface card. */
|
|
48
|
+
.ui-def {
|
|
49
|
+
background: var(--surface-raised);
|
|
50
|
+
border: 1px solid var(--line);
|
|
51
|
+
border-radius: var(--radius-md);
|
|
52
|
+
box-shadow: var(--shadow-raised);
|
|
53
|
+
color: var(--text);
|
|
54
|
+
font-family: var(--sans);
|
|
55
|
+
font-size: var(--text-sm);
|
|
56
|
+
line-height: 1.5;
|
|
57
|
+
margin: 0;
|
|
58
|
+
max-inline-size: 22rem;
|
|
59
|
+
padding: var(--space-sm) var(--space-md);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* Progressive enhancement: anchor the definition to its term where CSS anchor
|
|
63
|
+
positioning exists, so it opens beside the word and flips at the viewport
|
|
64
|
+
edge. The host sets the matching `anchor-name` on the term (see docs). Without
|
|
65
|
+
support the popover keeps its centred top-layer fallback. */
|
|
66
|
+
@supports (anchor-name: --x) {
|
|
67
|
+
.ui-def {
|
|
68
|
+
inset: auto;
|
|
69
|
+
margin-block-start: 0.4rem;
|
|
70
|
+
position-area: block-end span-inline-end;
|
|
71
|
+
position-try-fallbacks: flip-block, flip-inline;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* --- Glossary — the end-of-document <dl> the terms collect into. --- */
|
|
76
|
+
|
|
77
|
+
.ui-glossary {
|
|
78
|
+
border-block-start: 1px solid var(--line);
|
|
79
|
+
display: grid;
|
|
80
|
+
gap: var(--space-2xs) var(--space-md);
|
|
81
|
+
grid-template-columns: minmax(6rem, max-content) 1fr;
|
|
82
|
+
margin: 0;
|
|
83
|
+
padding-block-start: var(--space-md);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.ui-glossary__term {
|
|
87
|
+
color: var(--text);
|
|
88
|
+
font-family: var(--mono);
|
|
89
|
+
font-size: var(--text-xs);
|
|
90
|
+
font-weight: 600;
|
|
91
|
+
letter-spacing: var(--tracking-wide);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.ui-glossary__def {
|
|
95
|
+
color: var(--text-dim);
|
|
96
|
+
font-size: var(--text-sm);
|
|
97
|
+
margin: 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Narrow viewports: stack each term over its definition. */
|
|
101
|
+
@media (max-width: 32rem) {
|
|
102
|
+
.ui-glossary {
|
|
103
|
+
grid-template-columns: 1fr;
|
|
104
|
+
gap: 0.15rem var(--space-md);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.ui-glossary__def {
|
|
108
|
+
margin-block-end: var(--space-xs);
|
|
109
|
+
}
|
|
110
|
+
}
|
package/css/textref.css
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
textref — opt-in deep-link-to-the-cited-sentence provenance primitive.
|
|
3
|
+
|
|
4
|
+
A citation that jumps to the EXACT quoted text. The link's href is a URL
|
|
5
|
+
Text Fragment (`#…:~:text=`); the browser scrolls to the match and highlights
|
|
6
|
+
it for free, and Bronto owns the on-brand `::target-text` paint. The inline
|
|
7
|
+
counterpart to the static `ui-src` / `ui-citation` trust layer (sources.css),
|
|
8
|
+
which can label a source but not point inside it. Pure CSS + a host-built URL,
|
|
9
|
+
no kernel, SSR-static. Not imported by core.css.
|
|
10
|
+
|
|
11
|
+
Boundary: the HOST builds the fragment URL and sets it as the link's href.
|
|
12
|
+
The encoder is a three-line pure function (see docs/textref.md) — Bronto does
|
|
13
|
+
not ship runtime here, it owns the affordance class + the highlight paint.
|
|
14
|
+
`::target-text` is global by design: any text-fragment landing on the page
|
|
15
|
+
gets the brand highlight once this leaf is imported. On engines without Text
|
|
16
|
+
Fragments the link still navigates to the section; the highlight is additive.
|
|
17
|
+
========================================================================== */
|
|
18
|
+
|
|
19
|
+
.ui-textref {
|
|
20
|
+
--textref-highlight: var(--accent-soft);
|
|
21
|
+
|
|
22
|
+
color: var(--accent-text);
|
|
23
|
+
text-decoration: underline;
|
|
24
|
+
text-decoration-style: dotted;
|
|
25
|
+
text-underline-offset: 0.2em;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* A small leading caret signals "this jumps to the quoted text", distinct from
|
|
29
|
+
a plain external link. currentColor only — no raw paint. */
|
|
30
|
+
.ui-textref::before {
|
|
31
|
+
content: '\201F'; /* double high-reversed-9 quote — a quote-jump cue */
|
|
32
|
+
margin-inline-end: 0.15em;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@media (hover: hover) {
|
|
36
|
+
.ui-textref:hover {
|
|
37
|
+
text-decoration-style: solid;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.ui-textref:focus-visible {
|
|
42
|
+
outline: 2px solid var(--focus-ring);
|
|
43
|
+
outline-offset: 2px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* The browser-painted highlight on the matched fragment. Scoped to the page
|
|
47
|
+
the link lands on; the accent-soft wash is the same rationed-accent surface
|
|
48
|
+
the rest of the trust layer uses. `--textref-highlight` lets a host retune it
|
|
49
|
+
per-surface. */
|
|
50
|
+
::target-text {
|
|
51
|
+
background-color: var(--textref-highlight, var(--accent-soft));
|
|
52
|
+
color: var(--text);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Forced colours: the accent wash collapses to the system surface and the match
|
|
56
|
+
would be invisible — repaint with the system selection colours so the jump
|
|
57
|
+
target still reads. */
|
|
58
|
+
@media (forced-colors: active) {
|
|
59
|
+
::target-text {
|
|
60
|
+
background-color: Highlight;
|
|
61
|
+
color: HighlightText;
|
|
62
|
+
}
|
|
63
|
+
}
|
package/css/toc.css
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
toc — opt-in scrollspy table-of-contents rail for long reports.
|
|
3
|
+
|
|
4
|
+
A sticky contents list whose entry for the section currently in view is
|
|
5
|
+
highlighted, so a reader of a long generated report always knows where they
|
|
6
|
+
are. Long-document orientation, on the generated-reports pillar. Degrades to a
|
|
7
|
+
plain anchored list with zero JS. Not imported by core.css.
|
|
8
|
+
|
|
9
|
+
Boundary: the HOST owns the section IDs and the anchor list; Bronto owns the
|
|
10
|
+
rail's classes + the active treatment. The active state keys on the standard
|
|
11
|
+
`aria-current="true"` hook. CSS alone cannot know which section is in view, so
|
|
12
|
+
the host mirrors the in-view section onto its link's `aria-current` — either
|
|
13
|
+
statically (server-rendered "current page") or with a small IntersectionObserver
|
|
14
|
+
(~15 lines, copy-paste recipe in docs/toc.md). No Bronto kernel ships for it;
|
|
15
|
+
the rail is fully useful as a static sticky list without the observer.
|
|
16
|
+
========================================================================== */
|
|
17
|
+
|
|
18
|
+
.ui-toc {
|
|
19
|
+
--toc-top: var(--space-md);
|
|
20
|
+
|
|
21
|
+
align-self: start;
|
|
22
|
+
font-family: var(--mono);
|
|
23
|
+
font-size: var(--text-xs);
|
|
24
|
+
inset-block-start: var(--toc-top);
|
|
25
|
+
letter-spacing: var(--tracking-wide);
|
|
26
|
+
position: sticky;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* An optional eyebrow heading for the rail. */
|
|
30
|
+
.ui-toc__title {
|
|
31
|
+
color: var(--text-dim);
|
|
32
|
+
font-size: var(--text-2xs);
|
|
33
|
+
margin-block-end: var(--space-xs);
|
|
34
|
+
text-transform: uppercase;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.ui-toc__list {
|
|
38
|
+
display: grid;
|
|
39
|
+
gap: 1px;
|
|
40
|
+
list-style: none;
|
|
41
|
+
margin: 0;
|
|
42
|
+
padding: 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Nested lists indent for sub-sections. */
|
|
46
|
+
.ui-toc__list .ui-toc__list {
|
|
47
|
+
margin-inline-start: var(--space-sm);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.ui-toc__link {
|
|
51
|
+
border-inline-start: 2px solid var(--line);
|
|
52
|
+
color: var(--text-dim);
|
|
53
|
+
display: block;
|
|
54
|
+
padding: 0.3rem var(--space-sm);
|
|
55
|
+
text-decoration: none;
|
|
56
|
+
transition: color var(--duration-fast) var(--ease-standard);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* The section in view. Keys on `aria-current` (the framework rule every other
|
|
60
|
+
nav surface here uses) so a host that sets only aria-current still lights up. */
|
|
61
|
+
.ui-toc__link[aria-current]:not([aria-current='false']) {
|
|
62
|
+
border-inline-start-color: var(--accent);
|
|
63
|
+
color: var(--accent-text);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.ui-toc__link:focus-visible {
|
|
67
|
+
outline: 2px solid var(--focus-ring);
|
|
68
|
+
outline-offset: -2px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media (hover: hover) {
|
|
72
|
+
.ui-toc__link:hover:not([aria-current]:not([aria-current='false'])) {
|
|
73
|
+
color: var(--text);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* Forced colours: the accent border + text collapse to the system surface and
|
|
78
|
+
the active entry loses its only cue — re-assert with the system highlight. */
|
|
79
|
+
@media (forced-colors: active) {
|
|
80
|
+
.ui-toc__link[aria-current]:not([aria-current='false']) {
|
|
81
|
+
border-inline-start-color: Highlight;
|
|
82
|
+
color: Highlight;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Reduced motion: drop the colour transition. */
|
|
87
|
+
@media (prefers-reduced-motion: reduce) {
|
|
88
|
+
.ui-toc__link {
|
|
89
|
+
transition: none;
|
|
90
|
+
}
|
|
91
|
+
}
|
package/css/tokens.css
CHANGED
|
@@ -327,15 +327,28 @@
|
|
|
327
327
|
prints dark-on-white instead of light-grey text or a dark panel on white.
|
|
328
328
|
Lives here, in the exempt tier-definition file, because it is a token-value
|
|
329
329
|
override (ADR-0001), not component styling. CSS-only, like the presets above.
|
|
330
|
+
|
|
331
|
+
Selector is `:root:root:root` (specificity 0,3,0), not a bare `:root`: a media
|
|
332
|
+
query adds NO specificity, so a bare `:root` (0,1,0) loses the cascade to the
|
|
333
|
+
on-screen dark palette at `:root[data-theme='dark']` (0,2,0) and the OLED
|
|
334
|
+
surface at `:root[data-theme='dark'][data-surface='oled']` (0,3,0) — i.e. a
|
|
335
|
+
dark-mode user would print a near-black `.ui-card` on white paper, the exact
|
|
336
|
+
opposite of what this block promises. Tripling `:root` matches the OLED rule's
|
|
337
|
+
specificity and wins on source order (this block is last), so the remap also
|
|
338
|
+
beats the `prefers-color-scheme: dark` blocks. Neutralise the OLED-only dark
|
|
339
|
+
surfaces (--bg / --bg-elevated / --panel-strong) too, or they'd leak through.
|
|
330
340
|
-------------------------------------------------------------------------- */
|
|
331
341
|
@media print {
|
|
332
|
-
:root {
|
|
342
|
+
:root:root:root {
|
|
333
343
|
color-scheme: light;
|
|
334
344
|
|
|
335
345
|
--text: #111;
|
|
336
346
|
--text-soft: #2a2a2a;
|
|
337
347
|
--text-dim: #555;
|
|
348
|
+
--bg: #fff;
|
|
349
|
+
--bg-elevated: #fff;
|
|
338
350
|
--panel: #fff;
|
|
351
|
+
--panel-strong: #fff;
|
|
339
352
|
--panel-soft: #f7f7f7;
|
|
340
353
|
--line: #d9d9d9;
|
|
341
354
|
--line-strong: #b3b3b3;
|
package/css/tree.css
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
tree — opt-in hierarchy outline on nested native <details name> disclosures.
|
|
3
|
+
|
|
4
|
+
A depth-indented outline for hierarchies: file trees, report contents, nested
|
|
5
|
+
generated-content provenance, object graphs. Built on nested native
|
|
6
|
+
`<details>` (optionally `name` exclusive-accordion groups) so open/close,
|
|
7
|
+
keyboard toggling and animation come from the platform — this leaf is the
|
|
8
|
+
hierarchy LAYER (rails, indent, chevron), it does NOT reinvent the disclosure
|
|
9
|
+
grammar that `ui-accordion` already owns. Pure CSS, SSR-static. Not imported
|
|
10
|
+
by core.css.
|
|
11
|
+
|
|
12
|
+
Boundary: the HOST owns the nesting and the labels. A11y honesty — a native
|
|
13
|
+
`<details>` group is a disclosure group, NOT an ARIA `tree`; do not bolt on
|
|
14
|
+
`role="tree"`/`treeitem` without the roving-focus keyboard model it implies.
|
|
15
|
+
That kernel is intentionally NOT shipped here; it lands behind a real consumer
|
|
16
|
+
(see docs/tree.md). The visuals below work on the full browser floor with zero
|
|
17
|
+
JS.
|
|
18
|
+
========================================================================== */
|
|
19
|
+
|
|
20
|
+
.ui-tree {
|
|
21
|
+
color: var(--text);
|
|
22
|
+
font-family: var(--mono);
|
|
23
|
+
font-size: var(--text-sm);
|
|
24
|
+
line-height: 1.5;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* A branch is a <details>; a leaf is a plain row with no disclosure. Both are
|
|
28
|
+
rows in the outline. */
|
|
29
|
+
.ui-tree__branch,
|
|
30
|
+
.ui-tree__leaf {
|
|
31
|
+
display: block;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Nested rows indent and carry a hairline guide rail back to their parent. */
|
|
35
|
+
.ui-tree__branch .ui-tree__branch,
|
|
36
|
+
.ui-tree__branch .ui-tree__leaf {
|
|
37
|
+
border-inline-start: 1px solid var(--line);
|
|
38
|
+
margin-inline-start: 0.5rem;
|
|
39
|
+
padding-inline-start: var(--space-sm);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* The summary is the clickable branch row; reset the native marker, lay it out
|
|
43
|
+
as label + twist. */
|
|
44
|
+
.ui-tree__summary {
|
|
45
|
+
align-items: center;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
display: flex;
|
|
48
|
+
gap: var(--space-2xs);
|
|
49
|
+
list-style: none;
|
|
50
|
+
padding-block: var(--space-2xs);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.ui-tree__summary::-webkit-details-marker {
|
|
54
|
+
display: none;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* Twist chevron — a currentColor caret that rotates open. */
|
|
58
|
+
.ui-tree__summary::before {
|
|
59
|
+
block-size: 0.4rem;
|
|
60
|
+
border-block-end: 1.5px solid var(--text-dim);
|
|
61
|
+
border-inline-end: 1.5px solid var(--text-dim);
|
|
62
|
+
content: '';
|
|
63
|
+
flex: 0 0 auto;
|
|
64
|
+
inline-size: 0.4rem;
|
|
65
|
+
transform: rotate(-45deg);
|
|
66
|
+
transition: transform var(--duration-fast) var(--ease-spring);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.ui-tree__branch[open] > .ui-tree__summary::before {
|
|
70
|
+
border-color: var(--accent);
|
|
71
|
+
transform: rotate(45deg);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.ui-tree__branch[open] > .ui-tree__summary {
|
|
75
|
+
color: var(--accent-text);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* A leaf has no chevron; align its label with branch labels via a spacer the
|
|
79
|
+
width of the chevron + gap. */
|
|
80
|
+
.ui-tree__leaf {
|
|
81
|
+
align-items: center;
|
|
82
|
+
display: flex;
|
|
83
|
+
gap: var(--space-2xs);
|
|
84
|
+
padding-block: var(--space-2xs);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.ui-tree__leaf::before {
|
|
88
|
+
content: '';
|
|
89
|
+
flex: 0 0 auto;
|
|
90
|
+
inline-size: 0.4rem;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.ui-tree__label {
|
|
94
|
+
min-inline-size: 0;
|
|
95
|
+
overflow: hidden;
|
|
96
|
+
text-overflow: ellipsis;
|
|
97
|
+
white-space: nowrap;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Auto-height open/close, gated exactly like ui-accordion (Chrome 131+/Safari
|
|
101
|
+
18.4+; Firefox snaps). Strict progressive enhancement + reduced-motion. */
|
|
102
|
+
@supports selector(::details-content) {
|
|
103
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
104
|
+
.ui-tree {
|
|
105
|
+
interpolate-size: allow-keywords;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.ui-tree__branch::details-content {
|
|
109
|
+
block-size: 0;
|
|
110
|
+
overflow: hidden;
|
|
111
|
+
transition:
|
|
112
|
+
block-size var(--duration-base) var(--ease-out),
|
|
113
|
+
content-visibility var(--duration-base) allow-discrete;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.ui-tree__branch[open]::details-content {
|
|
117
|
+
block-size: auto;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* Reduced motion: no chevron spin. */
|
|
123
|
+
@media (prefers-reduced-motion: reduce) {
|
|
124
|
+
.ui-tree__summary::before {
|
|
125
|
+
transition: none;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* Forced colours: keep the open branch distinguishable when accent flattens. */
|
|
130
|
+
@media (forced-colors: active) {
|
|
131
|
+
.ui-tree__branch[open] > .ui-tree__summary::before {
|
|
132
|
+
border-color: Highlight;
|
|
133
|
+
}
|
|
134
|
+
}
|