@grafloria/element 0.3.23 → 0.4.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.
Files changed (69) hide show
  1. package/README.md +7 -7
  2. package/package.json +7 -9
  3. package/src/index.d.ts +16 -16
  4. package/src/index.js +58 -339
  5. package/src/lib/dashboard-kit/dashboard.d.ts +1 -1
  6. package/src/lib/dashboard-kit/dashboard.js +22 -26
  7. package/src/lib/dashboard-kit/grid-binder.d.ts +1 -1
  8. package/src/lib/dashboard-kit/grid-binder.js +62 -65
  9. package/src/lib/dashboard-kit/grid-mapping.js +14 -26
  10. package/src/lib/dashboard-kit/index.d.ts +5 -5
  11. package/src/lib/dashboard-kit/index.js +5 -30
  12. package/src/lib/dashboard-kit/styles.js +4 -8
  13. package/src/lib/dashboard-kit/widgets.d.ts +1 -1
  14. package/src/lib/dashboard-kit/widgets.js +16 -26
  15. package/src/lib/diagram-kit/card.d.ts +2 -2
  16. package/src/lib/diagram-kit/card.js +22 -32
  17. package/src/lib/diagram-kit/editing.js +15 -20
  18. package/src/lib/diagram-kit/er.d.ts +1 -1
  19. package/src/lib/diagram-kit/er.js +15 -18
  20. package/src/lib/diagram-kit/handles.d.ts +4 -4
  21. package/src/lib/diagram-kit/handles.js +16 -29
  22. package/src/lib/diagram-kit/index.d.ts +10 -10
  23. package/src/lib/diagram-kit/index.js +10 -50
  24. package/src/lib/diagram-kit/join-guidance.js +9 -18
  25. package/src/lib/diagram-kit/rows.js +1 -4
  26. package/src/lib/diagram-kit/styles.js +4 -8
  27. package/src/lib/diagram-kit/uml.js +10 -13
  28. package/src/lib/diagram-kit/update.d.ts +1 -1
  29. package/src/lib/diagram-kit/update.js +19 -26
  30. package/src/lib/grafloria-flow-element.js +19 -24
  31. package/src/lib/grafloria.d.ts +4 -4
  32. package/src/lib/grafloria.js +12 -17
  33. package/src/lib/load.d.ts +3 -3
  34. package/src/lib/load.js +19 -22
  35. package/src/lib/node-type-registry.js +6 -14
  36. package/src/lib/stencil-kit/builders.js +4 -10
  37. package/src/lib/stencil-kit/card-builders.js +14 -17
  38. package/src/lib/stencil-kit/index.d.ts +7 -7
  39. package/src/lib/stencil-kit/index.js +6 -16
  40. package/src/lib/stencil-kit/palette.js +14 -17
  41. package/src/lib/stencil-kit/shape-data.js +25 -28
  42. package/src/lib/stencil-kit/styles.js +1 -4
  43. package/esm/src/index.js +0 -295
  44. package/esm/src/lib/dashboard-kit/dashboard.js +0 -590
  45. package/esm/src/lib/dashboard-kit/grid-binder.js +0 -1633
  46. package/esm/src/lib/dashboard-kit/grid-mapping.js +0 -164
  47. package/esm/src/lib/dashboard-kit/index.js +0 -8
  48. package/esm/src/lib/dashboard-kit/styles.js +0 -205
  49. package/esm/src/lib/dashboard-kit/widgets.js +0 -379
  50. package/esm/src/lib/diagram-kit/card.js +0 -199
  51. package/esm/src/lib/diagram-kit/editing.js +0 -448
  52. package/esm/src/lib/diagram-kit/er.js +0 -160
  53. package/esm/src/lib/diagram-kit/handles.js +0 -312
  54. package/esm/src/lib/diagram-kit/index.js +0 -15
  55. package/esm/src/lib/diagram-kit/join-guidance.js +0 -322
  56. package/esm/src/lib/diagram-kit/rows.js +0 -144
  57. package/esm/src/lib/diagram-kit/styles.js +0 -118
  58. package/esm/src/lib/diagram-kit/uml.js +0 -135
  59. package/esm/src/lib/diagram-kit/update.js +0 -244
  60. package/esm/src/lib/grafloria-flow-element.js +0 -266
  61. package/esm/src/lib/grafloria.js +0 -69
  62. package/esm/src/lib/load.js +0 -252
  63. package/esm/src/lib/node-type-registry.js +0 -42
  64. package/esm/src/lib/stencil-kit/builders.js +0 -18
  65. package/esm/src/lib/stencil-kit/card-builders.js +0 -105
  66. package/esm/src/lib/stencil-kit/index.js +0 -9
  67. package/esm/src/lib/stencil-kit/palette.js +0 -427
  68. package/esm/src/lib/stencil-kit/shape-data.js +0 -537
  69. package/esm/src/lib/stencil-kit/styles.js +0 -126
@@ -1,164 +0,0 @@
1
- /**
2
- * Dashboard-kit pure math — Phase 2 of the dashboard-grid plan
3
- * (`documentation/api-architecture/dashboard-grid-plan.html`).
4
- *
5
- * Everything here is DOM-free and instance-free so it can be table-driven from
6
- * a jest spec: the cell↔pixel mapping in both sizing modes, the
7
- * GridItemConfig↔GridPackItem round-trip, and the gesture commit-batch
8
- * construction. The stateful binder (`grid-binder.ts`) is a thin pointer loop
9
- * over these functions plus the engine's `GridPackEngine` — the engine owns
10
- * ALL cell math (push/swap/gate/settle); this module owns only how cells and
11
- * pixels convert into each other and into undoable commands.
12
- *
13
- * SIZING MODES (user decision, recorded in the plan's Section 6):
14
- * 'fit' — DevExtreme-style compact. The board keeps its DESIGN height and
15
- * the row height re-derives from the content's row count, so every
16
- * widget always stays inside the frame — nothing can be pushed out
17
- * of reach. Guarded by `minRowHeight` so a pathological row count
18
- * squeezes to a floor instead of zero.
19
- * 'grow' — rows keep `baseRowHeight` and the board frame extends downward
20
- * to hold them (never below the design height). Camera refit after
21
- * growth is the page's concern (its existing `frameTab`).
22
- */
23
- import { MoveNodeCommand, ResizeNodeCommand, SetGridItemCommand, } from '@grafloria/engine';
24
- /** Row height for a board currently `rows` rows tall (both modes). */
25
- export function rowHeightFor(g, rows) {
26
- if (g.sizing === 'grow')
27
- return g.baseRowHeight;
28
- const r = Math.max(1, rows);
29
- // design = 2*padding + r*rowH + (r-1)*gap → solve for rowH.
30
- return Math.max(g.minRowHeight, (g.designHeight - 2 * g.padding - (r - 1) * g.gap) / r);
31
- }
32
- /** The board frame height the mode implies for `rows` rows. */
33
- export function boardHeightFor(g, rows) {
34
- if (g.sizing === 'fit')
35
- return g.designHeight;
36
- const r = Math.max(0, rows);
37
- const content = 2 * g.padding + (r === 0 ? 0 : r * g.baseRowHeight + (r - 1) * g.gap);
38
- return Math.max(g.designHeight, content);
39
- }
40
- /** Width of one column cell for a board `width` px wide. */
41
- export function columnUnitFor(g, width) {
42
- return (width - 2 * g.padding - (g.columns - 1) * g.gap) / g.columns;
43
- }
44
- /** Width in px of a `w`-column span (the pitch identity used by both mappings). */
45
- export function spanWidthPx(w, g, frameWidth) {
46
- const cu = columnUnitFor(g, frameWidth);
47
- return w * cu + (w - 1) * g.gap;
48
- }
49
- /**
50
- * Project integer cells into a world rectangle inside `frame`.
51
- *
52
- * RTL mirrors about the board's vertical centre line: the distance from the
53
- * board's RIGHT padding edge to the tile's RIGHT edge equals what the LTR
54
- * distance from the left padding edge to the tile's LEFT edge would be. Only
55
- * the x term changes — rows, heights and spans are direction-agnostic.
56
- */
57
- export function cellToRect(cell, frame, g, rows) {
58
- const cu = columnUnitFor(g, frame.width);
59
- const rh = rowHeightFor(g, rows);
60
- const width = cell.w * cu + (cell.w - 1) * g.gap;
61
- return {
62
- x: g.rtl
63
- ? frame.x + frame.width - g.padding - cell.x * (cu + g.gap) - width
64
- : frame.x + g.padding + cell.x * (cu + g.gap),
65
- y: frame.y + g.padding + cell.y * (rh + g.gap),
66
- width,
67
- height: cell.h * rh + (cell.h - 1) * g.gap,
68
- };
69
- }
70
- /**
71
- * The cell whose slot a tile TOP-LEFT at world (x, y) is closest to — the
72
- * prototype's margin-adjusted midpoint rounding (`round(L / cellPitch)`).
73
- * Clamping to the board is the ENGINE's job (moveCheck clamps), not ours.
74
- *
75
- * `spanW` is the tile's COLUMN SPAN and is used only when `g.rtl`: mirrored,
76
- * the cell is decided by the tile's RIGHT edge (its leading edge), so the
77
- * span is what converts the given left edge into it. LTR ignores it entirely,
78
- * which is why every existing call site keeps its exact behaviour. Getting
79
- * this wrong is the classic RTL drag bug — the tile lands a span away from
80
- * the placeholder — so the e2e battery asserts drop-on-placeholder in RTL.
81
- */
82
- export function pointToCell(x, y, frame, g, rows, spanW = 1) {
83
- const cu = columnUnitFor(g, frame.width);
84
- const rh = rowHeightFor(g, rows);
85
- const right = x + spanWidthPx(spanW, g, frame.width);
86
- return {
87
- x: g.rtl
88
- ? Math.round((frame.x + frame.width - g.padding - right) / (cu + g.gap))
89
- : Math.round((x - frame.x - g.padding) / (cu + g.gap)),
90
- y: Math.round((y - frame.y - g.padding) / (rh + g.gap)),
91
- };
92
- }
93
- /**
94
- * The integer span a fluid pixel size rounds to — the prototype's
95
- * `round((W + margin) / cellPitch)`, floored at 1×1.
96
- */
97
- export function sizeToSpan(widthPx, heightPx, frame, g, rows) {
98
- const cu = columnUnitFor(g, frame.width);
99
- const rh = rowHeightFor(g, rows);
100
- return {
101
- w: Math.max(1, Math.round((widthPx + g.gap) / (cu + g.gap))),
102
- h: Math.max(1, Math.round((heightPx + g.gap) / (rh + g.gap))),
103
- };
104
- }
105
- // ---------------------------------------------------------------------------
106
- // GridItemConfig ↔ engine cells.
107
- //
108
- // The cell state lives in the EXISTING GridItemConfig (1-based, exclusive-end
109
- // line numbers — CSS grid vocabulary): columnStart/rowStart are the cell + 1,
110
- // columnEnd/rowEnd are cell + span + 1. Nothing new is persisted; save/load
111
- // already round-trips gridItem.
112
- // ---------------------------------------------------------------------------
113
- /** Engine cells → the GridItemConfig that persists them. */
114
- export function gridItemFromCell(cell) {
115
- return {
116
- columnStart: cell.x + 1,
117
- columnEnd: cell.x + cell.w + 1,
118
- rowStart: cell.y + 1,
119
- rowEnd: cell.y + cell.h + 1,
120
- };
121
- }
122
- /**
123
- * GridItemConfig → engine cells, or null when the config carries no usable
124
- * placement (absent, or 'auto' lines). `fallback` fills spans a partial
125
- * config omits — the first-adoption path uses metadata `columnSpan` there.
126
- */
127
- export function cellFromGridItem(gi, fallback) {
128
- var _a, _b;
129
- if (!gi)
130
- return null;
131
- const num = (v) => typeof v === 'number' && Number.isFinite(v) ? v : null;
132
- const cs = num(gi.columnStart);
133
- const rs = num(gi.rowStart);
134
- if (cs === null || rs === null)
135
- return null;
136
- const ce = num(gi.columnEnd);
137
- const re = num(gi.rowEnd);
138
- const w = ce !== null ? ce - cs : (_a = fallback === null || fallback === void 0 ? void 0 : fallback.w) !== null && _a !== void 0 ? _a : 1;
139
- const h = re !== null ? re - rs : (_b = fallback === null || fallback === void 0 ? void 0 : fallback.h) !== null && _b !== void 0 ? _b : 1;
140
- return { x: cs - 1, y: rs - 1, w: Math.max(1, w), h: Math.max(1, h) };
141
- }
142
- const cellsDiffer = (a, b) => a.x !== b.x || a.y !== b.y || a.w !== b.w || a.h !== b.h;
143
- const EPS = 0.5;
144
- export function buildCommitCommands(deltas) {
145
- const commands = [];
146
- for (const d of deltas) {
147
- const cellChanged = cellsDiffer(d.cellBefore, d.cellAfter);
148
- if (cellChanged && !d.isGroup) {
149
- commands.push(new SetGridItemCommand(d.id, gridItemFromCell(d.cellAfter)));
150
- }
151
- if (d.locked || d.isGroup)
152
- continue;
153
- if (Math.abs(d.posAfter.x - d.posBefore.x) > EPS ||
154
- Math.abs(d.posAfter.y - d.posBefore.y) > EPS) {
155
- commands.push(new MoveNodeCommand(d.id, Object.assign({}, d.posAfter), Object.assign({}, d.posBefore), { mergeable: false }));
156
- }
157
- if (Math.abs(d.sizeAfter.width - d.sizeBefore.width) > EPS ||
158
- Math.abs(d.sizeAfter.height - d.sizeBefore.height) > EPS) {
159
- commands.push(new ResizeNodeCommand(d.id, Object.assign({ depth: 0 }, d.sizeAfter), Object.assign({ depth: 0 }, d.sizeBefore)));
160
- }
161
- }
162
- return commands;
163
- }
164
- //# sourceMappingURL=grid-mapping.js.map
@@ -1,8 +0,0 @@
1
- export { bindDashboardGrid, } from './grid-binder';
2
- export { rowHeightFor, boardHeightFor, columnUnitFor, cellToRect, pointToCell, sizeToSpan, spanWidthPx, gridItemFromCell, cellFromGridItem, buildCommitCommands, } from './grid-mapping';
3
- export { ensureDashboardKitStyles, DASHBOARD_KIT_STYLE_ID } from './styles';
4
- // The DATA-FIRST authoring API (the erDiagram/umlDiagram equivalent).
5
- export { dashboard, } from './dashboard';
6
- // The built-in renderers behind `kind` — dashboard()'s default renderWidget.
7
- export { defaultWidgetRenderer, renderKpiWidget, renderLineWidget, renderBarWidget, renderDonutWidget, renderFunnelWidget, renderTableWidget, BUILT_IN_WIDGET_KINDS, } from './widgets';
8
- //# sourceMappingURL=index.js.map
@@ -1,205 +0,0 @@
1
- /**
2
- * Dashboard-kit stylesheet — injected once, on first `bindDashboardGrid`.
3
- *
4
- * Everything is prefixed `axdb-` and scoped under `.grafloria-html-layer`, so
5
- * binding the kit can never restyle a host's own DOM. Four jobs:
6
- *
7
- * - GLIDE: the reflow transition (the pattern from commit 180a27974) that
8
- * makes displaced tiles slide to their new slot while a gesture is live.
9
- * The kit arms `.axdb-glide` on the html layer for the WHOLE gesture, so
10
- * every accepted moveCheck/resizeCheck animates the neighbours.
11
- * - GHOST: the held tile is transition-EXEMPT (it must track the pointer
12
- * 1:1), floats above everything, and dims + lifts like the prototype's
13
- * `.tile.drag`. When a drag leaves the board (drag-out-to-remove) the
14
- * ghost dims further as the "release deletes" affordance.
15
- * - PLACEHOLDER: the dashed slab that always shows the exact drop result
16
- * (the prototype's `#ph`). It JUMPS — never animates — so it is always
17
- * truthful about the engine's current cell.
18
- * - RESIZE HANDLE: a corner affordance INSIDE each widget card, bottom-right,
19
- * radius-matched via `--axdb-rs-radius`, revealed on hover. The binder
20
- * injects it into each member host and re-injects if the host repaints
21
- * (pages own their card innerHTML).
22
- */
23
- export const DASHBOARD_KIT_STYLE_ID = 'grafloria-dashboard-kit-styles';
24
- const CSS = `
25
- /* ===== reflow glide (armed on the html layer for the whole gesture) ===== */
26
- .grafloria-html-layer.axdb-glide > .grafloria-node-host {
27
- transition: left .28s cubic-bezier(.2, 0, .2, 1), top .28s cubic-bezier(.2, 0, .2, 1),
28
- width .28s cubic-bezier(.2, 0, .2, 1), height .28s cubic-bezier(.2, 0, .2, 1);
29
- }
30
-
31
- /* ===== the held tile: transition-exempt ghost, above everything ===== */
32
- .grafloria-html-layer > .grafloria-node-host.axdb-ghost,
33
- .grafloria-html-layer.axdb-glide > .grafloria-node-host.axdb-ghost {
34
- transition: none;
35
- z-index: 30;
36
- opacity: .85;
37
- cursor: grabbing;
38
- filter: drop-shadow(0 10px 16px rgba(16, 24, 40, .3));
39
- }
40
- /* Outside the board: release will REMOVE — dim the ghost to say so. */
41
- .grafloria-html-layer > .grafloria-node-host.axdb-ghost.axdb-out { opacity: .35; filter: grayscale(.6); }
42
-
43
- /* ===== the placeholder: dashed slab, truthful, never animated ===== */
44
- .grafloria-html-layer > .axdb-ph {
45
- position: absolute;
46
- border-radius: var(--axdb-rs-radius, 12px);
47
- background: rgba(30, 34, 45, .14);
48
- border: 2px dashed rgba(30, 34, 45, .28);
49
- box-sizing: border-box;
50
- pointer-events: none;
51
- z-index: 0;
52
- transition: none;
53
- }
54
- @media (prefers-color-scheme: dark) {
55
- .grafloria-html-layer > .axdb-ph { background: rgba(220, 225, 240, .12); border-color: rgba(220, 225, 240, .3); }
56
- }
57
-
58
- /* ===== corner resize handle (hover-revealed, radius-matched) ===== */
59
- .grafloria-node-host > .axdb-rs {
60
- position: absolute;
61
- right: 0;
62
- bottom: 0;
63
- width: 18px;
64
- height: 18px;
65
- cursor: nwse-resize;
66
- border-right: 3px solid rgba(120, 130, 148, .55);
67
- border-bottom: 3px solid rgba(120, 130, 148, .55);
68
- border-bottom-right-radius: var(--axdb-rs-radius, 12px);
69
- opacity: 0;
70
- transition: opacity .12s;
71
- z-index: 5;
72
- }
73
- .grafloria-node-host:hover > .axdb-rs { opacity: 1; }
74
- .grafloria-node-host > .axdb-rs:hover { border-color: #3b52d9; }
75
- /* RTL boards grow leftwards, so the grab corner mirrors with them. */
76
- .grafloria-node-host > .axdb-rs.axdb-rs--rtl {
77
- right: auto;
78
- left: 0;
79
- cursor: nesw-resize;
80
- border-right: none;
81
- border-left: 3px solid rgba(120, 130, 148, .55);
82
- border-bottom-right-radius: 0;
83
- border-bottom-left-radius: var(--axdb-rs-radius, 12px);
84
- }
85
-
86
- /* ===== palette drag-in chip (screen-space clone following the cursor) ===== */
87
- .axdb-drag-chip {
88
- position: fixed;
89
- z-index: 9999;
90
- pointer-events: none;
91
- opacity: .9;
92
- filter: drop-shadow(0 8px 14px rgba(16, 24, 40, .3));
93
- }
94
-
95
- /* ===========================================================================
96
- BUILT-IN WIDGET CARDS — what widgets.ts paints when a page writes no
97
- renderWidget. Class-prefixed (never element selectors), so this can only
98
- ever style DOM the kit itself produced. Colours are CSS variables on the
99
- card, so a page re-skins every built-in widget by setting them once; the
100
- corner radius follows --axdb-rs-radius, which is also the placeholder's and
101
- the resize handle's, so the three can never drift apart.
102
- =========================================================================== */
103
- .axdb-widget {
104
- --axdb-ink: #1f2430;
105
- --axdb-muted: #7a8496;
106
- --axdb-grid: rgba(120, 130, 148, .22);
107
- --axdb-card: #fff;
108
- --axdb-line: #e7eaf1;
109
- --axdb-soft: rgba(120, 130, 148, .14);
110
- box-sizing: border-box;
111
- width: 100%;
112
- height: 100%;
113
- display: flex;
114
- flex-direction: column;
115
- overflow: hidden;
116
- padding: 13px 15px 12px;
117
- background: var(--axdb-card);
118
- border: 1px solid var(--axdb-line);
119
- border-radius: var(--axdb-rs-radius, 12px);
120
- box-shadow: 0 1px 2px rgba(16, 24, 40, .05), 0 1px 3px rgba(16, 24, 40, .05);
121
- font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
122
- color: var(--axdb-ink);
123
- }
124
- .axdb-widget-h {
125
- display: flex;
126
- align-items: center;
127
- gap: 6px;
128
- margin-bottom: 8px;
129
- font: 600 11px/1.3 system-ui, sans-serif;
130
- letter-spacing: .4px;
131
- text-transform: uppercase;
132
- color: var(--axdb-muted);
133
- }
134
- .axdb-widget-b { flex: 1; min-height: 0; position: relative; }
135
- .axdb-widget-b > svg { display: block; width: 100%; height: 100%; }
136
- .axdb-widget-b.axdb-scroll { overflow: auto; }
137
- /* A chart WITH a legend under it: the plot yields height, the legend keeps its
138
- own (without this the 100%-tall svg pushes the legend out of the card). */
139
- .axdb-widget-b.axdb-has-lg { display: flex; flex-direction: column; }
140
- .axdb-widget-b.axdb-has-lg > svg { flex: 1; height: auto; min-height: 0; }
141
- .axdb-widget-empty {
142
- display: flex; align-items: center; justify-content: center; height: 100%;
143
- font: 500 11.5px/1.3 system-ui, sans-serif; color: var(--axdb-muted); opacity: .75;
144
- }
145
-
146
- /* kpi: value + delta stack, the spark yields its height before they do */
147
- /* A SIZE CONTAINER, so the card's type scales with the tile instead of
148
- clipping. Fit-mode shrinks tiles when rows are added (dropping a chart above
149
- the KPI row took these from 122px to 85px) and fixed 30px/12px lines were
150
- sliced mid-glyph by the card's overflow — the audited "trimmed" widgets.
151
- cqh = 1% of the body's own height, clamped so full-size tiles look exactly
152
- as before and short tiles compress instead of cutting. */
153
- .axdb-widget-b.axdb-kpi { display: flex; flex-direction: column; container-type: size; }
154
- .axdb-kpi-v { font: 700 clamp(15px, 44cqh, 30px)/1.05 system-ui, sans-serif; letter-spacing: -.02em; color: var(--axdb-ink); }
155
- .axdb-kpi-d { margin-top: clamp(1px, 5cqh, 6px); font: 600 clamp(9px, 19cqh, 12px)/1.2 system-ui, sans-serif; }
156
- .axdb-kpi-d span { color: var(--axdb-muted); font-weight: 500; }
157
- .axdb-kpi-d.up { color: #12a150; }
158
- .axdb-kpi-d.down { color: #e11d48; }
159
- .axdb-kpi-s { margin-top: auto; height: 34px; min-height: 0; flex: 0 1 34px; }
160
-
161
- /* donut: ring beside its legend */
162
- .axdb-widget-b.axdb-donut { display: flex; align-items: center; gap: 10px; }
163
- .axdb-widget-b.axdb-donut > svg { max-width: 150px; }
164
-
165
- /* legend chips, shared by line and donut */
166
- .axdb-lg { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 9px; }
167
- .axdb-lg--col { flex-direction: column; flex-wrap: nowrap; gap: 6px; margin-top: 0; }
168
- .axdb-lg i {
169
- display: inline-flex; align-items: center; gap: 5px; font-style: normal;
170
- font: 500 11px/1.3 system-ui, sans-serif; color: var(--axdb-muted);
171
- }
172
- .axdb-lg i b { width: 9px; height: 9px; border-radius: 3px; flex: none; }
173
-
174
- /* table */
175
- .axdb-table { width: 100%; border-collapse: collapse; font-size: 12px; color: var(--axdb-ink); }
176
- .axdb-table th {
177
- text-align: left; padding: 4px 8px 7px; border-bottom: 1px solid var(--axdb-line);
178
- font: 600 10px/1.3 system-ui, sans-serif; letter-spacing: .4px; text-transform: uppercase;
179
- color: var(--axdb-muted);
180
- }
181
- .axdb-table td { padding: 6px 8px; border-bottom: 1px solid var(--axdb-line); white-space: nowrap; }
182
- .axdb-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
183
- .axdb-table tr:last-child td { border-bottom: none; }
184
-
185
- @media (prefers-color-scheme: dark) {
186
- .axdb-widget {
187
- --axdb-ink: #eceef4;
188
- --axdb-muted: #98a1b4;
189
- --axdb-grid: rgba(150, 160, 182, .2);
190
- --axdb-card: #1a1d25;
191
- --axdb-line: #2b3040;
192
- --axdb-soft: rgba(150, 160, 182, .16);
193
- }
194
- }
195
- `;
196
- /** Idempotently inject the kit stylesheet (safe to call per binder). */
197
- export function ensureDashboardKitStyles(doc = document) {
198
- if (doc.getElementById(DASHBOARD_KIT_STYLE_ID))
199
- return;
200
- const style = doc.createElement('style');
201
- style.id = DASHBOARD_KIT_STYLE_ID;
202
- style.textContent = CSS;
203
- doc.head.appendChild(style);
204
- }
205
- //# sourceMappingURL=styles.js.map