@akhil-saxena/design-system 1.2.0 → 1.4.2

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,16 +1,18 @@
1
1
  import { X, Check, Minus, Plus, Copy, ChevronLeft, ChevronRight, ChevronDown, MoreHorizontal, Bold, Italic, Underline, Strikethrough, Code, Sun, Moon, Heading2, List, ListOrdered, Quote, Link2, XCircle, AlertTriangle, CheckCircle2, Info, Star, Clock } from './chunk-TG25XACB.js';
2
2
  export { Icon } from './chunk-TG25XACB.js';
3
- import { useComposedRefs, useReducedMotion, useClickOutside, useMatchMedia, useFocusTrap } from './chunk-FUXR6QZ3.js';
3
+ import { useComposedRefs, useReducedMotion, useSortableTable, useResizableColumns, useTableSelection, useClickOutside, useMatchMedia, useFocusTrap } from './chunk-34YNJKI2.js';
4
4
  import React, { forwardRef, useState, useRef, useEffect, createContext, useContext, useCallback, useMemo, useId, useLayoutEffect, Children, isValidElement, cloneElement, Fragment as Fragment$1 } from 'react';
5
5
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
6
  import { createPortal } from 'react-dom';
7
7
  import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
8
- import Link from '@tiptap/extension-link';
8
+ import HighlightExtension from '@tiptap/extension-highlight';
9
+ import Link4 from '@tiptap/extension-link';
9
10
  import Placeholder from '@tiptap/extension-placeholder';
10
11
  import UnderlineExtension from '@tiptap/extension-underline';
11
12
  import { useEditor, EditorContent } from '@tiptap/react';
12
13
  import StarterKit from '@tiptap/starter-kit';
13
14
  import { createLowlight } from 'lowlight';
15
+ import { Highlighter } from 'lucide-react';
14
16
  import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter, DragOverlay } from '@dnd-kit/core';
15
17
  import { useSortable, sortableKeyboardCoordinates, arrayMove, SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
16
18
  import { CSS } from '@dnd-kit/utilities';
@@ -38,12 +40,16 @@ var variantStyles = {
38
40
  borderColor: "var(--amber-d)",
39
41
  fontWeight: 600
40
42
  },
41
- // Secondary = outlined cream surface. Use for second-priority actions.
43
+ // Secondary = clean white outlined surface. Use for second-priority actions.
44
+ // Previous translucent glass (var(--g-bg) + backdrop-filter) rendered as a
45
+ // muted grey over cream and looked disabled/greyed-out. Plain white + wire
46
+ // border reads crisply on any background. Dark-mode override in primitives.css
47
+ // flips background to translucent-white over dark surfaces.
42
48
  secondary: {
43
- background: "var(--g-bg)",
44
- backdropFilter: "blur(6px)",
45
- WebkitBackdropFilter: "blur(6px)",
46
- color: "var(--ink-2)"
49
+ background: "#fff",
50
+ color: "var(--ink-2)",
51
+ borderColor: "var(--wire, rgba(0, 0, 0, 0.18))",
52
+ fontWeight: 600
47
53
  },
48
54
  // Ghost = transparent, text-only. Use for tertiary / icon-only / cancel-in-modal.
49
55
  // Color flips via `:root.dark .ds-atom-btn[data-variant="ghost"]` in primitives.css.
@@ -65,7 +71,11 @@ var sizeStyles = {
65
71
  xs: { fontSize: 10, padding: "3px 8px", borderRadius: 5 },
66
72
  sm: { fontSize: 11, padding: "5px 10px" },
67
73
  md: {},
68
- lg: { fontSize: 14, padding: "10px 20px", borderRadius: 9 }
74
+ // lg aligns with OAuthButton's shape so primary CTAs and OAuth buttons
75
+ // stack at the same height (44px) on auth/onboarding forms. fontSize: 13
76
+ // matches OAuthButton; padding swapped from 10px 20px (~40px implicit
77
+ // height) to explicit 0 20px + height 44px for a deterministic match.
78
+ lg: { fontSize: 13, height: 44, padding: "0 20px", borderRadius: 9, fontWeight: 700 }
69
79
  };
70
80
  var Button = forwardRef(function Button2({
71
81
  variant = "primary",
@@ -104,9 +114,95 @@ var Button = forwardRef(function Button2({
104
114
  function Spinner() {
105
115
  return /* @__PURE__ */ jsx("span", { className: "ds-atom-btn-spinner", "aria-hidden": "true" });
106
116
  }
117
+ var labels = {
118
+ google: "Continue with Google",
119
+ github: "Continue with GitHub",
120
+ apple: "Continue with Apple"
121
+ };
122
+ var OAuthButton = forwardRef(function OAuthButton2({ provider = "google", label, dark = false, type = "button", className, style, ...rest }, ref) {
123
+ const composedStyle = {
124
+ background: dark ? "rgba(255,255,255,.06)" : "#fff",
125
+ color: dark ? "var(--cream)" : "var(--ink-2)",
126
+ border: dark ? "1.5px solid rgba(255,255,255,.2)" : "1.5px solid var(--wire)",
127
+ ...style
128
+ };
129
+ return /* @__PURE__ */ jsxs(
130
+ "button",
131
+ {
132
+ ref,
133
+ type,
134
+ className: `ds-atom-oauthbtn${className ? ` ${className}` : ""}`,
135
+ "data-provider": provider,
136
+ "data-dark": dark ? "true" : void 0,
137
+ style: composedStyle,
138
+ ...rest,
139
+ children: [
140
+ /* @__PURE__ */ jsx(ProviderLogo, { provider }),
141
+ /* @__PURE__ */ jsx("span", { children: label ?? labels[provider] })
142
+ ]
143
+ }
144
+ );
145
+ });
146
+ function ProviderLogo({ provider }) {
147
+ if (provider === "google") return /* @__PURE__ */ jsx(GoogleLogo, {});
148
+ if (provider === "github") return /* @__PURE__ */ jsx(GitHubLogo, {});
149
+ if (provider === "apple") return /* @__PURE__ */ jsx(AppleLogo, {});
150
+ return null;
151
+ }
152
+ function GoogleLogo() {
153
+ return /* @__PURE__ */ jsxs("svg", { width: 18, height: 18, viewBox: "0 0 48 48", "aria-hidden": "true", children: [
154
+ /* @__PURE__ */ jsx(
155
+ "path",
156
+ {
157
+ fill: "#FFC107",
158
+ d: "M43.6 20.5H42V20H24v8h11.3a12 12 0 0 1-11.3 8 12 12 0 1 1 7.9-21l5.7-5.7A20 20 0 1 0 24 44a20 20 0 0 0 19.6-23.5z"
159
+ }
160
+ ),
161
+ /* @__PURE__ */ jsx(
162
+ "path",
163
+ {
164
+ fill: "#FF3D00",
165
+ d: "M6.3 14.7l6.6 4.8A12 12 0 0 1 24 12a12 12 0 0 1 7.9 3l5.7-5.7A20 20 0 0 0 6.3 14.7z"
166
+ }
167
+ ),
168
+ /* @__PURE__ */ jsx(
169
+ "path",
170
+ {
171
+ fill: "#4CAF50",
172
+ d: "M24 44a20 20 0 0 0 13.5-5.2l-6.2-5.3A12 12 0 0 1 12.7 28.3l-6.5 5A20 20 0 0 0 24 44z"
173
+ }
174
+ ),
175
+ /* @__PURE__ */ jsx(
176
+ "path",
177
+ {
178
+ fill: "#1976D2",
179
+ d: "M43.6 20.5H42V20H24v8h11.3a12 12 0 0 1-4 5.5l6.2 5.3a20 20 0 0 0 6.1-18.3z"
180
+ }
181
+ )
182
+ ] });
183
+ }
184
+ function GitHubLogo() {
185
+ return /* @__PURE__ */ jsx("svg", { width: 18, height: 18, viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
186
+ "path",
187
+ {
188
+ fill: "currentColor",
189
+ d: "M12 .3a12 12 0 0 0-3.8 23.4c.6.1.8-.3.8-.6v-2.1c-3.3.7-4-1.6-4-1.6-.6-1.4-1.4-1.8-1.4-1.8-1.1-.7.1-.7.1-.7 1.2.1 1.9 1.3 1.9 1.3 1.1 1.9 2.9 1.3 3.6 1 .1-.8.4-1.3.8-1.6-2.7-.3-5.5-1.3-5.5-6 0-1.3.5-2.4 1.3-3.3-.1-.3-.6-1.6.1-3.3 0 0 1-.3 3.3 1.3a11 11 0 0 1 6 0c2.3-1.6 3.3-1.3 3.3-1.3.7 1.7.3 3 .1 3.3a4.8 4.8 0 0 1 1.3 3.3c0 4.7-2.9 5.7-5.6 6 .5.4.9 1.2.9 2.3v3.5c0 .3.2.7.8.6A12 12 0 0 0 12 .3"
190
+ }
191
+ ) });
192
+ }
193
+ function AppleLogo() {
194
+ return /* @__PURE__ */ jsx("svg", { width: 18, height: 18, viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
195
+ "path",
196
+ {
197
+ fill: "currentColor",
198
+ d: "M17.6 12.5c0-2.2 1.8-3.2 1.9-3.3-1-1.5-2.6-1.7-3.2-1.7-1.4-.1-2.7.8-3.4.8-.7 0-1.8-.8-3-.8-1.5 0-2.9.9-3.7 2.3-1.6 2.7-.4 6.7 1.1 8.9.8 1.1 1.7 2.3 2.9 2.2 1.2 0 1.6-.8 3-.8 1.4 0 1.8.8 3 .7 1.3 0 2-1.1 2.8-2.2.9-1.3 1.2-2.5 1.3-2.6-.1 0-2.5-1-2.5-3.8zm-2.3-7c.6-.8 1.1-1.9 1-3a4 4 0 0 0-2.7 1.4c-.6.7-1.1 1.7-1 2.8 1.1.1 2.1-.5 2.7-1.2z"
199
+ }
200
+ ) });
201
+ }
107
202
  var baseInputStyle = {
108
203
  fontSize: 13,
109
- padding: "8px 10px",
204
+ height: 36,
205
+ padding: "0 10px",
110
206
  borderRadius: 8,
111
207
  border: "1px solid var(--rule)",
112
208
  background: "var(--cream)",
@@ -121,6 +217,7 @@ var wrapStyle = {
121
217
  display: "flex",
122
218
  alignItems: "center",
123
219
  gap: 8,
220
+ height: 36,
124
221
  padding: "0 10px",
125
222
  borderRadius: 8,
126
223
  border: "1px solid var(--rule)",
@@ -188,6 +285,58 @@ var TextInput = forwardRef(function TextInput2({ error, icon, prefix, suffix, kb
188
285
  }
189
286
  );
190
287
  });
288
+ var STRENGTH_LABELS = ["", "Weak", "Fair", "Good", "Strong"];
289
+ function segmentColor(index, score) {
290
+ if (score === 0 || index >= score) return "var(--ink-5)";
291
+ if (score === 1) return "var(--red)";
292
+ if (score === 4) return "var(--green-vivid)";
293
+ return "var(--amber)";
294
+ }
295
+ function labelColor(score) {
296
+ if (score <= 0) return "var(--ink-4)";
297
+ if (score === 1) return "var(--red)";
298
+ if (score <= 3) return "var(--amber-d)";
299
+ return "var(--green-vivid)";
300
+ }
301
+ function PasswordStrength({ score, className, style }) {
302
+ const label = STRENGTH_LABELS[score];
303
+ return /* @__PURE__ */ jsxs("div", { className: ["ds-atom-pwstrength", className].filter(Boolean).join(" "), style, children: [
304
+ /* @__PURE__ */ jsx("div", { className: "ds-atom-pwstrength-segs", children: [0, 1, 2, 3].map((i) => /* @__PURE__ */ jsx(
305
+ "span",
306
+ {
307
+ className: "ds-atom-pwstrength-seg",
308
+ style: { background: segmentColor(i, score) }
309
+ },
310
+ i
311
+ )) }),
312
+ label && /* @__PURE__ */ jsx("span", { className: "ds-atom-pwstrength-label", style: { color: labelColor(score) }, children: label })
313
+ ] });
314
+ }
315
+ function FieldError({ message, className }) {
316
+ if (!message) return null;
317
+ return /* @__PURE__ */ jsx("span", { role: "alert", className: ["ds-atom-field-error", className].filter(Boolean).join(" "), children: message });
318
+ }
319
+ function FormErrorSummary({
320
+ errors,
321
+ title = "Please fix the following errors:",
322
+ className
323
+ }) {
324
+ if (errors.length === 0) return null;
325
+ return /* @__PURE__ */ jsxs(
326
+ "div",
327
+ {
328
+ role: "alert",
329
+ className: ["ds-atom-form-error-summary", className].filter(Boolean).join(" "),
330
+ children: [
331
+ /* @__PURE__ */ jsx("strong", { children: title }),
332
+ /* @__PURE__ */ jsx("ul", { children: errors.map((err, i) => (
333
+ // biome-ignore lint/suspicious/noArrayIndexKey: static error list - order is stable and no unique IDs available
334
+ /* @__PURE__ */ jsx("li", { children: err }, i)
335
+ )) })
336
+ ]
337
+ }
338
+ );
339
+ }
191
340
  var baseTextareaStyle = {
192
341
  fontSize: 13,
193
342
  padding: "10px 12px",
@@ -248,7 +397,515 @@ var Textarea = forwardRef(function Textarea2({ error, className, style, maxLengt
248
397
  ) : null
249
398
  ] });
250
399
  });
400
+ var FONT_PRESETS = {
401
+ default: {
402
+ fontSize: 13,
403
+ fontFamily: "var(--font)",
404
+ fontWeight: 500,
405
+ background: "transparent",
406
+ border: "none",
407
+ borderBottom: "1px dashed var(--rule)",
408
+ padding: "2px 0"
409
+ },
410
+ mono: {
411
+ fontFamily: "var(--mono)",
412
+ fontSize: 10.5,
413
+ fontWeight: 700,
414
+ letterSpacing: ".12em",
415
+ textTransform: "uppercase",
416
+ background: "transparent",
417
+ border: "none",
418
+ borderBottom: "1px dashed var(--rule)",
419
+ padding: "4px 0"
420
+ },
421
+ serif: {
422
+ fontFamily: "'Newsreader', Georgia, serif",
423
+ fontSize: 14,
424
+ lineHeight: 1.55,
425
+ background: "var(--panel)",
426
+ border: "1px solid var(--rule)",
427
+ borderRadius: 6,
428
+ padding: "10px 12px",
429
+ resize: "vertical",
430
+ minHeight: 84
431
+ }
432
+ };
433
+ function InlineEditField({
434
+ value,
435
+ onSave,
436
+ multiline = false,
437
+ placeholder,
438
+ disabled = false,
439
+ maxLength,
440
+ ariaLabel,
441
+ font = "default",
442
+ className,
443
+ style
444
+ }) {
445
+ const [state, setState] = useState("idle");
446
+ const [draft, setDraft] = useState(value);
447
+ const [errorMsg, setErrorMsg] = useState(null);
448
+ const inputRef = useRef(null);
449
+ const textareaRef = useRef(null);
450
+ useEffect(() => {
451
+ if (state === "idle") setDraft(value);
452
+ }, [value, state]);
453
+ useEffect(() => {
454
+ if (state === "editing" || state === "error") {
455
+ if (multiline) {
456
+ textareaRef.current?.focus();
457
+ } else {
458
+ inputRef.current?.focus();
459
+ inputRef.current?.select();
460
+ }
461
+ }
462
+ }, [state, multiline]);
463
+ async function handleCommit() {
464
+ setState("saving");
465
+ setErrorMsg(null);
466
+ try {
467
+ await onSave(draft);
468
+ setState("idle");
469
+ } catch (err) {
470
+ const msg = err instanceof Error ? err.message : typeof err === "string" ? err : "Save failed";
471
+ setState("error");
472
+ setErrorMsg(msg);
473
+ }
474
+ }
475
+ function handleCancel() {
476
+ setDraft(value);
477
+ setState("idle");
478
+ setErrorMsg(null);
479
+ }
480
+ function handleKeyDown(e) {
481
+ if (e.key === "Escape") {
482
+ e.preventDefault();
483
+ handleCancel();
484
+ return;
485
+ }
486
+ if (e.key === "Enter") {
487
+ if (!multiline) {
488
+ e.preventDefault();
489
+ void handleCommit();
490
+ return;
491
+ }
492
+ if (e.metaKey || e.ctrlKey) {
493
+ e.preventDefault();
494
+ void handleCommit();
495
+ return;
496
+ }
497
+ }
498
+ }
499
+ function handleBlur() {
500
+ if (state === "editing" || state === "error") {
501
+ void handleCommit();
502
+ }
503
+ }
504
+ if (state !== "idle") {
505
+ const editStyle = { ...FONT_PRESETS[font], ...style };
506
+ const sharedProps = {
507
+ className: ["ds-atom-inlineeditfield-input", className].filter(Boolean).join(" "),
508
+ value: draft,
509
+ disabled: state === "saving",
510
+ onChange: (e) => setDraft(e.target.value),
511
+ onKeyDown: handleKeyDown,
512
+ onBlur: handleBlur,
513
+ "data-state": state,
514
+ error: state === "error",
515
+ "aria-label": ariaLabel,
516
+ maxLength,
517
+ style: editStyle
518
+ };
519
+ return /* @__PURE__ */ jsxs("span", { className: "ds-atom-inlineeditfield-wrap", children: [
520
+ multiline ? /* @__PURE__ */ jsx(Textarea, { ref: textareaRef, ...sharedProps }) : /* @__PURE__ */ jsx(TextInput, { ref: inputRef, ...sharedProps, type: "text" }),
521
+ /* @__PURE__ */ jsx(FieldError, { message: state === "error" ? errorMsg : null })
522
+ ] });
523
+ }
524
+ return /* @__PURE__ */ jsx(
525
+ "span",
526
+ {
527
+ className: ["ds-atom-inlineeditfield", className].filter(Boolean).join(" "),
528
+ "data-state": "idle",
529
+ role: "button",
530
+ tabIndex: disabled ? -1 : 0,
531
+ "aria-label": ariaLabel,
532
+ "aria-disabled": disabled,
533
+ onClick: disabled ? void 0 : () => setState("editing"),
534
+ onKeyDown: (e) => {
535
+ if ((e.key === "Enter" || e.key === " ") && !disabled) {
536
+ e.preventDefault();
537
+ setState("editing");
538
+ }
539
+ },
540
+ style,
541
+ children: value || (placeholder ? /* @__PURE__ */ jsx("span", { style: { color: "var(--ink-4)", fontStyle: "italic" }, children: placeholder }) : null)
542
+ }
543
+ );
544
+ }
251
545
  var baseStyle2 = {
546
+ display: "inline-block",
547
+ fontFamily: "var(--mono)",
548
+ fontWeight: "var(--weight-bold)",
549
+ letterSpacing: "var(--ls-wide)",
550
+ textTransform: "uppercase",
551
+ lineHeight: 1
552
+ };
553
+ var sizeStyles2 = {
554
+ xs: { fontSize: 8 },
555
+ sm: { fontSize: "var(--text-2xs)" },
556
+ md: { fontSize: "var(--text-xs)" }
557
+ };
558
+ var Eyebrow = forwardRef(function Eyebrow2({ size = "sm", color, tone, className, style, children, ...rest }, ref) {
559
+ return /* @__PURE__ */ jsx(
560
+ "span",
561
+ {
562
+ ref,
563
+ className: `ds-atom-eyebrow${className ? ` ${className}` : ""}`,
564
+ "data-tone": tone,
565
+ style: {
566
+ ...baseStyle2,
567
+ ...sizeStyles2[size],
568
+ ...color ? { color } : tone ? null : { color: "var(--ink-3)" },
569
+ ...style
570
+ },
571
+ ...rest,
572
+ children
573
+ }
574
+ );
575
+ });
576
+ var baseStyle3 = {
577
+ fontFamily: "var(--font)",
578
+ margin: 0
579
+ };
580
+ var variantStyles2 = {
581
+ body: { fontSize: "var(--text-base)", color: "var(--ink-2)" },
582
+ small: { fontSize: "var(--text-sm)", color: "var(--ink-3)" },
583
+ caption: { fontSize: "var(--text-sm)", color: "var(--ink-3)" },
584
+ legal: {
585
+ fontSize: "var(--text-xs)",
586
+ color: "var(--ink-4)",
587
+ lineHeight: "var(--lh-normal)"
588
+ }
589
+ };
590
+ var Text = forwardRef(function Text2({
591
+ variant = "body",
592
+ as = "p",
593
+ color,
594
+ maxWidth,
595
+ size,
596
+ weight,
597
+ tone,
598
+ mono,
599
+ leading,
600
+ className,
601
+ style,
602
+ children,
603
+ ...rest
604
+ }, ref) {
605
+ const Tag = as;
606
+ const variantBase = variantStyles2[variant];
607
+ const variantPick = {
608
+ ...size ? null : { fontSize: variantBase.fontSize },
609
+ ...tone ? null : { color: variantBase.color },
610
+ ...variantBase.lineHeight !== void 0 ? { lineHeight: variantBase.lineHeight } : null
611
+ };
612
+ const composed = {
613
+ ...baseStyle3,
614
+ lineHeight: leading ? void 0 : "var(--lh-relaxed)",
615
+ ...variantPick,
616
+ ...color ? { color } : null,
617
+ ...maxWidth ? { maxWidth } : null,
618
+ ...style
619
+ };
620
+ return /* @__PURE__ */ jsx(
621
+ Tag,
622
+ {
623
+ ref,
624
+ className: `ds-atom-text${className ? ` ${className}` : ""}`,
625
+ "data-variant": variant,
626
+ "data-size": size,
627
+ "data-weight": weight,
628
+ "data-tone": tone,
629
+ "data-mono": mono ? "true" : void 0,
630
+ "data-leading": leading,
631
+ style: composed,
632
+ ...rest,
633
+ children
634
+ }
635
+ );
636
+ });
637
+ var Heading = forwardRef(function Heading3({ level = 2, size = 28, weight = 900, color, tone, as, className, style, children, ...rest }, ref) {
638
+ const Tag = as ?? `h${level}`;
639
+ const isTokenSize = typeof size === "string";
640
+ const isTokenWeight = typeof weight === "string";
641
+ const dataSize = isTokenSize ? size : void 0;
642
+ const dataWeight = isTokenWeight ? weight : void 0;
643
+ const composed = {
644
+ fontFamily: "var(--display)",
645
+ color: color ?? (tone ? void 0 : "var(--ink)"),
646
+ margin: 0,
647
+ ...isTokenSize ? null : {
648
+ fontSize: size,
649
+ lineHeight: 1,
650
+ letterSpacing: size > 28 ? "var(--ls-tighter)" : size > 20 ? "var(--ls-tight)" : "var(--ls-base)"
651
+ },
652
+ ...isTokenWeight ? null : { fontWeight: weight },
653
+ ...style
654
+ };
655
+ return /* @__PURE__ */ jsx(
656
+ Tag,
657
+ {
658
+ ref,
659
+ className: `ds-atom-heading${className ? ` ${className}` : ""}`,
660
+ "data-size": dataSize,
661
+ "data-weight": dataWeight,
662
+ "data-tone": tone,
663
+ style: composed,
664
+ ...rest,
665
+ children
666
+ }
667
+ );
668
+ });
669
+ var Divider = forwardRef(function Divider2({ label, vertical = false, color, spacing, accent, className, style, ...rest }, ref) {
670
+ const ruleColor = color ?? "var(--rule)";
671
+ const orient = vertical ? "vertical" : "horizontal";
672
+ const inlineBg = accent ? void 0 : ruleColor;
673
+ if (vertical) {
674
+ return /* @__PURE__ */ jsx(
675
+ "div",
676
+ {
677
+ ref,
678
+ className: `ds-atom-divider${className ? ` ${className}` : ""}`,
679
+ "data-orient": orient,
680
+ "data-spacing": spacing,
681
+ "data-style": accent,
682
+ style: {
683
+ width: 1,
684
+ alignSelf: "stretch",
685
+ background: inlineBg,
686
+ ...style
687
+ },
688
+ ...rest
689
+ }
690
+ );
691
+ }
692
+ if (!label) {
693
+ return /* @__PURE__ */ jsx(
694
+ "div",
695
+ {
696
+ ref,
697
+ className: `ds-atom-divider${className ? ` ${className}` : ""}`,
698
+ "data-orient": orient,
699
+ "data-spacing": spacing,
700
+ "data-style": accent,
701
+ style: {
702
+ height: 1,
703
+ width: "100%",
704
+ background: inlineBg,
705
+ ...style
706
+ },
707
+ ...rest
708
+ }
709
+ );
710
+ }
711
+ const baseLabeled = {
712
+ display: "flex",
713
+ alignItems: "center",
714
+ gap: 12,
715
+ ...style
716
+ };
717
+ const lineStyle = {
718
+ flex: 1,
719
+ height: 1,
720
+ background: ruleColor
721
+ };
722
+ const labelStyle4 = {
723
+ fontFamily: "var(--mono)",
724
+ fontSize: 9.5,
725
+ fontWeight: 700,
726
+ letterSpacing: "0.1em",
727
+ textTransform: "uppercase",
728
+ color: "var(--ink-4)"
729
+ };
730
+ return /* @__PURE__ */ jsxs(
731
+ "div",
732
+ {
733
+ ref,
734
+ className: `ds-atom-divider${className ? ` ${className}` : ""}`,
735
+ "data-orient": orient,
736
+ "data-spacing": spacing,
737
+ "data-labeled": "true",
738
+ style: baseLabeled,
739
+ ...rest,
740
+ children: [
741
+ /* @__PURE__ */ jsx("span", { style: lineStyle }),
742
+ /* @__PURE__ */ jsx("span", { style: labelStyle4, children: label }),
743
+ /* @__PURE__ */ jsx("span", { style: lineStyle })
744
+ ]
745
+ }
746
+ );
747
+ });
748
+ var baseStyle4 = {
749
+ fontFamily: "var(--font)",
750
+ cursor: "pointer",
751
+ transition: "color .15s, text-decoration-color .15s"
752
+ };
753
+ var variantStyles3 = {
754
+ inline: {
755
+ color: "var(--amber-d)",
756
+ textDecoration: "underline",
757
+ textDecorationColor: "var(--amber-d)",
758
+ textUnderlineOffset: 2
759
+ },
760
+ footer: {
761
+ fontSize: 12.5,
762
+ fontWeight: 600,
763
+ color: "var(--ink)",
764
+ textDecoration: "underline",
765
+ textDecorationColor: "rgba(0, 0, 0, 0.25)",
766
+ textUnderlineOffset: 2
767
+ },
768
+ action: {
769
+ fontSize: 12.5,
770
+ fontWeight: 700,
771
+ color: "var(--ink)",
772
+ textDecoration: "underline",
773
+ textDecorationColor: "rgba(0, 0, 0, 0.25)",
774
+ textUnderlineOffset: 2
775
+ }
776
+ };
777
+ var Link = forwardRef(function Link3({ variant = "inline", color, as, className, style, children, ...rest }, ref) {
778
+ const Tag = as ?? "a";
779
+ const variantInline = variantStyles3[variant];
780
+ return /* @__PURE__ */ jsx(
781
+ Tag,
782
+ {
783
+ ref,
784
+ className: `ds-atom-link${className ? ` ${className}` : ""}`,
785
+ "data-variant": variant,
786
+ style: {
787
+ ...baseStyle4,
788
+ ...variantInline ?? null,
789
+ ...color ? { color } : null,
790
+ ...style
791
+ },
792
+ ...rest,
793
+ children
794
+ }
795
+ );
796
+ });
797
+ var DotGrid = forwardRef(function DotGrid2({
798
+ color = "var(--cream)",
799
+ opacity = 0.055,
800
+ tile = 18,
801
+ dotRadius = 1.4,
802
+ style,
803
+ className,
804
+ ...rest
805
+ }, ref) {
806
+ const composed = {
807
+ opacity,
808
+ backgroundImage: `radial-gradient(circle, ${color} ${dotRadius}px, transparent ${dotRadius + 0.2}px)`,
809
+ backgroundSize: `${tile}px ${tile}px`,
810
+ ...style
811
+ };
812
+ return /* @__PURE__ */ jsx(
813
+ "div",
814
+ {
815
+ ref,
816
+ "aria-hidden": "true",
817
+ className: `ds-atom-dotgrid${className ? ` ${className}` : ""}`,
818
+ style: composed,
819
+ ...rest
820
+ }
821
+ );
822
+ });
823
+ var SplitHero = forwardRef(function SplitHero2({
824
+ aside,
825
+ main,
826
+ ratio = "1fr 1fr",
827
+ asideBackground = "var(--ink)",
828
+ mainBackground = "var(--cream)",
829
+ stackBelow = 900,
830
+ hideAsideBelow = 600,
831
+ className,
832
+ style,
833
+ ...rest
834
+ }, ref) {
835
+ const rootStyle = {
836
+ height: "100vh",
837
+ display: "grid",
838
+ gridTemplateColumns: ratio,
839
+ background: mainBackground,
840
+ overflow: "hidden",
841
+ ...style
842
+ };
843
+ const asideStyle = {
844
+ display: "flex",
845
+ height: "100%",
846
+ overflow: "hidden",
847
+ background: asideBackground
848
+ };
849
+ const mainStyle = {
850
+ background: mainBackground,
851
+ padding: "48px",
852
+ display: "flex",
853
+ flexDirection: "column",
854
+ justifyContent: "center",
855
+ gap: 20,
856
+ overflowY: "auto"
857
+ };
858
+ const id = `dssh-${stackBelow}-${hideAsideBelow}`;
859
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
860
+ /* @__PURE__ */ jsx("style", { children: `
861
+ @media (max-width: ${stackBelow}px) {
862
+ .${id} {
863
+ height: auto !important;
864
+ min-height: 100vh;
865
+ grid-template-columns: 1fr !important;
866
+ grid-template-rows: auto 1fr;
867
+ overflow: visible !important;
868
+ }
869
+ .${id} > [data-slot="aside"] {
870
+ height: auto;
871
+ min-height: auto;
872
+ overflow: visible;
873
+ }
874
+ .${id} > [data-slot="main"] {
875
+ padding: 40px 32px;
876
+ justify-content: flex-start;
877
+ overflow-y: visible;
878
+ }
879
+ }
880
+ @media (max-width: ${hideAsideBelow}px) {
881
+ .${id} {
882
+ grid-template-rows: 1fr;
883
+ }
884
+ .${id} > [data-slot="aside"] {
885
+ display: none;
886
+ }
887
+ .${id} > [data-slot="main"] {
888
+ padding: 24px;
889
+ gap: 16px;
890
+ }
891
+ }
892
+ ` }),
893
+ /* @__PURE__ */ jsxs(
894
+ "main",
895
+ {
896
+ ref,
897
+ className: `ds-layout-splithero ${id}${className ? ` ${className}` : ""}`,
898
+ style: rootStyle,
899
+ ...rest,
900
+ children: [
901
+ /* @__PURE__ */ jsx("div", { "data-slot": "aside", style: asideStyle, children: aside }),
902
+ /* @__PURE__ */ jsx("div", { "data-slot": "main", style: mainStyle, children: main })
903
+ ]
904
+ }
905
+ )
906
+ ] });
907
+ });
908
+ var baseStyle5 = {
252
909
  fontFamily: "var(--mono)",
253
910
  fontSize: 9.5,
254
911
  padding: "3px 8px",
@@ -278,7 +935,7 @@ var dotColors = {
278
935
  neutral: "var(--ink-3)"
279
936
  };
280
937
  var Badge = forwardRef(function Badge2({ tone = "neutral", dot, dotColor, children, style, ...rest }, ref) {
281
- return /* @__PURE__ */ jsxs("span", { ref, style: { ...baseStyle2, ...toneStyles[tone], ...style }, ...rest, children: [
938
+ return /* @__PURE__ */ jsxs("span", { ref, style: { ...baseStyle5, ...toneStyles[tone], ...style }, ...rest, children: [
282
939
  dot ? /* @__PURE__ */ jsx(
283
940
  "span",
284
941
  {
@@ -295,7 +952,34 @@ var Badge = forwardRef(function Badge2({ tone = "neutral", dot, dotColor, childr
295
952
  children
296
953
  ] });
297
954
  });
298
- var baseStyle3 = {
955
+ var baseStyle6 = {
956
+ fontFamily: "var(--mono)",
957
+ fontSize: 11,
958
+ lineHeight: 1,
959
+ padding: "2px 6px",
960
+ borderRadius: 4,
961
+ display: "inline-flex",
962
+ alignItems: "center",
963
+ whiteSpace: "nowrap",
964
+ flexShrink: 0
965
+ };
966
+ var sizeStyles3 = {
967
+ sm: { fontSize: 9.5, padding: "1px 5px" },
968
+ md: {}
969
+ };
970
+ var Kbd = forwardRef(function Kbd2({ size = "md", children, style, className, ...rest }, ref) {
971
+ return /* @__PURE__ */ jsx(
972
+ "kbd",
973
+ {
974
+ ref,
975
+ className: `ds-atom-kbd${className ? ` ${className}` : ""}`,
976
+ style: { ...baseStyle6, ...sizeStyles3[size], ...style },
977
+ ...rest,
978
+ children
979
+ }
980
+ );
981
+ });
982
+ var baseStyle7 = {
299
983
  display: "inline-flex",
300
984
  alignItems: "center",
301
985
  gap: 5,
@@ -337,7 +1021,7 @@ var Chip = forwardRef(function Chip2({ tone = "default", onRemove, icon, childre
337
1021
  {
338
1022
  ref,
339
1023
  className: "ds-atom-chip",
340
- style: { ...baseStyle3, ...toneStyles2[tone], ...style },
1024
+ style: { ...baseStyle7, ...toneStyles2[tone], ...style },
341
1025
  ...rest,
342
1026
  children: [
343
1027
  icon ? /* @__PURE__ */ jsx("span", { style: { display: "inline-flex", alignItems: "center" }, children: icon }) : null,
@@ -887,7 +1571,7 @@ var NumberStepper = forwardRef(
887
1571
  var DIGITS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
888
1572
  function RollingNumber({
889
1573
  value,
890
- format,
1574
+ format: format2,
891
1575
  prefix,
892
1576
  suffix,
893
1577
  variant = "default",
@@ -895,7 +1579,7 @@ function RollingNumber({
895
1579
  className,
896
1580
  style
897
1581
  }) {
898
- const core = format ? format(value) : String(value);
1582
+ const core = format2 ? format2(value) : String(value);
899
1583
  const display = `${prefix ?? ""}${core}${suffix ?? ""}`;
900
1584
  const firstRender = useRef(true);
901
1585
  useEffect(() => {
@@ -921,31 +1605,272 @@ function RollingNumber({
921
1605
  children: /* @__PURE__ */ jsx(
922
1606
  "span",
923
1607
  {
924
- className: "ds-atom-rolling-strip",
1608
+ className: "ds-atom-rolling-strip",
1609
+ style: {
1610
+ transform: `translateY(${-digit * 22}px)`,
1611
+ ...stripTransitionStyle
1612
+ },
1613
+ children: DIGITS.map((n) => /* @__PURE__ */ jsx("span", { children: n }, n))
1614
+ }
1615
+ )
1616
+ },
1617
+ `d-${i}`
1618
+ );
1619
+ }
1620
+ return /* @__PURE__ */ jsx(
1621
+ "span",
1622
+ {
1623
+ className: "ds-atom-rolling-static",
1624
+ "aria-hidden": "true",
1625
+ children: char
1626
+ },
1627
+ `s-${i}`
1628
+ );
1629
+ })
1630
+ }
1631
+ );
1632
+ }
1633
+ function Sparkline({
1634
+ data,
1635
+ width = 100,
1636
+ height = 28,
1637
+ color = "var(--amber)",
1638
+ fill = true,
1639
+ ariaLabel = "Trend chart"
1640
+ }) {
1641
+ if (data.length < 2) {
1642
+ if (process.env.NODE_ENV !== "production") {
1643
+ console.warn("Sparkline: data must have at least 2 points; received", data.length);
1644
+ }
1645
+ return null;
1646
+ }
1647
+ const min = Math.min(...data);
1648
+ const max = Math.max(...data);
1649
+ const range = max - min || 1;
1650
+ const points = data.map((v, i) => {
1651
+ const x = i / (data.length - 1) * width;
1652
+ const y = height - (v - min) / range * (height - 4) - 2;
1653
+ return `${x},${y}`;
1654
+ }).join(" ");
1655
+ const fillPath = `M0,${height} L${points} L${width},${height} Z`;
1656
+ const last = data[data.length - 1];
1657
+ const dotY = height - (last - min) / range * (height - 4) - 2;
1658
+ return /* @__PURE__ */ jsxs(
1659
+ "svg",
1660
+ {
1661
+ width,
1662
+ height,
1663
+ viewBox: `0 0 ${width} ${height}`,
1664
+ style: { display: "block" },
1665
+ role: "img",
1666
+ "aria-label": ariaLabel,
1667
+ children: [
1668
+ fill && /* @__PURE__ */ jsx("path", { d: fillPath, fill: color, opacity: ".1" }),
1669
+ /* @__PURE__ */ jsx(
1670
+ "polyline",
1671
+ {
1672
+ points,
1673
+ fill: "none",
1674
+ stroke: color,
1675
+ strokeWidth: "1.5",
1676
+ strokeLinecap: "round",
1677
+ strokeLinejoin: "round"
1678
+ }
1679
+ ),
1680
+ /* @__PURE__ */ jsx("circle", { cx: width, cy: dotY, r: "2.5", fill: color })
1681
+ ]
1682
+ }
1683
+ );
1684
+ }
1685
+ function StatCard({
1686
+ label,
1687
+ value,
1688
+ change,
1689
+ changeDir,
1690
+ data,
1691
+ className,
1692
+ style
1693
+ }) {
1694
+ const up = changeDir === "up";
1695
+ const sentimentColor = changeDir === "up" ? "var(--green)" : changeDir === "down" ? "var(--red)" : "var(--amber)";
1696
+ return /* @__PURE__ */ jsxs(
1697
+ "div",
1698
+ {
1699
+ className: ["glass", className].filter(Boolean).join(" "),
1700
+ style: { padding: 16, borderRadius: 12, ...style },
1701
+ children: [
1702
+ /* @__PURE__ */ jsx(
1703
+ "div",
1704
+ {
1705
+ "data-part": "label",
1706
+ style: {
1707
+ fontFamily: "var(--mono)",
1708
+ fontSize: 9,
1709
+ color: "var(--ink-3)",
1710
+ letterSpacing: ".08em",
1711
+ textTransform: "uppercase",
1712
+ fontWeight: 700
1713
+ },
1714
+ children: label
1715
+ }
1716
+ ),
1717
+ /* @__PURE__ */ jsxs(
1718
+ "div",
1719
+ {
1720
+ style: {
1721
+ display: "flex",
1722
+ justifyContent: "space-between",
1723
+ alignItems: "flex-start"
1724
+ },
1725
+ children: [
1726
+ /* @__PURE__ */ jsx(
1727
+ "div",
1728
+ {
925
1729
  style: {
926
- transform: `translateY(${-digit * 22}px)`,
927
- ...stripTransitionStyle
1730
+ fontFamily: "var(--display)",
1731
+ fontWeight: 800,
1732
+ fontSize: 28,
1733
+ letterSpacing: "-.02em",
1734
+ marginTop: 4
928
1735
  },
929
- children: DIGITS.map((n) => /* @__PURE__ */ jsx("span", { children: n }, n))
1736
+ children: value
1737
+ }
1738
+ ),
1739
+ change && /* @__PURE__ */ jsx(
1740
+ "div",
1741
+ {
1742
+ "data-part": "badge",
1743
+ style: {
1744
+ padding: "3px 7px",
1745
+ borderRadius: 4,
1746
+ background: up ? "rgba(34,197,94,.1)" : "rgba(239,68,68,.08)",
1747
+ fontFamily: "var(--mono)",
1748
+ fontSize: 10,
1749
+ fontWeight: 700,
1750
+ color: up ? "var(--green)" : "var(--red)"
1751
+ },
1752
+ children: change
930
1753
  }
931
1754
  )
932
- },
933
- `d-${i}`
934
- );
935
- }
936
- return /* @__PURE__ */ jsx(
937
- "span",
1755
+ ]
1756
+ }
1757
+ ),
1758
+ data && data.length >= 2 && /* @__PURE__ */ jsx("div", { style: { marginTop: 10 }, children: /* @__PURE__ */ jsx(Sparkline, { data, color: sentimentColor }) })
1759
+ ]
1760
+ }
1761
+ );
1762
+ }
1763
+ function MiniDonut({
1764
+ value,
1765
+ max = 100,
1766
+ size = 48,
1767
+ strokeWidth = 5,
1768
+ color = "var(--amber)",
1769
+ ariaLabel
1770
+ }) {
1771
+ const reducedMotion = useReducedMotion();
1772
+ const r = (size - strokeWidth) / 2;
1773
+ const circ = 2 * Math.PI * r;
1774
+ const pct = Math.min(value / max, 1);
1775
+ const arcStyle = reducedMotion ? void 0 : { transition: "stroke-dashoffset 0.6s ease-out" };
1776
+ return /* @__PURE__ */ jsxs(
1777
+ "svg",
1778
+ {
1779
+ width: size,
1780
+ height: size,
1781
+ viewBox: `0 0 ${size} ${size}`,
1782
+ style: { display: "block", transform: "rotate(-90deg)" },
1783
+ role: "img",
1784
+ "aria-label": ariaLabel ?? `${Math.round(pct * 100)}%`,
1785
+ children: [
1786
+ /* @__PURE__ */ jsx(
1787
+ "circle",
938
1788
  {
939
- className: "ds-atom-rolling-static",
940
- "aria-hidden": "true",
941
- children: char
942
- },
943
- `s-${i}`
944
- );
945
- })
1789
+ cx: size / 2,
1790
+ cy: size / 2,
1791
+ r,
1792
+ fill: "none",
1793
+ stroke: "var(--cream-2)",
1794
+ strokeWidth
1795
+ }
1796
+ ),
1797
+ /* @__PURE__ */ jsx(
1798
+ "circle",
1799
+ {
1800
+ cx: size / 2,
1801
+ cy: size / 2,
1802
+ r,
1803
+ fill: "none",
1804
+ stroke: color,
1805
+ strokeWidth,
1806
+ strokeDasharray: circ,
1807
+ strokeDashoffset: circ * (1 - pct),
1808
+ strokeLinecap: "round",
1809
+ style: arcStyle
1810
+ }
1811
+ )
1812
+ ]
946
1813
  }
947
1814
  );
948
1815
  }
1816
+ function MiniBar({ data, labels: labels2, height = 100, barColor = "var(--amber)" }) {
1817
+ const max = Math.max(...data);
1818
+ return /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "flex-end", gap: 6, height }, children: data.map((v, i) => /* @__PURE__ */ jsxs(
1819
+ "div",
1820
+ {
1821
+ style: {
1822
+ flex: 1,
1823
+ display: "flex",
1824
+ flexDirection: "column",
1825
+ alignItems: "center",
1826
+ gap: 4,
1827
+ height: "100%",
1828
+ justifyContent: "flex-end"
1829
+ },
1830
+ children: [
1831
+ /* @__PURE__ */ jsx(
1832
+ "span",
1833
+ {
1834
+ style: {
1835
+ fontFamily: "var(--mono)",
1836
+ fontSize: 9,
1837
+ color: "var(--ink-3)",
1838
+ fontWeight: 600
1839
+ },
1840
+ children: v
1841
+ }
1842
+ ),
1843
+ /* @__PURE__ */ jsx(
1844
+ "div",
1845
+ {
1846
+ style: {
1847
+ width: "100%",
1848
+ maxWidth: 32,
1849
+ borderRadius: "4px 4px 0 0",
1850
+ height: `${v / max * 70}%`,
1851
+ minHeight: 4,
1852
+ background: barColor,
1853
+ opacity: 0.8,
1854
+ transition: "height 0.4s ease-out"
1855
+ }
1856
+ }
1857
+ ),
1858
+ labels2 && /* @__PURE__ */ jsx(
1859
+ "span",
1860
+ {
1861
+ style: {
1862
+ fontFamily: "var(--mono)",
1863
+ fontSize: 8,
1864
+ color: "var(--ink-4)"
1865
+ },
1866
+ children: labels2[i]
1867
+ }
1868
+ )
1869
+ ]
1870
+ },
1871
+ i
1872
+ )) });
1873
+ }
949
1874
  var RangeSlider = forwardRef(function RangeSlider2({
950
1875
  value,
951
1876
  onChange,
@@ -1064,7 +1989,43 @@ function StarRating({
1064
1989
  }
1065
1990
  );
1066
1991
  }
1067
- var baseStyle4 = {
1992
+ var StatusPill = forwardRef(
1993
+ function StatusPill2({ stage, withChevron, interactive = true, className, children, ...rest }, ref) {
1994
+ const cls3 = `ds-atom-statuspill${className ? ` ${className}` : ""}`;
1995
+ if (interactive) {
1996
+ return /* @__PURE__ */ jsxs(
1997
+ "button",
1998
+ {
1999
+ ref,
2000
+ type: "button",
2001
+ className: cls3,
2002
+ "data-stage": stage,
2003
+ "data-interactive": "true",
2004
+ ...rest,
2005
+ children: [
2006
+ children,
2007
+ withChevron && /* @__PURE__ */ jsx("span", { className: "ds-atom-statuspill-chev", "aria-hidden": "true", children: "\u25BE" })
2008
+ ]
2009
+ }
2010
+ );
2011
+ }
2012
+ return /* @__PURE__ */ jsxs(
2013
+ "span",
2014
+ {
2015
+ ref,
2016
+ className: cls3,
2017
+ "data-stage": stage,
2018
+ "data-interactive": "false",
2019
+ ...rest,
2020
+ children: [
2021
+ children,
2022
+ withChevron && /* @__PURE__ */ jsx("span", { className: "ds-atom-statuspill-chev", "aria-hidden": "true", children: "\u25BE" })
2023
+ ]
2024
+ }
2025
+ );
2026
+ }
2027
+ );
2028
+ var baseStyle8 = {
1068
2029
  display: "block",
1069
2030
  boxSizing: "border-box",
1070
2031
  fontFamily: "var(--font)"
@@ -1076,25 +2037,30 @@ var StickyNote = forwardRef(function StickyNote2({ rotation = "right", className
1076
2037
  ref,
1077
2038
  className: `ds-atom-stickynote${className ? ` ${className}` : ""}`,
1078
2039
  "data-rotation": rotation,
1079
- style: { ...baseStyle4, ...style },
2040
+ style: { ...baseStyle8, ...style },
1080
2041
  ...rest,
1081
2042
  children
1082
2043
  }
1083
2044
  );
1084
2045
  });
1085
- var baseStyle5 = {
2046
+ var baseStyle9 = {
1086
2047
  display: "block",
1087
2048
  boxSizing: "border-box",
1088
2049
  fontFamily: "var(--font)"
1089
2050
  };
1090
- var Card = forwardRef(function Card2({ variant = "glass", className, style, children, ...rest }, ref) {
2051
+ var Card = forwardRef(function Card2({ variant = "glass", padding, radius, tone, hover, as, className, style, children, ...rest }, ref) {
2052
+ const Tag = as ?? "div";
1091
2053
  return /* @__PURE__ */ jsx(
1092
- "div",
2054
+ Tag,
1093
2055
  {
1094
2056
  ref,
1095
2057
  className: `ds-atom-card${className ? ` ${className}` : ""}`,
1096
2058
  "data-variant": variant,
1097
- style: { ...baseStyle5, ...style },
2059
+ "data-padding": padding,
2060
+ "data-radius": radius,
2061
+ "data-tone": tone,
2062
+ "data-hover": hover,
2063
+ style: { ...baseStyle9, ...style },
1098
2064
  ...rest,
1099
2065
  children
1100
2066
  }
@@ -1451,52 +2417,459 @@ function Modal({
1451
2417
  /* @__PURE__ */ jsx(
1452
2418
  Button,
1453
2419
  {
1454
- variant: "ghost",
1455
- size: "sm",
1456
- "aria-label": "Close",
1457
- onClick: onClose,
1458
- style: { marginLeft: "auto", flexShrink: 0 },
1459
- children: /* @__PURE__ */ jsx(X, { size: 16 })
2420
+ variant: "ghost",
2421
+ size: "sm",
2422
+ "aria-label": "Close",
2423
+ onClick: onClose,
2424
+ style: { marginLeft: "auto", flexShrink: 0 },
2425
+ children: /* @__PURE__ */ jsx(X, { size: 16 })
2426
+ }
2427
+ )
2428
+ ] }),
2429
+ /* @__PURE__ */ jsxs("div", { className: "ds-atom-modal-body", children: [
2430
+ description ? /* @__PURE__ */ jsx("div", { id: descId, children: description }) : null,
2431
+ children
2432
+ ] }),
2433
+ footer ? /* @__PURE__ */ jsx("footer", { className: "ds-atom-modal-ft", children: footer }) : null
2434
+ ]
2435
+ }
2436
+ ) }) });
2437
+ }
2438
+ var tones = {
2439
+ danger: {
2440
+ color: "var(--red)",
2441
+ bg: "rgba(239,68,68,.1)",
2442
+ icon: /* @__PURE__ */ jsxs(
2443
+ "svg",
2444
+ {
2445
+ "aria-hidden": "true",
2446
+ viewBox: "0 0 24 24",
2447
+ width: "22",
2448
+ height: "22",
2449
+ fill: "none",
2450
+ stroke: "currentColor",
2451
+ strokeWidth: "2",
2452
+ children: [
2453
+ /* @__PURE__ */ jsx("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
2454
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
2455
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
2456
+ ]
2457
+ }
2458
+ )
2459
+ },
2460
+ warn: {
2461
+ color: "var(--amber-d)",
2462
+ bg: "rgba(245,158,11,.12)",
2463
+ icon: /* @__PURE__ */ jsxs(
2464
+ "svg",
2465
+ {
2466
+ "aria-hidden": "true",
2467
+ viewBox: "0 0 24 24",
2468
+ width: "22",
2469
+ height: "22",
2470
+ fill: "none",
2471
+ stroke: "currentColor",
2472
+ strokeWidth: "2",
2473
+ children: [
2474
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
2475
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
2476
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
2477
+ ]
2478
+ }
2479
+ )
2480
+ },
2481
+ success: {
2482
+ color: "var(--green)",
2483
+ bg: "rgba(34,197,94,.1)",
2484
+ icon: /* @__PURE__ */ jsxs(
2485
+ "svg",
2486
+ {
2487
+ "aria-hidden": "true",
2488
+ viewBox: "0 0 24 24",
2489
+ width: "22",
2490
+ height: "22",
2491
+ fill: "none",
2492
+ stroke: "currentColor",
2493
+ strokeWidth: "2",
2494
+ children: [
2495
+ /* @__PURE__ */ jsx("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
2496
+ /* @__PURE__ */ jsx("polyline", { points: "22 4 12 14.01 9 11.01" })
2497
+ ]
2498
+ }
2499
+ )
2500
+ },
2501
+ neutral: {
2502
+ color: "var(--ink)",
2503
+ bg: "rgba(0,0,0,.05)",
2504
+ icon: /* @__PURE__ */ jsxs(
2505
+ "svg",
2506
+ {
2507
+ "aria-hidden": "true",
2508
+ viewBox: "0 0 24 24",
2509
+ width: "22",
2510
+ height: "22",
2511
+ fill: "none",
2512
+ stroke: "currentColor",
2513
+ strokeWidth: "2",
2514
+ children: [
2515
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
2516
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
2517
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
2518
+ ]
2519
+ }
2520
+ )
2521
+ }
2522
+ };
2523
+ var toneButtonStyle = {
2524
+ danger: { variant: "danger", style: { background: "var(--red)", borderColor: "var(--red)" } },
2525
+ warn: { variant: "primary", style: void 0 },
2526
+ success: {
2527
+ variant: "primary",
2528
+ style: { background: "var(--amber-d)", borderColor: "var(--amber-d)", color: "#fff" }
2529
+ },
2530
+ neutral: {
2531
+ variant: "secondary",
2532
+ style: { background: "var(--ink)", borderColor: "var(--ink)", color: "#fff" }
2533
+ }
2534
+ };
2535
+ var panelStyle = {
2536
+ width: 360,
2537
+ background: "rgba(255,255,255,.97)",
2538
+ // intentionally NOT the cream token — always-light (CONSTRAINT-010)
2539
+ backdropFilter: "blur(14px)",
2540
+ WebkitBackdropFilter: "blur(14px)",
2541
+ borderRadius: 14,
2542
+ border: "1px solid var(--rule)",
2543
+ padding: 22,
2544
+ boxShadow: "0 16px 48px rgba(0,0,0,.18)"
2545
+ };
2546
+ function ConfirmDialog({
2547
+ open,
2548
+ onClose,
2549
+ onConfirm,
2550
+ tone = "danger",
2551
+ title,
2552
+ body,
2553
+ confirmLabel = "Confirm",
2554
+ cancelLabel = "Cancel"
2555
+ }) {
2556
+ const [panel, setPanel] = useState(null);
2557
+ const generatedTitleId = useId();
2558
+ const generatedDescId = useId();
2559
+ const titleId = title ? generatedTitleId : void 0;
2560
+ const descId = body ? generatedDescId : void 0;
2561
+ useFocusTrap(panel, open);
2562
+ useEffect(() => {
2563
+ if (!open) return;
2564
+ function onKey(e) {
2565
+ if (e.key === "Escape") onClose();
2566
+ if (e.key === "Enter") onConfirm();
2567
+ }
2568
+ document.addEventListener("keydown", onKey);
2569
+ return () => document.removeEventListener("keydown", onKey);
2570
+ }, [open, onClose, onConfirm]);
2571
+ if (!open) return null;
2572
+ function handleBackdropClick(e) {
2573
+ if (e.target !== e.currentTarget) return;
2574
+ }
2575
+ const t = tones[tone];
2576
+ const btnConfig = toneButtonStyle[tone];
2577
+ return /* @__PURE__ */ jsx(DSPortal, { children: /* @__PURE__ */ jsx("div", { className: "ds-atom-modal-backdrop", onClick: handleBackdropClick, children: /* @__PURE__ */ jsxs(
2578
+ "div",
2579
+ {
2580
+ ref: setPanel,
2581
+ className: "ds-atom-confirm-panel",
2582
+ role: "alertdialog",
2583
+ "aria-modal": "true",
2584
+ "aria-labelledby": titleId,
2585
+ "aria-describedby": descId,
2586
+ tabIndex: -1,
2587
+ style: panelStyle,
2588
+ children: [
2589
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 14, marginBottom: 12 }, children: [
2590
+ /* @__PURE__ */ jsx(
2591
+ "div",
2592
+ {
2593
+ style: {
2594
+ width: 40,
2595
+ height: 40,
2596
+ borderRadius: 10,
2597
+ background: t.bg,
2598
+ color: t.color,
2599
+ display: "flex",
2600
+ alignItems: "center",
2601
+ justifyContent: "center",
2602
+ flexShrink: 0
2603
+ },
2604
+ children: t.icon
2605
+ }
2606
+ ),
2607
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, paddingTop: 2 }, children: [
2608
+ /* @__PURE__ */ jsx(
2609
+ "div",
2610
+ {
2611
+ id: titleId,
2612
+ style: {
2613
+ fontFamily: "var(--display)",
2614
+ fontWeight: 700,
2615
+ fontSize: 15,
2616
+ marginBottom: 5
2617
+ },
2618
+ children: title
2619
+ }
2620
+ ),
2621
+ body ? /* @__PURE__ */ jsx("div", { id: descId, style: { fontSize: 12.5, color: "var(--ink-2)", lineHeight: 1.5 }, children: body }) : null
2622
+ ] })
2623
+ ] }),
2624
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 18 }, children: [
2625
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: onClose, children: cancelLabel }),
2626
+ /* @__PURE__ */ jsx(Button, { variant: btnConfig.variant, style: btnConfig.style, onClick: onConfirm, children: confirmLabel })
2627
+ ] })
2628
+ ]
2629
+ }
2630
+ ) }) });
2631
+ }
2632
+ function TypeToConfirm({
2633
+ open,
2634
+ onClose,
2635
+ onConfirm,
2636
+ title,
2637
+ body,
2638
+ guardWord = "DELETE",
2639
+ confirmLabel = "Delete forever",
2640
+ cancelLabel = "Cancel"
2641
+ }) {
2642
+ const [panel, setPanel] = useState(null);
2643
+ const [v, setV] = useState("");
2644
+ const ok = v === guardWord;
2645
+ const generatedTitleId = useId();
2646
+ const titleId = title ? generatedTitleId : void 0;
2647
+ useFocusTrap(panel, open);
2648
+ useEffect(() => {
2649
+ if (!open) return;
2650
+ function onKey(e) {
2651
+ if (e.key === "Escape") onClose();
2652
+ if (e.key === "Enter" && ok) onConfirm();
2653
+ }
2654
+ document.addEventListener("keydown", onKey);
2655
+ return () => document.removeEventListener("keydown", onKey);
2656
+ }, [open, onClose, onConfirm, ok]);
2657
+ useEffect(() => {
2658
+ if (!open) setV("");
2659
+ }, [open]);
2660
+ if (!open) return null;
2661
+ function handleBackdropClick(e) {
2662
+ if (e.target !== e.currentTarget) return;
2663
+ }
2664
+ return /* @__PURE__ */ jsx(DSPortal, { children: /* @__PURE__ */ jsx("div", { className: "ds-atom-modal-backdrop", onClick: handleBackdropClick, children: /* @__PURE__ */ jsxs(
2665
+ "div",
2666
+ {
2667
+ ref: setPanel,
2668
+ className: "ds-atom-confirm-panel",
2669
+ role: "alertdialog",
2670
+ "aria-modal": "true",
2671
+ "aria-labelledby": titleId,
2672
+ tabIndex: -1,
2673
+ style: panelStyle,
2674
+ children: [
2675
+ /* @__PURE__ */ jsx(
2676
+ "div",
2677
+ {
2678
+ id: titleId,
2679
+ style: { fontFamily: "var(--display)", fontWeight: 700, fontSize: 15, marginBottom: 5 },
2680
+ children: title
2681
+ }
2682
+ ),
2683
+ body ? /* @__PURE__ */ jsx(
2684
+ "div",
2685
+ {
2686
+ style: { fontSize: 12.5, color: "var(--ink-2)", lineHeight: 1.5, marginBottom: 12 },
2687
+ children: body
2688
+ }
2689
+ ) : null,
2690
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 11, color: "var(--ink-3)", marginBottom: 6 }, children: [
2691
+ "Type ",
2692
+ /* @__PURE__ */ jsx(Kbd, { size: "sm", children: guardWord }),
2693
+ " to confirm"
2694
+ ] }),
2695
+ /* @__PURE__ */ jsx(
2696
+ TextInput,
2697
+ {
2698
+ value: v,
2699
+ onChange: (e) => setV(e.target.value),
2700
+ placeholder: `Type ${guardWord}`,
2701
+ style: { width: "100%", marginBottom: 14 }
2702
+ }
2703
+ ),
2704
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
2705
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: onClose, children: cancelLabel }),
2706
+ /* @__PURE__ */ jsx(
2707
+ Button,
2708
+ {
2709
+ variant: "danger",
2710
+ disabled: !ok,
2711
+ style: !ok ? { background: "var(--ink-5)", opacity: 0.6, borderColor: "transparent" } : { background: "var(--red)", borderColor: "transparent" },
2712
+ onClick: onConfirm,
2713
+ children: confirmLabel
1460
2714
  }
1461
2715
  )
1462
- ] }),
1463
- /* @__PURE__ */ jsxs("div", { className: "ds-atom-modal-body", children: [
1464
- description ? /* @__PURE__ */ jsx("div", { id: descId, children: description }) : null,
1465
- children
1466
- ] }),
1467
- footer ? /* @__PURE__ */ jsx("footer", { className: "ds-atom-modal-ft", children: footer }) : null
2716
+ ] })
1468
2717
  ]
1469
2718
  }
1470
2719
  ) }) });
1471
2720
  }
1472
- function ConfirmDialog({
2721
+ function CommandPalette({
1473
2722
  open,
1474
2723
  onClose,
1475
- title,
1476
- description,
1477
- confirmLabel = "Confirm",
1478
- cancelLabel = "Cancel",
1479
- danger = false,
1480
- onConfirm
2724
+ items,
2725
+ placeholder = "Type a command or search\u2026",
2726
+ emptyText,
2727
+ className,
2728
+ style
1481
2729
  }) {
1482
- const descriptionString = typeof description === "string" ? description : void 0;
1483
- const descriptionNode = typeof description !== "string" && description ? description : null;
1484
- return /* @__PURE__ */ jsx(
1485
- Modal,
2730
+ const [panel, setPanel] = useState(null);
2731
+ const [query, setQuery] = useState("");
2732
+ const [activeIndex, setActiveIndex] = useState(-1);
2733
+ useFocusTrap(panel, open);
2734
+ const filtered = useMemo(() => {
2735
+ if (!query.trim()) return items;
2736
+ const q = query.toLowerCase();
2737
+ return items.filter((i) => i.label.toLowerCase().includes(q));
2738
+ }, [items, query]);
2739
+ useEffect(() => {
2740
+ setActiveIndex(-1);
2741
+ }, [query]);
2742
+ useEffect(() => {
2743
+ if (!open) {
2744
+ setQuery("");
2745
+ setActiveIndex(-1);
2746
+ }
2747
+ }, [open]);
2748
+ useEffect(() => {
2749
+ if (!open) return;
2750
+ function onKey(e) {
2751
+ if (e.key === "Escape") {
2752
+ e.preventDefault();
2753
+ onClose();
2754
+ return;
2755
+ }
2756
+ if (e.key === "ArrowDown") {
2757
+ e.preventDefault();
2758
+ setActiveIndex((i) => Math.min(filtered.length - 1, i + 1));
2759
+ return;
2760
+ }
2761
+ if (e.key === "ArrowUp") {
2762
+ e.preventDefault();
2763
+ setActiveIndex((i) => i <= 0 ? i : i - 1);
2764
+ return;
2765
+ }
2766
+ if (e.key === "Enter") {
2767
+ if (activeIndex >= 0 && activeIndex < filtered.length) {
2768
+ e.preventDefault();
2769
+ const item = filtered[activeIndex];
2770
+ if (item) {
2771
+ item.onSelect();
2772
+ onClose();
2773
+ }
2774
+ }
2775
+ }
2776
+ }
2777
+ document.addEventListener("keydown", onKey);
2778
+ return () => document.removeEventListener("keydown", onKey);
2779
+ }, [open, filtered, activeIndex, onClose]);
2780
+ if (!open) return null;
2781
+ function handleBackdropClick(e) {
2782
+ if (e.target === e.currentTarget) onClose();
2783
+ }
2784
+ const groups = [];
2785
+ for (const item of filtered) {
2786
+ let g = groups.find((x) => x.name === item.group);
2787
+ if (!g) {
2788
+ g = { name: item.group, items: [] };
2789
+ groups.push(g);
2790
+ }
2791
+ g.items.push(item);
2792
+ }
2793
+ let flatIdx = 0;
2794
+ return /* @__PURE__ */ jsx(DSPortal, { children: /* @__PURE__ */ jsx(
2795
+ "div",
1486
2796
  {
1487
- open,
1488
- onClose,
1489
- title,
1490
- description: descriptionString,
1491
- role: danger ? "alertdialog" : "dialog",
1492
- closeOnBackdropClick: !danger,
1493
- footer: /* @__PURE__ */ jsxs(Fragment, { children: [
1494
- /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: onClose, children: cancelLabel }),
1495
- /* @__PURE__ */ jsx(Button, { variant: danger ? "danger" : "primary", onClick: onConfirm, children: confirmLabel })
1496
- ] }),
1497
- children: descriptionNode
2797
+ className: "ds-atom-modal-backdrop",
2798
+ style: { alignItems: "flex-start", paddingTop: "15vh" },
2799
+ onClick: handleBackdropClick,
2800
+ children: /* @__PURE__ */ jsxs(
2801
+ "div",
2802
+ {
2803
+ ref: setPanel,
2804
+ role: "dialog",
2805
+ "aria-modal": "true",
2806
+ "aria-label": "Command palette",
2807
+ className: `ds-atom-cmd-panel${className ? ` ${className}` : ""}`,
2808
+ style,
2809
+ tabIndex: -1,
2810
+ children: [
2811
+ /* @__PURE__ */ jsxs("div", { className: "ds-atom-cmd-search", children: [
2812
+ /* @__PURE__ */ jsxs(
2813
+ "svg",
2814
+ {
2815
+ "aria-hidden": "true",
2816
+ viewBox: "0 0 24 24",
2817
+ width: "16",
2818
+ height: "16",
2819
+ fill: "none",
2820
+ stroke: "currentColor",
2821
+ strokeWidth: "2",
2822
+ children: [
2823
+ /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "8" }),
2824
+ /* @__PURE__ */ jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })
2825
+ ]
2826
+ }
2827
+ ),
2828
+ /* @__PURE__ */ jsx(
2829
+ "input",
2830
+ {
2831
+ autoFocus: true,
2832
+ className: "ds-atom-cmd-input",
2833
+ placeholder,
2834
+ value: query,
2835
+ onChange: (e) => setQuery(e.target.value),
2836
+ "aria-label": "Search commands"
2837
+ }
2838
+ ),
2839
+ /* @__PURE__ */ jsx(Kbd, { size: "sm", children: "ESC" })
2840
+ ] }),
2841
+ /* @__PURE__ */ jsx("div", { className: "ds-atom-cmd-list", children: filtered.length === 0 ? /* @__PURE__ */ jsx("div", { className: "ds-atom-cmd-empty", children: emptyText ?? `No results for "${query}"` }) : groups.map((g) => /* @__PURE__ */ jsxs("div", { children: [
2842
+ /* @__PURE__ */ jsx("div", { className: "ds-atom-cmd-group", children: g.name }),
2843
+ g.items.map((item) => {
2844
+ const myIndex = flatIdx++;
2845
+ const isActive = myIndex === activeIndex;
2846
+ return /* @__PURE__ */ jsxs(
2847
+ "button",
2848
+ {
2849
+ type: "button",
2850
+ className: "ds-atom-cmd-item",
2851
+ "data-active": isActive ? "true" : void 0,
2852
+ "aria-selected": isActive ? "true" : void 0,
2853
+ onClick: () => {
2854
+ item.onSelect();
2855
+ onClose();
2856
+ },
2857
+ onMouseEnter: () => setActiveIndex(myIndex),
2858
+ children: [
2859
+ item.icon ? /* @__PURE__ */ jsx("span", { className: "ds-atom-cmd-item-icon", children: item.icon }) : null,
2860
+ /* @__PURE__ */ jsx("span", { className: "ds-atom-cmd-item-label", children: item.label }),
2861
+ item.shortcut ? /* @__PURE__ */ jsx("span", { className: "ds-atom-cmd-item-shortcut", children: /* @__PURE__ */ jsx(Kbd, { size: "sm", children: item.shortcut }) }) : null
2862
+ ]
2863
+ },
2864
+ item.id
2865
+ );
2866
+ })
2867
+ ] }, g.name)) })
2868
+ ]
2869
+ }
2870
+ )
1498
2871
  }
1499
- );
2872
+ ) });
1500
2873
  }
1501
2874
  function Sheet({
1502
2875
  open,
@@ -1917,7 +3290,7 @@ function Lightbox({ open, onClose, items, activeIndex = 0, onIndexChange }) {
1917
3290
  }
1918
3291
  ) });
1919
3292
  }
1920
- var baseStyle6 = {
3293
+ var baseStyle10 = {
1921
3294
  boxSizing: "border-box",
1922
3295
  display: "block",
1923
3296
  width: "100%",
@@ -1937,7 +3310,7 @@ var ProgressBar = forwardRef(function ProgressBar2({ value = 0, max = 100, loadi
1937
3310
  role: "status",
1938
3311
  "aria-live": "polite",
1939
3312
  "aria-label": typeof label === "string" ? label : "Loading",
1940
- style: { ...baseStyle6, ...style },
3313
+ style: { ...baseStyle10, ...style },
1941
3314
  ...rest,
1942
3315
  children: /* @__PURE__ */ jsxs("span", { className: "ds-atom-progress-dots", "aria-hidden": "true", children: [
1943
3316
  /* @__PURE__ */ jsx("span", { className: "ds-atom-progress-dot" }),
@@ -1959,7 +3332,7 @@ var ProgressBar = forwardRef(function ProgressBar2({ value = 0, max = 100, loadi
1959
3332
  "aria-valuemin": 0,
1960
3333
  "aria-valuemax": safeMax,
1961
3334
  "aria-label": typeof label === "string" ? label : "Progress",
1962
- style: { ...baseStyle6, ...style },
3335
+ style: { ...baseStyle10, ...style },
1963
3336
  ...rest,
1964
3337
  children: /* @__PURE__ */ jsx("div", { className: "ds-atom-progress-track", children: /* @__PURE__ */ jsx("div", { className: "ds-atom-progress-fill", style: { width: `${pct}%` } }) })
1965
3338
  }
@@ -2112,7 +3485,7 @@ var TONE_ICON = {
2112
3485
  warning: /* @__PURE__ */ jsx(AlertTriangle, { size: 16, "aria-hidden": "true" }),
2113
3486
  error: /* @__PURE__ */ jsx(XCircle, { size: 16, "aria-hidden": "true" })
2114
3487
  };
2115
- var baseStyle7 = {
3488
+ var baseStyle11 = {
2116
3489
  boxSizing: "border-box",
2117
3490
  display: "flex"
2118
3491
  };
@@ -2124,6 +3497,7 @@ var AlertBanner = forwardRef(function AlertBanner2({
2124
3497
  description,
2125
3498
  children,
2126
3499
  dismissible,
3500
+ boldTitle = true,
2127
3501
  className,
2128
3502
  style,
2129
3503
  ...rest
@@ -2137,7 +3511,8 @@ var AlertBanner = forwardRef(function AlertBanner2({
2137
3511
  ref,
2138
3512
  className: `ds-atom-banner${className ? ` ${className}` : ""}`,
2139
3513
  "data-variant": tone,
2140
- style: { ...baseStyle7, ...style },
3514
+ "data-bold-title": boldTitle ? void 0 : "false",
3515
+ style: { ...baseStyle11, ...style },
2141
3516
  ...rest,
2142
3517
  children: [
2143
3518
  /* @__PURE__ */ jsx("span", { className: "ds-atom-banner-icon", "aria-hidden": "true", children: TONE_ICON[tone] }),
@@ -2159,7 +3534,7 @@ var AlertBanner = forwardRef(function AlertBanner2({
2159
3534
  }
2160
3535
  );
2161
3536
  });
2162
- var baseStyle8 = {
3537
+ var baseStyle12 = {
2163
3538
  boxSizing: "border-box"
2164
3539
  };
2165
3540
  var EmptyState = forwardRef(function EmptyState2({ icon, title, description, children, className, style, ...rest }, ref) {
@@ -2168,7 +3543,7 @@ var EmptyState = forwardRef(function EmptyState2({ icon, title, description, chi
2168
3543
  {
2169
3544
  ref,
2170
3545
  className: ["ds-atom-empty", className].filter(Boolean).join(" "),
2171
- style: { ...baseStyle8, ...style },
3546
+ style: { ...baseStyle12, ...style },
2172
3547
  ...rest,
2173
3548
  children: [
2174
3549
  icon ? /* @__PURE__ */ jsx("div", { className: "ds-atom-empty-icon", "aria-hidden": "true", children: icon }) : null,
@@ -2305,6 +3680,123 @@ function ToastNode({ entry, onDismiss }) {
2305
3680
  }
2306
3681
  );
2307
3682
  }
3683
+ var SnackbarContext = createContext(null);
3684
+ var DEFAULT_DURATION2 = 5e3;
3685
+ var SLIDE_OUT_MS2 = 200;
3686
+ function useSnackbar() {
3687
+ const ctx = useContext(SnackbarContext);
3688
+ if (!ctx) {
3689
+ throw new Error("useSnackbar must be used within a <SnackbarProvider>");
3690
+ }
3691
+ return ctx;
3692
+ }
3693
+ var nextSnackbarId = 0;
3694
+ function SnackbarProvider({ children }) {
3695
+ const [entry, setEntry] = useState(null);
3696
+ const dismissTimer = useRef(null);
3697
+ const clearTimer = () => {
3698
+ if (dismissTimer.current !== null) {
3699
+ window.clearTimeout(dismissTimer.current);
3700
+ dismissTimer.current = null;
3701
+ }
3702
+ };
3703
+ const scheduleRemoval = useCallback(() => {
3704
+ window.setTimeout(() => {
3705
+ setEntry((prev) => prev?.dismissing ? null : prev);
3706
+ }, SLIDE_OUT_MS2);
3707
+ }, []);
3708
+ const startDismiss = useCallback(
3709
+ (id) => {
3710
+ clearTimer();
3711
+ setEntry((prev) => {
3712
+ if (!prev || prev.id !== id || prev.dismissing) return prev;
3713
+ return { ...prev, dismissing: true };
3714
+ });
3715
+ scheduleRemoval();
3716
+ },
3717
+ [scheduleRemoval]
3718
+ );
3719
+ const show = useCallback(
3720
+ (message, opts) => {
3721
+ const id = ++nextSnackbarId;
3722
+ const duration = opts?.duration ?? DEFAULT_DURATION2;
3723
+ const action = opts?.action ?? null;
3724
+ const dismissible = opts?.dismissible ?? action === null;
3725
+ clearTimer();
3726
+ setEntry({
3727
+ id,
3728
+ tone: opts?.tone ?? "neutral",
3729
+ message,
3730
+ action,
3731
+ duration,
3732
+ dismissible,
3733
+ dismissing: false
3734
+ });
3735
+ if (Number.isFinite(duration)) {
3736
+ dismissTimer.current = window.setTimeout(() => startDismiss(id), duration);
3737
+ }
3738
+ return id;
3739
+ },
3740
+ [startDismiss]
3741
+ );
3742
+ const api = useMemo(
3743
+ () => ({
3744
+ show,
3745
+ dismiss: (id) => startDismiss(id)
3746
+ }),
3747
+ [show, startDismiss]
3748
+ );
3749
+ useEffect(
3750
+ () => () => {
3751
+ clearTimer();
3752
+ },
3753
+ []
3754
+ );
3755
+ return /* @__PURE__ */ jsxs(SnackbarContext.Provider, { value: api, children: [
3756
+ children,
3757
+ entry ? /* @__PURE__ */ jsx(DSPortal, { children: /* @__PURE__ */ jsx("div", { className: "ds-atom-snackbar-region", "aria-label": "Action confirmations", children: /* @__PURE__ */ jsx(
3758
+ SnackbarNode,
3759
+ {
3760
+ entry,
3761
+ onAction: () => {
3762
+ if (entry.action) {
3763
+ entry.action.onClick();
3764
+ startDismiss(entry.id);
3765
+ }
3766
+ },
3767
+ onDismiss: () => startDismiss(entry.id)
3768
+ }
3769
+ ) }) }) : null
3770
+ ] });
3771
+ }
3772
+ function SnackbarNode({ entry, onAction, onDismiss }) {
3773
+ const role = entry.tone === "error" ? "alert" : "status";
3774
+ const ariaLive = role === "alert" ? "assertive" : "polite";
3775
+ return /* @__PURE__ */ jsxs(
3776
+ "div",
3777
+ {
3778
+ className: "ds-atom-snackbar",
3779
+ "data-tone": entry.tone,
3780
+ "data-dismissing": entry.dismissing ? "true" : void 0,
3781
+ role,
3782
+ "aria-live": ariaLive,
3783
+ children: [
3784
+ /* @__PURE__ */ jsx("span", { className: "ds-atom-snackbar-msg", children: entry.message }),
3785
+ entry.action ? /* @__PURE__ */ jsx("button", { type: "button", className: "ds-atom-snackbar-action", onClick: onAction, children: entry.action.label }) : null,
3786
+ entry.dismissible ? /* @__PURE__ */ jsx(
3787
+ "button",
3788
+ {
3789
+ type: "button",
3790
+ className: "ds-atom-snackbar-close",
3791
+ "aria-label": "Dismiss",
3792
+ onClick: onDismiss,
3793
+ children: /* @__PURE__ */ jsx(X, { size: 14, "aria-hidden": "true" })
3794
+ }
3795
+ ) : null
3796
+ ]
3797
+ }
3798
+ );
3799
+ }
2308
3800
  var CopyToClipboard = forwardRef(
2309
3801
  function CopyToClipboard2({ value, label, copiedLabel, onCopy, onError, className, style, ...rest }, ref) {
2310
3802
  const [copied, setCopied] = useState(false);
@@ -2317,19 +3809,28 @@ var CopyToClipboard = forwardRef(
2317
3809
  }
2318
3810
  };
2319
3811
  }, []);
2320
- const handleClick = useCallback(async () => {
2321
- const showCopied = () => {
2322
- setCopied(true);
2323
- onCopy?.();
2324
- if (timerRef.current !== null) globalThis.clearTimeout(timerRef.current);
2325
- timerRef.current = globalThis.setTimeout(() => {
2326
- setCopied(false);
3812
+ const revertOptimistic = useCallback(
3813
+ (err) => {
3814
+ if (timerRef.current !== null) {
3815
+ globalThis.clearTimeout(timerRef.current);
2327
3816
  timerRef.current = null;
2328
- }, 2e3);
2329
- };
3817
+ }
3818
+ setCopied(false);
3819
+ console.warn("CopyToClipboard: copy failed", err);
3820
+ onError?.(err);
3821
+ },
3822
+ [onError]
3823
+ );
3824
+ const handleClick = useCallback(async () => {
3825
+ setCopied(true);
3826
+ onCopy?.();
3827
+ if (timerRef.current !== null) globalThis.clearTimeout(timerRef.current);
3828
+ timerRef.current = globalThis.setTimeout(() => {
3829
+ setCopied(false);
3830
+ timerRef.current = null;
3831
+ }, 2e3);
2330
3832
  try {
2331
3833
  await navigator.clipboard.writeText(value);
2332
- showCopied();
2333
3834
  return;
2334
3835
  } catch {
2335
3836
  }
@@ -2340,27 +3841,23 @@ var CopyToClipboard = forwardRef(
2340
3841
  document.body.appendChild(ta);
2341
3842
  ta.focus();
2342
3843
  ta.select();
2343
- const ok = document.execCommand("copy");
3844
+ const execCommand = document.execCommand.bind(document);
3845
+ const ok = execCommand("copy");
2344
3846
  ta.remove();
2345
- if (ok) {
2346
- showCopied();
2347
- } else {
2348
- const error = new Error("Copy command unavailable");
2349
- console.warn("[CopyToClipboard]", error.message);
2350
- onError?.(error);
3847
+ if (!ok) {
3848
+ revertOptimistic(new Error("Copy command unavailable"));
2351
3849
  }
2352
3850
  } catch (fallbackErr) {
2353
3851
  const error = fallbackErr instanceof Error ? fallbackErr : new Error(String(fallbackErr));
2354
- console.warn("[CopyToClipboard] clipboard unavailable:", error.message);
2355
- onError?.(error);
3852
+ revertOptimistic(error);
2356
3853
  }
2357
- }, [value, onCopy, onError]);
3854
+ }, [value, onCopy, revertOptimistic]);
2358
3855
  return /* @__PURE__ */ jsxs(
2359
3856
  "button",
2360
3857
  {
2361
3858
  ref,
2362
3859
  type: "button",
2363
- className: `ds-atom-copy${className ? ` ${className}` : ""}`,
3860
+ className: ["ds-atom-copy", className].filter(Boolean).join(" "),
2364
3861
  "data-state": copied ? "copied" : "idle",
2365
3862
  "aria-label": `Copy ${label ?? value}`,
2366
3863
  style,
@@ -2381,6 +3878,46 @@ var CopyToClipboard = forwardRef(
2381
3878
  );
2382
3879
  }
2383
3880
  );
3881
+ function format(d) {
3882
+ const now = /* @__PURE__ */ new Date();
3883
+ const diffMs = now.getTime() - d.getTime();
3884
+ const diffMin = Math.floor(diffMs / 6e4);
3885
+ const diffH = Math.floor(diffMin / 60);
3886
+ const diffD = Math.floor(diffH / 24);
3887
+ if (diffMin < 0) return `in ${Math.abs(diffMin)}m`;
3888
+ if (diffMin < 60) return `${diffMin}m ago`;
3889
+ if (diffH < 24) return `${diffH}h ago`;
3890
+ if (diffD < 30) return `${diffD}d ago`;
3891
+ return d.toLocaleDateString();
3892
+ }
3893
+ var RelativeTime = forwardRef(function RelativeTime2({ date, prefix, updateInterval = 6e4, className, style, ...rest }, ref) {
3894
+ const d = new Date(date);
3895
+ const [rel, setRel] = useState(() => format(d));
3896
+ useEffect(() => {
3897
+ setRel(format(new Date(date)));
3898
+ if (updateInterval === 0) return;
3899
+ const id = globalThis.setInterval(() => setRel(format(new Date(date))), updateInterval);
3900
+ return () => globalThis.clearInterval(id);
3901
+ }, [date, updateInterval]);
3902
+ return /* @__PURE__ */ jsxs(
3903
+ "time",
3904
+ {
3905
+ ref,
3906
+ dateTime: d.toISOString(),
3907
+ title: d.toLocaleString(),
3908
+ className: `ds-atom-relative-time${className ? ` ${className}` : ""}`,
3909
+ style,
3910
+ ...rest,
3911
+ children: [
3912
+ prefix ? /* @__PURE__ */ jsxs("span", { style: { color: "var(--ink-4)" }, children: [
3913
+ prefix,
3914
+ " "
3915
+ ] }) : null,
3916
+ rel
3917
+ ]
3918
+ }
3919
+ );
3920
+ });
2384
3921
 
2385
3922
  // src/_internals/dateUtils.ts
2386
3923
  function startOfMonth(d) {
@@ -2452,7 +3989,9 @@ function buildMonthGrid(year, month, weekStart = 0) {
2452
3989
  }
2453
3990
  const weeks = [];
2454
3991
  for (let w = 0; w < 6; w++) {
2455
- weeks.push(cells.slice(w * 7, (w + 1) * 7));
3992
+ const week = cells.slice(w * 7, (w + 1) * 7);
3993
+ if (week.every((c) => !c.inMonth)) break;
3994
+ weeks.push(week);
2456
3995
  }
2457
3996
  return { weeks, cells, weekStart, monthStart };
2458
3997
  }
@@ -2460,9 +3999,23 @@ var NARROW_SUN = ["S", "M", "T", "W", "T", "F", "S"];
2460
3999
  var NARROW_MON = ["M", "T", "W", "T", "F", "S", "S"];
2461
4000
  var SHORT_SUN = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
2462
4001
  var SHORT_MON = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
2463
- function getWeekDayLabels(weekStart, format = "narrow") {
2464
- if (weekStart === 0) return format === "short" ? [...SHORT_SUN] : [...NARROW_SUN];
2465
- return format === "short" ? [...SHORT_MON] : [...NARROW_MON];
4002
+ function getWeekDayLabels(weekStart, format2 = "narrow") {
4003
+ if (weekStart === 0) return format2 === "short" ? [...SHORT_SUN] : [...NARROW_SUN];
4004
+ return format2 === "short" ? [...SHORT_MON] : [...NARROW_MON];
4005
+ }
4006
+ function defaultFormatLabel(d, showTime) {
4007
+ const datePart = d.toLocaleDateString(void 0, {
4008
+ weekday: "short",
4009
+ day: "numeric",
4010
+ month: "short"
4011
+ });
4012
+ if (!showTime) return datePart;
4013
+ const timePart = d.toLocaleTimeString(void 0, {
4014
+ hour: "numeric",
4015
+ minute: "2-digit",
4016
+ hour12: true
4017
+ });
4018
+ return `${datePart} \xB7 ${timePart}`;
2466
4019
  }
2467
4020
  var WEEKDAY_HEADERS = ["S", "M", "T", "W", "T", "F", "S"];
2468
4021
  var MONTH_NAMES = [
@@ -2496,10 +4049,19 @@ var DatePicker = forwardRef(function DatePicker2({
2496
4049
  isCellSelected,
2497
4050
  isRangeStart,
2498
4051
  isRangeEnd,
4052
+ variant = "inline",
4053
+ placeholder = "Pick a date",
4054
+ formatLabel,
2499
4055
  className,
2500
4056
  style,
2501
4057
  ...rest
2502
4058
  }, ref) {
4059
+ const triggerRef = useRef(null);
4060
+ const [popoverOpen, setPopoverOpen] = useState(false);
4061
+ const [valueAtOpen, setValueAtOpen] = useState(null);
4062
+ useEffect(() => {
4063
+ if (popoverOpen) setValueAtOpen(value);
4064
+ }, [popoverOpen, value]);
2503
4065
  const [viewMonth, setViewMonth] = useState(
2504
4066
  () => startOfMonth(value ?? defaultMonth ?? /* @__PURE__ */ new Date())
2505
4067
  );
@@ -2572,127 +4134,190 @@ var DatePicker = forwardRef(function DatePicker2({
2572
4134
  out.setHours(targetIsPm ? currentHours + 12 : currentHours - 12);
2573
4135
  onChange(out);
2574
4136
  }
2575
- const displayHour24 = value?.getHours() ?? 0;
2576
- const displayHour12 = displayHour24 % 12 === 0 ? 12 : displayHour24 % 12;
2577
- const displayPeriod = displayHour24 >= 12 ? "PM" : "AM";
2578
- const eventSet = useMemo(() => new Set((events ?? []).map((e) => dayKey(e))), [events]);
2579
- return /* @__PURE__ */ jsxs(
4137
+ const displayHour24 = value?.getHours() ?? 0;
4138
+ const displayHour12 = displayHour24 % 12 === 0 ? 12 : displayHour24 % 12;
4139
+ const displayPeriod = displayHour24 >= 12 ? "PM" : "AM";
4140
+ const eventSet = useMemo(() => new Set((events ?? []).map((e) => dayKey(e))), [events]);
4141
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
4142
+ /* @__PURE__ */ jsxs("div", { className: "ds-atom-datepicker-header", children: [
4143
+ /* @__PURE__ */ jsx(
4144
+ "button",
4145
+ {
4146
+ type: "button",
4147
+ "aria-label": "Previous month",
4148
+ onClick: () => step(-1),
4149
+ className: "ds-atom-datepicker-nav",
4150
+ children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
4151
+ }
4152
+ ),
4153
+ /* @__PURE__ */ jsxs("div", { className: "ds-atom-datepicker-label", children: [
4154
+ MONTH_NAMES[viewMonth.getMonth()],
4155
+ " ",
4156
+ viewMonth.getFullYear()
4157
+ ] }),
4158
+ /* @__PURE__ */ jsx(
4159
+ "button",
4160
+ {
4161
+ type: "button",
4162
+ "aria-label": "Next month",
4163
+ onClick: () => step(1),
4164
+ className: "ds-atom-datepicker-nav",
4165
+ children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
4166
+ }
4167
+ )
4168
+ ] }),
4169
+ /* @__PURE__ */ jsx("div", { className: "ds-atom-datepicker-weekdays", children: WEEKDAY_HEADERS.map((w, i) => /* @__PURE__ */ jsx("div", { className: "ds-atom-datepicker-weekday", children: w }, `wd-${i}-${w}`)) }),
4170
+ /* @__PURE__ */ jsx("div", { className: "ds-atom-datepicker-grid", role: "grid", children: cells.map(({ date, inMonth }) => {
4171
+ const selected = isCellSelected ? isCellSelected(date) : !!(value && isSameDay(date, value));
4172
+ const todayCell = isToday(date);
4173
+ const isDisabled = !!disabled?.(date) || isPastDisabled(date) || isFutureDisabled(date);
4174
+ const inRangeMatch = !!inRange?.(date);
4175
+ const isRangeStartCell = !!isRangeStart?.(date);
4176
+ const isRangeEndCell = !!isRangeEnd?.(date);
4177
+ const hasEvent = eventSet.has(dayKey(date));
4178
+ const cls3 = [
4179
+ "ds-atom-datepicker-cell",
4180
+ !inMonth && "is-out",
4181
+ selected && "is-selected",
4182
+ isRangeStartCell && "is-range-start",
4183
+ isRangeEndCell && "is-range-end",
4184
+ todayCell && "is-today",
4185
+ isDisabled && "is-disabled",
4186
+ inRangeMatch && "is-in-range"
4187
+ ].filter(Boolean).join(" ");
4188
+ return /* @__PURE__ */ jsxs(
4189
+ "button",
4190
+ {
4191
+ type: "button",
4192
+ role: "gridcell",
4193
+ "aria-selected": selected ? true : void 0,
4194
+ "aria-current": todayCell ? "date" : void 0,
4195
+ "aria-disabled": isDisabled || void 0,
4196
+ className: cls3,
4197
+ disabled: isDisabled,
4198
+ onClick: () => handleSelect(date),
4199
+ children: [
4200
+ /* @__PURE__ */ jsx("span", { className: "ds-atom-datepicker-cell-num", children: date.getDate() }),
4201
+ hasEvent ? /* @__PURE__ */ jsx("span", { className: "ds-atom-datepicker-event-dot", "aria-hidden": "true" }) : null
4202
+ ]
4203
+ },
4204
+ dayKey(date)
4205
+ );
4206
+ }) }),
4207
+ showTime ? /* @__PURE__ */ jsxs("div", { className: "ds-atom-datepicker-time", children: [
4208
+ /* @__PURE__ */ jsx(
4209
+ "input",
4210
+ {
4211
+ type: "number",
4212
+ "aria-label": "Hours",
4213
+ min: 1,
4214
+ max: 12,
4215
+ value: displayHour12,
4216
+ onChange: (e) => updateHour12(Number(e.target.value))
4217
+ }
4218
+ ),
4219
+ /* @__PURE__ */ jsx("span", { className: "ds-atom-datepicker-time-sep", children: ":" }),
4220
+ /* @__PURE__ */ jsx(
4221
+ "input",
4222
+ {
4223
+ type: "number",
4224
+ "aria-label": "Minutes",
4225
+ min: 0,
4226
+ max: 59,
4227
+ value: value?.getMinutes() ?? 0,
4228
+ onChange: (e) => updateMinute(Number(e.target.value))
4229
+ }
4230
+ ),
4231
+ /* @__PURE__ */ jsx(
4232
+ Button,
4233
+ {
4234
+ size: "sm",
4235
+ variant: displayPeriod === "PM" ? "primary" : "secondary",
4236
+ "aria-label": `Currently ${displayPeriod} - click to switch`,
4237
+ "aria-pressed": displayPeriod === "PM",
4238
+ onClick: () => togglePeriod(displayPeriod === "AM" ? "PM" : "AM"),
4239
+ style: {
4240
+ fontFamily: "var(--mono)",
4241
+ fontWeight: 700,
4242
+ letterSpacing: "0.04em",
4243
+ flexShrink: 0,
4244
+ width: 48
4245
+ },
4246
+ children: displayPeriod
4247
+ }
4248
+ )
4249
+ ] }) : null
4250
+ ] });
4251
+ if (variant === "popover") {
4252
+ const fmt = formatLabel ?? defaultFormatLabel;
4253
+ const triggerLabel = value ? fmt(value, showTime) : placeholder;
4254
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
4255
+ /* @__PURE__ */ jsxs(
4256
+ "button",
4257
+ {
4258
+ ref: triggerRef,
4259
+ type: "button",
4260
+ className: `ds-atom-datepicker-trigger${popoverOpen ? " is-open" : ""}${className ? ` ${className}` : ""}`,
4261
+ "aria-haspopup": "dialog",
4262
+ "aria-expanded": popoverOpen,
4263
+ onClick: () => setPopoverOpen((o) => !o),
4264
+ style,
4265
+ children: [
4266
+ /* @__PURE__ */ jsx("span", { className: `ds-atom-datepicker-trigger-label${value ? "" : " is-placeholder"}`, children: triggerLabel }),
4267
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ds-atom-datepicker-trigger-caret", children: "\u25BE" })
4268
+ ]
4269
+ }
4270
+ ),
4271
+ /* @__PURE__ */ jsx(
4272
+ Popover,
4273
+ {
4274
+ anchorRef: triggerRef,
4275
+ open: popoverOpen,
4276
+ onOpenChange: setPopoverOpen,
4277
+ placement: "bottom-start",
4278
+ offset: 6,
4279
+ className: "ds-atom-datepicker-popover",
4280
+ children: /* @__PURE__ */ jsxs("div", { ref, className: "ds-atom-datepicker is-popover", ...rest, children: [
4281
+ body,
4282
+ /* @__PURE__ */ jsxs("div", { className: "ds-atom-datepicker-popover-actions", children: [
4283
+ /* @__PURE__ */ jsx(
4284
+ Button,
4285
+ {
4286
+ size: "sm",
4287
+ variant: "secondary",
4288
+ onClick: () => {
4289
+ if (valueAtOpen !== value) {
4290
+ if (valueAtOpen) onChange(valueAtOpen);
4291
+ }
4292
+ setPopoverOpen(false);
4293
+ },
4294
+ children: "Cancel"
4295
+ }
4296
+ ),
4297
+ /* @__PURE__ */ jsx(
4298
+ Button,
4299
+ {
4300
+ size: "sm",
4301
+ variant: "primary",
4302
+ onClick: () => setPopoverOpen(false),
4303
+ disabled: !value,
4304
+ children: "Apply"
4305
+ }
4306
+ )
4307
+ ] })
4308
+ ] })
4309
+ }
4310
+ )
4311
+ ] });
4312
+ }
4313
+ return /* @__PURE__ */ jsx(
2580
4314
  "div",
2581
4315
  {
2582
4316
  ref,
2583
4317
  className: `ds-atom-datepicker${className ? ` ${className}` : ""}`,
2584
4318
  style,
2585
4319
  ...rest,
2586
- children: [
2587
- /* @__PURE__ */ jsxs("div", { className: "ds-atom-datepicker-header", children: [
2588
- /* @__PURE__ */ jsx(
2589
- "button",
2590
- {
2591
- type: "button",
2592
- "aria-label": "Previous month",
2593
- onClick: () => step(-1),
2594
- className: "ds-atom-datepicker-nav",
2595
- children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
2596
- }
2597
- ),
2598
- /* @__PURE__ */ jsxs("div", { className: "ds-atom-datepicker-label", children: [
2599
- MONTH_NAMES[viewMonth.getMonth()],
2600
- " ",
2601
- viewMonth.getFullYear()
2602
- ] }),
2603
- /* @__PURE__ */ jsx(
2604
- "button",
2605
- {
2606
- type: "button",
2607
- "aria-label": "Next month",
2608
- onClick: () => step(1),
2609
- className: "ds-atom-datepicker-nav",
2610
- children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
2611
- }
2612
- )
2613
- ] }),
2614
- /* @__PURE__ */ jsx("div", { className: "ds-atom-datepicker-weekdays", children: WEEKDAY_HEADERS.map((w, i) => /* @__PURE__ */ jsx("div", { className: "ds-atom-datepicker-weekday", children: w }, `wd-${i}-${w}`)) }),
2615
- /* @__PURE__ */ jsx("div", { className: "ds-atom-datepicker-grid", role: "grid", children: cells.map(({ date, inMonth }) => {
2616
- const selected = isCellSelected ? isCellSelected(date) : !!(value && isSameDay(date, value));
2617
- const todayCell = isToday(date);
2618
- const isDisabled = !!disabled?.(date) || isPastDisabled(date) || isFutureDisabled(date);
2619
- const inRangeMatch = !!inRange?.(date);
2620
- const isRangeStartCell = !!isRangeStart?.(date);
2621
- const isRangeEndCell = !!isRangeEnd?.(date);
2622
- const hasEvent = eventSet.has(dayKey(date));
2623
- const cls2 = [
2624
- "ds-atom-datepicker-cell",
2625
- !inMonth && "is-out",
2626
- selected && "is-selected",
2627
- isRangeStartCell && "is-range-start",
2628
- isRangeEndCell && "is-range-end",
2629
- todayCell && "is-today",
2630
- isDisabled && "is-disabled",
2631
- inRangeMatch && "is-in-range"
2632
- ].filter(Boolean).join(" ");
2633
- return /* @__PURE__ */ jsxs(
2634
- "button",
2635
- {
2636
- type: "button",
2637
- role: "gridcell",
2638
- "aria-selected": selected ? true : void 0,
2639
- "aria-current": todayCell ? "date" : void 0,
2640
- "aria-disabled": isDisabled || void 0,
2641
- className: cls2,
2642
- disabled: isDisabled,
2643
- onClick: () => handleSelect(date),
2644
- children: [
2645
- /* @__PURE__ */ jsx("span", { children: date.getDate() }),
2646
- hasEvent ? /* @__PURE__ */ jsx("span", { className: "ds-atom-datepicker-event-dot", "aria-hidden": "true" }) : null
2647
- ]
2648
- },
2649
- dayKey(date)
2650
- );
2651
- }) }),
2652
- showTime ? /* @__PURE__ */ jsxs("div", { className: "ds-atom-datepicker-time", children: [
2653
- /* @__PURE__ */ jsx(
2654
- "input",
2655
- {
2656
- type: "number",
2657
- "aria-label": "Hours",
2658
- min: 1,
2659
- max: 12,
2660
- value: displayHour12,
2661
- onChange: (e) => updateHour12(Number(e.target.value))
2662
- }
2663
- ),
2664
- /* @__PURE__ */ jsx("span", { className: "ds-atom-datepicker-time-sep", children: ":" }),
2665
- /* @__PURE__ */ jsx(
2666
- "input",
2667
- {
2668
- type: "number",
2669
- "aria-label": "Minutes",
2670
- min: 0,
2671
- max: 59,
2672
- value: value?.getMinutes() ?? 0,
2673
- onChange: (e) => updateMinute(Number(e.target.value))
2674
- }
2675
- ),
2676
- /* @__PURE__ */ jsx(
2677
- Button,
2678
- {
2679
- size: "sm",
2680
- variant: displayPeriod === "PM" ? "primary" : "secondary",
2681
- "aria-label": `Currently ${displayPeriod} - click to switch`,
2682
- "aria-pressed": displayPeriod === "PM",
2683
- onClick: () => togglePeriod(displayPeriod === "AM" ? "PM" : "AM"),
2684
- style: {
2685
- fontFamily: "var(--mono)",
2686
- fontWeight: 700,
2687
- letterSpacing: "0.04em",
2688
- flexShrink: 0,
2689
- width: 48
2690
- },
2691
- children: displayPeriod
2692
- }
2693
- )
2694
- ] }) : null
2695
- ]
4320
+ children: body
2696
4321
  }
2697
4322
  );
2698
4323
  });
@@ -2914,7 +4539,19 @@ function DSDropdown({
2914
4539
  );
2915
4540
  return /* @__PURE__ */ jsx(DSPortal, { children: isDarkCtx ? /* @__PURE__ */ jsx("div", { className: "dark", children: dropdownEl }) : dropdownEl });
2916
4541
  }
2917
- var MultiSelect = forwardRef(function MultiSelect2({ value, onChange, options, placeholder = "Select\u2026", disabled = false, className, style }, ref) {
4542
+ var MultiSelect = forwardRef(function MultiSelect2({
4543
+ value,
4544
+ onChange,
4545
+ options,
4546
+ placeholder = "Select\u2026",
4547
+ compact = false,
4548
+ allSelectedLabel = "All",
4549
+ tone = "default",
4550
+ size = "md",
4551
+ disabled = false,
4552
+ className,
4553
+ style
4554
+ }, ref) {
2918
4555
  const triggerRef = useRef(null);
2919
4556
  const moreChipRef = useRef(null);
2920
4557
  const [open, setOpen] = useState(false);
@@ -2951,7 +4588,7 @@ var MultiSelect = forwardRef(function MultiSelect2({ value, onChange, options, p
2951
4588
  {
2952
4589
  ref: combineRefs,
2953
4590
  type: "button",
2954
- className: `ds-atom-multiselect${className ? ` ${className}` : ""}`,
4591
+ className: `ds-atom-multiselect${compact ? " ds-atom-multiselect-compact" : ""}${className ? ` ${className}` : ""}`,
2955
4592
  role: "combobox",
2956
4593
  "aria-expanded": open,
2957
4594
  "aria-haspopup": "listbox",
@@ -2959,10 +4596,17 @@ var MultiSelect = forwardRef(function MultiSelect2({ value, onChange, options, p
2959
4596
  "aria-activedescendant": open ? optionId(activeIndex) : void 0,
2960
4597
  disabled,
2961
4598
  "data-state": open ? "open" : "closed",
4599
+ "data-tone": tone,
4600
+ "data-size": size,
2962
4601
  onClick: () => !disabled && setOpen((o) => !o),
2963
4602
  style,
2964
4603
  children: [
2965
- /* @__PURE__ */ jsx("span", { className: "ds-atom-multiselect-chips", children: selectedOpts.length === 0 ? /* @__PURE__ */ jsx("span", { className: "ds-atom-multiselect-placeholder", children: placeholder }) : /* @__PURE__ */ jsxs(Fragment, { children: [
4604
+ /* @__PURE__ */ jsx("span", { className: "ds-atom-multiselect-chips", children: compact ? (
4605
+ // Single-line trigger: never render chips. Show placeholder when
4606
+ // nothing selected, allSelectedLabel when every option is selected,
4607
+ // or `${placeholder} (${count})` for any partial selection.
4608
+ /* @__PURE__ */ jsx("span", { className: "ds-atom-multiselect-placeholder", children: selectedOpts.length === 0 ? placeholder : selectedOpts.length === options.length ? allSelectedLabel : `${placeholder} (${selectedOpts.length})` })
4609
+ ) : selectedOpts.length === 0 ? /* @__PURE__ */ jsx("span", { className: "ds-atom-multiselect-placeholder", children: placeholder }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2966
4610
  visibleChips.map((o) => /* @__PURE__ */ jsxs("span", { className: "ds-atom-multiselect-chip", children: [
2967
4611
  /* @__PURE__ */ jsx("span", { children: o.label }),
2968
4612
  /* @__PURE__ */ jsx(
@@ -3079,6 +4723,8 @@ var Select = forwardRef(function Select2({
3079
4723
  options,
3080
4724
  placeholder = "Select\u2026",
3081
4725
  searchable = true,
4726
+ tone = "default",
4727
+ size = "md",
3082
4728
  disabled = false,
3083
4729
  className,
3084
4730
  style
@@ -3126,6 +4772,8 @@ var Select = forwardRef(function Select2({
3126
4772
  "aria-activedescendant": open && filtered.length > 0 ? optionId(activeIndex) : void 0,
3127
4773
  disabled,
3128
4774
  "data-state": open ? "open" : "closed",
4775
+ "data-tone": tone,
4776
+ "data-size": size,
3129
4777
  onClick: () => !disabled && setOpen((o) => !o),
3130
4778
  style,
3131
4779
  children: [
@@ -3413,6 +5061,686 @@ function Autocomplete({
3413
5061
  )
3414
5062
  ] });
3415
5063
  }
5064
+ function FileInput({
5065
+ onSelect,
5066
+ accept,
5067
+ multiple = false,
5068
+ maxSizeBytes,
5069
+ onError,
5070
+ disabled = false,
5071
+ variant = "dropzone",
5072
+ ariaLabel = "Upload file",
5073
+ children,
5074
+ className,
5075
+ style
5076
+ }) {
5077
+ const inputRef = useRef(null);
5078
+ const [dragOver, setDragOver] = useState(false);
5079
+ function validateFiles(files) {
5080
+ const arr = Array.from(files);
5081
+ if (arr.length === 0) return null;
5082
+ const subset = multiple ? arr : arr.slice(0, 1);
5083
+ for (const f of subset) {
5084
+ if (accept) {
5085
+ const tokens = accept.split(",").map((t) => t.trim()).filter(Boolean);
5086
+ const matches = tokens.some(
5087
+ (t) => t.startsWith(".") ? f.name.toLowerCase().endsWith(t.toLowerCase()) : f.type === t
5088
+ );
5089
+ if (!matches) {
5090
+ onError?.(`Only ${accept} files are accepted.`);
5091
+ return null;
5092
+ }
5093
+ }
5094
+ if (typeof maxSizeBytes === "number" && f.size > maxSizeBytes) {
5095
+ const mb = Math.round(maxSizeBytes / (1024 * 1024));
5096
+ onError?.(`File must be under ${mb} MB.`);
5097
+ return null;
5098
+ }
5099
+ }
5100
+ return subset;
5101
+ }
5102
+ function handlePickedFiles(files) {
5103
+ if (!files) return;
5104
+ const valid = validateFiles(files);
5105
+ if (valid) onSelect(valid);
5106
+ }
5107
+ function handleTriggerClick() {
5108
+ if (disabled) return;
5109
+ inputRef.current?.click();
5110
+ }
5111
+ const hiddenInput = /* @__PURE__ */ jsx(
5112
+ "input",
5113
+ {
5114
+ ref: inputRef,
5115
+ type: "file",
5116
+ accept,
5117
+ multiple,
5118
+ style: { display: "none" },
5119
+ onChange: (e) => handlePickedFiles(e.target.files)
5120
+ }
5121
+ );
5122
+ if (variant === "button") {
5123
+ return /* @__PURE__ */ jsxs(
5124
+ "span",
5125
+ {
5126
+ className: ["ds-atom-fileinput-button", className].filter(Boolean).join(" "),
5127
+ style,
5128
+ children: [
5129
+ /* @__PURE__ */ jsx(
5130
+ Button,
5131
+ {
5132
+ variant: "secondary",
5133
+ onClick: handleTriggerClick,
5134
+ disabled,
5135
+ "aria-label": ariaLabel,
5136
+ children: children ?? "Upload file"
5137
+ }
5138
+ ),
5139
+ hiddenInput
5140
+ ]
5141
+ }
5142
+ );
5143
+ }
5144
+ const triggerStyle = {
5145
+ width: "100%",
5146
+ padding: 18,
5147
+ background: dragOver ? "var(--paper-deep)" : "var(--paper-warm)",
5148
+ border: `2px dashed ${dragOver ? "var(--amber)" : "#E8D9AC"}`,
5149
+ borderRadius: 10,
5150
+ display: "flex",
5151
+ alignItems: "center",
5152
+ gap: 14,
5153
+ cursor: disabled ? "not-allowed" : "pointer",
5154
+ textAlign: "left",
5155
+ opacity: disabled ? 0.5 : 1,
5156
+ pointerEvents: disabled ? "none" : "auto",
5157
+ transition: "background-color .15s, border-color .15s",
5158
+ ...style
5159
+ };
5160
+ const dropzoneClasses = [
5161
+ "ds-atom-fileinput",
5162
+ dragOver ? "ds-atom-fileinput--dragover" : null,
5163
+ disabled ? "ds-atom-fileinput--disabled" : null,
5164
+ className
5165
+ ].filter(Boolean).join(" ");
5166
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5167
+ /* @__PURE__ */ jsx(
5168
+ "button",
5169
+ {
5170
+ type: "button",
5171
+ className: dropzoneClasses,
5172
+ "data-state": dragOver ? "dragover" : "idle",
5173
+ "aria-label": ariaLabel,
5174
+ "aria-disabled": disabled,
5175
+ disabled,
5176
+ onClick: handleTriggerClick,
5177
+ onDragOver: (e) => {
5178
+ e.preventDefault();
5179
+ if (!disabled) setDragOver(true);
5180
+ },
5181
+ onDragLeave: () => setDragOver(false),
5182
+ onDrop: (e) => {
5183
+ e.preventDefault();
5184
+ setDragOver(false);
5185
+ if (disabled) return;
5186
+ handlePickedFiles(e.dataTransfer.files);
5187
+ },
5188
+ style: triggerStyle,
5189
+ children: children ?? /* @__PURE__ */ jsx(DefaultDropzoneContent, {})
5190
+ }
5191
+ ),
5192
+ hiddenInput
5193
+ ] });
5194
+ }
5195
+ function DefaultDropzoneContent() {
5196
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5197
+ /* @__PURE__ */ jsx(
5198
+ "span",
5199
+ {
5200
+ "aria-hidden": "true",
5201
+ style: {
5202
+ width: 36,
5203
+ height: 36,
5204
+ borderRadius: 8,
5205
+ background: "var(--panel)",
5206
+ border: "1px solid var(--rule)",
5207
+ display: "flex",
5208
+ alignItems: "center",
5209
+ justifyContent: "center",
5210
+ color: "var(--amber)",
5211
+ fontSize: 18,
5212
+ flexShrink: 0
5213
+ },
5214
+ children: "\u2913"
5215
+ }
5216
+ ),
5217
+ /* @__PURE__ */ jsxs("span", { style: { display: "flex", flexDirection: "column", minWidth: 0 }, children: [
5218
+ /* @__PURE__ */ jsx(
5219
+ "b",
5220
+ {
5221
+ style: {
5222
+ fontFamily: "var(--font)",
5223
+ fontSize: 13.5,
5224
+ fontWeight: 600,
5225
+ color: "var(--ink)",
5226
+ lineHeight: 1.4,
5227
+ marginBottom: 3
5228
+ },
5229
+ children: "Drop a file here, or click to upload"
5230
+ }
5231
+ ),
5232
+ /* @__PURE__ */ jsx(
5233
+ "span",
5234
+ {
5235
+ style: {
5236
+ fontFamily: "var(--mono)",
5237
+ fontSize: 10,
5238
+ color: "var(--ink-3)",
5239
+ letterSpacing: ".04em",
5240
+ lineHeight: 1.4
5241
+ },
5242
+ children: "File picker"
5243
+ }
5244
+ )
5245
+ ] })
5246
+ ] });
5247
+ }
5248
+
5249
+ // src/inputs/ColorPicker/colorUtils.ts
5250
+ function hexToHsv(hex) {
5251
+ const r = Number.parseInt(hex.slice(1, 3), 16) / 255;
5252
+ const g = Number.parseInt(hex.slice(3, 5), 16) / 255;
5253
+ const b = Number.parseInt(hex.slice(5, 7), 16) / 255;
5254
+ const max = Math.max(r, g, b);
5255
+ const min = Math.min(r, g, b);
5256
+ const d = max - min;
5257
+ const v = max;
5258
+ const s = max === 0 ? 0 : d / max;
5259
+ let h = 0;
5260
+ if (d !== 0) {
5261
+ if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
5262
+ else if (max === g) h = ((b - r) / d + 2) / 6;
5263
+ else h = ((r - g) / d + 4) / 6;
5264
+ }
5265
+ return [h * 360, s, v];
5266
+ }
5267
+ function hsvToHex(h, s, v) {
5268
+ const i = Math.floor(h / 60) % 6;
5269
+ const f = h / 60 - Math.floor(h / 60);
5270
+ const p = v * (1 - s);
5271
+ const q = v * (1 - f * s);
5272
+ const t = v * (1 - (1 - f) * s);
5273
+ const table = [
5274
+ [v, t, p],
5275
+ [q, v, p],
5276
+ [p, v, t],
5277
+ [p, q, v],
5278
+ [t, p, v],
5279
+ [v, p, q]
5280
+ ];
5281
+ const triplet = table[i];
5282
+ if (!triplet) {
5283
+ return "#000000";
5284
+ }
5285
+ const [r, g, b] = triplet;
5286
+ return `#${[r, g, b].map(
5287
+ (x) => Math.round(x * 255).toString(16).padStart(2, "0")
5288
+ ).join("")}`;
5289
+ }
5290
+ var PRESETS_DEFAULT = [
5291
+ "#f59e0b",
5292
+ "#ef4444",
5293
+ "#3b82f6",
5294
+ "#8b5cf6",
5295
+ "#22c55e",
5296
+ "#ec4899",
5297
+ "#06b6d4",
5298
+ "#f97316",
5299
+ "#14b8a6",
5300
+ "#6366f1"
5301
+ ];
5302
+ var TONAL_STRIPS = [
5303
+ {
5304
+ label: "Amber",
5305
+ colors: [
5306
+ "#fef3c7",
5307
+ "#fde68a",
5308
+ "#fcd34d",
5309
+ "#fbbf24",
5310
+ "#f59e0b",
5311
+ "#d97706",
5312
+ "#b45309",
5313
+ "#92400e"
5314
+ ]
5315
+ },
5316
+ {
5317
+ label: "Blue",
5318
+ colors: [
5319
+ "#dbeafe",
5320
+ "#bfdbfe",
5321
+ "#93c5fd",
5322
+ "#60a5fa",
5323
+ "#3b82f6",
5324
+ "#2563eb",
5325
+ "#1d4ed8",
5326
+ "#1e40af"
5327
+ ]
5328
+ },
5329
+ {
5330
+ label: "Neutral",
5331
+ colors: [
5332
+ "#f5f3f0",
5333
+ "#ece8e3",
5334
+ "#e7e2dc",
5335
+ "#d6d3d1",
5336
+ "#a8a29e",
5337
+ "#6b6560",
5338
+ "#44403c",
5339
+ "#292524"
5340
+ ]
5341
+ }
5342
+ ];
5343
+ var HEX_RE = /^#[0-9a-fA-F]{6}$/;
5344
+ function ColorPicker({
5345
+ value,
5346
+ onChange,
5347
+ defaultValue = "#f59e0b",
5348
+ presets = PRESETS_DEFAULT,
5349
+ className,
5350
+ style
5351
+ }) {
5352
+ const initial = value ?? defaultValue;
5353
+ const [color, setColor] = useState(initial);
5354
+ const [hex, setHex] = useState(initial);
5355
+ const [hue, setHue] = useState(() => hexToHsv(initial)[0]);
5356
+ const [opacity, setOpacity] = useState(100);
5357
+ useEffect(() => {
5358
+ if (value !== void 0 && value !== color) {
5359
+ setColor(value);
5360
+ setHex(value);
5361
+ }
5362
+ }, [value]);
5363
+ function emit(next) {
5364
+ setColor(next);
5365
+ setHex(next);
5366
+ onChange?.(next);
5367
+ }
5368
+ function startDrag(target, el, initialEvent) {
5369
+ try {
5370
+ el.setPointerCapture(initialEvent.pointerId);
5371
+ } catch {
5372
+ }
5373
+ const rect = el.getBoundingClientRect();
5374
+ function update(e) {
5375
+ const x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
5376
+ const y = Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height));
5377
+ if (target === "canvas") {
5378
+ const newHex = hsvToHex(hue, x, 1 - y);
5379
+ emit(newHex);
5380
+ } else if (target === "hue") {
5381
+ const newHue = x * 360;
5382
+ setHue(newHue);
5383
+ const [, s, v] = hexToHsv(color);
5384
+ emit(hsvToHex(newHue, s || 1, v || 1));
5385
+ } else {
5386
+ setOpacity(Math.round(x * 100));
5387
+ }
5388
+ }
5389
+ update(initialEvent);
5390
+ function onMove(e) {
5391
+ update(e);
5392
+ }
5393
+ function onUp() {
5394
+ document.removeEventListener("pointermove", onMove);
5395
+ document.removeEventListener("pointerup", onUp);
5396
+ }
5397
+ document.addEventListener("pointermove", onMove);
5398
+ document.addEventListener("pointerup", onUp);
5399
+ }
5400
+ function handleHexChange(e) {
5401
+ const next = e.target.value;
5402
+ setHex(next);
5403
+ if (HEX_RE.test(next)) {
5404
+ setColor(next);
5405
+ setHue(hexToHsv(next)[0]);
5406
+ onChange?.(next);
5407
+ }
5408
+ }
5409
+ const [, sat, val] = hexToHsv(color);
5410
+ const labelStyle4 = {
5411
+ fontFamily: "var(--mono)",
5412
+ fontSize: 9,
5413
+ color: "var(--ink-4)",
5414
+ marginBottom: 4,
5415
+ fontWeight: 700
5416
+ };
5417
+ return /* @__PURE__ */ jsxs(
5418
+ "div",
5419
+ {
5420
+ className: ["ds-atom-colorpicker", className].filter(Boolean).join(" "),
5421
+ style: { width: 260, padding: 16, borderRadius: 14, ...style },
5422
+ children: [
5423
+ /* @__PURE__ */ jsx(
5424
+ "div",
5425
+ {
5426
+ role: "slider",
5427
+ "aria-label": "Saturation and brightness",
5428
+ "aria-valuenow": Math.round(sat * 100),
5429
+ "aria-valuemin": 0,
5430
+ "aria-valuemax": 100,
5431
+ tabIndex: 0,
5432
+ className: "ds-atom-colorpicker-canvas",
5433
+ onPointerDown: (e) => startDrag("canvas", e.currentTarget, e),
5434
+ style: {
5435
+ width: "100%",
5436
+ height: 150,
5437
+ borderRadius: 10,
5438
+ marginBottom: 12,
5439
+ position: "relative",
5440
+ cursor: "crosshair",
5441
+ background: `linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, ${hsvToHex(hue, 1, 1)})`
5442
+ },
5443
+ children: /* @__PURE__ */ jsx(
5444
+ "div",
5445
+ {
5446
+ className: "ds-atom-colorpicker-thumb",
5447
+ style: {
5448
+ left: `${sat * 100}%`,
5449
+ top: `${(1 - val) * 100}%`,
5450
+ width: 16,
5451
+ height: 16,
5452
+ borderRadius: "50%",
5453
+ border: "2.5px solid #fff",
5454
+ boxShadow: "0 1px 4px rgba(0,0,0,.35)"
5455
+ }
5456
+ }
5457
+ )
5458
+ }
5459
+ ),
5460
+ /* @__PURE__ */ jsx("div", { style: labelStyle4, children: "HUE" }),
5461
+ /* @__PURE__ */ jsx(
5462
+ "div",
5463
+ {
5464
+ role: "slider",
5465
+ "aria-label": "Hue",
5466
+ "aria-valuenow": Math.round(hue),
5467
+ "aria-valuemin": 0,
5468
+ "aria-valuemax": 360,
5469
+ tabIndex: 0,
5470
+ className: "ds-atom-colorpicker-huebar",
5471
+ onPointerDown: (e) => startDrag("hue", e.currentTarget, e),
5472
+ style: {
5473
+ width: "100%",
5474
+ height: 12,
5475
+ borderRadius: 6,
5476
+ marginBottom: 12,
5477
+ background: "linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00)",
5478
+ position: "relative",
5479
+ cursor: "pointer"
5480
+ },
5481
+ children: /* @__PURE__ */ jsx(
5482
+ "div",
5483
+ {
5484
+ className: "ds-atom-colorpicker-thumb",
5485
+ style: {
5486
+ left: `${hue / 360 * 100}%`,
5487
+ top: "50%",
5488
+ width: 14,
5489
+ height: 14,
5490
+ borderRadius: "50%",
5491
+ border: "2px solid #fff",
5492
+ boxShadow: "0 1px 3px rgba(0,0,0,.3)",
5493
+ background: hsvToHex(hue, 1, 1)
5494
+ }
5495
+ }
5496
+ )
5497
+ }
5498
+ ),
5499
+ /* @__PURE__ */ jsx("div", { style: labelStyle4, children: "OPACITY" }),
5500
+ /* @__PURE__ */ jsx(
5501
+ "div",
5502
+ {
5503
+ role: "slider",
5504
+ "aria-label": "Opacity",
5505
+ "aria-valuenow": opacity,
5506
+ "aria-valuemin": 0,
5507
+ "aria-valuemax": 100,
5508
+ tabIndex: 0,
5509
+ className: "ds-atom-colorpicker-opacitybar",
5510
+ onPointerDown: (e) => startDrag("opacity", e.currentTarget, e),
5511
+ style: {
5512
+ width: "100%",
5513
+ height: 12,
5514
+ borderRadius: 6,
5515
+ marginBottom: 14,
5516
+ background: `linear-gradient(to right, transparent, ${color}), repeating-conic-gradient(#ccc 0% 25%, #fff 0% 50%) 50%/8px 8px`,
5517
+ position: "relative",
5518
+ cursor: "pointer"
5519
+ },
5520
+ children: /* @__PURE__ */ jsx(
5521
+ "div",
5522
+ {
5523
+ className: "ds-atom-colorpicker-thumb",
5524
+ style: {
5525
+ left: `${opacity}%`,
5526
+ top: "50%",
5527
+ width: 14,
5528
+ height: 14,
5529
+ borderRadius: "50%",
5530
+ border: "2px solid #fff",
5531
+ boxShadow: "0 1px 3px rgba(0,0,0,.3)",
5532
+ background: color
5533
+ }
5534
+ }
5535
+ )
5536
+ }
5537
+ ),
5538
+ /* @__PURE__ */ jsxs(
5539
+ "div",
5540
+ {
5541
+ style: {
5542
+ display: "flex",
5543
+ gap: 8,
5544
+ alignItems: "center",
5545
+ marginBottom: 14
5546
+ },
5547
+ children: [
5548
+ /* @__PURE__ */ jsx(
5549
+ "div",
5550
+ {
5551
+ style: {
5552
+ width: 36,
5553
+ height: 36,
5554
+ borderRadius: 8,
5555
+ background: color,
5556
+ border: "1px solid var(--rule)",
5557
+ flexShrink: 0,
5558
+ boxShadow: "0 1px 4px rgba(0,0,0,.08)"
5559
+ }
5560
+ }
5561
+ ),
5562
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1 }, children: [
5563
+ /* @__PURE__ */ jsx(
5564
+ "label",
5565
+ {
5566
+ style: {
5567
+ fontFamily: "var(--mono)",
5568
+ fontSize: 9,
5569
+ color: "var(--ink-4)",
5570
+ fontWeight: 700,
5571
+ display: "block",
5572
+ marginBottom: 2
5573
+ },
5574
+ children: "HEX"
5575
+ }
5576
+ ),
5577
+ /* @__PURE__ */ jsx(
5578
+ "input",
5579
+ {
5580
+ className: "ds-input",
5581
+ value: hex,
5582
+ onChange: handleHexChange,
5583
+ "aria-label": "Hex color",
5584
+ style: { fontFamily: "var(--mono)", fontSize: 12, width: "100%" }
5585
+ }
5586
+ )
5587
+ ] }),
5588
+ /* @__PURE__ */ jsxs("div", { style: { width: 56 }, children: [
5589
+ /* @__PURE__ */ jsx(
5590
+ "label",
5591
+ {
5592
+ style: {
5593
+ fontFamily: "var(--mono)",
5594
+ fontSize: 9,
5595
+ color: "var(--ink-4)",
5596
+ fontWeight: 700,
5597
+ display: "block",
5598
+ marginBottom: 2
5599
+ },
5600
+ children: "ALPHA"
5601
+ }
5602
+ ),
5603
+ /* @__PURE__ */ jsx(
5604
+ "input",
5605
+ {
5606
+ className: "ds-input",
5607
+ value: `${opacity}%`,
5608
+ readOnly: true,
5609
+ "aria-label": "Alpha opacity",
5610
+ style: {
5611
+ fontFamily: "var(--mono)",
5612
+ fontSize: 12,
5613
+ textAlign: "center",
5614
+ width: "100%"
5615
+ }
5616
+ }
5617
+ )
5618
+ ] })
5619
+ ]
5620
+ }
5621
+ ),
5622
+ /* @__PURE__ */ jsx("div", { style: { ...labelStyle4, marginBottom: 6 }, children: "PRESETS" }),
5623
+ /* @__PURE__ */ jsx(
5624
+ "div",
5625
+ {
5626
+ style: {
5627
+ display: "flex",
5628
+ gap: 5,
5629
+ flexWrap: "wrap",
5630
+ marginBottom: 14
5631
+ },
5632
+ children: presets.map((c) => /* @__PURE__ */ jsx(
5633
+ "button",
5634
+ {
5635
+ type: "button",
5636
+ className: "ds-atom-colorpicker-swatch",
5637
+ "aria-label": `Color ${c}`,
5638
+ "aria-pressed": color === c,
5639
+ onClick: () => {
5640
+ emit(c);
5641
+ setHue(hexToHsv(c)[0]);
5642
+ },
5643
+ style: {
5644
+ width: 24,
5645
+ height: 24,
5646
+ borderRadius: 6,
5647
+ background: c,
5648
+ border: color === c ? "2.5px solid var(--ink)" : "1px solid var(--rule)"
5649
+ }
5650
+ },
5651
+ c
5652
+ ))
5653
+ }
5654
+ ),
5655
+ TONAL_STRIPS.map((strip) => /* @__PURE__ */ jsxs("div", { style: { marginBottom: 8 }, children: [
5656
+ /* @__PURE__ */ jsx("div", { style: labelStyle4, children: strip.label.toUpperCase() }),
5657
+ /* @__PURE__ */ jsx(
5658
+ "div",
5659
+ {
5660
+ style: {
5661
+ display: "flex",
5662
+ gap: 2,
5663
+ borderRadius: 4,
5664
+ overflow: "hidden"
5665
+ },
5666
+ children: strip.colors.map((c) => /* @__PURE__ */ jsx(
5667
+ "button",
5668
+ {
5669
+ type: "button",
5670
+ className: "ds-atom-colorpicker-cell",
5671
+ "aria-label": `${strip.label} ${c}`,
5672
+ "aria-pressed": color === c,
5673
+ onClick: () => {
5674
+ emit(c);
5675
+ setHue(hexToHsv(c)[0]);
5676
+ },
5677
+ style: { flex: 1, height: 18, background: c }
5678
+ },
5679
+ c
5680
+ ))
5681
+ }
5682
+ )
5683
+ ] }, strip.label))
5684
+ ]
5685
+ }
5686
+ );
5687
+ }
5688
+ var HEX_RE2 = /^#[0-9a-fA-F]{6}$/;
5689
+ function ColorInput({
5690
+ value,
5691
+ onChange,
5692
+ defaultValue = "#f59e0b",
5693
+ label,
5694
+ className,
5695
+ style
5696
+ }) {
5697
+ const initial = value ?? defaultValue;
5698
+ const [color, setColor] = useState(initial);
5699
+ const [hex, setHex] = useState(initial);
5700
+ useEffect(() => {
5701
+ if (value !== void 0 && value !== color) {
5702
+ setColor(value);
5703
+ setHex(value);
5704
+ }
5705
+ }, [value]);
5706
+ function handleChange(e) {
5707
+ const next = e.target.value;
5708
+ setHex(next);
5709
+ if (HEX_RE2.test(next)) {
5710
+ setColor(next);
5711
+ onChange?.(next);
5712
+ }
5713
+ }
5714
+ return /* @__PURE__ */ jsxs("div", { className: ["ds-atom-colorinput", className].filter(Boolean).join(" "), style, children: [
5715
+ label && /* @__PURE__ */ jsx("label", { className: "ds-label", style: { display: "block", marginBottom: 4 }, children: label }),
5716
+ /* @__PURE__ */ jsxs("div", { className: "ds-input-wrap", style: { display: "flex", alignItems: "center", gap: 8 }, children: [
5717
+ /* @__PURE__ */ jsx(
5718
+ "div",
5719
+ {
5720
+ "aria-hidden": "true",
5721
+ style: {
5722
+ width: 28,
5723
+ height: 28,
5724
+ borderRadius: 6,
5725
+ background: color,
5726
+ border: "1px solid var(--rule)",
5727
+ flexShrink: 0
5728
+ }
5729
+ }
5730
+ ),
5731
+ /* @__PURE__ */ jsx(
5732
+ "input",
5733
+ {
5734
+ className: "ds-input",
5735
+ value: hex,
5736
+ onChange: handleChange,
5737
+ "aria-label": label ?? "Color hex",
5738
+ style: { fontFamily: "var(--mono)", fontSize: 12, flex: 1 }
5739
+ }
5740
+ )
5741
+ ] })
5742
+ ] });
5743
+ }
3416
5744
  function SegmentedControlInner({
3417
5745
  options,
3418
5746
  value,
@@ -3784,9 +6112,9 @@ function AccordionItem({
3784
6112
  const generatedId = useId();
3785
6113
  const headerId = `${generatedId}-h`;
3786
6114
  const panelId = `${generatedId}-p`;
3787
- const Heading = HEADING_TAGS[headingLevel];
6115
+ const Heading4 = HEADING_TAGS[headingLevel];
3788
6116
  return /* @__PURE__ */ jsxs("div", { className: "ds-atom-accordion-item", "data-open": open || void 0, children: [
3789
- /* @__PURE__ */ jsx(Heading, { className: "ds-atom-accordion-heading", children: /* @__PURE__ */ jsxs(
6117
+ /* @__PURE__ */ jsx(Heading4, { className: "ds-atom-accordion-heading", children: /* @__PURE__ */ jsxs(
3790
6118
  "button",
3791
6119
  {
3792
6120
  type: "button",
@@ -4927,6 +7255,366 @@ function AgendaList({
4927
7255
  }
4928
7256
  var CalendarRootForward = forwardRef(CalendarRoot);
4929
7257
  var Calendar = Object.assign(CalendarRootForward, { Agenda: AgendaList });
7258
+ function getPageRange(current, total) {
7259
+ if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);
7260
+ const items = [1];
7261
+ if (current > 3) items.push("\u2026");
7262
+ for (let p = Math.max(2, current - 1); p <= Math.min(total - 1, current + 1); p++) {
7263
+ items.push(p);
7264
+ }
7265
+ if (current < total - 2) items.push("\u2026");
7266
+ items.push(total);
7267
+ return items;
7268
+ }
7269
+ var Pagination = forwardRef(function Pagination2({
7270
+ totalPages,
7271
+ currentPage,
7272
+ onPageChange,
7273
+ variant = "full",
7274
+ ariaLabel = "Pagination",
7275
+ className,
7276
+ style
7277
+ }, ref) {
7278
+ const listRef = useRef(null);
7279
+ function handleListKeyDown(e) {
7280
+ if (e.key !== "ArrowLeft" && e.key !== "ArrowRight") return;
7281
+ const buttons = Array.from(
7282
+ listRef.current?.querySelectorAll(
7283
+ "button.ds-atom-pagination-btn:not(:disabled)"
7284
+ ) ?? []
7285
+ );
7286
+ const focused = document.activeElement;
7287
+ const idx = buttons.indexOf(focused);
7288
+ if (idx === -1) return;
7289
+ if (e.key === "ArrowLeft" && idx > 0) {
7290
+ e.preventDefault();
7291
+ buttons[idx - 1].focus();
7292
+ } else if (e.key === "ArrowRight" && idx < buttons.length - 1) {
7293
+ e.preventDefault();
7294
+ buttons[idx + 1].focus();
7295
+ }
7296
+ }
7297
+ if (variant === "compact") {
7298
+ return /* @__PURE__ */ jsx(
7299
+ "nav",
7300
+ {
7301
+ ref,
7302
+ "aria-label": ariaLabel,
7303
+ className: `ds-atom-pagination${className ? ` ${className}` : ""}`,
7304
+ style,
7305
+ children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
7306
+ /* @__PURE__ */ jsx(
7307
+ "button",
7308
+ {
7309
+ type: "button",
7310
+ className: "ds-atom-pagination-icbtn",
7311
+ "aria-label": "Previous page",
7312
+ disabled: currentPage <= 1,
7313
+ onClick: () => onPageChange(currentPage - 1),
7314
+ children: /* @__PURE__ */ jsx(ChevronLeft, { size: 11, "aria-hidden": true })
7315
+ }
7316
+ ),
7317
+ /* @__PURE__ */ jsxs("span", { className: "ds-atom-pagination-count", children: [
7318
+ currentPage,
7319
+ " / ",
7320
+ totalPages
7321
+ ] }),
7322
+ /* @__PURE__ */ jsx(
7323
+ "button",
7324
+ {
7325
+ type: "button",
7326
+ className: "ds-atom-pagination-icbtn",
7327
+ "aria-label": "Next page",
7328
+ disabled: currentPage >= totalPages,
7329
+ onClick: () => onPageChange(currentPage + 1),
7330
+ children: /* @__PURE__ */ jsx(ChevronRight, { size: 11, "aria-hidden": true })
7331
+ }
7332
+ )
7333
+ ] })
7334
+ }
7335
+ );
7336
+ }
7337
+ const pages = getPageRange(currentPage, totalPages);
7338
+ let ellipsisCount = 0;
7339
+ const pageItems = pages.map((p) => {
7340
+ if (p === "\u2026") {
7341
+ ellipsisCount += 1;
7342
+ return { kind: "ellipsis", key: `ellipsis-${ellipsisCount}` };
7343
+ }
7344
+ return { kind: "page", page: p, key: `page-${p}` };
7345
+ });
7346
+ return /* @__PURE__ */ jsxs(
7347
+ "nav",
7348
+ {
7349
+ ref,
7350
+ "aria-label": ariaLabel,
7351
+ className: `ds-atom-pagination${className ? ` ${className}` : ""}`,
7352
+ style,
7353
+ children: [
7354
+ /* @__PURE__ */ jsxs("ol", { ref: listRef, className: "ds-atom-pagination-list", onKeyDown: handleListKeyDown, children: [
7355
+ /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
7356
+ "button",
7357
+ {
7358
+ type: "button",
7359
+ className: "ds-atom-pagination-icbtn",
7360
+ "aria-label": "Previous page",
7361
+ disabled: currentPage <= 1,
7362
+ onClick: () => onPageChange(currentPage - 1),
7363
+ children: /* @__PURE__ */ jsx(ChevronLeft, { size: 12, "aria-hidden": true })
7364
+ }
7365
+ ) }),
7366
+ pageItems.map(
7367
+ (item) => item.kind === "ellipsis" ? /* @__PURE__ */ jsx("li", { "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { className: "ds-atom-pagination-ellipsis", "aria-hidden": "true", children: "\u2026" }) }, item.key) : /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
7368
+ "button",
7369
+ {
7370
+ type: "button",
7371
+ className: "ds-atom-pagination-btn",
7372
+ "aria-label": `Page ${item.page}`,
7373
+ "aria-current": item.page === currentPage ? "page" : void 0,
7374
+ onClick: () => item.page !== currentPage && onPageChange(item.page),
7375
+ children: item.page
7376
+ }
7377
+ ) }, item.key)
7378
+ ),
7379
+ /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
7380
+ "button",
7381
+ {
7382
+ type: "button",
7383
+ className: "ds-atom-pagination-icbtn",
7384
+ "aria-label": "Next page",
7385
+ disabled: currentPage >= totalPages,
7386
+ onClick: () => onPageChange(currentPage + 1),
7387
+ children: /* @__PURE__ */ jsx(ChevronRight, { size: 12, "aria-hidden": true })
7388
+ }
7389
+ ) })
7390
+ ] }),
7391
+ /* @__PURE__ */ jsxs("span", { className: "ds-atom-pagination-label", children: [
7392
+ "Page ",
7393
+ currentPage,
7394
+ " of ",
7395
+ totalPages
7396
+ ] })
7397
+ ]
7398
+ }
7399
+ );
7400
+ });
7401
+ function cls2(base, extra) {
7402
+ return extra ? `${base} ${extra}` : base;
7403
+ }
7404
+ var STATUS_BADGE = {
7405
+ applied: { label: "Applied", tone: "upcoming" },
7406
+ interviewing: { label: "Interview", tone: "done" },
7407
+ offer: { label: "Offer", tone: "passed" },
7408
+ rejected: { label: "Rejected", tone: "pending" }
7409
+ };
7410
+ var PRIORITY_COLOR = {
7411
+ high: "var(--red-vivid)",
7412
+ medium: "var(--amber-vivid)",
7413
+ low: "var(--green-vivid)"
7414
+ };
7415
+ var DataGrid = forwardRef(function DataGrid2({
7416
+ columns,
7417
+ rows,
7418
+ page = 1,
7419
+ totalPages = 1,
7420
+ onPageChange,
7421
+ onSelectionChange,
7422
+ className,
7423
+ onKeyDown,
7424
+ ...rest
7425
+ }, ref) {
7426
+ const rowIds = rows.map((r) => r.id);
7427
+ const { sorted, sortCol, sortDir, toggleSort } = useSortableTable(rows);
7428
+ const initialWidths = Object.fromEntries(columns.map((c) => [c.key, c.width]));
7429
+ const { widths, startResize } = useResizableColumns(initialWidths, { minWidth: 60 });
7430
+ const { selectedIds, isAllSelected, isIndeterminate, isSelected, toggle, toggleAll, clear } = useTableSelection(rowIds, { onSelectionChange });
7431
+ const [focusedCell, setFocusedCell] = useState([0, 1]);
7432
+ const tableRef = useRef(null);
7433
+ const handleGridKeyDown = useCallback(
7434
+ (e) => {
7435
+ onKeyDown?.(e);
7436
+ if (e.defaultPrevented) return;
7437
+ const totalRows = sorted.length;
7438
+ const totalCols = columns.length + 1;
7439
+ let [r, c] = focusedCell;
7440
+ if (e.key === "ArrowDown") {
7441
+ e.preventDefault();
7442
+ r = Math.min(r + 1, totalRows - 1);
7443
+ } else if (e.key === "ArrowUp") {
7444
+ e.preventDefault();
7445
+ r = Math.max(r - 1, 0);
7446
+ } else if (e.key === "ArrowRight") {
7447
+ e.preventDefault();
7448
+ c = Math.min(c + 1, totalCols - 1);
7449
+ } else if (e.key === "ArrowLeft") {
7450
+ e.preventDefault();
7451
+ c = Math.max(c - 1, 0);
7452
+ } else if (e.key === " ") {
7453
+ e.preventDefault();
7454
+ const target = e.target;
7455
+ const tr = target.closest("tr");
7456
+ let rowIdx = r;
7457
+ if (tr) {
7458
+ const tbody = tr.parentElement;
7459
+ if (tbody) {
7460
+ const idx = Array.from(tbody.children).indexOf(tr);
7461
+ if (idx >= 0) rowIdx = idx;
7462
+ }
7463
+ }
7464
+ const row = sorted[rowIdx];
7465
+ if (row) toggle(row.id);
7466
+ return;
7467
+ } else {
7468
+ return;
7469
+ }
7470
+ setFocusedCell([r, c]);
7471
+ const trs = tableRef.current?.querySelectorAll("tbody tr");
7472
+ trs?.[r]?.querySelectorAll("td")?.[c]?.focus();
7473
+ },
7474
+ [focusedCell, sorted, columns.length, toggle, onKeyDown]
7475
+ );
7476
+ const selectionCount = selectedIds.length;
7477
+ return /* @__PURE__ */ jsxs(
7478
+ "div",
7479
+ {
7480
+ ref,
7481
+ className: cls2("ds-atom-datagrid glass", className),
7482
+ onKeyDown: handleGridKeyDown,
7483
+ ...rest,
7484
+ children: [
7485
+ selectionCount > 0 && /* @__PURE__ */ jsxs("div", { className: "ds-atom-datagrid-bulkbar", children: [
7486
+ /* @__PURE__ */ jsxs("span", { className: "ds-atom-datagrid-bulkbar-count", children: [
7487
+ selectionCount,
7488
+ " selected"
7489
+ ] }),
7490
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "xs", children: "Export" }),
7491
+ /* @__PURE__ */ jsx(Button, { variant: "danger", size: "xs", children: "Archive" }),
7492
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "xs", style: { marginLeft: "auto" }, onClick: clear, children: "Clear" })
7493
+ ] }),
7494
+ /* @__PURE__ */ jsx("div", { className: "ds-atom-datagrid-scroll", children: /* @__PURE__ */ jsxs(
7495
+ Table.Root,
7496
+ {
7497
+ ref: tableRef,
7498
+ role: "grid",
7499
+ multiSelectable: true,
7500
+ ariaLabel: "Job applications",
7501
+ density: "comfortable",
7502
+ style: { tableLayout: "fixed", width: "100%" },
7503
+ children: [
7504
+ /* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
7505
+ /* @__PURE__ */ jsx(
7506
+ Table.SelectAllCell,
7507
+ {
7508
+ isAllSelected,
7509
+ isIndeterminate,
7510
+ onToggleAll: toggleAll
7511
+ }
7512
+ ),
7513
+ columns.map((col) => /* @__PURE__ */ jsx(
7514
+ Table.HeaderCell,
7515
+ {
7516
+ sortable: col.sortable,
7517
+ sortDir: sortCol === col.key ? sortDir : null,
7518
+ onToggleSort: () => col.sortable && toggleSort(col.key),
7519
+ resizable: true,
7520
+ width: widths[col.key],
7521
+ onResizeStart: (e) => startResize(col.key, e),
7522
+ style: { textAlign: col.align ?? "left" },
7523
+ children: col.label
7524
+ },
7525
+ col.key
7526
+ ))
7527
+ ] }) }),
7528
+ /* @__PURE__ */ jsx(Table.Body, { children: sorted.map((row, rowIdx) => /* @__PURE__ */ jsxs(Table.Row, { selected: isSelected(row.id), children: [
7529
+ /* @__PURE__ */ jsx(
7530
+ Table.SelectCell,
7531
+ {
7532
+ selected: isSelected(row.id),
7533
+ onToggle: () => toggle(row.id),
7534
+ tabIndex: focusedCell[0] === rowIdx && focusedCell[1] === 0 ? 0 : -1
7535
+ }
7536
+ ),
7537
+ columns.map((col, colIdx) => {
7538
+ const cellTabIndex = focusedCell[0] === rowIdx && focusedCell[1] === colIdx + 1 ? 0 : -1;
7539
+ if (col.key === "status") {
7540
+ const entry = STATUS_BADGE[row[col.key]];
7541
+ return /* @__PURE__ */ jsx(Table.Cell, { tabIndex: cellTabIndex, children: /* @__PURE__ */ jsx(Badge, { tone: entry?.tone ?? "neutral", children: entry?.label ?? String(row[col.key]) }) }, col.key);
7542
+ }
7543
+ if (col.key === "priority") {
7544
+ const color = PRIORITY_COLOR[row[col.key]] ?? "var(--ink-4)";
7545
+ return /* @__PURE__ */ jsx(Table.Cell, { tabIndex: cellTabIndex, children: /* @__PURE__ */ jsxs(
7546
+ "span",
7547
+ {
7548
+ style: {
7549
+ display: "inline-flex",
7550
+ alignItems: "center",
7551
+ gap: 6
7552
+ },
7553
+ children: [
7554
+ /* @__PURE__ */ jsx(
7555
+ "span",
7556
+ {
7557
+ "data-part": "priority-dot",
7558
+ style: {
7559
+ width: 6,
7560
+ height: 6,
7561
+ borderRadius: "50%",
7562
+ background: color,
7563
+ flexShrink: 0,
7564
+ display: "inline-block"
7565
+ },
7566
+ "aria-hidden": "true"
7567
+ }
7568
+ ),
7569
+ /* @__PURE__ */ jsx(
7570
+ "span",
7571
+ {
7572
+ style: {
7573
+ fontSize: 12,
7574
+ textTransform: "capitalize"
7575
+ },
7576
+ children: String(row[col.key])
7577
+ }
7578
+ )
7579
+ ]
7580
+ }
7581
+ ) }, col.key);
7582
+ }
7583
+ return /* @__PURE__ */ jsx(
7584
+ Table.Cell,
7585
+ {
7586
+ tabIndex: cellTabIndex,
7587
+ style: { textAlign: col.align ?? "left" },
7588
+ children: String(row[col.key] ?? "")
7589
+ },
7590
+ col.key
7591
+ );
7592
+ })
7593
+ ] }, String(row.id))) })
7594
+ ]
7595
+ }
7596
+ ) }),
7597
+ /* @__PURE__ */ jsxs("div", { className: "ds-atom-datagrid-footer", children: [
7598
+ /* @__PURE__ */ jsxs("span", { className: "ds-atom-datagrid-footer-count", children: [
7599
+ rows.length,
7600
+ " rows"
7601
+ ] }),
7602
+ /* @__PURE__ */ jsx(
7603
+ Pagination,
7604
+ {
7605
+ totalPages,
7606
+ currentPage: page,
7607
+ onPageChange: onPageChange ?? (() => {
7608
+ }),
7609
+ variant: "full",
7610
+ ariaLabel: "DataGrid pagination"
7611
+ }
7612
+ )
7613
+ ] })
7614
+ ]
7615
+ }
7616
+ );
7617
+ });
4930
7618
 
4931
7619
  // node_modules/highlight.js/es/languages/css.js
4932
7620
  var MODES = (hljs) => {
@@ -8109,10 +10797,12 @@ var RichText = forwardRef(function RichText2({
8109
10797
  // then we add our own configured versions below (avoids "Duplicate extension" warning).
8110
10798
  StarterKit.configure({ link: false, underline: false, codeBlock: false }),
8111
10799
  CodeBlockLowlight.configure({ lowlight, defaultLanguage: "plaintext" }),
8112
- Link.configure({ openOnClick: false, autolink: true }),
10800
+ Link4.configure({ openOnClick: false, autolink: true }),
8113
10801
  Placeholder.configure({ placeholder: placeholder ?? "" }),
8114
10802
  // NOTE: UnderlineExtension - renamed import to avoid collision with Underline icon
8115
- UnderlineExtension
10803
+ UnderlineExtension,
10804
+ // NOTE: HighlightExtension - multicolor:false keeps output as plain <mark>
10805
+ HighlightExtension.configure({ multicolor: false })
8116
10806
  ],
8117
10807
  content: value,
8118
10808
  editable: !readOnly,
@@ -8184,6 +10874,18 @@ var RichText = forwardRef(function RichText2({
8184
10874
  children: /* @__PURE__ */ jsx(Underline, { size: 16 })
8185
10875
  }
8186
10876
  ),
10877
+ /* @__PURE__ */ jsx(
10878
+ Button,
10879
+ {
10880
+ variant: "ghost",
10881
+ size: "sm",
10882
+ "aria-label": "Highlight",
10883
+ "aria-pressed": isActive("highlight"),
10884
+ "data-active": isActive("highlight") || void 0,
10885
+ onClick: () => editor?.chain().focus().toggleHighlight().run(),
10886
+ children: /* @__PURE__ */ jsx(Highlighter, { size: 16 })
10887
+ }
10888
+ ),
8187
10889
  /* @__PURE__ */ jsx(
8188
10890
  Button,
8189
10891
  {
@@ -8715,58 +11417,6 @@ var Footer = forwardRef(
8715
11417
  }
8716
11418
  );
8717
11419
  Footer.displayName = "Footer";
8718
- var STRENGTH_LABELS = ["", "Weak", "Fair", "Good", "Strong"];
8719
- function segmentColor(index, score) {
8720
- if (score === 0 || index >= score) return "var(--ink-5)";
8721
- if (score === 1) return "var(--red)";
8722
- if (score === 4) return "var(--green-vivid)";
8723
- return "var(--amber)";
8724
- }
8725
- function labelColor(score) {
8726
- if (score <= 0) return "var(--ink-4)";
8727
- if (score === 1) return "var(--red)";
8728
- if (score <= 3) return "var(--amber-d)";
8729
- return "var(--green-vivid)";
8730
- }
8731
- function PasswordStrength({ score, className, style }) {
8732
- const label = STRENGTH_LABELS[score];
8733
- return /* @__PURE__ */ jsxs("div", { className: ["ds-atom-pwstrength", className].filter(Boolean).join(" "), style, children: [
8734
- /* @__PURE__ */ jsx("div", { className: "ds-atom-pwstrength-segs", children: [0, 1, 2, 3].map((i) => /* @__PURE__ */ jsx(
8735
- "span",
8736
- {
8737
- className: "ds-atom-pwstrength-seg",
8738
- style: { background: segmentColor(i, score) }
8739
- },
8740
- i
8741
- )) }),
8742
- label && /* @__PURE__ */ jsx("span", { className: "ds-atom-pwstrength-label", style: { color: labelColor(score) }, children: label })
8743
- ] });
8744
- }
8745
- function FieldError({ message, className }) {
8746
- if (!message) return null;
8747
- return /* @__PURE__ */ jsx("span", { role: "alert", className: ["ds-atom-field-error", className].filter(Boolean).join(" "), children: message });
8748
- }
8749
- function FormErrorSummary({
8750
- errors,
8751
- title = "Please fix the following errors:",
8752
- className
8753
- }) {
8754
- if (errors.length === 0) return null;
8755
- return /* @__PURE__ */ jsxs(
8756
- "div",
8757
- {
8758
- role: "alert",
8759
- className: ["ds-atom-form-error-summary", className].filter(Boolean).join(" "),
8760
- children: [
8761
- /* @__PURE__ */ jsx("strong", { children: title }),
8762
- /* @__PURE__ */ jsx("ul", { children: errors.map((err, i) => (
8763
- // biome-ignore lint/suspicious/noArrayIndexKey: static error list - order is stable and no unique IDs available
8764
- /* @__PURE__ */ jsx("li", { children: err }, i)
8765
- )) })
8766
- ]
8767
- }
8768
- );
8769
- }
8770
11420
  function readDismissed(storageKey) {
8771
11421
  if (typeof window === "undefined") return false;
8772
11422
  if (!storageKey) return false;
@@ -9195,6 +11845,6 @@ function Sortable({ items, onReorder, renderItem, id, className, style }) {
9195
11845
  );
9196
11846
  }
9197
11847
 
9198
- export { Accordion2 as Accordion, AlertBanner, AppBar, AppShell, Autocomplete, Avatar, AvatarStack, Badge, BottomSheet, Breadcrumbs, Button, Calendar, Card, Carousel, Checkbox, Chip, Coachmark, ConfirmDialog, ContextMenu, CopyToClipboard, DSPortal, DatePicker, DateRangePicker, EmptyState, FieldError, Footer, FormErrorSummary, HoverCard, InfiniteList, InlineConfirm, InlineEdit, Lightbox, Modal, MultiSelect, NumberStepper, PasswordStrength, Popover, ProgressBar, Radio, RadioGroup, RangeSlider, RichText, RollingNumber, SearchAndFilters, SegmentedControl, Select, Sheet, Skeleton, Sortable, SortableDndContext, SortableItem, SplitButton, StarRating, StickyNote, Table, Tabs, TextInput, Textarea, Timeline, ToastProvider, Toggle, Tooltip, Wizard, deriveGradient, deriveInitials, useToast };
11848
+ export { Accordion2 as Accordion, AlertBanner, AppBar, AppShell, Autocomplete, Avatar, AvatarStack, Badge, BottomSheet, Breadcrumbs, Button, Calendar, Card, Carousel, Checkbox, Chip, Coachmark, ColorInput, ColorPicker, CommandPalette, ConfirmDialog, ContextMenu, CopyToClipboard, DSPortal, DataGrid, DatePicker, DateRangePicker, Divider, DotGrid, EmptyState, Eyebrow, FieldError, FileInput, Footer, FormErrorSummary, Heading, HoverCard, InfiniteList, InlineConfirm, InlineEdit, InlineEditField, Kbd, Lightbox, Link, MiniBar, MiniDonut, Modal, MultiSelect, NumberStepper, OAuthButton, Pagination, PasswordStrength, Popover, ProgressBar, Radio, RadioGroup, RangeSlider, RelativeTime, RichText, RollingNumber, SearchAndFilters, SegmentedControl, Select, Sheet, Skeleton, SnackbarProvider, Sortable, SortableDndContext, SortableItem, Sparkline, SplitButton, SplitHero, StarRating, StatCard, StatusPill, StickyNote, Table, Tabs, Text, TextInput, Textarea, Timeline, ToastProvider, Toggle, Tooltip, TypeToConfirm, Wizard, deriveGradient, deriveInitials, useSnackbar, useToast };
9199
11849
  //# sourceMappingURL=index.js.map
9200
11850
  //# sourceMappingURL=index.js.map