@lovett/ui 0.0.10 → 0.1.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/dist/chunk-RBYWGBQ2.js +2752 -0
- package/dist/chunk-RBYWGBQ2.js.map +1 -0
- package/dist/index.d.ts +6064 -80
- package/dist/index.js +21561 -9696
- package/dist/index.js.map +1 -1
- package/dist/rich-composer-impl-5NO443A6.js +1859 -0
- package/dist/rich-composer-impl-5NO443A6.js.map +1 -0
- package/dist/styles.css +1586 -2
- package/dist/theme-v2.css +228 -0
- package/dist/tokens.css +121 -0
- package/package.json +8 -1
- package/src/__tests__/anchor.test.tsx +422 -0
- package/src/__tests__/avatar.test.tsx +272 -0
- package/src/__tests__/bar-chart.test.tsx +809 -0
- package/src/__tests__/board.test.tsx +420 -0
- package/src/__tests__/chart-math.test.ts +922 -0
- package/src/__tests__/chart-series.test.ts +339 -0
- package/src/__tests__/code-block.test.tsx +134 -0
- package/src/__tests__/combobox.test.tsx +677 -0
- package/src/__tests__/display-popover.test.tsx +195 -0
- package/src/__tests__/display-store.test.tsx +208 -0
- package/src/__tests__/donut-chart.test.tsx +397 -0
- package/src/__tests__/dropdown-menu.test.tsx +572 -0
- package/src/__tests__/filter-menu.test.tsx +175 -0
- package/src/__tests__/gauge-ring.test.tsx +233 -0
- package/src/__tests__/helpers/geometry.ts +58 -0
- package/src/__tests__/layer-stack.test.tsx +228 -0
- package/src/__tests__/line-chart.test.tsx +612 -0
- package/src/__tests__/popover.test.tsx +460 -0
- package/src/__tests__/ranked-bars.test.tsx +343 -0
- package/src/__tests__/remark-underline.test.ts +194 -0
- package/src/__tests__/select.test.tsx +543 -0
- package/src/__tests__/sparkline.test.tsx +368 -0
- package/src/__tests__/stat-layer.test.tsx +271 -0
- package/src/__tests__/stat-strip.test.tsx +175 -0
- package/src/__tests__/status.test.tsx +293 -0
- package/src/__tests__/tabs.test.tsx +303 -0
- package/src/__tests__/token-shape.test.ts +132 -2
- package/src/__tests__/tooltip.test.tsx +355 -0
- package/src/avatar.tsx +352 -0
- package/src/bar-chart.tsx +1214 -0
- package/src/board.tsx +658 -0
- package/src/calculator-shell-v2.tsx +19 -39
- package/src/chart-frame.tsx +960 -0
- package/src/chart-legend.tsx +304 -0
- package/src/chart-tooltip.tsx +267 -0
- package/src/code-block.tsx +62 -8
- package/src/combobox.tsx +796 -0
- package/src/delta-chip.tsx +263 -0
- package/src/detail/__tests__/activity-pane.test.tsx +186 -0
- package/src/detail/__tests__/detail-chrome.test.tsx +134 -0
- package/src/detail/__tests__/detail-surface.test.tsx +529 -0
- package/src/detail/__tests__/field-row.test.tsx +357 -0
- package/src/detail/activity-pane.tsx +507 -0
- package/src/detail/calendar.tsx +355 -0
- package/src/detail/detail-divider.tsx +261 -0
- package/src/detail/detail-header.tsx +287 -0
- package/src/detail/detail-menu.tsx +254 -0
- package/src/detail/detail-surface.tsx +1110 -0
- package/src/detail/field-list.tsx +196 -0
- package/src/detail/field-row.tsx +1131 -0
- package/src/detail/index.ts +58 -0
- package/src/detail/segmented-choice.tsx +94 -0
- package/src/detail/types.ts +129 -0
- package/src/display-popover.tsx +487 -0
- package/src/display-store.tsx +242 -0
- package/src/donut-chart.tsx +988 -0
- package/src/dropdown-menu.tsx +412 -151
- package/src/filter-core/EXPORTS.md +85 -0
- package/src/filter-core/__tests__/columns.test.ts +159 -0
- package/src/filter-core/__tests__/faceting.test.ts +193 -0
- package/src/filter-core/__tests__/filter-fns.test.ts +519 -0
- package/src/filter-core/__tests__/operators.test.ts +235 -0
- package/src/filter-core/__tests__/state.test.ts +268 -0
- package/src/filter-core/__tests__/url.test.ts +350 -0
- package/src/filter-core/columns.ts +134 -0
- package/src/filter-core/date-utils.ts +38 -0
- package/src/filter-core/examples/task-filter-columns.ts +121 -0
- package/src/filter-core/faceting.ts +120 -0
- package/src/filter-core/filter-fns.ts +335 -0
- package/src/filter-core/index.ts +105 -0
- package/src/filter-core/operators.ts +433 -0
- package/src/filter-core/state.ts +280 -0
- package/src/filter-core/types.ts +247 -0
- package/src/filter-core/url.ts +261 -0
- package/src/filter-dropdown.tsx +12 -0
- package/src/filter-menu.tsx +649 -0
- package/src/floating-drawer.tsx +19 -1
- package/src/gauge-ring.tsx +435 -0
- package/src/hue.ts +52 -0
- package/src/index.ts +402 -0
- package/src/kbd.tsx +27 -4
- package/src/lib/anchor.ts +427 -0
- package/src/lib/chart.ts +866 -0
- package/src/lib/focus.ts +74 -0
- package/src/lib/layer-stack.ts +215 -0
- package/src/lib/refs.ts +31 -0
- package/src/lib/remark-underline.ts +443 -0
- package/src/lib/series.ts +169 -0
- package/src/line-chart.tsx +1176 -0
- package/src/markdown.tsx +26 -7
- package/src/metric-card.tsx +57 -22
- package/src/modal.tsx +73 -66
- package/src/popover.tsx +407 -0
- package/src/progress-ledger.tsx +304 -0
- package/src/ranked-bars.tsx +386 -0
- package/src/segmented-pill.tsx +32 -9
- package/src/select.tsx +646 -0
- package/src/sortable.tsx +315 -1
- package/src/sparkline.tsx +416 -0
- package/src/stat-card.tsx +376 -0
- package/src/stat-row.tsx +108 -70
- package/src/stat-strip.tsx +327 -0
- package/src/status.tsx +215 -0
- package/src/styles.css +1586 -2
- package/src/tabs.tsx +206 -25
- package/src/task-card.tsx +610 -0
- package/src/thread/__tests__/comment-body-hostile.test.tsx +331 -0
- package/src/thread/__tests__/comment-tree.test.ts +151 -0
- package/src/thread/__tests__/emoji.test.ts +187 -0
- package/src/thread/__tests__/fixtures/thread-fixture.ts +235 -0
- package/src/thread/__tests__/link-preview-source.test.ts +120 -0
- package/src/thread/__tests__/link-preview.test.tsx +600 -0
- package/src/thread/__tests__/markdown-format.test.ts +82 -0
- package/src/thread/__tests__/markdown-spec.test.ts +469 -0
- package/src/thread/__tests__/relative-time.test.ts +71 -0
- package/src/thread/__tests__/rich-composer.test.tsx +799 -0
- package/src/thread/__tests__/scroll-caret.test.ts +58 -0
- package/src/thread/__tests__/suggestion-list.test.tsx +648 -0
- package/src/thread/__tests__/thread-scroll-ownership.test.tsx +88 -0
- package/src/thread/__tests__/thread.test.tsx +662 -0
- package/src/thread/__tests__/use-attachments.test.tsx +679 -0
- package/src/thread/actions.tsx +196 -0
- package/src/thread/attachments.tsx +1071 -0
- package/src/thread/comment-body.tsx +148 -0
- package/src/thread/comment-tree.ts +182 -0
- package/src/thread/comment.tsx +915 -0
- package/src/thread/composer-footer.tsx +125 -0
- package/src/thread/composer.tsx +319 -0
- package/src/thread/emoji.ts +283 -0
- package/src/thread/index.ts +153 -0
- package/src/thread/link-preview.tsx +341 -0
- package/src/thread/markdown-format.ts +155 -0
- package/src/thread/markdown-spec.ts +754 -0
- package/src/thread/rail.tsx +372 -0
- package/src/thread/reactions.tsx +415 -0
- package/src/thread/relative-time.tsx +94 -0
- package/src/thread/rich-composer-impl.tsx +1601 -0
- package/src/thread/rich-composer.tsx +195 -0
- package/src/thread/scroll-caret.ts +37 -0
- package/src/thread/suggestion-list.tsx +182 -0
- package/src/thread/thread.tsx +718 -0
- package/src/thread/types.ts +218 -0
- package/src/thread/use-attachments.ts +598 -0
- package/src/thread/use-now.ts +73 -0
- package/src/thread/use-thread.ts +316 -0
- package/src/tokens.css +121 -0
- package/src/tooltip.tsx +297 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @lovett/ui — v2 theme, SCOPED.
|
|
3
|
+
*
|
|
4
|
+
* GENERATED. Regenerate with:
|
|
5
|
+
* python3 scripts/figma/emit-theme.py <corpus> --out packages/ui/src/theme-v2.css
|
|
6
|
+
*
|
|
7
|
+
* Opt in by putting `data-ds="v2"` on any element. Everything inside it
|
|
8
|
+
* renders on the v2 palette, including existing @lovett/ui primitives —
|
|
9
|
+
* they read the same token names, which now resolve to different values.
|
|
10
|
+
* Nothing outside the scope changes.
|
|
11
|
+
*
|
|
12
|
+
* Derived from a 13-kit Figma corpus; see docs/design-system/figma-corpus/.
|
|
13
|
+
* The direction is Vertex Lab: pure-white trays, near-neutral greys, a
|
|
14
|
+
* navy-tinted ink used as a SURFACE and not only as text.
|
|
15
|
+
*
|
|
16
|
+
* The semantic reassignment is the load-bearing change:
|
|
17
|
+
* --accent red brand identity and the primary action, nothing else
|
|
18
|
+
* --success green save, publish, approve, live
|
|
19
|
+
* --destructive AMBER destructive. No longer red.
|
|
20
|
+
* --warning gold caution
|
|
21
|
+
* --info violet
|
|
22
|
+
*
|
|
23
|
+
* Consequence worth knowing before adopting: amber is a weaker danger
|
|
24
|
+
* signal than red, so destructive actions must carry an icon and an
|
|
25
|
+
* explicit verb. Colour alone no longer does that work.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
[data-ds="v2"] {
|
|
29
|
+
/* ── Surfaces ─────────────────────────────────────────────── */
|
|
30
|
+
/* The frame/tray step is 2.1 pts — ratified as `medium`. Both being
|
|
31
|
+
white removes the distinction the card pattern is built on. */
|
|
32
|
+
--page-bg: 240 241 242;
|
|
33
|
+
--background: 240 241 242;
|
|
34
|
+
--main-content-bg: 240 241 242;
|
|
35
|
+
--bg-surface: 248 248 249;
|
|
36
|
+
--surface-frame: 248 248 249;
|
|
37
|
+
--card-frame-bg: 248 248 249;
|
|
38
|
+
--bg-card: 255 255 255;
|
|
39
|
+
--card: 255 255 255;
|
|
40
|
+
--tray-bg: 255 255 255;
|
|
41
|
+
--bg-elevated: 255 255 255;
|
|
42
|
+
--surface-raised: 255 255 255;
|
|
43
|
+
--popover: 255 255 255;
|
|
44
|
+
--bg-input: 255 255 255;
|
|
45
|
+
--bg-card-hover: 250 251 252;
|
|
46
|
+
--bg-input-hover: 250 251 252;
|
|
47
|
+
--muted: 246 247 248;
|
|
48
|
+
--canvas-placement-bg: 246 247 248;
|
|
49
|
+
|
|
50
|
+
/* ── Ink ──────────────────────────────────────────────────── */
|
|
51
|
+
/* Navy-tinted, not black. Vertex uses #1c274c 6,522 times — far too
|
|
52
|
+
many for text: it is a panel colour, so it gets a full ramp. */
|
|
53
|
+
--ink-15: 253 253 253;
|
|
54
|
+
--ink-25: 250 251 254;
|
|
55
|
+
--ink-30: 247 248 252;
|
|
56
|
+
--ink-40: 241 245 253;
|
|
57
|
+
--ink-60: 235 241 254;
|
|
58
|
+
--ink-50: 243 247 255;
|
|
59
|
+
--ink-100: 229 237 254;
|
|
60
|
+
--ink-200: 207 217 238;
|
|
61
|
+
--ink-300: 182 193 217;
|
|
62
|
+
--ink-400: 150 163 191;
|
|
63
|
+
--ink-500: 119 134 165;
|
|
64
|
+
--ink-600: 93 108 140;
|
|
65
|
+
--ink-700: 70 82 109;
|
|
66
|
+
--ink-800: 48 58 80;
|
|
67
|
+
--ink-900: 27 35 51;
|
|
68
|
+
--ink-950: 11 16 28;
|
|
69
|
+
--foreground: 11 16 28;
|
|
70
|
+
--card-foreground: 11 16 28;
|
|
71
|
+
--popover-foreground: 11 16 28;
|
|
72
|
+
--text-secondary: 93 108 140;
|
|
73
|
+
--muted-foreground: 93 108 140;
|
|
74
|
+
--text-tertiary: 119 134 165;
|
|
75
|
+
--text-muted: 150 163 191;
|
|
76
|
+
--secondary: 246 247 248;
|
|
77
|
+
--secondary-foreground: 11 16 28;
|
|
78
|
+
|
|
79
|
+
/* ── Borders ──────────────────────────────────────────────── */
|
|
80
|
+
/* Structure only. Depth is shadow — a hard hairline on a depth
|
|
81
|
+
surface reads as a form field. Inputs keep theirs deliberately. */
|
|
82
|
+
--border: 0 0 0 / 0.05;
|
|
83
|
+
--border-strong: 0 0 0 / 0.10;
|
|
84
|
+
--border-card: 0 0 0 / 0.06;
|
|
85
|
+
--border-input: 0 0 0 / 0.12;
|
|
86
|
+
--main-content-border: 0 0 0 / 0.06;
|
|
87
|
+
--input: 246 247 248;
|
|
88
|
+
|
|
89
|
+
/* ── Brand ────────────────────────────────────────────────── */
|
|
90
|
+
/* --accent is the AA-safe action red (4.77:1 with white). The bright
|
|
91
|
+
step is 4.01:1 and cannot carry a white label, so it is exposed
|
|
92
|
+
separately for accents, marks, charts and active fills. */
|
|
93
|
+
--accent: 221 40 34;
|
|
94
|
+
--accent-bright: 228 70 58;
|
|
95
|
+
--accent-hover: 201 17 17;
|
|
96
|
+
--accent-muted: 228 70 58 / 0.10;
|
|
97
|
+
--accent-subtle: 228 70 58 / 0.05;
|
|
98
|
+
--accent-glow: 228 70 58 / 0.22;
|
|
99
|
+
--primary: 221 40 34;
|
|
100
|
+
--primary-hover: 201 17 17;
|
|
101
|
+
--primary-foreground: 255 255 255;
|
|
102
|
+
--ring: 221 40 34;
|
|
103
|
+
--brand-15: 253 253 253;
|
|
104
|
+
--brand-25: 252 251 250;
|
|
105
|
+
--brand-30: 252 247 246;
|
|
106
|
+
--brand-40: 255 242 240;
|
|
107
|
+
--brand-60: 254 237 234;
|
|
108
|
+
--brand-50: 255 244 242;
|
|
109
|
+
--brand-100: 253 231 228;
|
|
110
|
+
--brand-200: 253 204 196;
|
|
111
|
+
--brand-300: 254 166 154;
|
|
112
|
+
--brand-400: 251 114 99;
|
|
113
|
+
--brand-500: 228 70 58;
|
|
114
|
+
--brand-600: 201 17 17;
|
|
115
|
+
--brand-700: 157 8 9;
|
|
116
|
+
--brand-800: 114 4 4;
|
|
117
|
+
--brand-900: 72 2 2;
|
|
118
|
+
--brand-950: 41 0 0;
|
|
119
|
+
|
|
120
|
+
/* ── Semantic — REASSIGNED ────────────────────────────────── */
|
|
121
|
+
--success: 13 128 75;
|
|
122
|
+
--success-bg: 6 160 93 / 0.12;
|
|
123
|
+
--warning: 100 80 1;
|
|
124
|
+
--warning-bg: 161 131 18 / 0.14;
|
|
125
|
+
/* Amber. The collision between a red brand and a red danger state
|
|
126
|
+
cannot be solved by moving the hue — every credible danger red
|
|
127
|
+
sits within a few degrees of the brand. Moving the MEANING can. */
|
|
128
|
+
--destructive: 115 71 9;
|
|
129
|
+
--destructive-bg: 187 116 2 / 0.14;
|
|
130
|
+
--destructive-foreground: 255 255 255;
|
|
131
|
+
--info: 130 62 210;
|
|
132
|
+
--info-bg: 155 97 235 / 0.12;
|
|
133
|
+
|
|
134
|
+
/* ── Categorical series ───────────────────────────────────── */
|
|
135
|
+
/* Constant lightness so no series outranks another; chroma tuned per
|
|
136
|
+
hue so each is equally vivid rather than equally saturated. */
|
|
137
|
+
--series-1: 226 74 62;
|
|
138
|
+
--series-2: 153 100 229;
|
|
139
|
+
--series-3: 9 160 93;
|
|
140
|
+
--series-4: 186 116 4;
|
|
141
|
+
--series-5: 2 137 234;
|
|
142
|
+
--series-6: 14 154 148;
|
|
143
|
+
--series-7: 212 73 150;
|
|
144
|
+
--series-8: 113 149 3;
|
|
145
|
+
|
|
146
|
+
/* ── Elevation ────────────────────────────────────────────── */
|
|
147
|
+
--shadow-sm: 0 0 0 1px oklch(0 0 0 / 0.06), 0 1px 2px -1px oklch(0 0 0 / 0.06), 0 2px 4px 0 oklch(0 0 0 / 0.04);
|
|
148
|
+
--shadow-md: 0 0 0 1px oklch(0 0 0 / 0.06), 0 2px 4px -2px oklch(0 0 0 / 0.08), 0 4px 10px -2px oklch(0 0 0 / 0.06);
|
|
149
|
+
--shadow-lg: 0 0 0 1px oklch(0 0 0 / 0.06), 0 6px 16px -4px oklch(0 0 0 / 0.12);
|
|
150
|
+
--shadow-xl: 0 0 0 1px oklch(0 0 0 / 0.06), 0 12px 32px -8px oklch(0 0 0 / 0.18);
|
|
151
|
+
--shadow-2xl: 0 0 0 1px oklch(0 0 0 / 0.06), 0 24px 56px -12px oklch(0 0 0 / 0.24);
|
|
152
|
+
--shadow-glow: 0 0 20px oklch(0 0 0 / 0);
|
|
153
|
+
--card-shadow-rest: 0 0 0 1px oklch(0 0 0 / 0.06), 0 1px 2px -1px oklch(0 0 0 / 0.06), 0 2px 4px 0 oklch(0 0 0 / 0.04), inset 0 1px 0 0 oklch(1 0 0 / 0.9);
|
|
154
|
+
--card-shadow-hover: 0 0 0 1px oklch(0 0 0 / 0.08), 0 2px 4px -1px oklch(0 0 0 / 0.08), 0 6px 14px -2px oklch(0 0 0 / 0.08), inset 0 1px 0 0 oklch(1 0 0 / 0.9);
|
|
155
|
+
--inset-highlight: 255 255 255 / 0.9;
|
|
156
|
+
--modal-overlay: 0 0 0 / 0.32;
|
|
157
|
+
/* Solid, matching the base theme — a 3px translucent halo measures ~1.4:1
|
|
158
|
+
against its surface, under the 3:1 WCAG 2.2 SC 2.4.11 asks of a focus
|
|
159
|
+
indicator. See the note on --ring-focus in tokens.css. */
|
|
160
|
+
--ring-focus: 0 0 0 2px rgb(var(--accent));
|
|
161
|
+
--ring-error: 0 0 0 2px rgb(var(--destructive));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/*
|
|
165
|
+
* Dark. Derived by SELECTING different steps from the same OKLCH ramps,
|
|
166
|
+
* not by inverting the light values — mechanical inversion is what
|
|
167
|
+
* produces muddy dark modes. The ink ramp supplies the surfaces here,
|
|
168
|
+
* which is the same navy that supplies the text in light.
|
|
169
|
+
*/
|
|
170
|
+
[data-ds="v2"][data-theme="dark"] {
|
|
171
|
+
--page-bg: 11 16 28;
|
|
172
|
+
--background: 11 16 28;
|
|
173
|
+
--main-content-bg: 11 16 28;
|
|
174
|
+
--bg-surface: 27 35 51;
|
|
175
|
+
--surface-frame: 27 35 51;
|
|
176
|
+
--card-frame-bg: 27 35 51;
|
|
177
|
+
--bg-card: 48 58 80;
|
|
178
|
+
--card: 48 58 80;
|
|
179
|
+
--tray-bg: 48 58 80;
|
|
180
|
+
--bg-elevated: 70 82 109;
|
|
181
|
+
--surface-raised: 70 82 109;
|
|
182
|
+
--popover: 70 82 109;
|
|
183
|
+
--bg-input: 27 35 51;
|
|
184
|
+
--bg-card-hover: 70 82 109;
|
|
185
|
+
--bg-input-hover: 48 58 80;
|
|
186
|
+
--muted: 48 58 80;
|
|
187
|
+
--canvas-placement-bg: 27 35 51;
|
|
188
|
+
--foreground: 250 251 252;
|
|
189
|
+
--card-foreground: 250 251 252;
|
|
190
|
+
--popover-foreground: 250 251 252;
|
|
191
|
+
--text-secondary: 192 193 195;
|
|
192
|
+
--muted-foreground: 192 193 195;
|
|
193
|
+
--text-tertiary: 162 163 165;
|
|
194
|
+
--text-muted: 133 134 136;
|
|
195
|
+
--secondary: 48 58 80;
|
|
196
|
+
--secondary-foreground: 250 251 252;
|
|
197
|
+
--border: 255 255 255 / 0.08;
|
|
198
|
+
--border-strong: 255 255 255 / 0.14;
|
|
199
|
+
--border-card: 255 255 255 / 0.08;
|
|
200
|
+
--border-input: 255 255 255 / 0.14;
|
|
201
|
+
--main-content-border: 255 255 255 / 0.08;
|
|
202
|
+
/* Accents brighten in dark — the light-mode steps go muddy on a dark
|
|
203
|
+
surface because the surrounding lightness has moved. */
|
|
204
|
+
--accent: 228 70 58;
|
|
205
|
+
--accent-bright: 251 114 99;
|
|
206
|
+
--accent-hover: 251 114 99;
|
|
207
|
+
--primary: 228 70 58;
|
|
208
|
+
--primary-hover: 251 114 99;
|
|
209
|
+
--success: 80 188 126;
|
|
210
|
+
--warning: 190 160 64;
|
|
211
|
+
--destructive: 218 145 55;
|
|
212
|
+
--info: 181 134 254;
|
|
213
|
+
--success-bg: 6 160 93 / 0.16;
|
|
214
|
+
--warning-bg: 161 131 18 / 0.16;
|
|
215
|
+
--destructive-bg: 187 116 2 / 0.16;
|
|
216
|
+
--info-bg: 155 97 235 / 0.16;
|
|
217
|
+
/* Layered depth shadows are invisible on dark; a single ring reads. */
|
|
218
|
+
--shadow-sm: 0 0 0 1px oklch(1 0 0 / 0.08);
|
|
219
|
+
--shadow-md: 0 0 0 1px oklch(1 0 0 / 0.08), 0 4px 12px oklch(0 0 0 / 0.4);
|
|
220
|
+
--shadow-lg: 0 0 0 1px oklch(1 0 0 / 0.08), 0 8px 24px oklch(0 0 0 / 0.5);
|
|
221
|
+
--shadow-xl: 0 0 0 1px oklch(1 0 0 / 0.10), 0 16px 40px oklch(0 0 0 / 0.55);
|
|
222
|
+
--shadow-2xl: 0 0 0 1px oklch(1 0 0 / 0.10), 0 24px 60px oklch(0 0 0 / 0.6);
|
|
223
|
+
--card-shadow-rest: 0 0 0 1px oklch(1 0 0 / 0.08);
|
|
224
|
+
--card-shadow-hover: 0 0 0 1px oklch(1 0 0 / 0.14);
|
|
225
|
+
--inset-highlight: 255 255 255 / 0.05;
|
|
226
|
+
--modal-overlay: 0 0 0 / 0.7;
|
|
227
|
+
--ring-focus: 0 0 0 2px rgb(var(--accent));
|
|
228
|
+
}
|
package/dist/tokens.css
CHANGED
|
@@ -33,6 +33,14 @@
|
|
|
33
33
|
* --destructive(-bg, -foreground)
|
|
34
34
|
* • Folder: --folder-red/amber/emerald/teal/blue/violet/pink/
|
|
35
35
|
* slate/ink (categorical palette for folder accents)
|
|
36
|
+
* • Series: --series-1…8 (categorical CHART palette; ADR-146 D2.
|
|
37
|
+
* theme-INDEPENDENT, and the SLOT ORDER IS LOAD-BEARING
|
|
38
|
+
* — see the block near the end of this file before
|
|
39
|
+
* "tidying" it)
|
|
40
|
+
* • Chart: --chart-grid, --chart-axis, --chart-band (chart
|
|
41
|
+
* structure — gridlines, the darker baseline rule, and
|
|
42
|
+
* the hover band; ADR-146 D3. Theme-tuned, and all
|
|
43
|
+
* three ALREADY CARRY ALPHA — never add a second one)
|
|
36
44
|
* • Spacing: --space-1…12 (4 / 8 / 12 / 16 / 20 / 24 / 32 / 40 / 48)
|
|
37
45
|
* • Radius: --radius-xs/sm/md/lg/xl/2xl/full, --radius (legacy)
|
|
38
46
|
* • Motion: --ease-out, --ease-spring, --ease-in-out,
|
|
@@ -95,6 +103,14 @@
|
|
|
95
103
|
--accent-muted: 207 14 15 / 0.12;
|
|
96
104
|
--accent-subtle: 207 14 15 / 0.06;
|
|
97
105
|
--accent-glow: 207 14 15 / 0.25;
|
|
106
|
+
/* Text-selection highlight. PUBLIC, and a full colour (not a triple) so
|
|
107
|
+
`::selection { background: var(--selection-bg) }` is valid at :root.
|
|
108
|
+
`@lovett/shell` ships that exact global rule while defining the
|
|
109
|
+
variable only inside `.cs-frame`; unset at the root, `background`
|
|
110
|
+
computed to transparent and every selection in the app was invisible
|
|
111
|
+
(ADR-145 amendment, 2026-09-04). Neutral blue like a native selection,
|
|
112
|
+
not the accent — the accent earns impact from scarcity. */
|
|
113
|
+
--selection-bg: rgb(var(--info) / 0.34);
|
|
98
114
|
/* Ink ON an accent fill. PUBLIC, and theme-independent because --accent is:
|
|
99
115
|
the brand red does not change between light and dark, so its foreground
|
|
100
116
|
must not either. Measures 5.64:1 on --accent.
|
|
@@ -180,6 +196,34 @@
|
|
|
180
196
|
|
|
181
197
|
--border: 255 255 255 / 0.08;
|
|
182
198
|
--border-strong: 255 255 255 / 0.14;
|
|
199
|
+
|
|
200
|
+
/* ============================================================
|
|
201
|
+
CHART STRUCTURE — PUBLIC, theme-tuned (ADR-146 D3).
|
|
202
|
+
The greys a chart needs that are NOT a card border, plus the
|
|
203
|
+
hover-band fill. This is the "structure is required, not banned"
|
|
204
|
+
layer of the data-display recipe (CLAUDE.md §2): gridlines and a
|
|
205
|
+
baseline are what make a plot legible, and deleting them is the
|
|
206
|
+
flat/floating defect, not a cleanup.
|
|
207
|
+
|
|
208
|
+
--chart-axis IS DELIBERATELY DARKER THAN --chart-grid. The
|
|
209
|
+
baseline rule must outrank the gridlines. Every chart in the
|
|
210
|
+
Metoric kit draws it that way (#111111 baseline vs #dfe1e6 grid)
|
|
211
|
+
and it is the single detail that does most for chart legibility.
|
|
212
|
+
It lives as its own token precisely so it cannot drift back to
|
|
213
|
+
"same grey as the grid".
|
|
214
|
+
|
|
215
|
+
ALL THREE ALREADY CARRY AN ALPHA — they composite onto whichever
|
|
216
|
+
panel they sit on, so the panel stays opaque and the structure
|
|
217
|
+
stays translucent. Consume as `rgb(var(--chart-grid))` and NEVER
|
|
218
|
+
as `rgb(var(--chart-grid) / 0.5)`: a second alpha expands to
|
|
219
|
+
`rgb(255 255 255 / 0.07 / 0.5)`, which is invalid CSS and is
|
|
220
|
+
SILENTLY DISCARDED. `__tests__/token-shape.test.ts` fails on
|
|
221
|
+
exactly that shape.
|
|
222
|
+
============================================================ */
|
|
223
|
+
--chart-grid: 255 255 255 / 0.07;
|
|
224
|
+
--chart-axis: 255 255 255 / 0.22;
|
|
225
|
+
--chart-band: 255 255 255 / 0.05;
|
|
226
|
+
|
|
183
227
|
/* Semantic — PUBLIC */
|
|
184
228
|
--success: 16 185 129;
|
|
185
229
|
--success-bg: 16 185 129 / 0.12;
|
|
@@ -460,6 +504,7 @@
|
|
|
460
504
|
[data-theme="light"], [data-theme="combo"] {
|
|
461
505
|
/* Brand accent — base stays, hover darkens, glow softens */
|
|
462
506
|
--accent-hover: 178 8 9;
|
|
507
|
+
--selection-bg: rgb(var(--info) / 0.24);
|
|
463
508
|
/* Brand red passes on a light card (5.64:1) — see the :root note. */
|
|
464
509
|
--accent-ink: var(--accent);
|
|
465
510
|
/* Solved against the DARKEST tint these inks land on, not the lightest.
|
|
@@ -518,6 +563,14 @@
|
|
|
518
563
|
|
|
519
564
|
--border: 0 0 0 / 0.12;
|
|
520
565
|
--border-strong: 0 0 0 / 0.20;
|
|
566
|
+
|
|
567
|
+
/* Chart structure — see the :root block for the reasoning. The same
|
|
568
|
+
two invariants hold in light: --chart-axis stays darker than
|
|
569
|
+
--chart-grid, and all three already carry their alpha. */
|
|
570
|
+
--chart-grid: 0 0 0 / 0.08;
|
|
571
|
+
--chart-axis: 0 0 0 / 0.24;
|
|
572
|
+
--chart-band: 0 0 0 / 0.04;
|
|
573
|
+
|
|
521
574
|
/* Bumped from 0.16 → 0.22 — inputs on a white --bg-input (above) sitting
|
|
522
575
|
* inside a Card (--bg-card = 255 / same as input) need a stronger border
|
|
523
576
|
* to delineate. The 0.16 value worked when --bg-input was slate-tinted; on
|
|
@@ -804,3 +857,71 @@
|
|
|
804
857
|
--media-on-scrim: 255 255 255 / 0.88;
|
|
805
858
|
--media-overlay-btn: 255 255 255 / 0.14;
|
|
806
859
|
}
|
|
860
|
+
|
|
861
|
+
/* ============================================================
|
|
862
|
+
CATEGORICAL SERIES PALETTE (theme-INDEPENDENT) — PUBLIC
|
|
863
|
+
------------------------------------------------------------
|
|
864
|
+
The chart series palette (ADR-146 D2). Hues carried over from
|
|
865
|
+
`theme-v2.css`, which designed them at constant lightness ~0.62
|
|
866
|
+
and then never shipped a consumer.
|
|
867
|
+
|
|
868
|
+
THEME-INDEPENDENT ON PURPOSE, and verified rather than assumed:
|
|
869
|
+
lightness 0.62 sits inside BOTH the light band (0.43-0.77) and the
|
|
870
|
+
dark band (0.48-0.67), and all eight clear 3:1 against #ffffff,
|
|
871
|
+
against --surface-frame (#f7f7f9) and against dark --surface-card
|
|
872
|
+
(#1b1b1e). Same precedent as --hierarchy-* and --platform-* above:
|
|
873
|
+
one block, no light/dark override.
|
|
874
|
+
|
|
875
|
+
BARE TRIPLES. The call site owns the alpha — a line is
|
|
876
|
+
`rgb(var(--series-1))` and the area under it is
|
|
877
|
+
`rgb(var(--series-1) / 0.12)`. A baked-in alpha would expand to
|
|
878
|
+
`rgb(2 137 234 / 0.3 / 0.12)`, which is invalid and silently
|
|
879
|
+
dropped, and it would make the token un-shareable between the two
|
|
880
|
+
uses.
|
|
881
|
+
|
|
882
|
+
------------------------------------------------------------
|
|
883
|
+
THE SLOT ORDER IS LOAD-BEARING. DO NOT "TIDY" IT.
|
|
884
|
+
------------------------------------------------------------
|
|
885
|
+
The order was chosen by measurement (the dataviz skill's
|
|
886
|
+
validate_palette.js, adjacent-pair list, both modes), not by eye.
|
|
887
|
+
The order declared in theme-v2.css FAILS — teal against pink is
|
|
888
|
+
ΔE 1.2 for a deuteranope. This order passes all five checks in
|
|
889
|
+
both themes: worst adjacent pair ΔE 13.2 deutan / 21.0 normal,
|
|
890
|
+
identical light and dark. Re-ordering the slots breaks that, and
|
|
891
|
+
nothing in the build will tell you.
|
|
892
|
+
|
|
893
|
+
Three placements are deliberate:
|
|
894
|
+
• BLUE IS SLOT 1, not red. Slot 1 is the single-series default,
|
|
895
|
+
so a red slot 1 would paint every one-series chart in the
|
|
896
|
+
brand accent and destroy accent scarcity. Blue carries no
|
|
897
|
+
product meaning.
|
|
898
|
+
• RED IS SLOT 8. Red is reserved for --accent and
|
|
899
|
+
--destructive. It only enters a chart at eight series, where
|
|
900
|
+
the reader has bigger problems. It stays in the palette so
|
|
901
|
+
the eight-slot contract holds rather than being deleted.
|
|
902
|
+
• GREEN (slot 2) AND RED (slot 8) ARE FAR APART, so a
|
|
903
|
+
two-series chart never accidentally reads as pass/fail.
|
|
904
|
+
|
|
905
|
+
THE SCATTER / ALL-PAIRS CAP. Forms where any two marks can touch
|
|
906
|
+
— scatter, bubble, choropleth, small multiples — take the harder
|
|
907
|
+
all-pairs test, which no ordering of these eight can pass. Those
|
|
908
|
+
forms use ONLY slots 1, 6 and 7 (blue / amber / teal: verified
|
|
909
|
+
all-pairs in both modes, worst ΔE 14.8, all five checks PASS) and
|
|
910
|
+
CAP AT THREE SERIES. A fourth folds into "Other" or facets into
|
|
911
|
+
small multiples. Never generate a ninth hue.
|
|
912
|
+
|
|
913
|
+
Resolution is a frozen literal lookup in the primitive, never a
|
|
914
|
+
constructed name (ADR-146 D8): `--series-${i}` that misses yields
|
|
915
|
+
an undefined property, which makes rgb() invalid, which the
|
|
916
|
+
browser discards in silence with every gate still green.
|
|
917
|
+
============================================================ */
|
|
918
|
+
:root {
|
|
919
|
+
--series-1: 2 137 234; /* blue */
|
|
920
|
+
--series-2: 9 160 93; /* green */
|
|
921
|
+
--series-3: 153 100 229; /* violet */
|
|
922
|
+
--series-4: 113 149 3; /* olive */
|
|
923
|
+
--series-5: 212 73 150; /* pink */
|
|
924
|
+
--series-6: 186 116 4; /* amber */
|
|
925
|
+
--series-7: 14 154 148; /* teal */
|
|
926
|
+
--series-8: 226 74 62; /* red */
|
|
927
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lovett/ui",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Design system primitives, tokens, layouts, and patterns for the Lovett portfolio.",
|
|
@@ -55,6 +55,13 @@
|
|
|
55
55
|
"@dnd-kit/core": "^6.3.1",
|
|
56
56
|
"@dnd-kit/sortable": "^10.0.0",
|
|
57
57
|
"@dnd-kit/utilities": "^3.2.2",
|
|
58
|
+
"@tiptap/core": "3.31.3",
|
|
59
|
+
"@tiptap/extension-mention": "3.31.3",
|
|
60
|
+
"@tiptap/extension-placeholder": "3.31.3",
|
|
61
|
+
"@tiptap/markdown": "3.31.3",
|
|
62
|
+
"@tiptap/pm": "3.31.3",
|
|
63
|
+
"@tiptap/react": "3.31.3",
|
|
64
|
+
"@tiptap/starter-kit": "3.31.3",
|
|
58
65
|
"clsx": "^2.1.1",
|
|
59
66
|
"mammoth": "^1.12.0",
|
|
60
67
|
"react-markdown": "^10.1.0",
|