@ceebee/ui 0.5.2 → 1.0.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/index.js CHANGED
@@ -1,6 +1,4 @@
1
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { isValidElement, cloneElement } from 'react';
3
- import { ChevronRight, Check } from 'lucide-react';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
2
 
5
3
  // src/lib/cn.ts
6
4
  function cn(...parts) {
@@ -94,220 +92,36 @@ function Heading({ level = 2, size, className, children }) {
94
92
  const resolved = size ?? ["3xl", "2xl", "xl", "lg"][level - 1] ?? "lg";
95
93
  return /* @__PURE__ */ jsx(Tag, { className: cn("cb-heading", `cb-text--${resolved}`, className), children });
96
94
  }
97
- function LinkButton({
98
- variant = "solid",
99
- tone = "brand",
100
- size = "md",
101
- iconStart,
102
- iconEnd,
103
- className,
104
- children,
105
- render,
106
- ...rest
107
- }) {
108
- const iconOnly = children === void 0 || children === null || children === false || children === "";
109
- const classes = cn(
110
- "cb-button",
111
- "cb-link-button",
112
- `cb-button--${variant}`,
113
- `cb-button--${size}`,
114
- iconOnly && "cb-button--icon",
115
- className
116
- );
117
- const body = /* @__PURE__ */ jsxs(Fragment, { children: [
118
- iconStart,
119
- iconOnly ? null : /* @__PURE__ */ jsx("span", { className: "cb-button__label", children }),
120
- iconOnly ? null : iconEnd
121
- ] });
122
- if (render && isValidElement(render)) {
123
- return cloneElement(render, {
124
- className: cn(classes, render.props.className),
125
- "data-tone": tone,
126
- ...rest,
127
- children: body
128
- });
129
- }
130
- return /* @__PURE__ */ jsx(
131
- "a",
132
- {
133
- className: cn(
134
- "cb-button",
135
- "cb-link-button",
136
- `cb-button--${variant}`,
137
- `cb-button--${size}`,
138
- iconOnly && "cb-button--icon",
139
- className
140
- ),
141
- "data-tone": tone,
142
- ...rest,
143
- children: body
144
- }
145
- );
146
- }
147
- function Divider({ children, orientation = "horizontal", className }) {
148
- if (orientation === "vertical") {
149
- return /* @__PURE__ */ jsx("span", { className: cn("cb-divider", "cb-divider--vertical", className), role: "separator", "aria-orientation": "vertical" });
150
- }
151
- if (children) {
152
- return /* @__PURE__ */ jsx("div", { className: cn("cb-divider", "cb-divider--labelled", className), role: "separator", children: /* @__PURE__ */ jsx("span", { className: "cb-divider__label", children }) });
153
- }
154
- return /* @__PURE__ */ jsx("hr", { className: cn("cb-divider", className) });
155
- }
156
- function Badge({ children, tone = "neutral", variant = "soft", size = "md", dot, className }) {
157
- return /* @__PURE__ */ jsxs("span", { className: cn("cb-badge", `cb-badge--${variant}`, `cb-badge--${size}`, className), "data-tone": tone, children: [
158
- dot ? /* @__PURE__ */ jsx("span", { className: "cb-badge__dot", "aria-hidden": "true" }) : null,
159
- children
160
- ] });
161
- }
162
- function Empty({ title, description, icon, actions, variant = "first-run", className }) {
163
- return /* @__PURE__ */ jsxs("div", { className: cn("cb-empty", className), "data-variant": variant, children: [
164
- icon ? /* @__PURE__ */ jsx("span", { className: "cb-empty__icon", children: icon }) : null,
165
- /* @__PURE__ */ jsx("p", { className: "cb-empty__title", children: title }),
166
- description ? /* @__PURE__ */ jsx("p", { className: "cb-empty__description", children: description }) : null,
167
- actions ? /* @__PURE__ */ jsx("div", { className: "cb-empty__actions", children: actions }) : null
168
- ] });
169
- }
170
- function Spin({ size = "md", tone = "brand", label, className }) {
171
- return /* @__PURE__ */ jsx(
172
- "span",
173
- {
174
- className: cn("cb-spin", `cb-spin--${size}`, className),
175
- "data-tone": tone,
176
- role: label ? "status" : void 0,
177
- "aria-label": label,
178
- "aria-hidden": label ? void 0 : true
179
- }
180
- );
181
- }
182
- function ProgressBar({ value, max = 100, tone = "brand", size = "md", label, showValue, className }) {
183
- const indeterminate = value === void 0;
184
- const clamped = indeterminate ? 0 : Math.min(Math.max(value, 0), max);
185
- const percent = max > 0 ? Math.round(clamped / max * 100) : 0;
186
- return /* @__PURE__ */ jsxs("div", { className: cn("cb-progress", className), "data-tone": tone, "data-size": size, children: [
187
- /* @__PURE__ */ jsx(
188
- "div",
189
- {
190
- className: "cb-progress__track",
191
- role: "progressbar",
192
- "aria-label": label,
193
- "aria-valuemin": indeterminate ? void 0 : 0,
194
- "aria-valuemax": indeterminate ? void 0 : max,
195
- "aria-valuenow": indeterminate ? void 0 : clamped,
196
- children: /* @__PURE__ */ jsx(
197
- "div",
198
- {
199
- className: "cb-progress__fill",
200
- "data-indeterminate": indeterminate || void 0,
201
- style: indeterminate ? void 0 : { width: `${percent}%` }
202
- }
203
- )
204
- }
205
- ),
206
- showValue && !indeterminate ? /* @__PURE__ */ jsxs("span", { className: "cb-progress__value", children: [
207
- percent,
208
- "%"
209
- ] }) : null
210
- ] });
211
- }
212
- function box({ width = "100%", height = "1rem", radius = "md", className }) {
213
- const style = { "--cb-skeleton-w": width, "--cb-skeleton-h": height };
214
- return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("cb-skeleton", `cb-radius--${radius}`, className), style });
215
- }
216
- function text({ lines = 3, lastLineWidth = "62%", className }) {
217
- return /* @__PURE__ */ jsx("span", { className: cn("cb-skeleton-text", className), children: Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsx(SkeletonBox, { height: "0.75rem", width: i === lines - 1 ? lastLineWidth : "100%" }, i)) });
218
- }
219
- function circle({ size = "2.5rem", className }) {
220
- return /* @__PURE__ */ jsx(SkeletonBox, { width: size, height: size, radius: "full", className });
221
- }
222
- var SkeletonBox = box;
223
- var Skeleton = Object.assign(box, {
224
- Text: text,
225
- Circle: circle,
226
- Rect: box
227
- });
228
- function TimelineRoot({ entries, className }) {
229
- return /* @__PURE__ */ jsx("ol", { className: cn("cb-timeline", className), children: entries.map((entry, index) => /* @__PURE__ */ jsxs("li", { className: "cb-timeline__entry", "data-tone": entry.tone ?? "neutral", children: [
230
- /* @__PURE__ */ jsx("span", { className: "cb-timeline__rail", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { className: "cb-timeline__marker", children: entry.icon }) }),
231
- /* @__PURE__ */ jsxs("div", { className: "cb-timeline__body", children: [
232
- /* @__PURE__ */ jsxs("div", { className: "cb-timeline__head", children: [
233
- /* @__PURE__ */ jsx("p", { className: "cb-timeline__title", children: entry.title }),
234
- /* @__PURE__ */ jsx("span", { className: "cb-timeline__time", children: entry.time })
95
+ function PageContainerSkeleton({ breadcrumb = true, subtitle = true, extra = true, tabs = false, lines = 4, containerSize = "lg" }) {
96
+ return /* @__PURE__ */ jsx(Container, { size: containerSize, children: /* @__PURE__ */ jsxs("section", { className: "cb-page-container cb-page-container--skeleton", "aria-hidden": "true", children: [
97
+ breadcrumb ? /* @__PURE__ */ jsx("span", { className: "cb-page-container__skeleton-breadcrumb" }) : null,
98
+ /* @__PURE__ */ jsxs("header", { className: "cb-page-container__header", children: [
99
+ /* @__PURE__ */ jsxs("div", { className: "cb-page-container__heading", children: [
100
+ /* @__PURE__ */ jsx("span", { className: "cb-page-container__skeleton-title" }),
101
+ subtitle ? /* @__PURE__ */ jsx("span", { className: "cb-page-container__skeleton-subtitle" }) : null
235
102
  ] }),
236
- entry.description ? /* @__PURE__ */ jsx("p", { className: "cb-timeline__description", children: entry.description }) : null
237
- ] })
238
- ] }, index)) });
239
- }
240
- function TimelineSkeleton({ entries = 3, className }) {
241
- return /* @__PURE__ */ jsx("div", { className: cn("cb-timeline", className), "aria-hidden": "true", children: Array.from({ length: entries }, (_, index) => /* @__PURE__ */ jsxs("div", { className: "cb-timeline__entry", children: [
242
- /* @__PURE__ */ jsx("span", { className: "cb-timeline__rail", children: /* @__PURE__ */ jsx(Skeleton.Circle, { size: "1.5rem" }) }),
243
- /* @__PURE__ */ jsxs("div", { className: "cb-timeline__body", children: [
244
- /* @__PURE__ */ jsx(Skeleton, { width: "45%", height: "0.875rem" }),
245
- /* @__PURE__ */ jsx("div", { style: { marginTop: "var(--cb-space-2)" }, children: /* @__PURE__ */ jsx(Skeleton, { width: "70%", height: "0.75rem" }) })
246
- ] })
247
- ] }, index)) });
248
- }
249
- var Timeline = Object.assign(TimelineRoot, { Skeleton: TimelineSkeleton });
250
-
251
- // src/data/progress-ring.math.ts
252
- function ringGeometry(value, max, size, thickness) {
253
- const safeMax = max > 0 ? max : 1;
254
- const clamped = Math.min(Math.max(Number.isFinite(value) ? value : 0, 0), safeMax);
255
- const radius = (size - thickness) / 2;
256
- const circumference = 2 * Math.PI * radius;
257
- const dashOffset = circumference * (1 - clamped / safeMax);
258
- return { radius, circumference, dashOffset, clamped };
103
+ extra ? /* @__PURE__ */ jsx("span", { className: "cb-page-container__skeleton-extra" }) : null
104
+ ] }),
105
+ tabs ? /* @__PURE__ */ jsx("span", { className: "cb-page-container__skeleton-tabs" }) : null,
106
+ Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx("span", { className: "cb-page-container__skeleton-line" }, index))
107
+ ] }) });
259
108
  }
260
- function ProgressRing({
261
- value,
262
- max = 100,
263
- size = 96,
264
- thickness = 10,
265
- tone = "brand",
266
- hue,
267
- children,
268
- label,
269
- className
270
- }) {
271
- const { radius, circumference, dashOffset, clamped } = ringGeometry(value, max, size, thickness);
272
- const center = size / 2;
273
- const style = {
274
- "--cb-ring-size": `${size}px`,
275
- "--cb-ring-circumference": `${circumference}`,
276
- "--cb-ring-offset": `${dashOffset}`
277
- };
278
- return /* @__PURE__ */ jsxs(
279
- "div",
280
- {
281
- className: cn("cb-ring", className),
282
- style,
283
- "data-tone": tone,
284
- "data-hue": hue,
285
- role: "img",
286
- "aria-label": `${label}: ${Math.round(clamped / (max || 1) * 100)}%`,
287
- children: [
288
- /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, "aria-hidden": "true", children: [
289
- /* @__PURE__ */ jsx("circle", { className: "cb-ring__track", cx: center, cy: center, r: radius, strokeWidth: thickness, fill: "none" }),
290
- /* @__PURE__ */ jsx(
291
- "circle",
292
- {
293
- className: "cb-ring__value",
294
- cx: center,
295
- cy: center,
296
- r: radius,
297
- strokeWidth: thickness,
298
- fill: "none",
299
- strokeLinecap: "round",
300
- strokeDasharray: circumference,
301
- strokeDashoffset: dashOffset,
302
- transform: `rotate(-90 ${center} ${center})`
303
- }
304
- )
305
- ] }),
306
- /* @__PURE__ */ jsx("div", { className: "cb-ring__center", children: children ?? `${Math.round(clamped / (max || 1) * 100)}%` })
307
- ]
308
- }
309
- );
109
+ function PageContainerRoot({ breadcrumb, title, subtitle, extra, tabs, children, containerSize = "lg" }) {
110
+ const hasHeader = title != null || subtitle != null || extra != null;
111
+ return /* @__PURE__ */ jsx(Container, { size: containerSize, children: /* @__PURE__ */ jsxs("section", { className: "cb-page-container", children: [
112
+ breadcrumb != null ? /* @__PURE__ */ jsx("div", { className: "cb-page-container__breadcrumb", children: breadcrumb }) : null,
113
+ hasHeader ? /* @__PURE__ */ jsxs("header", { className: "cb-page-container__header", children: [
114
+ /* @__PURE__ */ jsxs("div", { className: "cb-page-container__heading", children: [
115
+ title != null ? /* @__PURE__ */ jsx("div", { className: "cb-page-container__title", children: title }) : null,
116
+ subtitle != null ? /* @__PURE__ */ jsx("div", { className: "cb-page-container__subtitle", children: subtitle }) : null
117
+ ] }),
118
+ extra != null ? /* @__PURE__ */ jsx("div", { className: "cb-page-container__extra", children: extra }) : null
119
+ ] }) : null,
120
+ tabs != null ? /* @__PURE__ */ jsx("div", { className: "cb-page-container__tabs", children: tabs }) : null,
121
+ children != null ? /* @__PURE__ */ jsx("div", { className: "cb-page-container__body", children }) : null
122
+ ] }) });
310
123
  }
124
+ var PageContainer = Object.assign(PageContainerRoot, { Skeleton: PageContainerSkeleton });
311
125
 
312
126
  // src/data/donut.math.ts
313
127
  function donutArcs(slices, circumference) {
@@ -414,8 +228,6 @@ function BarMini({ values, width = 120, height = 32, tone = "brand", hue, label,
414
228
  );
415
229
  }) }) });
416
230
  }
417
-
418
- // src/media/avatar.util.ts
419
231
  var HUES = ["violet", "blue", "teal", "green", "amber", "rose"];
420
232
  function initialsOf(name) {
421
233
  const words = name.trim().split(/\s+/).filter(Boolean);
@@ -429,31 +241,6 @@ function hueForName(name) {
429
241
  for (let i = 0; i < name.length; i += 1) hash = hash * 31 + name.charCodeAt(i) >>> 0;
430
242
  return HUES[hash % HUES.length];
431
243
  }
432
- function Avatar({ name, src, size = "md", hue, status, className }) {
433
- return /* @__PURE__ */ jsxs(
434
- "span",
435
- {
436
- className: cn("cb-avatar", `cb-avatar--${size}`, className),
437
- "data-hue": hue ?? hueForName(name),
438
- role: "img",
439
- "aria-label": name,
440
- children: [
441
- /* @__PURE__ */ jsx("span", { className: "cb-avatar__initials", "aria-hidden": "true", children: initialsOf(name) }),
442
- src ? /* @__PURE__ */ jsx("img", { className: "cb-avatar__image", src, alt: "", loading: "lazy" }) : null,
443
- status ? /* @__PURE__ */ jsx("span", { className: "cb-avatar__status", "data-status": status, "aria-hidden": "true" }) : null
444
- ]
445
- }
446
- );
447
- }
448
- function AvatarGroup({ children, overflow, size = "md", className }) {
449
- return /* @__PURE__ */ jsxs("span", { className: cn("cb-avatar-group", className), children: [
450
- children,
451
- overflow && overflow > 0 ? /* @__PURE__ */ jsx("span", { className: cn("cb-avatar", `cb-avatar--${size}`, "cb-avatar--overflow"), children: /* @__PURE__ */ jsxs("span", { className: "cb-avatar__initials", children: [
452
- "+",
453
- overflow
454
- ] }) }) : null
455
- ] });
456
- }
457
244
  function LeaderboardRoot({ entries, label, medals = true, className }) {
458
245
  return /* @__PURE__ */ jsx("ol", { className: cn("cb-leaderboard", className), "aria-label": label, children: entries.map((entry, index) => {
459
246
  const rank = index + 1;
@@ -465,7 +252,19 @@ function LeaderboardRoot({ entries, label, medals = true, className }) {
465
252
  "data-you": entry.you || void 0,
466
253
  children: [
467
254
  /* @__PURE__ */ jsx("span", { className: "cb-leaderboard__rank", "aria-hidden": "true", children: rank }),
468
- /* @__PURE__ */ jsx(Avatar, { name: entry.name, src: entry.avatarSrc, size: "sm", hue: entry.hue }),
255
+ /* @__PURE__ */ jsxs(
256
+ "span",
257
+ {
258
+ className: "cb-leaderboard__avatar",
259
+ "data-hue": entry.hue ?? hueForName(entry.name),
260
+ role: "img",
261
+ "aria-label": entry.name,
262
+ children: [
263
+ /* @__PURE__ */ jsx("span", { className: "cb-leaderboard__initials", "aria-hidden": "true", children: initialsOf(entry.name) }),
264
+ entry.avatarSrc ? /* @__PURE__ */ jsx("img", { className: "cb-leaderboard__photo", src: entry.avatarSrc, alt: "", loading: "lazy" }) : null
265
+ ]
266
+ }
267
+ ),
469
268
  /* @__PURE__ */ jsxs("span", { className: "cb-leaderboard__text", children: [
470
269
  /* @__PURE__ */ jsxs("span", { className: "cb-leaderboard__name", children: [
471
270
  entry.name,
@@ -481,68 +280,6 @@ function LeaderboardRoot({ entries, label, medals = true, className }) {
481
280
  );
482
281
  }) });
483
282
  }
484
- function LeaderboardSkeleton({ rows = 5, className }) {
485
- return /* @__PURE__ */ jsx("div", { className: cn("cb-leaderboard", className), "aria-hidden": "true", children: Array.from({ length: rows }, (_, index) => /* @__PURE__ */ jsxs("div", { className: "cb-leaderboard__row", children: [
486
- /* @__PURE__ */ jsx("span", { className: "cb-leaderboard__rank", children: /* @__PURE__ */ jsx(Skeleton, { width: "0.75rem", height: "0.75rem" }) }),
487
- /* @__PURE__ */ jsx(Skeleton.Circle, { size: "1.75rem" }),
488
- /* @__PURE__ */ jsx("span", { className: "cb-leaderboard__text", children: /* @__PURE__ */ jsx(Skeleton, { width: "7rem", height: "0.875rem" }) }),
489
- /* @__PURE__ */ jsx(Skeleton, { width: "2.5rem", height: "0.875rem" })
490
- ] }, index)) });
491
- }
492
- var Leaderboard = Object.assign(LeaderboardRoot, { Skeleton: LeaderboardSkeleton });
493
- function Breadcrumb({ items, maxItems = 4, className }) {
494
- const collapsed = items.length > maxItems ? [items[0], { label: "\u2026" }, ...items.slice(items.length - (maxItems - 2))] : items;
495
- return /* @__PURE__ */ jsx("nav", { className: cn("cb-crumbs", className), "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: "cb-crumbs__list", children: collapsed.map((crumb, index) => {
496
- const isLast = index === collapsed.length - 1;
497
- return /* @__PURE__ */ jsxs("li", { className: "cb-crumbs__item", children: [
498
- isLast ? /* @__PURE__ */ jsx("span", { className: "cb-crumbs__current", "aria-current": "page", children: crumb.label }) : crumb.href ? /* @__PURE__ */ jsx("a", { className: "cb-crumbs__link", href: crumb.href, children: crumb.label }) : /* @__PURE__ */ jsx("span", { className: "cb-crumbs__text", children: crumb.label }),
499
- isLast ? null : /* @__PURE__ */ jsx(ChevronRight, { size: 14, className: "cb-crumbs__separator", "aria-hidden": "true" })
500
- ] }, `${String(crumb.label)}-${index}`);
501
- }) }) });
502
- }
503
- function Steps({ steps, current, orientation = "horizontal", className }) {
504
- return /* @__PURE__ */ jsx("ol", { className: cn("cb-steps", `cb-steps--${orientation}`, className), children: steps.map((step, index) => {
505
- const state = index < current ? "done" : index === current ? "current" : "todo";
506
- return /* @__PURE__ */ jsxs("li", { className: "cb-steps__step", "data-state": state, children: [
507
- /* @__PURE__ */ jsx("span", { className: "cb-steps__marker", "aria-hidden": "true", children: state === "done" ? /* @__PURE__ */ jsx(Check, { size: 13, strokeWidth: 3 }) : index + 1 }),
508
- /* @__PURE__ */ jsxs("span", { className: "cb-steps__text", children: [
509
- /* @__PURE__ */ jsxs("span", { className: "cb-steps__label", children: [
510
- step.label,
511
- /* @__PURE__ */ jsx("span", { className: "cb-visually-hidden", children: state === "done" ? " (completed)" : state === "current" ? " (current step)" : "" })
512
- ] }),
513
- step.description ? /* @__PURE__ */ jsx("span", { className: "cb-steps__description", children: step.description }) : null
514
- ] })
515
- ] }, index);
516
- }) });
517
- }
518
- function Statistic({ label, value, delta, caption, hue, icon, visual, className }) {
519
- return /* @__PURE__ */ jsxs(Surface, { variant: "tinted", hue, radius: "lg", padding: "md", className: cn("cb-stat", className), children: [
520
- /* @__PURE__ */ jsxs("div", { className: "cb-stat__head", children: [
521
- /* @__PURE__ */ jsx(Text, { size: "sm", tone: "muted", weight: "medium", children: label }),
522
- icon ? /* @__PURE__ */ jsx("span", { className: "cb-stat__icon", children: icon }) : null
523
- ] }),
524
- /* @__PURE__ */ jsxs("div", { className: "cb-stat__body", children: [
525
- /* @__PURE__ */ jsxs("div", { children: [
526
- /* @__PURE__ */ jsx("p", { className: "cb-stat__value cb-numeric", children: value }),
527
- delta ? /* @__PURE__ */ jsx("span", { className: "cb-stat__delta", "data-direction": delta.direction, children: delta.value }) : null,
528
- caption ? /* @__PURE__ */ jsx(Text, { size: "xs", tone: "subtle", className: "cb-stat__caption", children: caption }) : null
529
- ] }),
530
- visual ? /* @__PURE__ */ jsx("div", { className: "cb-stat__visual", children: visual }) : null
531
- ] })
532
- ] });
533
- }
534
- function StatCardSkeleton({ withVisual = false, className }) {
535
- return /* @__PURE__ */ jsxs(Surface, { variant: "tinted", radius: "lg", padding: "md", className: cn("cb-stat", className), children: [
536
- /* @__PURE__ */ jsx("div", { className: "cb-stat__head", children: /* @__PURE__ */ jsx(Skeleton, { width: "7rem", height: "0.875rem" }) }),
537
- /* @__PURE__ */ jsxs("div", { className: "cb-stat__body", children: [
538
- /* @__PURE__ */ jsxs("div", { className: "cb-stat__skeleton-col", children: [
539
- /* @__PURE__ */ jsx(Skeleton, { width: "5.5rem", height: "2rem" }),
540
- /* @__PURE__ */ jsx(Skeleton, { width: "3.5rem", height: "0.75rem" })
541
- ] }),
542
- withVisual ? /* @__PURE__ */ jsx(Skeleton.Circle, { size: "4rem" }) : null
543
- ] })
544
- ] });
545
- }
546
- Statistic.Skeleton = StatCardSkeleton;
283
+ var Leaderboard = LeaderboardRoot;
547
284
 
548
- export { Avatar, AvatarGroup, Badge, BarMini, Breadcrumb, Container, Divider, Donut, Empty, Flex, Grid, Heading, Leaderboard, LinkButton, ProgressBar, ProgressRing, Skeleton, Sparkline, Spin, Statistic, Steps, Surface, Text, Timeline, cn, donutArcs, hueForName, initialsOf, ringGeometry, sparklineGeometry };
285
+ export { BarMini, Container, Donut, Flex, Grid, Heading, Leaderboard, PageContainer, PageContainerSkeleton, Sparkline, Surface, Text, cn, donutArcs, sparklineGeometry };
@@ -1,5 +1,5 @@
1
1
  /* The "Astra" skin: the violet-to-blue gradient dashboard look from the reference board.
2
- A Skin rewrites skin tokens only — never structure, never a component rule (ADR 0002). */
2
+ A Skin rewrites skin tokens only — never structure, never a component rule. */
3
3
  :root {
4
4
  --cb-hue-brand: 278;
5
5