@ponchia/ui 0.4.1 → 0.6.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/CHANGELOG.md +552 -8
- package/MIGRATIONS.json +106 -0
- package/README.md +34 -8
- package/annotations/index.d.ts +402 -0
- package/annotations/index.d.ts.map +1 -0
- package/annotations/index.js +792 -0
- package/behaviors/carousel.js +198 -0
- package/behaviors/combobox.js +226 -0
- package/behaviors/command.js +190 -0
- package/behaviors/connectors.js +95 -0
- package/behaviors/crosshair.js +57 -0
- package/behaviors/dialog.js +74 -0
- package/behaviors/disclosure.js +26 -0
- package/behaviors/dismissible.js +25 -0
- package/behaviors/forms.js +186 -0
- package/behaviors/glyph.js +108 -0
- package/behaviors/index.d.ts +79 -0
- package/behaviors/index.js +18 -1409
- package/behaviors/internal.js +97 -0
- package/behaviors/legend.js +67 -0
- package/behaviors/menu.js +47 -0
- package/behaviors/popover.js +179 -0
- package/behaviors/spotlight.js +52 -0
- package/behaviors/table.js +136 -0
- package/behaviors/tabs.js +103 -0
- package/behaviors/theme.js +84 -0
- package/behaviors/toast.js +164 -0
- package/classes/classes.json +1857 -0
- package/classes/index.d.ts +306 -13
- package/classes/index.js +339 -12
- package/classes/vscode.css-custom-data.json +12 -0
- package/connectors/index.d.ts +191 -0
- package/connectors/index.d.ts.map +1 -0
- package/connectors/index.js +275 -0
- package/css/analytical.css +21 -0
- package/css/annotations.css +292 -0
- package/css/app.css +43 -13
- package/css/base.css +15 -10
- package/css/command.css +97 -0
- package/css/connectors.css +110 -0
- package/css/content.css +7 -1
- package/css/crosshair.css +100 -0
- package/css/dataviz.css +5 -1
- package/css/disclosure.css +38 -6
- package/css/dots.css +57 -0
- package/css/feedback.css +111 -2
- package/css/fonts.css +11 -7
- package/css/forms.css +42 -1
- package/css/generated.css +117 -0
- package/css/legend.css +272 -0
- package/css/marks.css +174 -0
- package/css/motion.css +24 -44
- package/css/navigation.css +7 -0
- package/css/overlay.css +31 -1
- package/css/primitives.css +109 -5
- package/css/report.css +39 -81
- package/css/selection.css +46 -0
- package/css/site.css +16 -2
- package/css/sources.css +221 -0
- package/css/spotlight.css +104 -0
- package/css/state.css +121 -0
- package/css/tokens.css +60 -37
- package/css/workbench.css +83 -0
- package/dist/bronto.css +1 -1
- package/dist/css/analytical.css +1 -0
- package/dist/css/annotations.css +1 -0
- package/dist/css/app.css +1 -1
- package/dist/css/base.css +1 -1
- package/dist/css/command.css +1 -0
- package/dist/css/connectors.css +1 -0
- package/dist/css/content.css +1 -1
- package/dist/css/crosshair.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/fonts.css +1 -1
- package/dist/css/forms.css +1 -1
- package/dist/css/generated.css +1 -0
- package/dist/css/legend.css +1 -0
- package/dist/css/marks.css +1 -0
- package/dist/css/motion.css +1 -1
- package/dist/css/navigation.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/selection.css +1 -0
- package/dist/css/site.css +1 -1
- package/dist/css/sources.css +1 -0
- package/dist/css/spotlight.css +1 -0
- package/dist/css/state.css +1 -0
- package/dist/css/tokens.css +1 -1
- package/dist/css/workbench.css +1 -0
- package/docs/adr/0003-theme-model.md +7 -4
- package/docs/annotations.md +425 -0
- package/docs/architecture.md +246 -0
- package/docs/command.md +95 -0
- package/docs/connectors.md +91 -0
- package/docs/contrast.md +116 -92
- package/docs/crosshair.md +63 -0
- package/docs/d2.md +195 -0
- package/docs/generated.md +91 -0
- package/docs/legends.md +184 -0
- package/docs/marks.md +93 -0
- package/docs/mermaid.md +152 -0
- package/docs/reference.md +385 -23
- package/docs/reporting.md +436 -63
- package/docs/selection.md +40 -0
- package/docs/sources.md +137 -0
- package/docs/spotlight.md +78 -0
- package/docs/stability.md +24 -2
- package/docs/state.md +85 -0
- package/docs/usage.md +123 -4
- package/docs/vega.md +225 -0
- package/docs/workbench.md +78 -0
- package/fonts/doto-400.woff2 +0 -0
- package/fonts/doto-500.woff2 +0 -0
- package/fonts/doto-600.woff2 +0 -0
- package/fonts/doto-700.woff2 +0 -0
- package/fonts/doto-800.woff2 +0 -0
- package/fonts/doto-900.woff2 +0 -0
- package/glyphs/glyphs.js +6 -4
- package/llms.txt +362 -14
- package/package.json +115 -12
- package/qwik/index.d.ts +42 -54
- package/qwik/index.d.ts.map +1 -0
- package/qwik/index.js +75 -3
- package/react/index.d.ts +39 -56
- package/react/index.d.ts.map +1 -0
- package/react/index.js +67 -3
- package/solid/index.d.ts +64 -56
- package/solid/index.d.ts.map +1 -0
- package/solid/index.js +70 -3
- package/tokens/d2.d.ts +38 -0
- package/tokens/d2.js +71 -0
- package/tokens/d2.json +43 -0
- package/tokens/index.d.ts +5 -5
- package/tokens/index.js +23 -5
- package/tokens/index.json +9 -0
- package/tokens/mermaid.d.ts +23 -0
- package/tokens/mermaid.js +181 -0
- package/tokens/mermaid.json +163 -0
- package/tokens/resolved.json +45 -1
- package/tokens/skins.js +3 -2
- package/tokens/tokens.dtcg.json +26 -0
- package/tokens/vega.d.ts +34 -0
- package/tokens/vega.js +155 -0
- package/tokens/vega.json +179 -0
- package/fonts/doto-400.ttf +0 -0
- package/fonts/doto-500.ttf +0 -0
- package/fonts/doto-600.ttf +0 -0
- package/fonts/doto-700.ttf +0 -0
- package/fonts/doto-800.ttf +0 -0
- package/fonts/doto-900.ttf +0 -0
package/docs/command.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Command palette
|
|
2
|
+
|
|
3
|
+
`@ponchia/ui/css/command.css` + `initCommand` are an opt-in **command palette**:
|
|
4
|
+
a filter input over a grouped listbox of commands with shortcut hints. Command
|
|
5
|
+
palettes turn a product from a page collection into a tool. Existing libraries
|
|
6
|
+
(cmdk, kbar) are good — Bronto owns the *design-system contract* (the shell,
|
|
7
|
+
shortcuts, groups, meta) and a small navigation behavior, not the action registry.
|
|
8
|
+
|
|
9
|
+
```css
|
|
10
|
+
@import '@ponchia/ui';
|
|
11
|
+
@import '@ponchia/ui/css/command.css';
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import { initCommand, initDialog } from '@ponchia/ui/behaviors';
|
|
16
|
+
initDialog(); // open/close the dialog the palette lives in
|
|
17
|
+
initCommand(); // filter + keyboard-navigate the list
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Bronto** filters and keyboard-navigates a DOM-authored list. **The host** owns
|
|
21
|
+
the action registry, permission checks, routing, async effects, and execution —
|
|
22
|
+
it listens for `bronto:command:select` and runs the command. There is **no global
|
|
23
|
+
Cmd/Ctrl+K**; you open the palette yourself (e.g. a `<dialog>` opened by a button
|
|
24
|
+
or your own shortcut). Pairs with the [`ui-shortcut`](./reference.md) hint. Not in
|
|
25
|
+
the core bundle.
|
|
26
|
+
|
|
27
|
+
## Markup
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<dialog class="ui-modal" id="cmdk" data-bronto-dialog-light aria-label="Command palette">
|
|
31
|
+
<div class="ui-command" data-bronto-command>
|
|
32
|
+
<input class="ui-command__input" aria-label="Command" placeholder="Type a command…" />
|
|
33
|
+
<ul class="ui-command__list">
|
|
34
|
+
<li class="ui-command__group">Navigation</li>
|
|
35
|
+
<li class="ui-command__item" data-value="dashboard">
|
|
36
|
+
<span>Go to dashboard</span>
|
|
37
|
+
<span class="ui-command__shortcut"><kbd class="ui-kbd">G</kbd> <kbd class="ui-kbd">D</kbd></span>
|
|
38
|
+
</li>
|
|
39
|
+
<li class="ui-command__group">Actions</li>
|
|
40
|
+
<li class="ui-command__item" data-value="invoice">
|
|
41
|
+
<span>New invoice</span>
|
|
42
|
+
<span class="ui-command__meta">Create</span>
|
|
43
|
+
</li>
|
|
44
|
+
</ul>
|
|
45
|
+
<p class="ui-command__empty" hidden>No commands</p>
|
|
46
|
+
</div>
|
|
47
|
+
</dialog>
|
|
48
|
+
<button class="ui-button" data-bronto-open="cmdk" type="button">Commands</button>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
| Class | Role |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `ui-command` | The palette shell (input + list + empty). |
|
|
54
|
+
| `ui-command__input` | The filter input (becomes `role="combobox"`). |
|
|
55
|
+
| `ui-command__list` | The listbox of commands. |
|
|
56
|
+
| `ui-command__group` | A non-selectable group label; auto-hidden when its items all filter out. |
|
|
57
|
+
| `ui-command__item` | A command row (`role="option"`); optional `data-value`. |
|
|
58
|
+
| `ui-command__shortcut` | A trailing shortcut hint (use `ui-kbd`). |
|
|
59
|
+
| `ui-command__meta` | Trailing secondary text (category, hint). |
|
|
60
|
+
| `ui-command__empty` | Shown when nothing matches. |
|
|
61
|
+
|
|
62
|
+
## Behavior & events
|
|
63
|
+
|
|
64
|
+
`initCommand()` owns ids, `role`/`aria-activedescendant`, a roving active item,
|
|
65
|
+
substring filtering, the full keyboard (Down/Up/Home/End/Enter/Escape), and
|
|
66
|
+
pointer select. It emits:
|
|
67
|
+
|
|
68
|
+
- `bronto:command:select` — `{ value, label }`. The host executes and closes.
|
|
69
|
+
- `bronto:command:close` — on Escape. The host closes the dialog.
|
|
70
|
+
|
|
71
|
+
> **Permission boundary:** `initCommand()` owns the `hidden` attribute on items
|
|
72
|
+
> (that is how it filters), so it will reveal any item you pre-hid the moment the
|
|
73
|
+
> query changes. To gate a command by permission, **omit it from the DOM** —
|
|
74
|
+
> don't render it hidden.
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
const dialog = document.getElementById('cmdk');
|
|
78
|
+
document.querySelector('[data-bronto-command]').addEventListener('bronto:command:select', (e) => {
|
|
79
|
+
run(e.detail.value); // YOUR action registry
|
|
80
|
+
dialog.close();
|
|
81
|
+
});
|
|
82
|
+
document.querySelector('[data-bronto-command]').addEventListener('bronto:command:close', () =>
|
|
83
|
+
dialog.close(),
|
|
84
|
+
);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Framework hook: `useCommand()` in `@ponchia/ui/react` · `/solid` · `/qwik`.
|
|
88
|
+
|
|
89
|
+
## Accessibility
|
|
90
|
+
|
|
91
|
+
- The input is a `combobox`, the list a `listbox`, items `option`s, with
|
|
92
|
+
`aria-activedescendant` tracking the active row — standard APG listbox semantics.
|
|
93
|
+
- Focus stays in the input while arrows move the active item; Enter selects it.
|
|
94
|
+
- Open the palette in a focus-trapping `<dialog>` (Bronto's `initDialog`) so focus
|
|
95
|
+
returns to the trigger on close.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Connectors (leader lines)
|
|
2
|
+
|
|
3
|
+
`@ponchia/ui/css/connectors.css` + `@ponchia/ui/connectors` draw a **leader line
|
|
4
|
+
between two DOM elements** — connect a note to a card, a card to a chart point,
|
|
5
|
+
or two related regions. This is the page-coordinate, element-to-element cousin
|
|
6
|
+
of the figure-coordinate [annotations](./annotations.md) layer.
|
|
7
|
+
|
|
8
|
+
```css
|
|
9
|
+
@import '@ponchia/ui';
|
|
10
|
+
@import '@ponchia/ui/css/connectors.css';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Bronto computes the **geometry** (pure functions) and styles the line; the
|
|
14
|
+
optional `initConnectors` behavior draws and keeps it in sync. It owns no
|
|
15
|
+
layout, no scales — just the path between two rects.
|
|
16
|
+
|
|
17
|
+
## Markup
|
|
18
|
+
|
|
19
|
+
An `.ui-connector` is an SVG that overlays a **positioned** container. Give it
|
|
20
|
+
the ids of the two elements to connect; `initConnectors` fills in the path.
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<div style="position: relative">
|
|
24
|
+
<div id="card-a" class="ui-card">…</div>
|
|
25
|
+
<div id="note-b" class="ui-card">…</div>
|
|
26
|
+
|
|
27
|
+
<svg
|
|
28
|
+
class="ui-connector ui-connector--accent"
|
|
29
|
+
data-bronto-connector
|
|
30
|
+
data-from="card-a"
|
|
31
|
+
data-to="note-b"
|
|
32
|
+
data-shape="elbow"
|
|
33
|
+
data-end="arrow"
|
|
34
|
+
aria-hidden="true"
|
|
35
|
+
></svg>
|
|
36
|
+
</div>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
import { initConnectors } from '@ponchia/ui/behaviors';
|
|
41
|
+
const stop = initConnectors(); // redraws on resize/scroll; returns a cleanup
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
A connector is decorative — mark it `aria-hidden="true"` and make sure the
|
|
45
|
+
relationship it depicts is also clear from the content/DOM order.
|
|
46
|
+
|
|
47
|
+
| Attribute | Values |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| `data-from` / `data-to` | ids of the elements to connect (required). |
|
|
50
|
+
| `data-shape` | `straight` (default), `elbow`, `curve`. |
|
|
51
|
+
| `data-from-side` / `data-to-side` | `top`/`right`/`bottom`/`left`/`center`. Omit a side to auto-pick it (set neither for fully automatic facing edges). |
|
|
52
|
+
| `data-end` | `arrow` (default), `dot`, `none`. |
|
|
53
|
+
|
|
54
|
+
Tones: `ui-connector--accent` / `--muted` / `--success` / `--warning` /
|
|
55
|
+
`--danger` / `--info` (monochrome by default). `ui-connector--dashed` for a
|
|
56
|
+
dashed line; `ui-connector--draw` strokes it in once (reduced-motion-safe).
|
|
57
|
+
`ui.connector({ tone, dashed, motion })` builds the class string.
|
|
58
|
+
|
|
59
|
+
## Geometry helpers (no DOM)
|
|
60
|
+
|
|
61
|
+
For SSR, canvas, or your own renderer, the pure helpers return SVG strings /
|
|
62
|
+
coordinates and never touch the DOM:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
import { connectRects, arrowHead } from '@ponchia/ui/connectors';
|
|
66
|
+
|
|
67
|
+
const { d, to, angle } = connectRects({
|
|
68
|
+
fromRect: { x: 0, y: 0, width: 80, height: 32 },
|
|
69
|
+
toRect: { x: 220, y: 120, width: 80, height: 32 },
|
|
70
|
+
shape: 'curve',
|
|
71
|
+
});
|
|
72
|
+
const head = arrowHead(to, angle); // place at the endpoint
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- `anchorPoint(rect, side)` — a point on a rect's edge.
|
|
76
|
+
- `connectorPath({ from, to, shape, curvature, mid })` — path between two points.
|
|
77
|
+
- `straightPath` / `elbowPath` / `curvePath` — the individual shapes.
|
|
78
|
+
- `connectRects(opts)` → `{ d, from, to, angle }`.
|
|
79
|
+
- `arrowHead(point, angle, size)` / `dotMark(point, radius)` — end markers.
|
|
80
|
+
- `autoSides(fromRect, toRect)` / `angleBetween(from, to)`.
|
|
81
|
+
- `endTangentAngle(from, to, shape)` — the angle the path *arrives* at `to`
|
|
82
|
+
(chord for `straight`, axis-aligned for `elbow`/`curve`); rotate an end marker
|
|
83
|
+
by this so it points along the path. `connectRects().angle` already uses it.
|
|
84
|
+
|
|
85
|
+
## Coordinate model
|
|
86
|
+
|
|
87
|
+
`initConnectors` measures the from/to elements relative to the connector SVG's
|
|
88
|
+
own box (via `getBoundingClientRect`), so place the SVG as an overlay
|
|
89
|
+
(`position: absolute; inset: 0`, which `.ui-connector` sets) inside a
|
|
90
|
+
`position: relative` container that holds both endpoints. The SVG has no
|
|
91
|
+
`viewBox`, so its user units are CSS pixels.
|
package/docs/contrast.md
CHANGED
|
@@ -40,51 +40,57 @@ Overall: **all contractual pairings meet their floor ✅**.
|
|
|
40
40
|
|
|
41
41
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
42
42
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
43
|
-
| `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 17.98:1 | Lc 99 | ✅ pass |
|
|
44
|
-
| `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 19.80:1 | Lc
|
|
45
|
-
| `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 16.74:1 | Lc 94 | ✅ pass |
|
|
46
|
-
| `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.16:1 | Lc 91 | ✅ pass |
|
|
47
|
-
| `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 12.29:1 | Lc 98 | ✅ pass |
|
|
48
|
-
| `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 10.39:1 | Lc
|
|
49
|
-
| `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 5.09:1 | Lc 71 | ✅ pass |
|
|
50
|
-
| `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 5.60:1 | Lc 78 | ✅ pass |
|
|
51
|
-
| `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 4.74:1 | Lc
|
|
52
|
-
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.32:1 | Lc 75 | ✅ pass |
|
|
53
|
-
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 6.96:1 | Lc 82 | ✅ pass |
|
|
54
|
-
| `--
|
|
55
|
-
| `--
|
|
56
|
-
| `--
|
|
57
|
-
| `--accent` | `--
|
|
58
|
-
| `--
|
|
59
|
-
| `--
|
|
60
|
-
| `--
|
|
61
|
-
| `--
|
|
62
|
-
| `--
|
|
43
|
+
| `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 17.98:1 | Lc 99.2 | ✅ pass |
|
|
44
|
+
| `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 19.80:1 | Lc 105.8 | ✅ pass |
|
|
45
|
+
| `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 16.74:1 | Lc 94.5 | ✅ pass |
|
|
46
|
+
| `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.16:1 | Lc 91.4 | ✅ pass |
|
|
47
|
+
| `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 12.29:1 | Lc 98.1 | ✅ pass |
|
|
48
|
+
| `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 10.39:1 | Lc 86.7 | ✅ pass |
|
|
49
|
+
| `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 5.09:1 | Lc 71.4 | ✅ pass |
|
|
50
|
+
| `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 5.60:1 | Lc 78.0 | ✅ pass |
|
|
51
|
+
| `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 4.74:1 | Lc 66.7 | ✅ pass |
|
|
52
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.32:1 | Lc 75.4 | ✅ pass |
|
|
53
|
+
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 6.96:1 | Lc 82.1 | ✅ pass |
|
|
54
|
+
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 5.91:1 | Lc 71.0 | ℹ️ not gated |
|
|
55
|
+
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 6.31:1 | Lc 75.3 | ℹ️ not gated |
|
|
56
|
+
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.18:1 | Lc 78.9 | ✅ pass |
|
|
57
|
+
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 5.18:1 | Lc 78.9 | ✅ pass |
|
|
58
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 4.71:1 | Lc 66.8 | ✅ pass |
|
|
59
|
+
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 5.18:1 | Lc 73.5 | ✅ pass |
|
|
60
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 4.71:1 | Lc 66.8 | ✅ pass |
|
|
61
|
+
| `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 5.04:1 | Lc 74.6 | ✅ pass |
|
|
62
|
+
| `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 5.60:1 | Lc 77.8 | ✅ pass |
|
|
63
|
+
| `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 6.21:1 | Lc 78.9 | ✅ pass |
|
|
64
|
+
| `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 5.77:1 | Lc 78.3 | ✅ pass |
|
|
65
|
+
| `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.39:1 | Lc 47.1 | ℹ️ not gated |
|
|
63
66
|
|
|
64
67
|
## Dark theme
|
|
65
68
|
|
|
66
69
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
67
70
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
68
|
-
| `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 15.01:1 | Lc 91 | ✅ pass |
|
|
69
|
-
| `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 13.65:1 | Lc 90 | ✅ pass |
|
|
70
|
-
| `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 12.44:1 | Lc
|
|
71
|
-
| `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.20:1 | Lc
|
|
72
|
-
| `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 10.19:1 | Lc
|
|
73
|
-
| `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 9.28:1 | Lc
|
|
74
|
-
| `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 7.16:1 | Lc 50 | ✅ pass |
|
|
75
|
-
| `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 6.52:1 | Lc 49 | ✅ pass |
|
|
76
|
-
| `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 5.94:1 | Lc 48 | ✅ pass |
|
|
77
|
-
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.14:1 | Lc
|
|
78
|
-
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 5.58:1 | Lc
|
|
79
|
-
| `--
|
|
80
|
-
| `--
|
|
81
|
-
| `--
|
|
82
|
-
| `--accent` | `--
|
|
83
|
-
| `--
|
|
84
|
-
| `--
|
|
85
|
-
| `--
|
|
86
|
-
| `--
|
|
87
|
-
| `--
|
|
71
|
+
| `--text` | `--bg` | Body text on page background | AA text (4.5:1) | 15.01:1 | Lc 91.1 | ✅ pass |
|
|
72
|
+
| `--text` | `--surface` | Body text on a card/panel | AA text (4.5:1) | 13.65:1 | Lc 90.1 | ✅ pass |
|
|
73
|
+
| `--text` | `--surface-muted` | Body text on a muted panel | AA text (4.5:1) | 12.44:1 | Lc 88.9 | ✅ pass |
|
|
74
|
+
| `--text-soft` | `--bg` | Secondary text on page background | AA text (4.5:1) | 11.20:1 | Lc 72.7 | ✅ pass |
|
|
75
|
+
| `--text-soft` | `--surface` | Secondary text on a card | AA text (4.5:1) | 10.19:1 | Lc 71.7 | ✅ pass |
|
|
76
|
+
| `--text-soft` | `--surface-muted` | Secondary text on a muted panel | AA text (4.5:1) | 9.28:1 | Lc 70.6 | ✅ pass |
|
|
77
|
+
| `--text-dim` | `--bg` | Dim/meta text on page background | AA text (4.5:1) | 7.16:1 | Lc 50.3 | ✅ pass |
|
|
78
|
+
| `--text-dim` | `--surface` | Dim/meta text on a card | AA text (4.5:1) | 6.52:1 | Lc 49.3 | ✅ pass |
|
|
79
|
+
| `--text-dim` | `--surface-muted` | Dim/meta text on a muted panel | AA text (4.5:1) | 5.94:1 | Lc 48.1 | ✅ pass |
|
|
80
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.14:1 | Lc 44.9 | ✅ pass |
|
|
81
|
+
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 5.58:1 | Lc 43.9 | ✅ pass |
|
|
82
|
+
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 2.53:1 | Lc 43.8 | ℹ️ not gated |
|
|
83
|
+
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 2.75:1 | Lc 49.1 | ℹ️ not gated |
|
|
84
|
+
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.95:1 | Lc 42.9 | ✅ pass |
|
|
85
|
+
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 5.95:1 | Lc 42.9 | ✅ pass |
|
|
86
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 5.31:1 | Lc 40.0 | ✅ pass |
|
|
87
|
+
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 4.83:1 | Lc 39.0 | ✅ pass |
|
|
88
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 5.31:1 | Lc 40.0 | ✅ pass |
|
|
89
|
+
| `--success` | `--surface` | Success indicator vs a card | UI / large (3:1) | 7.58:1 | Lc 56.6 | ✅ pass |
|
|
90
|
+
| `--warning` | `--surface` | Warning indicator vs a card | UI / large (3:1) | 9.29:1 | Lc 66.6 | ✅ pass |
|
|
91
|
+
| `--danger` | `--surface` | Danger indicator vs a card | UI / large (3:1) | 5.23:1 | Lc 41.5 | ✅ pass |
|
|
92
|
+
| `--info` | `--surface` | Info indicator vs a card | UI / large (3:1) | 7.33:1 | Lc 54.8 | ✅ pass |
|
|
93
|
+
| `--line-strong` | `--surface` | Strong hairline vs a card | Decorative (1.4.11-exempt) | 2.29:1 | Lc 14.5 | ℹ️ not gated |
|
|
88
94
|
|
|
89
95
|
## Display colorways (skins)
|
|
90
96
|
|
|
@@ -101,67 +107,85 @@ palette untouched). Accents are authored in OKLCH; `--accent-text` is the
|
|
|
101
107
|
|
|
102
108
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
103
109
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
104
|
-
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.75:1 | Lc
|
|
105
|
-
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 7.44:1 | Lc
|
|
106
|
-
| `--
|
|
107
|
-
| `--
|
|
108
|
-
| `--
|
|
109
|
-
| `--accent` | `--
|
|
110
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.75:1 | Lc 78.9 | ✅ pass |
|
|
111
|
+
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 7.44:1 | Lc 85.6 | ✅ pass |
|
|
112
|
+
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 6.31:1 | Lc 74.5 | ℹ️ not gated |
|
|
113
|
+
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 6.74:1 | Lc 78.8 | ℹ️ not gated |
|
|
114
|
+
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.66:1 | Lc 83.3 | ✅ pass |
|
|
115
|
+
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 5.66:1 | Lc 83.3 | ✅ pass |
|
|
116
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 5.14:1 | Lc 71.4 | ✅ pass |
|
|
117
|
+
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 5.66:1 | Lc 78.0 | ✅ pass |
|
|
118
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 5.14:1 | Lc 71.4 | ✅ pass |
|
|
110
119
|
|
|
111
120
|
### Amber CRT — dark
|
|
112
121
|
|
|
113
122
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
114
123
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
115
|
-
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 11.57:1 | Lc
|
|
116
|
-
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 10.52:1 | Lc
|
|
117
|
-
| `--
|
|
118
|
-
| `--
|
|
119
|
-
| `--
|
|
120
|
-
| `--accent` | `--
|
|
124
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 11.57:1 | Lc 74.8 | ✅ pass |
|
|
125
|
+
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 10.52:1 | Lc 73.8 | ✅ pass |
|
|
126
|
+
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 1.34:1 | Lc 15.1 | ℹ️ not gated |
|
|
127
|
+
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 1.46:1 | Lc 20.3 | ℹ️ not gated |
|
|
128
|
+
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 11.88:1 | Lc 71.6 | ✅ pass |
|
|
129
|
+
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 11.88:1 | Lc 71.6 | ✅ pass |
|
|
130
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 10.60:1 | Lc 69.9 | ✅ pass |
|
|
131
|
+
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 9.64:1 | Lc 68.9 | ✅ pass |
|
|
132
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 10.60:1 | Lc 69.9 | ✅ pass |
|
|
121
133
|
|
|
122
134
|
### E-ink — light
|
|
123
135
|
|
|
124
136
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
125
137
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
126
|
-
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.23:1 | Lc 93 | ✅ pass |
|
|
127
|
-
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 13.47:1 | Lc
|
|
128
|
-
| `--
|
|
129
|
-
| `--
|
|
130
|
-
| `--
|
|
131
|
-
| `--accent` | `--
|
|
138
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.23:1 | Lc 93.3 | ✅ pass |
|
|
139
|
+
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 13.47:1 | Lc 99.9 | ✅ pass |
|
|
140
|
+
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 11.43:1 | Lc 88.8 | ℹ️ not gated |
|
|
141
|
+
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 12.22:1 | Lc 93.2 | ℹ️ not gated |
|
|
142
|
+
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 11.74:1 | Lc 100.6 | ✅ pass |
|
|
143
|
+
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 11.74:1 | Lc 100.6 | ✅ pass |
|
|
144
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 10.66:1 | Lc 90.4 | ✅ pass |
|
|
145
|
+
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 11.74:1 | Lc 97.0 | ✅ pass |
|
|
146
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 10.66:1 | Lc 90.4 | ✅ pass |
|
|
132
147
|
|
|
133
148
|
### E-ink — dark
|
|
134
149
|
|
|
135
150
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
136
151
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
137
|
-
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.47:1 | Lc 79 | ✅ pass |
|
|
138
|
-
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 11.35:1 | Lc 78 | ✅ pass |
|
|
139
|
-
| `--
|
|
140
|
-
| `--
|
|
141
|
-
| `--
|
|
142
|
-
| `--accent` | `--
|
|
152
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.47:1 | Lc 79.1 | ✅ pass |
|
|
153
|
+
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 11.35:1 | Lc 78.1 | ✅ pass |
|
|
154
|
+
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 1.25:1 | Lc 11.0 | ℹ️ not gated |
|
|
155
|
+
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 1.35:1 | Lc 16.3 | ℹ️ not gated |
|
|
156
|
+
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 12.86:1 | Lc 75.6 | ✅ pass |
|
|
157
|
+
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 12.86:1 | Lc 75.6 | ✅ pass |
|
|
158
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 11.48:1 | Lc 74.1 | ✅ pass |
|
|
159
|
+
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 10.44:1 | Lc 73.1 | ✅ pass |
|
|
160
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 11.48:1 | Lc 74.1 | ✅ pass |
|
|
143
161
|
|
|
144
162
|
### Phosphor Green — light
|
|
145
163
|
|
|
146
164
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
147
165
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
148
|
-
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.22:1 | Lc
|
|
149
|
-
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 6.85:1 | Lc 83 | ✅ pass |
|
|
150
|
-
| `--
|
|
151
|
-
| `--
|
|
152
|
-
| `--
|
|
153
|
-
| `--accent` | `--
|
|
166
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 6.22:1 | Lc 76.6 | ✅ pass |
|
|
167
|
+
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 6.85:1 | Lc 83.3 | ✅ pass |
|
|
168
|
+
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 5.81:1 | Lc 72.2 | ℹ️ not gated |
|
|
169
|
+
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 6.21:1 | Lc 76.5 | ℹ️ not gated |
|
|
170
|
+
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 5.19:1 | Lc 80.7 | ✅ pass |
|
|
171
|
+
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 5.19:1 | Lc 80.7 | ✅ pass |
|
|
172
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 4.71:1 | Lc 68.6 | ✅ pass |
|
|
173
|
+
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 5.19:1 | Lc 75.3 | ✅ pass |
|
|
174
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 4.71:1 | Lc 68.6 | ✅ pass |
|
|
154
175
|
|
|
155
176
|
### Phosphor Green — dark
|
|
156
177
|
|
|
157
178
|
| Foreground | Background | Role | Held to | Ratio | APCA _(advisory)_ | Verdict |
|
|
158
179
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
159
|
-
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.97:1 | Lc
|
|
160
|
-
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 11.80:1 | Lc
|
|
161
|
-
| `--
|
|
162
|
-
| `--
|
|
163
|
-
| `--
|
|
164
|
-
| `--accent` | `--
|
|
180
|
+
| `--accent-text` | `--bg` | Accent text on page background | AA text (4.5:1) | 12.97:1 | Lc 81.8 | ✅ pass |
|
|
181
|
+
| `--accent-text` | `--surface` | Accent text on a card | AA text (4.5:1) | 11.80:1 | Lc 80.8 | ✅ pass |
|
|
182
|
+
| `--accent-text` | `--accent-soft` | Accent text on an accent tint | Advisory (translucent tint — not gated) | 1.20:1 | Lc 8.4 | ℹ️ not gated |
|
|
183
|
+
| `--accent-text` | `--bg-accent` | Accent text on an accent-tinted surface | Advisory (translucent tint — not gated) | 1.30:1 | Lc 13.7 | ℹ️ not gated |
|
|
184
|
+
| `--button-text` | `--accent` | Label on the primary button | AA text (4.5:1) | 13.75:1 | Lc 79.7 | ✅ pass |
|
|
185
|
+
| `--on-accent` | `--accent` | Ink on an accent fill | AA text (4.5:1) | 13.75:1 | Lc 79.7 | ✅ pass |
|
|
186
|
+
| `--focus-ring` | `--bg` | Focus ring vs page background | UI / large (3:1) | 12.27:1 | Lc 78.5 | ✅ pass |
|
|
187
|
+
| `--focus-ring` | `--surface` | Focus ring vs a card | UI / large (3:1) | 11.16:1 | Lc 77.5 | ✅ pass |
|
|
188
|
+
| `--accent` | `--bg` | Accent fill vs page background | UI / large (3:1) | 12.27:1 | Lc 78.5 | ✅ pass |
|
|
165
189
|
|
|
166
190
|
## Data-viz palette (advisory)
|
|
167
191
|
|
|
@@ -178,27 +202,27 @@ the brand accent.
|
|
|
178
202
|
|
|
179
203
|
| Series | Colour | Ratio _(advisory)_ | APCA _(advisory)_ |
|
|
180
204
|
| --- | --- | --- | --- |
|
|
181
|
-
| 1 _(accent)_ | `#d71921` | 4.71:1 | Lc
|
|
182
|
-
| 2 | `#e69f00` | 2.05:1 | Lc 37 |
|
|
183
|
-
| 3 | `#56b4e9` | 2.10:1 | Lc
|
|
184
|
-
| 4 | `#009e73` | 3.11:1 | Lc 54 |
|
|
185
|
-
| 5 | `#f0e442` | 1.20:1 | Lc 9 |
|
|
186
|
-
| 6 | `#0072b2` | 4.71:1 | Lc 68 |
|
|
187
|
-
| 7 | `#cc79a7` | 2.78:1 | Lc
|
|
188
|
-
| 8 | `#4d5358` | 7.08:1 | Lc 80 |
|
|
205
|
+
| 1 _(accent)_ | `#d71921` | 4.71:1 | Lc 66.8 |
|
|
206
|
+
| 2 | `#e69f00` | 2.05:1 | Lc 37.4 |
|
|
207
|
+
| 3 | `#56b4e9` | 2.10:1 | Lc 38.6 |
|
|
208
|
+
| 4 | `#009e73` | 3.11:1 | Lc 54.4 |
|
|
209
|
+
| 5 | `#f0e442` | 1.20:1 | Lc 9.1 |
|
|
210
|
+
| 6 | `#0072b2` | 4.71:1 | Lc 68.4 |
|
|
211
|
+
| 7 | `#cc79a7` | 2.78:1 | Lc 50.6 |
|
|
212
|
+
| 8 | `#4d5358` | 7.08:1 | Lc 80.4 |
|
|
189
213
|
|
|
190
214
|
### Dark theme — categorical vs `--bg`
|
|
191
215
|
|
|
192
216
|
| Series | Colour | Ratio _(advisory)_ | APCA _(advisory)_ |
|
|
193
217
|
| --- | --- | --- | --- |
|
|
194
|
-
| 1 _(accent)_ | `#ff3b41` | 5.31:1 | Lc 40 |
|
|
195
|
-
| 2 | `#e69f00` | 8.32:1 | Lc
|
|
196
|
-
| 3 | `#56b4e9` | 8.12:1 | Lc 56 |
|
|
197
|
-
| 4 | `#009e73` | 5.48:1 | Lc 40 |
|
|
198
|
-
| 5 | `#f0e442` | 14.17:1 | Lc 87 |
|
|
199
|
-
| 6 | `#0072b2` | 3.61:1 | Lc 26 |
|
|
200
|
-
| 7 | `#cc79a7` | 6.12:1 | Lc
|
|
201
|
-
| 8 | `#4d5358` | 2.40:1 | Lc 14 |
|
|
218
|
+
| 1 _(accent)_ | `#ff3b41` | 5.31:1 | Lc 40.0 |
|
|
219
|
+
| 2 | `#e69f00` | 8.32:1 | Lc 57.5 |
|
|
220
|
+
| 3 | `#56b4e9` | 8.12:1 | Lc 56.3 |
|
|
221
|
+
| 4 | `#009e73` | 5.48:1 | Lc 40.0 |
|
|
222
|
+
| 5 | `#f0e442` | 14.17:1 | Lc 87.4 |
|
|
223
|
+
| 6 | `#0072b2` | 3.61:1 | Lc 26.1 |
|
|
224
|
+
| 7 | `#cc79a7` | 6.12:1 | Lc 43.9 |
|
|
225
|
+
| 8 | `#4d5358` | 2.40:1 | Lc 14.4 |
|
|
202
226
|
|
|
203
227
|
## Scope & caveats
|
|
204
228
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Crosshair & readout
|
|
2
|
+
|
|
3
|
+
`@ponchia/ui/css/crosshair.css` is an opt-in **ruler + readout** for reading a
|
|
4
|
+
value off a plot: pointer-tracking crosshair rules, axis value badges, and a
|
|
5
|
+
pinned readout chip.
|
|
6
|
+
|
|
7
|
+
```css
|
|
8
|
+
@import '@ponchia/ui';
|
|
9
|
+
@import '@ponchia/ui/css/crosshair.css';
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Bronto draws the rules and (via `initCrosshair`) tracks the pointer — it reports
|
|
13
|
+
**where** the pointer is, as pixels and 0–1 fractions. It does **not** find the
|
|
14
|
+
nearest data point or map pixels to data values; that needs your scales. So this
|
|
15
|
+
is the *visual + pointer* layer, not a chart engine.
|
|
16
|
+
|
|
17
|
+
## Markup
|
|
18
|
+
|
|
19
|
+
The plot is `[data-bronto-crosshair]` (a `position: relative` box); it contains a
|
|
20
|
+
`.ui-crosshair` overlay with the rule(s) you want.
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<figure data-bronto-crosshair style="position: relative">
|
|
24
|
+
<!-- your chart / image / canvas -->
|
|
25
|
+
<div class="ui-crosshair" aria-hidden="true">
|
|
26
|
+
<div class="ui-crosshair__line ui-crosshair__line--x"></div>
|
|
27
|
+
<div class="ui-crosshair__line ui-crosshair__line--y"></div>
|
|
28
|
+
<div class="ui-readout" id="readout"></div>
|
|
29
|
+
</div>
|
|
30
|
+
</figure>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
import { initCrosshair } from '@ponchia/ui/behaviors';
|
|
35
|
+
const stop = initCrosshair(); // returns a cleanup
|
|
36
|
+
document.querySelector('[data-bronto-crosshair]').addEventListener(
|
|
37
|
+
'bronto:crosshair:move',
|
|
38
|
+
(e) => {
|
|
39
|
+
const { x, y, fx, fy } = e.detail; // px + 0..1 fractions
|
|
40
|
+
// YOU map the fraction to a data value with your scale:
|
|
41
|
+
readout.textContent = `${(fx * 100).toFixed(0)}%`;
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
| Class | Role |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| `ui-crosshair` | The overlay. Hidden until `.is-active` (set on the first pointer move over the plot). |
|
|
49
|
+
| `ui-crosshair__line` + `--x` / `--y` | Vertical / horizontal rule, positioned by `--crosshair-x` / `--crosshair-y`. |
|
|
50
|
+
| `ui-crosshair__badge` | An axis value chip (you set its text + edge). |
|
|
51
|
+
| `ui-readout` | A pinned readout chip; follows the crosshair point. |
|
|
52
|
+
|
|
53
|
+
`ui-crosshair--muted` is a subtler neutral crosshair. `ui.crosshair({ muted })`
|
|
54
|
+
builds the class string. Include only the lines you need (just `--x` for a
|
|
55
|
+
vertical scrubber, etc.).
|
|
56
|
+
|
|
57
|
+
## Events
|
|
58
|
+
|
|
59
|
+
- `bronto:crosshair:move` — `{ x, y, fx, fy }` (px within the plot + fractions).
|
|
60
|
+
- `bronto:crosshair:leave` — pointer left the plot.
|
|
61
|
+
|
|
62
|
+
The crosshair is decorative (`aria-hidden`); expose the underlying values to
|
|
63
|
+
assistive tech through a data table or text, not the rules.
|