altitude-design 0.1.2 → 0.2.1

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
@@ -230,6 +230,63 @@ function deriveAccent(accent, surfaces) {
230
230
  "--accent-soft": rgbToHex(mix(hexToRgb(ground), a, dark ? 0.2 : 0.13))
231
231
  };
232
232
  }
233
+ var SURFACES = ["surface-trench", "surface-well", "surface-ground", "surface-raised", "surface-lifted", "surface-floating", "surface-overlay", "surface-modal"];
234
+ var PAIRS = [];
235
+ for (const t of ["ink", "ink-muted", "accent-ink", "positive", "caution", "critical"]) for (const g of SURFACES) PAIRS.push([t, g, 4.5]);
236
+ for (const [t, g] of [
237
+ ["ink", "accent-soft"],
238
+ ["accent-ink", "accent-soft"],
239
+ ["positive", "positive-soft"],
240
+ ["caution", "caution-soft"],
241
+ ["critical", "critical-soft"],
242
+ ["ink", "critical-soft"],
243
+ ["ink", "positive-soft"],
244
+ ["ink", "caution-soft"],
245
+ ["ink-muted", "accent-soft"],
246
+ ["on-accent", "accent"],
247
+ ["on-critical", "critical"]
248
+ ]) PAIRS.push([t, g, 4.5]);
249
+ for (const g of ["surface-ground", "surface-well", "surface-raised", "surface-trench"]) PAIRS.push(["line-control", g, 3], ["accent", g, 3]);
250
+ for (const p of ["presence-1", "presence-2", "presence-3"]) {
251
+ PAIRS.push(["on-presence", p, 4.5]);
252
+ for (const g of SURFACES) PAIRS.push([p, g, 3]);
253
+ }
254
+ var isHex = (v) => /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(v);
255
+ function checkScheme(colors) {
256
+ const cs = typeof Element !== "undefined" && colors instanceof Element ? getComputedStyle(colors) : null;
257
+ const get = (n) => (cs ? cs.getPropertyValue("--" + n) : colors[n] ?? "").trim();
258
+ const out = [];
259
+ const seen = /* @__PURE__ */ new Set();
260
+ const ok = (n) => {
261
+ const v = get(n);
262
+ if (isHex(v)) return true;
263
+ if (!seen.has(n)) {
264
+ seen.add(n);
265
+ out.push(v ? `${n} is ${v}: use a 3- or 6-digit hex colour so it can be checked.` : `${n} is missing.`);
266
+ }
267
+ return false;
268
+ };
269
+ const L = (n) => lum(hexToRgb(get(n)));
270
+ for (let i = 1; i < SURFACES.length; i++) {
271
+ const lo = SURFACES[i - 1], hi = SURFACES[i];
272
+ if (!ok(lo) || !ok(hi)) continue;
273
+ if (i <= 3 ? L(hi) <= L(lo) : L(hi) < L(lo)) out.push(`${hi} (${get(hi)}) must be ${i <= 3 ? "lighter than" : "at least as light as"} ${lo} (${get(lo)}).`);
274
+ }
275
+ for (const [t, g, min] of PAIRS) {
276
+ if (!ok(t) || !ok(g)) continue;
277
+ const r = contrast(get(t), get(g));
278
+ if (r < min) out.push(`${t} on ${g} is ${r.toFixed(2)}:1; it needs ${min}:1.`);
279
+ }
280
+ return out;
281
+ }
282
+ var SHADOW_OR_LINE = /^(trench|well|elev-\d|lip-top|lip-bottom|line)$/;
283
+ function schemeCss(sel, tokens) {
284
+ const decl = (keep) => Object.entries(tokens).filter(([k, v]) => keep(k) && typeof v === "string" && /^[\w-]+$/.test(k) && !/[;{}<>]/.test(v)).map(([k, v]) => `--${k}: ${v};`).join(" ");
285
+ const plain = decl((k) => !SHADOW_OR_LINE.test(k)), soft = decl((k) => SHADOW_OR_LINE.test(k));
286
+ let css = plain ? `${sel} { ${plain} }` : "";
287
+ if (soft) css += `@media not (prefers-contrast: more) { ${sel}:not([data-contrast="more"], [data-contrast="more"] *) { ${soft} } }`;
288
+ return css;
289
+ }
233
290
  var AltitudeContext = React.createContext(null);
234
291
  var useAltitude = () => React.useContext(AltitudeContext);
235
292
  function AltitudeProvider({ scheme, accent, motion = "system", contrast: contrast2 = "system", recede = true, approach = true, className, style, children, ...rest }) {
@@ -237,6 +294,18 @@ function AltitudeProvider({ scheme, accent, motion = "system", contrast: contras
237
294
  const [host, setHost] = React.useState(null);
238
295
  const [layers, setLayers] = React.useState(0);
239
296
  const [accentVars, setAccentVars] = React.useState(null);
297
+ const custom = scheme && typeof scheme === "object" ? scheme : null;
298
+ const schemeKey = custom ? JSON.stringify(custom) : scheme;
299
+ const scope = React.useId();
300
+ const schemeSel = `.alt-root[data-scheme-id="${scope}"]`;
301
+ const warned = React.useRef("");
302
+ React.useEffect(() => {
303
+ if (!custom || !rootRef.current || warned.current === schemeKey) return;
304
+ warned.current = schemeKey;
305
+ const issues = checkScheme(rootRef.current);
306
+ if (issues.length) console.warn(`Altitude: the scheme "${custom.name}" breaks ${issues.length} of the scheme invariants (see Theming.md):
307
+ ` + issues.join("\n"));
308
+ }, [schemeKey]);
240
309
  useIsoLayoutEffect(() => {
241
310
  if (!accent || !rootRef.current) {
242
311
  setAccentVars(null);
@@ -252,7 +321,7 @@ function AltitudeProvider({ scheme, accent, motion = "system", contrast: contras
252
321
  const mo = new MutationObserver(compute);
253
322
  mo.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
254
323
  return () => mo.disconnect();
255
- }, [accent, scheme]);
324
+ }, [accent, schemeKey]);
256
325
  const api = React.useMemo(() => ({
257
326
  host,
258
327
  pushLayer: () => {
@@ -265,13 +334,16 @@ function AltitudeProvider({ scheme, accent, motion = "system", contrast: contras
265
334
  {
266
335
  ref: rootRef,
267
336
  className: cx("alt-root", className),
268
- "data-theme": scheme,
337
+ "data-theme": custom ? custom.base ?? "daylight" : scheme,
338
+ "data-scheme": custom?.name,
339
+ "data-scheme-id": custom ? scope : void 0,
269
340
  "data-motion": motion === "system" ? void 0 : motion,
270
341
  "data-contrast": contrast2 === "more" ? "more" : void 0,
271
342
  "data-approach-off": approach ? void 0 : "",
272
343
  style: { ...accentVars, ...style },
273
344
  ...rest
274
345
  },
346
+ custom && /* @__PURE__ */ React.createElement("style", null, schemeCss(schemeSel, custom.tokens)),
275
347
  /* @__PURE__ */ React.createElement("div", { className: "alt-stage", "data-receded": recede && layers > 0 ? "" : void 0 }, children),
276
348
  /* @__PURE__ */ React.createElement("div", { className: "alt-layers", ref: setHost })
277
349
  ));
@@ -363,9 +435,190 @@ function Kbd({ listen, className, children, ...rest }) {
363
435
  }
364
436
 
365
437
  // project/components/src/controls.tsx
438
+ import * as React3 from "react";
439
+
440
+ // project/components/src/suspense.tsx
366
441
  import * as React2 from "react";
367
- var Button = React2.forwardRef(function Button2({ variant = "secondary", size = "md", square, loading, leading, trailing, className, children, disabled, type = "button", ...rest }, ref) {
442
+ var isPromise = (v) => !!v && (typeof v === "object" || typeof v === "function") && typeof v.then === "function";
443
+ var hasPromise = (children) => Array.isArray(children) ? children.some(isPromise) : isPromise(children);
444
+ var settled = /* @__PURE__ */ new WeakMap();
445
+ var reactUse = React2.use;
446
+ function readPromised(v) {
447
+ if (!isPromise(v)) return v;
448
+ if (reactUse) return reactUse(v);
449
+ let r = settled.get(v);
450
+ if (!r) {
451
+ const rec = { s: "pending" };
452
+ settled.set(v, rec);
453
+ v.then((x) => {
454
+ rec.s = "done";
455
+ rec.v = x;
456
+ }, (e) => {
457
+ rec.s = "error";
458
+ rec.e = e;
459
+ });
460
+ r = rec;
461
+ }
462
+ if (r.s === "done") return r.v;
463
+ if (r.s === "error") throw r.e;
464
+ throw v;
465
+ }
466
+ function readChildren(children) {
467
+ return Array.isArray(children) ? children.map((c) => readPromised(c)) : readPromised(children);
468
+ }
469
+ function useArrival(waiting) {
470
+ const d = React2.useRef(null);
471
+ if (waiting && !d.current) {
472
+ let done;
473
+ d.current = { p: new Promise((r) => {
474
+ done = r;
475
+ }), done };
476
+ }
477
+ const cur = d.current;
478
+ useIsoLayoutEffect(() => {
479
+ if (!waiting && cur) {
480
+ cur.done();
481
+ if (d.current === cur) d.current = null;
482
+ }
483
+ });
484
+ return waiting && cur ? cur.p : null;
485
+ }
486
+ function Arrive({ when, children }) {
487
+ if (when) readPromised(when);
488
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, children);
489
+ }
490
+ function useHasWaited(waiting) {
491
+ const r = React2.useRef(false);
492
+ if (waiting) r.current = true;
493
+ return r.current;
494
+ }
495
+ var ScopeContext = React2.createContext(null);
496
+ function LoadingScope({ children }) {
497
+ const [members] = React2.useState(() => /* @__PURE__ */ new Set());
498
+ const [waiting, setWaiting] = React2.useState(false);
499
+ const report = React2.useCallback((id, w) => {
500
+ if (w) members.add(id);
501
+ else members.delete(id);
502
+ setWaiting(members.size > 0);
503
+ }, [members]);
504
+ const value = React2.useMemo(() => ({ report, waiting }), [report, waiting]);
505
+ return /* @__PURE__ */ React2.createElement(ScopeContext.Provider, { value }, children);
506
+ }
507
+ function useReportWaiting(waiting) {
508
+ const scope = React2.useContext(ScopeContext);
509
+ const [id] = React2.useState(() => ({}));
510
+ const report = scope?.report;
511
+ useIsoLayoutEffect(() => {
512
+ report?.(id, waiting);
513
+ }, [report, waiting]);
514
+ useIsoLayoutEffect(() => () => report?.(id, false), [report]);
515
+ }
516
+ var useScopeWaiting = () => !!React2.useContext(ScopeContext)?.waiting;
517
+ var Group = class {
518
+ constructor() {
519
+ this.waiting = /* @__PURE__ */ new Set();
520
+ this.held = /* @__PURE__ */ new Map();
521
+ }
522
+ wait(id) {
523
+ this.waiting.add(id);
524
+ }
525
+ /** Returns true when this was the last one: everything held is released together. */
526
+ land(id, release) {
527
+ this.waiting.delete(id);
528
+ this.held.set(id, release);
529
+ if (this.waiting.size) return false;
530
+ this.flush();
531
+ return true;
532
+ }
533
+ leave(id) {
534
+ this.waiting.delete(id);
535
+ this.held.delete(id);
536
+ if (!this.waiting.size && this.held.size) this.flush();
537
+ }
538
+ flush() {
539
+ const all = Array.from(this.held.values());
540
+ this.held.clear();
541
+ all.forEach((f) => f());
542
+ }
543
+ };
544
+ var GroupContext = React2.createContext(null);
545
+ function RevealGroup({ children }) {
546
+ const group = React2.useMemo(() => new Group(), []);
547
+ return /* @__PURE__ */ React2.createElement(GroupContext.Provider, { value: group }, children);
548
+ }
549
+ var GRACE = 300;
550
+ function Await({ imprint, shape = "block", inline, enabled = true, className, children }) {
551
+ const group = React2.useContext(GroupContext);
552
+ const box = React2.useRef({ id: {}, since: null });
553
+ React2.useEffect(() => () => group?.leave(box.current.id), [group]);
554
+ if (!enabled) return /* @__PURE__ */ React2.createElement(React2.Fragment, null, children);
555
+ return /* @__PURE__ */ React2.createElement(React2.Suspense, { fallback: /* @__PURE__ */ React2.createElement(Imprint, { box, group, inline }, imprint) }, /* @__PURE__ */ React2.createElement(Landed, { box, group, shape, inline, className, imprint }, children));
556
+ }
557
+ function Imprint({ box, group, inline, children }) {
558
+ useIsoLayoutEffect(() => {
559
+ if (box.current.since === null) box.current.since = performance.now();
560
+ group?.wait(box.current.id);
561
+ }, []);
562
+ return /* @__PURE__ */ React2.createElement("span", { className: "alt-await-wait", "data-inline": inline ? "" : void 0, "aria-busy": "true" }, children, /* @__PURE__ */ React2.createElement("span", { className: "alt-sr" }, "Loading"));
563
+ }
564
+ function Landed({ box, group, shape, inline, className, imprint, children }) {
565
+ const [phase, setPhase] = React2.useState(null);
566
+ const [delay, setDelay] = React2.useState(0);
567
+ const [graceLeft, setGraceLeft] = React2.useState(0);
568
+ const done = React2.useRef(void 0);
569
+ useIsoLayoutEffect(() => {
570
+ const since = box.current.since;
571
+ box.current.since = null;
572
+ if (since === null) return;
573
+ const release = () => {
574
+ clearTimeout(done.current);
575
+ if (performance.now() - since < GRACE) {
576
+ setPhase(null);
577
+ return;
578
+ }
579
+ const d = riseDelay();
580
+ setDelay(d);
581
+ setPhase("reveal");
582
+ done.current = setTimeout(() => setPhase(null), d + 320);
583
+ };
584
+ if (group && !group.land(box.current.id, release)) {
585
+ setGraceLeft(Math.max(0, GRACE - (performance.now() - since)));
586
+ setPhase("held");
587
+ } else if (!group) release();
588
+ }, []);
589
+ React2.useEffect(() => () => clearTimeout(done.current), []);
368
590
  return /* @__PURE__ */ React2.createElement(
591
+ "span",
592
+ {
593
+ className: cx("alt-await", className),
594
+ "data-phase": phase ?? void 0,
595
+ "data-inline": inline ? "" : void 0,
596
+ "data-shape": shape,
597
+ "aria-busy": phase === "held" || void 0,
598
+ style: phase ? { ["--alt-rise-delay"]: delay + "ms", ["--alt-grace-left"]: graceLeft + "ms" } : void 0
599
+ },
600
+ phase === "held" && /* @__PURE__ */ React2.createElement("span", { className: "alt-await-held", "data-early": graceLeft > 0 ? "" : void 0, "aria-hidden": "true" }, imprint),
601
+ phase === "reveal" && shape !== "none" && /* @__PURE__ */ React2.createElement("span", { className: "alt-skeleton alt-await-imprint", "data-shape": shape, "aria-hidden": "true" }),
602
+ /* @__PURE__ */ React2.createElement("span", { className: "alt-await-face" }, children)
603
+ );
604
+ }
605
+ var LINE_WIDTHS = ["100%", "94%", "82%", "97%", "64%"];
606
+ function TextImprint({ lines = 1, width, className }) {
607
+ return /* @__PURE__ */ React2.createElement("span", { className: cx("alt-await-lines", className), style: { ["--lines"]: lines, width } }, Array.from({ length: lines }, (_, i) => /* @__PURE__ */ React2.createElement(
608
+ "span",
609
+ {
610
+ key: i,
611
+ className: "alt-skeleton",
612
+ "data-shape": "text",
613
+ style: { width: lines === 1 ? "100%" : i === lines - 1 ? "60%" : LINE_WIDTHS[i % LINE_WIDTHS.length], ["--i"]: i }
614
+ }
615
+ )));
616
+ }
617
+ var hint = (s) => typeof s === "object" ? s : {};
618
+
619
+ // project/components/src/controls.tsx
620
+ var Button = React3.forwardRef(function Button2({ variant = "secondary", size = "md", square, loading, leading, trailing, className, children, disabled, type = "button", ...rest }, ref) {
621
+ return /* @__PURE__ */ React3.createElement(
369
622
  "button",
370
623
  {
371
624
  ref,
@@ -380,14 +633,15 @@ var Button = React2.forwardRef(function Button2({ variant = "secondary", size =
380
633
  ...rest,
381
634
  onClick: loading ? (e) => e.preventDefault() : rest.onClick
382
635
  },
383
- /* @__PURE__ */ React2.createElement("span", { className: "alt-btn-label" }, leading, children, trailing),
384
- loading && /* @__PURE__ */ React2.createElement("span", { className: "alt-btn-spinner" }, /* @__PURE__ */ React2.createElement(Spinner, { size: size === "sm" ? 14 : 16 }))
636
+ /* @__PURE__ */ React3.createElement("span", { className: "alt-btn-label" }, leading, children, trailing),
637
+ loading && /* @__PURE__ */ React3.createElement("span", { className: "alt-btn-spinner" }, /* @__PURE__ */ React3.createElement(Spinner, { size: size === "sm" ? 14 : 16 }))
385
638
  );
386
639
  });
387
- var Card = React2.forwardRef(function Card2({ interactive, className, onKeyDown, settle, status, heldBy, relevance, style, ...rest }, ref) {
640
+ var Card = React3.forwardRef(function Card2({ interactive, className, onKeyDown, settle, status, heldBy, relevance, style, skeleton, children, ...rest }, ref) {
388
641
  const actionable = interactive && !!rest.onClick;
389
642
  const { style: depthStyle, ...depth } = useDepth({ settle, status, heldBy, relevance });
390
- return /* @__PURE__ */ React2.createElement(
643
+ const { lines = 3 } = hint(skeleton);
644
+ return /* @__PURE__ */ React3.createElement(
391
645
  "div",
392
646
  {
393
647
  ref,
@@ -404,29 +658,51 @@ var Card = React2.forwardRef(function Card2({ interactive, className, onKeyDown,
404
658
  ...depth,
405
659
  style: { ...depthStyle, ...style },
406
660
  ...rest
407
- }
661
+ },
662
+ /* @__PURE__ */ React3.createElement(LoadingScope, null, /* @__PURE__ */ React3.createElement(Await, { shape: "none", enabled: skeleton !== false, imprint: /* @__PURE__ */ React3.createElement("span", { className: "alt-await-card" }, /* @__PURE__ */ React3.createElement(TextImprint, { className: "alt-card-title", width: "45%" }), /* @__PURE__ */ React3.createElement(TextImprint, { className: "alt-await-card-body", lines })) }, children))
408
663
  );
409
664
  });
410
- var CardHeader = ({ className, ...p }) => /* @__PURE__ */ React2.createElement("div", { className: cx("alt-card-header", className), ...p });
411
- var CardTitle = ({ className, ...p }) => /* @__PURE__ */ React2.createElement("h3", { className: cx("alt-card-title", className), ...p });
412
- var CardDescription = ({ className, ...p }) => /* @__PURE__ */ React2.createElement("p", { className: cx("alt-card-desc", className), ...p });
413
- var CardContent = ({ className, ...p }) => /* @__PURE__ */ React2.createElement("div", { className: cx("alt-card-content", className), ...p });
414
- var CardFooter = ({ className, ...p }) => /* @__PURE__ */ React2.createElement("div", { className: cx("alt-card-footer", className), ...p });
415
- var Input = React2.forwardRef(function Input2({ invalid, leading, trailing, size = "md", className, disabled, placeholder, ...rest }, ref) {
665
+ var CardHeader = ({ className, ...p }) => /* @__PURE__ */ React3.createElement("div", { className: cx("alt-card-header", className), ...p });
666
+ var Promised$ = ({ children }) => /* @__PURE__ */ React3.createElement(React3.Fragment, null, readChildren(children));
667
+ function usePendingText(children, skeleton, required) {
668
+ const scopeWaiting = useScopeWaiting();
669
+ const missing = skeleton !== false && children === void 0 && (required || scopeWaiting);
670
+ useReportWaiting(required && skeleton !== false && (children === void 0 || hasPromise(children)));
671
+ const arrival = useArrival(missing);
672
+ const waited = useHasWaited(missing || hasPromise(children));
673
+ return { arrival, waited };
674
+ }
675
+ function PendingText({ children, skeleton, lines, width, required }) {
676
+ const { arrival, waited } = usePendingText(children, skeleton, required);
677
+ if (!waited) return /* @__PURE__ */ React3.createElement(React3.Fragment, null, children);
678
+ const h = hint(skeleton);
679
+ return /* @__PURE__ */ React3.createElement(Await, { shape: "text", enabled: skeleton !== false, imprint: /* @__PURE__ */ React3.createElement(TextImprint, { lines: h.lines ?? lines, width: h.width ?? width }) }, /* @__PURE__ */ React3.createElement(Arrive, { when: arrival }, /* @__PURE__ */ React3.createElement(Promised$, null, children)));
680
+ }
681
+ var CardTitle = ({ className, children, skeleton, ...p }) => /* @__PURE__ */ React3.createElement("h3", { className: cx("alt-card-title", className), ...p }, /* @__PURE__ */ React3.createElement(PendingText, { skeleton, lines: 1, width: "55%", required: true }, children));
682
+ var CardDescription = ({ className, children, skeleton, ...p }) => /* @__PURE__ */ React3.createElement("p", { className: cx("alt-card-desc", className), ...p }, /* @__PURE__ */ React3.createElement(PendingText, { skeleton, lines: 2, required: false }, children));
683
+ var CardContent = ({ className, skeleton, children, ...p }) => {
684
+ const { lines = 3 } = hint(skeleton);
685
+ const scopeWaiting = useScopeWaiting();
686
+ const missing = skeleton !== false && children === void 0 && scopeWaiting;
687
+ const arrival = useArrival(missing);
688
+ return /* @__PURE__ */ React3.createElement("div", { className: cx("alt-card-content", className), ...p }, /* @__PURE__ */ React3.createElement(Await, { shape: "none", enabled: skeleton !== false, imprint: /* @__PURE__ */ React3.createElement(TextImprint, { lines }) }, /* @__PURE__ */ React3.createElement(Arrive, { when: arrival }, children)));
689
+ };
690
+ var CardFooter = ({ className, ...p }) => /* @__PURE__ */ React3.createElement("div", { className: cx("alt-card-footer", className), ...p });
691
+ var Input = React3.forwardRef(function Input2({ invalid, leading, trailing, size = "md", className, disabled, placeholder, ...rest }, ref) {
416
692
  useApproach();
417
693
  useKeyFocus();
418
- return /* @__PURE__ */ React2.createElement("div", { className: cx("alt-input", className), "data-size": size, "data-approach": "56", "data-invalid": invalid ? "" : void 0, "data-disabled": disabled ? "" : void 0 }, leading && /* @__PURE__ */ React2.createElement("span", { className: "alt-input-adorn" }, leading), /* @__PURE__ */ React2.createElement("input", { ref, disabled, "aria-invalid": invalid || void 0, placeholder: placeholder ?? " ", ...rest }), trailing && /* @__PURE__ */ React2.createElement("span", { className: "alt-input-adorn" }, trailing));
694
+ return /* @__PURE__ */ React3.createElement("div", { className: cx("alt-input", className), "data-size": size, "data-approach": "56", "data-invalid": invalid ? "" : void 0, "data-disabled": disabled ? "" : void 0 }, leading && /* @__PURE__ */ React3.createElement("span", { className: "alt-input-adorn" }, leading), /* @__PURE__ */ React3.createElement("input", { ref, disabled, "aria-invalid": invalid || void 0, placeholder: placeholder ?? " ", ...rest }), trailing && /* @__PURE__ */ React3.createElement("span", { className: "alt-input-adorn" }, trailing));
419
695
  });
420
- var Textarea = React2.forwardRef(function Textarea2({ invalid, className, disabled, placeholder, maxLength, showFill = true, onChange, value, defaultValue, ...rest }, ref) {
421
- const [len, setLen] = React2.useState(() => String(value ?? defaultValue ?? "").length);
422
- React2.useEffect(() => {
696
+ var Textarea = React3.forwardRef(function Textarea2({ invalid, className, disabled, placeholder, maxLength, showFill = true, onChange, value, defaultValue, ...rest }, ref) {
697
+ const [len, setLen] = React3.useState(() => String(value ?? defaultValue ?? "").length);
698
+ React3.useEffect(() => {
423
699
  if (value !== void 0) setLen(String(value).length);
424
700
  }, [value]);
425
701
  const gauge = showFill && maxLength ? Math.min(1, len / maxLength) : null;
426
702
  const level = gauge === null ? void 0 : len >= maxLength ? "full" : gauge >= 0.9 ? "near" : "ok";
427
703
  useApproach();
428
704
  useKeyFocus();
429
- return /* @__PURE__ */ React2.createElement(
705
+ return /* @__PURE__ */ React3.createElement(
430
706
  "div",
431
707
  {
432
708
  className: cx("alt-input", className),
@@ -437,8 +713,8 @@ var Textarea = React2.forwardRef(function Textarea2({ invalid, className, disabl
437
713
  "data-fill": level,
438
714
  style: gauge !== null ? { ["--alt-fill"]: gauge } : void 0
439
715
  },
440
- gauge !== null && /* @__PURE__ */ React2.createElement("span", { className: "alt-input-gauge", "aria-hidden": "true" }),
441
- /* @__PURE__ */ React2.createElement(
716
+ gauge !== null && /* @__PURE__ */ React3.createElement("span", { className: "alt-input-gauge", "aria-hidden": "true" }),
717
+ /* @__PURE__ */ React3.createElement(
442
718
  "textarea",
443
719
  {
444
720
  ref,
@@ -455,22 +731,22 @@ var Textarea = React2.forwardRef(function Textarea2({ invalid, className, disabl
455
731
  }
456
732
  }
457
733
  ),
458
- gauge !== null && /* @__PURE__ */ React2.createElement("span", { className: "alt-input-count", "aria-live": "polite" }, len, " / ", maxLength)
734
+ gauge !== null && /* @__PURE__ */ React3.createElement("span", { className: "alt-input-count", "aria-live": "polite" }, len, " / ", maxLength)
459
735
  );
460
736
  });
461
- function Field({ label, hint, error, required, className, children }) {
462
- const id = React2.useId();
737
+ function Field({ label, hint: hint2, error, required, className, children }) {
738
+ const id = React3.useId();
463
739
  const controlId = children.props.id || id + "-control";
464
- const describedBy = [hint && id + "-hint", error && id + "-error"].filter(Boolean).join(" ") || void 0;
465
- return /* @__PURE__ */ React2.createElement("div", { className: cx("alt-field", className) }, /* @__PURE__ */ React2.createElement("label", { className: "alt-field-label", htmlFor: controlId }, label, required && /* @__PURE__ */ React2.createElement("span", { className: "alt-field-req", "aria-hidden": "true" }, " *")), React2.cloneElement(children, { id: controlId, "aria-describedby": describedBy, invalid: !!error || children.props.invalid, required }), hint && !error && /* @__PURE__ */ React2.createElement("p", { className: "alt-field-hint", id: id + "-hint" }, hint), error && /* @__PURE__ */ React2.createElement("p", { className: "alt-field-error", id: id + "-error", role: "alert" }, /* @__PURE__ */ React2.createElement(Icons.AlertCircle, { size: 14 }), error));
740
+ const describedBy = [hint2 && id + "-hint", error && id + "-error"].filter(Boolean).join(" ") || void 0;
741
+ return /* @__PURE__ */ React3.createElement("div", { className: cx("alt-field", className) }, /* @__PURE__ */ React3.createElement("label", { className: "alt-field-label", htmlFor: controlId }, label, required && /* @__PURE__ */ React3.createElement("span", { className: "alt-field-req", "aria-hidden": "true" }, " *")), React3.cloneElement(children, { id: controlId, "aria-describedby": describedBy, invalid: !!error || children.props.invalid, required }), hint2 && !error && /* @__PURE__ */ React3.createElement("p", { className: "alt-field-hint", id: id + "-hint" }, hint2), error && /* @__PURE__ */ React3.createElement("p", { className: "alt-field-error", id: id + "-error", role: "alert" }, /* @__PURE__ */ React3.createElement(Icons.AlertCircle, { size: 14 }), error));
466
742
  }
467
- var Checkbox = React2.forwardRef(function Checkbox2({ label, description, indeterminate, onCheckedChange, onChange, className, disabled, ...rest }, ref) {
468
- const inner = React2.useRef(null);
469
- React2.useImperativeHandle(ref, () => inner.current);
470
- React2.useEffect(() => {
743
+ var Checkbox = React3.forwardRef(function Checkbox2({ label, description, indeterminate, onCheckedChange, onChange, className, disabled, ...rest }, ref) {
744
+ const inner = React3.useRef(null);
745
+ React3.useImperativeHandle(ref, () => inner.current);
746
+ React3.useEffect(() => {
471
747
  if (inner.current) inner.current.indeterminate = !!indeterminate;
472
748
  }, [indeterminate]);
473
- return /* @__PURE__ */ React2.createElement("label", { className: cx("alt-check", className), "data-disabled": disabled ? "" : void 0 }, /* @__PURE__ */ React2.createElement(
749
+ return /* @__PURE__ */ React3.createElement("label", { className: cx("alt-check", className), "data-disabled": disabled ? "" : void 0 }, /* @__PURE__ */ React3.createElement(
474
750
  "input",
475
751
  {
476
752
  ref: inner,
@@ -482,20 +758,20 @@ var Checkbox = React2.forwardRef(function Checkbox2({ label, description, indete
482
758
  onCheckedChange?.(e.target.checked);
483
759
  }
484
760
  }
485
- ), /* @__PURE__ */ React2.createElement("span", { className: "alt-check-track", "aria-hidden": "true" }, /* @__PURE__ */ React2.createElement("span", { className: "alt-check-fill" }), /* @__PURE__ */ React2.createElement("svg", { className: "alt-check-mark", viewBox: "0 0 16 16", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2.25", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React2.createElement("path", { className: "alt-check-tick", d: "M3.5 8.5l3 3 6-6.5", pathLength: 16 }), /* @__PURE__ */ React2.createElement("path", { className: "alt-check-dash", d: "M4 8h8", pathLength: 16 }))), (label || description) && /* @__PURE__ */ React2.createElement("span", { className: "alt-check-text" }, label && /* @__PURE__ */ React2.createElement("span", { className: "alt-check-label" }, label), description && /* @__PURE__ */ React2.createElement("span", { className: "alt-check-desc" }, description)));
761
+ ), /* @__PURE__ */ React3.createElement("span", { className: "alt-check-track", "aria-hidden": "true" }, /* @__PURE__ */ React3.createElement("span", { className: "alt-check-fill" }), /* @__PURE__ */ React3.createElement("svg", { className: "alt-check-mark", viewBox: "0 0 16 16", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2.25", strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ React3.createElement("path", { className: "alt-check-tick", d: "M3.5 8.5l3 3 6-6.5", pathLength: 16 }), /* @__PURE__ */ React3.createElement("path", { className: "alt-check-dash", d: "M4 8h8", pathLength: 16 }))), (label || description) && /* @__PURE__ */ React3.createElement("span", { className: "alt-check-text" }, label && /* @__PURE__ */ React3.createElement("span", { className: "alt-check-label" }, label), description && /* @__PURE__ */ React3.createElement("span", { className: "alt-check-desc" }, description)));
486
762
  });
487
- var RadioCtx = React2.createContext(null);
763
+ var RadioCtx = React3.createContext(null);
488
764
  function RadioGroup({ value, defaultValue = "", onValueChange, name, disabled, orientation = "vertical", className, children, ...rest }) {
489
- const auto = React2.useId();
765
+ const auto = React3.useId();
490
766
  const [v, set] = useControllable(value, defaultValue, onValueChange);
491
- const root = React2.useRef(null);
492
- const slots = React2.useRef(/* @__PURE__ */ new Map());
493
- const [bead, setBead] = React2.useState(null);
494
- const register = React2.useCallback((val, el) => {
767
+ const root = React3.useRef(null);
768
+ const slots = React3.useRef(/* @__PURE__ */ new Map());
769
+ const [bead, setBead] = React3.useState(null);
770
+ const register = React3.useCallback((val, el) => {
495
771
  if (el) slots.current.set(val, el);
496
772
  else slots.current.delete(val);
497
773
  }, []);
498
- const measure = React2.useCallback(() => {
774
+ const measure = React3.useCallback(() => {
499
775
  const el = slots.current.get(v), r = root.current;
500
776
  if (!el || !r) {
501
777
  setBead(null);
@@ -508,13 +784,13 @@ function RadioGroup({ value, defaultValue = "", onValueChange, name, disabled, o
508
784
  useIsoLayoutEffect(() => {
509
785
  measure();
510
786
  }, [measure]);
511
- React2.useEffect(() => {
787
+ React3.useEffect(() => {
512
788
  const ro = new ResizeObserver(() => measure());
513
789
  if (root.current) ro.observe(root.current);
514
790
  document.fonts?.ready.then(() => measure());
515
791
  return () => ro.disconnect();
516
792
  }, [measure]);
517
- return /* @__PURE__ */ React2.createElement(RadioCtx.Provider, { value: { name: name || auto, value: v, set, disabled, register } }, /* @__PURE__ */ React2.createElement("div", { ref: root, role: "radiogroup", className: cx("alt-radio-group", className), "data-orientation": orientation, "data-disabled": disabled ? "" : void 0, ...rest }, children, bead && /* @__PURE__ */ React2.createElement(
793
+ return /* @__PURE__ */ React3.createElement(RadioCtx.Provider, { value: { name: name || auto, value: v, set, disabled, register } }, /* @__PURE__ */ React3.createElement("div", { ref: root, role: "radiogroup", className: cx("alt-radio-group", className), "data-orientation": orientation, "data-disabled": disabled ? "" : void 0, ...rest }, children, bead && /* @__PURE__ */ React3.createElement(
518
794
  "span",
519
795
  {
520
796
  className: "alt-radio-thumb",
@@ -525,9 +801,9 @@ function RadioGroup({ value, defaultValue = "", onValueChange, name, disabled, o
525
801
  )));
526
802
  }
527
803
  function Radio({ value, label, description, disabled, className }) {
528
- const g = React2.useContext(RadioCtx);
804
+ const g = React3.useContext(RadioCtx);
529
805
  const off = disabled || g?.disabled;
530
- return /* @__PURE__ */ React2.createElement("label", { className: cx("alt-check alt-radio", className), "data-disabled": off ? "" : void 0 }, /* @__PURE__ */ React2.createElement(
806
+ return /* @__PURE__ */ React3.createElement("label", { className: cx("alt-check alt-radio", className), "data-disabled": off ? "" : void 0 }, /* @__PURE__ */ React3.createElement(
531
807
  "input",
532
808
  {
533
809
  type: "radio",
@@ -537,11 +813,11 @@ function Radio({ value, label, description, disabled, className }) {
537
813
  checked: g ? g.value === value : void 0,
538
814
  onChange: () => g?.set(value)
539
815
  }
540
- ), /* @__PURE__ */ React2.createElement("span", { className: "alt-check-track", "data-round": "", "aria-hidden": "true", ref: (el) => g?.register(value, el) }, /* @__PURE__ */ React2.createElement("span", { className: "alt-check-fill" })), (label || description) && /* @__PURE__ */ React2.createElement("span", { className: "alt-check-text" }, label && /* @__PURE__ */ React2.createElement("span", { className: "alt-check-label" }, label), description && /* @__PURE__ */ React2.createElement("span", { className: "alt-check-desc" }, description)));
816
+ ), /* @__PURE__ */ React3.createElement("span", { className: "alt-check-track", "data-round": "", "aria-hidden": "true", ref: (el) => g?.register(value, el) }, /* @__PURE__ */ React3.createElement("span", { className: "alt-check-fill" })), (label || description) && /* @__PURE__ */ React3.createElement("span", { className: "alt-check-text" }, label && /* @__PURE__ */ React3.createElement("span", { className: "alt-check-label" }, label), description && /* @__PURE__ */ React3.createElement("span", { className: "alt-check-desc" }, description)));
541
817
  }
542
818
  function Switch({ checked, defaultChecked = false, onCheckedChange, label, className, disabled, ...rest }) {
543
819
  const [on, set] = useControllable(checked, defaultChecked, onCheckedChange);
544
- const control = /* @__PURE__ */ React2.createElement(
820
+ const control = /* @__PURE__ */ React3.createElement(
545
821
  "button",
546
822
  {
547
823
  type: "button",
@@ -555,29 +831,29 @@ function Switch({ checked, defaultChecked = false, onCheckedChange, label, class
555
831
  set(!on);
556
832
  }
557
833
  },
558
- /* @__PURE__ */ React2.createElement("span", { className: "alt-switch-fill" }),
559
- /* @__PURE__ */ React2.createElement("span", { className: "alt-switch-thumb" })
834
+ /* @__PURE__ */ React3.createElement("span", { className: "alt-switch-fill" }),
835
+ /* @__PURE__ */ React3.createElement("span", { className: "alt-switch-thumb" })
560
836
  );
561
837
  if (!label) return control;
562
- return /* @__PURE__ */ React2.createElement("label", { className: cx("alt-switch-row", className), "data-disabled": disabled ? "" : void 0 }, control, /* @__PURE__ */ React2.createElement("span", null, label));
838
+ return /* @__PURE__ */ React3.createElement("label", { className: cx("alt-switch-row", className), "data-disabled": disabled ? "" : void 0 }, control, /* @__PURE__ */ React3.createElement("span", null, label));
563
839
  }
564
- var TabsCtx = React2.createContext(null);
840
+ var TabsCtx = React3.createContext(null);
565
841
  function Tabs({ value, defaultValue = "", onValueChange, variant = "folder", className, children, ...rest }) {
566
842
  const [v, set] = useControllable(value, defaultValue, onValueChange);
567
- const id = React2.useId();
568
- const nodes = React2.useRef(/* @__PURE__ */ new Map());
569
- const register = React2.useCallback((val, el) => {
843
+ const id = React3.useId();
844
+ const nodes = React3.useRef(/* @__PURE__ */ new Map());
845
+ const register = React3.useCallback((val, el) => {
570
846
  if (el) nodes.current.set(val, el);
571
847
  else nodes.current.delete(val);
572
848
  }, []);
573
- return /* @__PURE__ */ React2.createElement(TabsCtx.Provider, { value: { value: v, set, id, variant, register, nodes } }, /* @__PURE__ */ React2.createElement("div", { className: cx("alt-tabs", className), "data-variant": variant, ...rest }, children));
849
+ return /* @__PURE__ */ React3.createElement(TabsCtx.Provider, { value: { value: v, set, id, variant, register, nodes } }, /* @__PURE__ */ React3.createElement("div", { className: cx("alt-tabs", className), "data-variant": variant, ...rest }, children));
574
850
  }
575
851
  function TabsList({ className, children, ...rest }) {
576
- const t = React2.useContext(TabsCtx);
577
- const listRef = React2.useRef(null);
852
+ const t = React3.useContext(TabsCtx);
853
+ const listRef = React3.useRef(null);
578
854
  const pill = t.variant === "segmented";
579
- const [ind, setInd] = React2.useState({ x: 0, w: 0, ready: false });
580
- const measure = React2.useCallback(() => {
855
+ const [ind, setInd] = React3.useState({ x: 0, w: 0, ready: false });
856
+ const measure = React3.useCallback(() => {
581
857
  if (!pill) return;
582
858
  const el = t.nodes.current.get(t.value);
583
859
  if (!el) return;
@@ -586,7 +862,7 @@ function TabsList({ className, children, ...rest }) {
586
862
  useIsoLayoutEffect(() => {
587
863
  measure();
588
864
  }, [measure]);
589
- React2.useEffect(() => {
865
+ React3.useEffect(() => {
590
866
  if (!pill) return;
591
867
  const ro = new ResizeObserver(measure);
592
868
  if (listRef.current) ro.observe(listRef.current);
@@ -603,7 +879,7 @@ function TabsList({ className, children, ...rest }) {
603
879
  t.nodes.current.get(next)?.focus();
604
880
  }
605
881
  };
606
- return /* @__PURE__ */ React2.createElement("div", { ref: listRef, role: "tablist", className: cx("alt-tabs-list", className), onKeyDown, ...rest }, pill && /* @__PURE__ */ React2.createElement(
882
+ return /* @__PURE__ */ React3.createElement("div", { ref: listRef, role: "tablist", className: cx("alt-tabs-list", className), onKeyDown, ...rest }, pill && /* @__PURE__ */ React3.createElement(
607
883
  "span",
608
884
  {
609
885
  className: "alt-tabs-indicator",
@@ -614,9 +890,9 @@ function TabsList({ className, children, ...rest }) {
614
890
  ), children);
615
891
  }
616
892
  function TabsTrigger({ value, className, children, ...rest }) {
617
- const t = React2.useContext(TabsCtx);
893
+ const t = React3.useContext(TabsCtx);
618
894
  const on = t.value === value;
619
- return /* @__PURE__ */ React2.createElement(
895
+ return /* @__PURE__ */ React3.createElement(
620
896
  "button",
621
897
  {
622
898
  ref: (el) => t.register(value, el),
@@ -634,21 +910,21 @@ function TabsTrigger({ value, className, children, ...rest }) {
634
910
  );
635
911
  }
636
912
  function TabsContent({ value, className, ...rest }) {
637
- const t = React2.useContext(TabsCtx);
913
+ const t = React3.useContext(TabsCtx);
638
914
  if (t.value !== value) return null;
639
- return /* @__PURE__ */ React2.createElement("div", { role: "tabpanel", id: `${t.id}-p-${value}`, "aria-labelledby": `${t.id}-t-${value}`, tabIndex: 0, className: cx("alt-tabs-content", className), ...rest });
915
+ return /* @__PURE__ */ React3.createElement("div", { role: "tabpanel", id: `${t.id}-p-${value}`, "aria-labelledby": `${t.id}-t-${value}`, tabIndex: 0, className: cx("alt-tabs-content", className), ...rest });
640
916
  }
641
917
  function Slider({ value, defaultValue = 50, onValueChange, min = 0, max = 100, step = 1, disabled, format = (v) => v, className, ...rest }) {
642
918
  const [v, set] = useControllable(value, defaultValue, onValueChange);
643
- const [drag, setDrag] = React2.useState(false);
644
- const track = React2.useRef(null);
919
+ const [drag, setDrag] = React3.useState(false);
920
+ const track = React3.useRef(null);
645
921
  const clamp = (n) => Math.min(max, Math.max(min, Math.round((n - min) / step) * step + min));
646
922
  const fromX = (x) => {
647
923
  const r = track.current.getBoundingClientRect();
648
924
  return clamp(min + (x - r.left) / r.width * (max - min));
649
925
  };
650
926
  const pct = (v - min) / (max - min) * 100;
651
- return /* @__PURE__ */ React2.createElement(
927
+ return /* @__PURE__ */ React3.createElement(
652
928
  "div",
653
929
  {
654
930
  className: cx("alt-slider", className),
@@ -668,8 +944,8 @@ function Slider({ value, defaultValue = 50, onValueChange, min = 0, max = 100, s
668
944
  onPointerCancel: () => setDrag(false),
669
945
  ...rest
670
946
  },
671
- /* @__PURE__ */ React2.createElement("div", { className: "alt-slider-track", ref: track }, /* @__PURE__ */ React2.createElement("div", { className: "alt-slider-fill", style: { width: pct + "%" } })),
672
- /* @__PURE__ */ React2.createElement(
947
+ /* @__PURE__ */ React3.createElement("div", { className: "alt-slider-track", ref: track }, /* @__PURE__ */ React3.createElement("div", { className: "alt-slider-fill", style: { width: pct + "%" } })),
948
+ /* @__PURE__ */ React3.createElement(
673
949
  "div",
674
950
  {
675
951
  className: "alt-slider-thumb",
@@ -690,13 +966,13 @@ function Slider({ value, defaultValue = 50, onValueChange, min = 0, max = 100, s
690
966
  }
691
967
  }
692
968
  },
693
- /* @__PURE__ */ React2.createElement("span", { className: "alt-slider-bubble", "aria-hidden": "true" }, format(v))
969
+ /* @__PURE__ */ React3.createElement("span", { className: "alt-slider-bubble", "aria-hidden": "true" }, format(v))
694
970
  )
695
971
  );
696
972
  }
697
973
  function Progress({ value = null, max = 100, className, ...rest }) {
698
974
  const ind = value === null || value === void 0;
699
- return /* @__PURE__ */ React2.createElement(
975
+ return /* @__PURE__ */ React3.createElement(
700
976
  "div",
701
977
  {
702
978
  role: "progressbar",
@@ -707,31 +983,72 @@ function Progress({ value = null, max = 100, className, ...rest }) {
707
983
  "data-indeterminate": ind ? "" : void 0,
708
984
  ...rest
709
985
  },
710
- /* @__PURE__ */ React2.createElement("div", { className: "alt-progress-fill", style: ind ? void 0 : { width: `${Math.max(0, Math.min(100, value / max * 100))}%` } })
986
+ /* @__PURE__ */ React3.createElement("div", { className: "alt-progress-fill", style: ind ? void 0 : { width: `${Math.max(0, Math.min(100, value / max * 100))}%` } })
711
987
  );
712
988
  }
713
- function Badge({ tone = "neutral", variant = "plate", lamp, dot, className, children, ...rest }) {
989
+ function Badge({ children, skeleton, ...props }) {
990
+ const missing = skeleton !== false && children === void 0;
991
+ useReportWaiting(missing || skeleton !== false && hasPromise(children));
992
+ const arrival = useArrival(missing);
993
+ if (!useHasWaited(missing || hasPromise(children))) return /* @__PURE__ */ React3.createElement(BadgeFace, { ...props }, children);
994
+ const h = hint(skeleton);
995
+ return /* @__PURE__ */ React3.createElement(
996
+ Await,
997
+ {
998
+ inline: true,
999
+ shape: "block",
1000
+ enabled: skeleton !== false,
1001
+ imprint: /* @__PURE__ */ React3.createElement("span", { className: "alt-skeleton alt-badge-imprint", "data-variant": props.variant === "count" ? "count" : void 0, style: { width: h.width } })
1002
+ },
1003
+ /* @__PURE__ */ React3.createElement(Arrive, { when: arrival }, /* @__PURE__ */ React3.createElement(BadgeLanded, { ...props }, children))
1004
+ );
1005
+ }
1006
+ function BadgeLanded({ children, ...props }) {
1007
+ return /* @__PURE__ */ React3.createElement(BadgeFace, { ...props }, readChildren(children));
1008
+ }
1009
+ function BadgeFace({ tone = "neutral", variant = "plate", lamp, dot, className, children, ...rest }) {
714
1010
  const v = variant === "soft" ? "tinted" : variant;
715
1011
  const showLamp = v !== "count" && !!(lamp ?? (dot || tone === "positive" || tone === "caution" || tone === "critical"));
716
1012
  const label = typeof children === "string" || typeof children === "number" ? String(children) : void 0;
717
- const [stamp, setStamp] = React2.useState(void 0);
718
- const [lit, setLit] = React2.useState(0);
719
- const prev = React2.useRef({ tone, label });
720
- React2.useEffect(() => {
1013
+ const [stamp, setStamp] = React3.useState(void 0);
1014
+ const [lit, setLit] = React3.useState(0);
1015
+ const prev = React3.useRef({ tone, label });
1016
+ React3.useEffect(() => {
721
1017
  const p = prev.current;
722
1018
  if (p.label !== label) setStamp((x) => x === "a" ? "b" : "a");
723
1019
  if (p.tone !== tone) setLit((n) => n + 1);
724
1020
  prev.current = { tone, label };
725
1021
  }, [tone, label]);
726
- return /* @__PURE__ */ React2.createElement("span", { className: cx("alt-badge", className), "data-tone": tone, "data-variant": v, "data-stamp": stamp, ...rest }, showLamp && /* @__PURE__ */ React2.createElement("span", { key: lit, className: "alt-badge-lamp", "aria-hidden": "true", "data-lit": lit ? "" : void 0, "data-pulse": lamp === "pulse" ? "" : void 0 }), children);
1022
+ return /* @__PURE__ */ React3.createElement("span", { className: cx("alt-badge", className), "data-tone": tone, "data-variant": v, "data-stamp": stamp, ...rest }, showLamp && /* @__PURE__ */ React3.createElement("span", { key: lit, className: "alt-badge-lamp", "aria-hidden": "true", "data-lit": lit ? "" : void 0, "data-pulse": lamp === "pulse" ? "" : void 0 }), children);
727
1023
  }
728
1024
  var TINTS = ["accent", "positive", "caution", "critical"];
729
- function Avatar({ name, src, size = 36, status, live, presence, lamp, className, style, onClick, ...rest }) {
1025
+ function Avatar({ skeleton, ...props }) {
1026
+ const missing = skeleton !== false && props.name === void 0;
1027
+ const promised = isPromise(props.name) || isPromise(props.src);
1028
+ useReportWaiting(missing || skeleton !== false && isPromise(props.name));
1029
+ const arrival = useArrival(missing);
1030
+ if (!useHasWaited(missing || promised)) return /* @__PURE__ */ React3.createElement(AvatarFace, { ...props, name: props.name ?? "", src: props.src });
1031
+ const size = props.size ?? 36;
1032
+ return /* @__PURE__ */ React3.createElement(
1033
+ Await,
1034
+ {
1035
+ inline: true,
1036
+ shape: "circle",
1037
+ enabled: skeleton !== false,
1038
+ imprint: /* @__PURE__ */ React3.createElement("span", { className: "alt-skeleton alt-avatar-imprint", "data-shape": "circle", style: { width: size, height: size } })
1039
+ },
1040
+ /* @__PURE__ */ React3.createElement(Arrive, { when: arrival }, /* @__PURE__ */ React3.createElement(AvatarLanded, { ...props }))
1041
+ );
1042
+ }
1043
+ function AvatarLanded(props) {
1044
+ return /* @__PURE__ */ React3.createElement(AvatarFace, { ...props, name: readPromised(props.name) ?? "", src: readPromised(props.src) });
1045
+ }
1046
+ function AvatarFace({ name, src, size = 36, status, live, presence, lamp, className, style, onClick, ...rest }) {
730
1047
  const initials = name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
731
1048
  const tint = TINTS[[...name].reduce((a, c) => a + c.charCodeAt(0), 0) % TINTS.length];
732
1049
  const label = [name, status, live && "live"].filter(Boolean).join(", ");
733
1050
  const showLamp = (lamp ?? size >= 24) && (status === "active" || status === "idle");
734
- return /* @__PURE__ */ React2.createElement(
1051
+ return /* @__PURE__ */ React3.createElement(
735
1052
  "span",
736
1053
  {
737
1054
  className: cx("alt-avatar", className),
@@ -754,29 +1071,29 @@ function Avatar({ name, src, size = 36, status, live, presence, lamp, className,
754
1071
  style: { ["--size"]: size + "px", ...style },
755
1072
  ...rest
756
1073
  },
757
- /* @__PURE__ */ React2.createElement("span", { className: "alt-avatar-shadow", "aria-hidden": "true" }),
758
- /* @__PURE__ */ React2.createElement("span", { className: "alt-avatar-face" }, src ? /* @__PURE__ */ React2.createElement("img", { src, alt: "" }) : initials),
759
- showLamp && /* @__PURE__ */ React2.createElement("span", { className: "alt-avatar-lamp", "aria-hidden": "true" })
1074
+ /* @__PURE__ */ React3.createElement("span", { className: "alt-avatar-shadow", "aria-hidden": "true" }),
1075
+ /* @__PURE__ */ React3.createElement("span", { className: "alt-avatar-face" }, src ? /* @__PURE__ */ React3.createElement("img", { src, alt: "" }) : initials),
1076
+ showLamp && /* @__PURE__ */ React3.createElement("span", { className: "alt-avatar-lamp", "aria-hidden": "true" })
760
1077
  );
761
1078
  }
762
1079
  function AvatarGroup({ className, children, max, style, ...rest }) {
763
- const all = React2.Children.toArray(children);
1080
+ const all = React3.Children.toArray(children);
764
1081
  const shown = max ? all.slice(0, max) : all;
765
1082
  const extra = all.length - shown.length;
766
1083
  const size = shown[0]?.props?.size || 36;
767
- return /* @__PURE__ */ React2.createElement("div", { className: cx("alt-avatar-group", className), style: { ["--size"]: size + "px", ...style }, ...rest }, shown, extra > 0 && /* @__PURE__ */ React2.createElement("span", { className: "alt-avatar", "data-tint": "more", role: "img", "aria-label": `${extra} more`, style: { ["--size"]: size + "px" } }, /* @__PURE__ */ React2.createElement("span", { className: "alt-avatar-shadow", "aria-hidden": "true" }), /* @__PURE__ */ React2.createElement("span", { className: "alt-avatar-face" }, "+", extra)));
1084
+ return /* @__PURE__ */ React3.createElement("div", { className: cx("alt-avatar-group", className), style: { ["--size"]: size + "px", ...style }, ...rest }, shown, extra > 0 && /* @__PURE__ */ React3.createElement("span", { className: "alt-avatar", "data-tint": "more", role: "img", "aria-label": `${extra} more`, style: { ["--size"]: size + "px" } }, /* @__PURE__ */ React3.createElement("span", { className: "alt-avatar-shadow", "aria-hidden": "true" }), /* @__PURE__ */ React3.createElement("span", { className: "alt-avatar-face" }, "+", extra)));
768
1085
  }
769
- var LINE_WIDTHS = ["100%", "94%", "82%", "97%", "64%"];
1086
+ var LINE_WIDTHS2 = ["100%", "94%", "82%", "97%", "64%"];
770
1087
  function Skeleton({ loaded, shape = "block", lines = 3, width, height, radius, className, style, children, ...rest }) {
771
- const [reveal, setReveal] = React2.useState(null);
772
- const was = React2.useRef(loaded);
773
- React2.useEffect(() => {
1088
+ const [reveal, setReveal] = React3.useState(null);
1089
+ const was = React3.useRef(loaded);
1090
+ React3.useEffect(() => {
774
1091
  if (loaded && !was.current) setReveal(riseDelay());
775
1092
  if (!loaded) setReveal(null);
776
1093
  was.current = loaded;
777
1094
  }, [loaded]);
778
1095
  if (loaded) {
779
- return /* @__PURE__ */ React2.createElement(
1096
+ return /* @__PURE__ */ React3.createElement(
780
1097
  "div",
781
1098
  {
782
1099
  className: cx("alt-reveal", className),
@@ -784,14 +1101,14 @@ function Skeleton({ loaded, shape = "block", lines = 3, width, height, radius, c
784
1101
  style: { ...reveal ? { ["--alt-rise-delay"]: reveal + "ms" } : null, ...style },
785
1102
  ...rest
786
1103
  },
787
- /* @__PURE__ */ React2.createElement("div", { className: "alt-reveal-inner" }, children)
1104
+ /* @__PURE__ */ React3.createElement("div", { className: "alt-reveal-inner" }, children)
788
1105
  );
789
1106
  }
790
1107
  if (shape === "text") {
791
- return /* @__PURE__ */ React2.createElement("div", { className: cx("alt-skeleton-lines", className), "aria-hidden": "true", style: { width, ...style }, ...rest }, Array.from({ length: lines }, (_, i) => /* @__PURE__ */ React2.createElement("div", { key: i, className: "alt-skeleton", "data-shape": "text", style: { width: i === lines - 1 && lines > 1 ? "60%" : LINE_WIDTHS[i % LINE_WIDTHS.length], height: height ?? 12, ["--i"]: i } })));
1108
+ return /* @__PURE__ */ React3.createElement("div", { className: cx("alt-skeleton-lines", className), "aria-hidden": "true", style: { width, ...style }, ...rest }, Array.from({ length: lines }, (_, i) => /* @__PURE__ */ React3.createElement("div", { key: i, className: "alt-skeleton", "data-shape": "text", style: { width: i === lines - 1 && lines > 1 ? "60%" : LINE_WIDTHS2[i % LINE_WIDTHS2.length], height: height ?? 12, ["--i"]: i } })));
792
1109
  }
793
1110
  const d = shape === "circle" ? width ?? height ?? 40 : void 0;
794
- return /* @__PURE__ */ React2.createElement(
1111
+ return /* @__PURE__ */ React3.createElement(
795
1112
  "div",
796
1113
  {
797
1114
  className: cx("alt-skeleton", className),
@@ -805,13 +1122,13 @@ function Skeleton({ loaded, shape = "block", lines = 3, width, height, radius, c
805
1122
  var toneIcon = { neutral: Icons.Info, accent: Icons.Info, positive: Icons.CircleCheck, caution: Icons.AlertTriangle, critical: Icons.AlertCircle };
806
1123
  function Alert({ tone = "neutral", variant = "flat", title, action, icon: icon2, onDismiss, settle, className, style, children, ...rest }) {
807
1124
  const I = toneIcon[tone];
808
- const [closing, setClosing] = React2.useState(false);
1125
+ const [closing, setClosing] = React3.useState(false);
809
1126
  const { style: depthStyle, ...depth } = useDepth({ settle });
810
1127
  const dismiss = () => {
811
1128
  setClosing(true);
812
1129
  window.setTimeout(() => onDismiss?.(), 400);
813
1130
  };
814
- return /* @__PURE__ */ React2.createElement(
1131
+ return /* @__PURE__ */ React3.createElement(
815
1132
  "div",
816
1133
  {
817
1134
  role: tone === "critical" ? "alert" : "status",
@@ -823,16 +1140,16 @@ function Alert({ tone = "neutral", variant = "flat", title, action, icon: icon2,
823
1140
  style: { ...depthStyle, ...style },
824
1141
  ...rest
825
1142
  },
826
- /* @__PURE__ */ React2.createElement("div", { className: "alt-alert-inner" }, /* @__PURE__ */ React2.createElement("span", { className: "alt-alert-icon", "aria-hidden": "true" }, icon2 ?? /* @__PURE__ */ React2.createElement(I, { size: 18 })), /* @__PURE__ */ React2.createElement("div", { className: "alt-alert-body" }, title && /* @__PURE__ */ React2.createElement("p", { className: "alt-alert-title" }, title), children && /* @__PURE__ */ React2.createElement("div", { className: "alt-alert-text" }, children)), action && /* @__PURE__ */ React2.createElement("div", { className: "alt-alert-action" }, action), onDismiss && /* @__PURE__ */ React2.createElement("button", { type: "button", className: "alt-alert-close", "aria-label": "Dismiss", onClick: dismiss }, /* @__PURE__ */ React2.createElement(Icons.X, { size: 14 })))
1143
+ /* @__PURE__ */ React3.createElement("div", { className: "alt-alert-inner" }, /* @__PURE__ */ React3.createElement("span", { className: "alt-alert-icon", "aria-hidden": "true" }, icon2 ?? /* @__PURE__ */ React3.createElement(I, { size: 18 })), /* @__PURE__ */ React3.createElement("div", { className: "alt-alert-body" }, title && /* @__PURE__ */ React3.createElement("p", { className: "alt-alert-title" }, title), children && /* @__PURE__ */ React3.createElement("div", { className: "alt-alert-text" }, children)), action && /* @__PURE__ */ React3.createElement("div", { className: "alt-alert-action" }, action), onDismiss && /* @__PURE__ */ React3.createElement("button", { type: "button", className: "alt-alert-close", "aria-label": "Dismiss", onClick: dismiss }, /* @__PURE__ */ React3.createElement(Icons.X, { size: 14 })))
827
1144
  );
828
1145
  }
829
1146
  function AlertStack({ children, expanded, defaultExpanded = false, onExpandedChange, moreLabel = (n) => `+${n} more`, lessLabel = "Show less", className, ...rest }) {
830
- const list = React2.Children.toArray(children).filter(React2.isValidElement);
1147
+ const list = React3.Children.toArray(children).filter(React3.isValidElement);
831
1148
  const [open, setOpen] = useControllable(expanded, defaultExpanded, onExpandedChange);
832
1149
  const topKey = list[0]?.key;
833
- const prevTop = React2.useRef(topKey);
834
- const [risen, setRisen] = React2.useState(0);
835
- React2.useEffect(() => {
1150
+ const prevTop = React3.useRef(topKey);
1151
+ const [risen, setRisen] = React3.useState(0);
1152
+ React3.useEffect(() => {
836
1153
  if (prevTop.current !== topKey) {
837
1154
  prevTop.current = topKey;
838
1155
  if (topKey != null) setRisen((r) => r + 1);
@@ -840,20 +1157,20 @@ function AlertStack({ children, expanded, defaultExpanded = false, onExpandedCha
840
1157
  }, [topKey]);
841
1158
  const hidden = list.length - 1;
842
1159
  const all = open || hidden < 1;
843
- return /* @__PURE__ */ React2.createElement("div", { className: cx("alt-alert-stack", className), "data-expanded": all ? "" : void 0, "data-sheets": all ? void 0 : Math.min(hidden, 2), ...rest }, all ? list.map((el, i) => /* @__PURE__ */ React2.createElement("div", { key: el.key, className: "alt-alert-stack-item", style: { ["--i"]: i } }, el)) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, list.slice(1, 3).map((el, i) => /* @__PURE__ */ React2.createElement("span", { key: el.key, className: "alt-alert-sheet", "aria-hidden": "true", "data-tone": el.props.tone ?? "neutral", style: { ["--i"]: i + 1 } })), /* @__PURE__ */ React2.createElement("div", { key: String(topKey) + risen, className: "alt-alert-stack-top", "data-risen": risen ? "" : void 0 }, list[0])), hidden > 0 && /* @__PURE__ */ React2.createElement("button", { type: "button", className: "alt-alert-more", "aria-expanded": all, onClick: () => setOpen(!open) }, all ? lessLabel : moreLabel(hidden)));
1160
+ return /* @__PURE__ */ React3.createElement("div", { className: cx("alt-alert-stack", className), "data-expanded": all ? "" : void 0, "data-sheets": all ? void 0 : Math.min(hidden, 2), ...rest }, all ? list.map((el, i) => /* @__PURE__ */ React3.createElement("div", { key: el.key, className: "alt-alert-stack-item", style: { ["--i"]: i } }, el)) : /* @__PURE__ */ React3.createElement(React3.Fragment, null, list.slice(1, 3).map((el, i) => /* @__PURE__ */ React3.createElement("span", { key: el.key, className: "alt-alert-sheet", "aria-hidden": "true", "data-tone": el.props.tone ?? "neutral", style: { ["--i"]: i + 1 } })), /* @__PURE__ */ React3.createElement("div", { key: String(topKey) + risen, className: "alt-alert-stack-top", "data-risen": risen ? "" : void 0 }, list[0])), hidden > 0 && /* @__PURE__ */ React3.createElement("button", { type: "button", className: "alt-alert-more", "aria-expanded": all, onClick: () => setOpen(!open) }, all ? lessLabel : moreLabel(hidden)));
844
1161
  }
845
1162
  function Accordion({ items, type = "single", defaultValue = [], className, ...rest }) {
846
- const [open, setOpen] = React2.useState(defaultValue);
847
- const id = React2.useId();
1163
+ const [open, setOpen] = React3.useState(defaultValue);
1164
+ const id = React3.useId();
848
1165
  const toggle = (v) => setOpen((o) => o.includes(v) ? o.filter((x) => x !== v) : type === "single" ? [v] : [...o, v]);
849
- return /* @__PURE__ */ React2.createElement("div", { className: cx("alt-acc", className), ...rest }, items.map((it) => {
1166
+ return /* @__PURE__ */ React3.createElement("div", { className: cx("alt-acc", className), ...rest }, items.map((it) => {
850
1167
  const on = open.includes(it.value);
851
- return /* @__PURE__ */ React2.createElement("div", { key: it.value, className: "alt-acc-item", "data-state": on ? "open" : "closed" }, /* @__PURE__ */ React2.createElement("h3", { className: "alt-acc-heading" }, /* @__PURE__ */ React2.createElement("button", { type: "button", className: "alt-acc-trigger", "aria-expanded": on, "aria-controls": `${id}-${it.value}`, onClick: () => toggle(it.value) }, /* @__PURE__ */ React2.createElement("span", null, it.title), /* @__PURE__ */ React2.createElement(Icons.ChevronDown, { className: "alt-acc-chevron", size: 18 }))), /* @__PURE__ */ React2.createElement("div", { className: "alt-acc-panel", id: `${id}-${it.value}`, role: "region", ...on ? {} : inert }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("div", { className: "alt-acc-content" }, it.content))));
1168
+ return /* @__PURE__ */ React3.createElement("div", { key: it.value, className: "alt-acc-item", "data-state": on ? "open" : "closed" }, /* @__PURE__ */ React3.createElement("h3", { className: "alt-acc-heading" }, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "alt-acc-trigger", "aria-expanded": on, "aria-controls": `${id}-${it.value}`, onClick: () => toggle(it.value) }, /* @__PURE__ */ React3.createElement("span", null, it.title), /* @__PURE__ */ React3.createElement(Icons.ChevronDown, { className: "alt-acc-chevron", size: 18 }))), /* @__PURE__ */ React3.createElement("div", { className: "alt-acc-panel", id: `${id}-${it.value}`, role: "region", ...on ? {} : inert }, /* @__PURE__ */ React3.createElement("div", null, /* @__PURE__ */ React3.createElement("div", { className: "alt-acc-content" }, it.content))));
852
1169
  }));
853
1170
  }
854
1171
  function HoldButton({ onConfirm, duration = 1e3, variant = "danger", holdingLabel, doneLabel, repeatable = false, className, children, style, disabled, onClick, ...rest }) {
855
- const [state, setState] = React2.useState("idle");
856
- const timer = React2.useRef(void 0);
1172
+ const [state, setState] = React3.useState("idle");
1173
+ const timer = React3.useRef(void 0);
857
1174
  const done = state === "done";
858
1175
  const start = () => {
859
1176
  if (disabled || state !== "idle") return;
@@ -870,9 +1187,9 @@ function HoldButton({ onConfirm, duration = 1e3, variant = "danger", holdingLabe
870
1187
  window.clearTimeout(timer.current);
871
1188
  setState("idle");
872
1189
  };
873
- React2.useEffect(() => () => window.clearTimeout(timer.current), []);
1190
+ React3.useEffect(() => () => window.clearTimeout(timer.current), []);
874
1191
  const label = done ? doneLabel ?? children : state === "holding" ? holdingLabel ?? children : children;
875
- return /* @__PURE__ */ React2.createElement(
1192
+ return /* @__PURE__ */ React3.createElement(
876
1193
  Button,
877
1194
  {
878
1195
  ...rest,
@@ -907,16 +1224,16 @@ function HoldButton({ onConfirm, duration = 1e3, variant = "danger", holdingLabe
907
1224
  },
908
1225
  onContextMenu: (e) => e.preventDefault()
909
1226
  },
910
- /* @__PURE__ */ React2.createElement("span", { className: "alt-hold-fill", "aria-hidden": "true" }),
911
- /* @__PURE__ */ React2.createElement("span", { className: "alt-hold-text" }, label),
912
- /* @__PURE__ */ React2.createElement("span", { className: "alt-sr", "aria-live": "polite" }, state === "holding" ? "Keep holding to confirm" : done ? "Confirmed" : "")
1227
+ /* @__PURE__ */ React3.createElement("span", { className: "alt-hold-fill", "aria-hidden": "true" }),
1228
+ /* @__PURE__ */ React3.createElement("span", { className: "alt-hold-text" }, label),
1229
+ /* @__PURE__ */ React3.createElement("span", { className: "alt-sr", "aria-live": "polite" }, state === "holding" ? "Keep holding to confirm" : done ? "Confirmed" : "")
913
1230
  );
914
1231
  }
915
1232
  function ScrollArea({ header, maxHeight = 280, className, children, ...rest }) {
916
- const body = React2.useRef(null);
917
- const inner = React2.useRef(null);
918
- const [edges, setEdges] = React2.useState({ top: false, bottom: false });
919
- const update = React2.useCallback(() => {
1233
+ const body = React3.useRef(null);
1234
+ const inner = React3.useRef(null);
1235
+ const [edges, setEdges] = React3.useState({ top: false, bottom: false });
1236
+ const update = React3.useCallback(() => {
920
1237
  const el = body.current;
921
1238
  if (!el) return;
922
1239
  const top = el.scrollTop > 1, bottom = el.scrollTop + el.clientHeight < el.scrollHeight - 1;
@@ -929,15 +1246,15 @@ function ScrollArea({ header, maxHeight = 280, className, children, ...rest }) {
929
1246
  if (inner.current) ro.observe(inner.current);
930
1247
  return () => ro.disconnect();
931
1248
  }, [update]);
932
- return /* @__PURE__ */ React2.createElement("div", { className: cx("alt-scroll", className), "data-top": edges.top ? "" : void 0, "data-bottom": edges.bottom ? "" : void 0, ...rest }, header && /* @__PURE__ */ React2.createElement("div", { className: "alt-scroll-header" }, header), /* @__PURE__ */ React2.createElement("div", { className: "alt-scroll-body", ref: body, onScroll: update, style: { maxHeight }, tabIndex: 0, "aria-label": rest["aria-label"] }, /* @__PURE__ */ React2.createElement("div", { ref: inner }, children)), /* @__PURE__ */ React2.createElement("span", { className: "alt-scroll-lip", "data-edge": "top", "aria-hidden": "true" }), /* @__PURE__ */ React2.createElement("span", { className: "alt-scroll-lip", "data-edge": "bottom", "aria-hidden": "true" }));
1249
+ return /* @__PURE__ */ React3.createElement("div", { className: cx("alt-scroll", className), "data-top": edges.top ? "" : void 0, "data-bottom": edges.bottom ? "" : void 0, ...rest }, header && /* @__PURE__ */ React3.createElement("div", { className: "alt-scroll-header" }, header), /* @__PURE__ */ React3.createElement("div", { className: "alt-scroll-body", ref: body, onScroll: update, style: { maxHeight }, tabIndex: 0, "aria-label": rest["aria-label"] }, /* @__PURE__ */ React3.createElement("div", { ref: inner }, children)), /* @__PURE__ */ React3.createElement("span", { className: "alt-scroll-lip", "data-edge": "top", "aria-hidden": "true" }), /* @__PURE__ */ React3.createElement("span", { className: "alt-scroll-lip", "data-edge": "bottom", "aria-hidden": "true" }));
933
1250
  }
934
1251
  function DropZone({ onFiles, accept, multiple = true, state, className, children, ...rest }) {
935
- const [armed, setArmed] = React2.useState(false);
936
- const [over, setOver] = React2.useState(false);
937
- const [landed, setLanded] = React2.useState(0);
938
- const input = React2.useRef(null);
1252
+ const [armed, setArmed] = React3.useState(false);
1253
+ const [over, setOver] = React3.useState(false);
1254
+ const [landed, setLanded] = React3.useState(0);
1255
+ const input = React3.useRef(null);
939
1256
  const { style: depthStyle, ...depth } = useDepth({ settle: landed || void 0 });
940
- React2.useEffect(() => {
1257
+ React3.useEffect(() => {
941
1258
  let n = 0;
942
1259
  const hasFiles = (e) => Array.from(e.dataTransfer?.types || []).includes("Files");
943
1260
  const enter = (e) => {
@@ -975,7 +1292,7 @@ function DropZone({ onFiles, accept, multiple = true, state, className, children
975
1292
  setLanded((x) => x + 1);
976
1293
  };
977
1294
  const visual = state ?? (over ? "over" : armed ? "armed" : "idle");
978
- return /* @__PURE__ */ React2.createElement(
1295
+ return /* @__PURE__ */ React3.createElement(
979
1296
  "div",
980
1297
  {
981
1298
  className: cx("alt-drop", className),
@@ -1004,7 +1321,7 @@ function DropZone({ onFiles, accept, multiple = true, state, className, children
1004
1321
  },
1005
1322
  ...rest
1006
1323
  },
1007
- /* @__PURE__ */ React2.createElement("input", { ref: input, type: "file", hidden: true, accept, multiple, onChange: (e) => take(Array.from(e.target.files || [])) }),
1324
+ /* @__PURE__ */ React3.createElement("input", { ref: input, type: "file", hidden: true, accept, multiple, onChange: (e) => take(Array.from(e.target.files || [])) }),
1008
1325
  children
1009
1326
  );
1010
1327
  }
@@ -1015,12 +1332,12 @@ var move = (arr, from, to) => {
1015
1332
  return a;
1016
1333
  };
1017
1334
  function SortableList({ items, getKey, onReorder, renderItem, getLabel = (i) => String(getKey(i)), gap = 8, className, ...rest }) {
1018
- const nodes = React2.useRef(/* @__PURE__ */ new Map());
1019
- const before = React2.useRef(/* @__PURE__ */ new Map());
1020
- const start = React2.useRef(null);
1021
- const [drag, setDrag] = React2.useState(null);
1022
- const [kb, setKb] = React2.useState(null);
1023
- const [msg, setMsg] = React2.useState("");
1335
+ const nodes = React3.useRef(/* @__PURE__ */ new Map());
1336
+ const before = React3.useRef(/* @__PURE__ */ new Map());
1337
+ const start = React3.useRef(null);
1338
+ const [drag, setDrag] = React3.useState(null);
1339
+ const [kb, setKb] = React3.useState(null);
1340
+ const [msg, setMsg] = React3.useState("");
1024
1341
  const snapshot = () => {
1025
1342
  before.current.clear();
1026
1343
  nodes.current.forEach((el, k) => before.current.set(k, el.getBoundingClientRect().top));
@@ -1099,7 +1416,7 @@ function SortableList({ items, getKey, onReorder, renderItem, getLabel = (i) =>
1099
1416
  const s = start.current;
1100
1417
  const h = drag && s ? s.hs[drag.from] + gap : 0;
1101
1418
  const slotTop = drag && s ? drag.to <= drag.from ? s.tops[drag.to] : s.tops[drag.to] + s.hs[drag.to] - s.hs[drag.from] : 0;
1102
- return /* @__PURE__ */ React2.createElement("div", { className: cx("alt-sort", className), style: { gap }, role: "list", "aria-label": rest["aria-label"], "data-dragging": drag ? "" : void 0 }, drag && s && /* @__PURE__ */ React2.createElement("div", { className: "alt-sort-slot", "aria-hidden": "true", style: { top: slotTop, height: s.hs[drag.from] } }), items.map((item, i) => {
1419
+ return /* @__PURE__ */ React3.createElement("div", { className: cx("alt-sort", className), style: { gap }, role: "list", "aria-label": rest["aria-label"], "data-dragging": drag ? "" : void 0 }, drag && s && /* @__PURE__ */ React3.createElement("div", { className: "alt-sort-slot", "aria-hidden": "true", style: { top: slotTop, height: s.hs[drag.from] } }), items.map((item, i) => {
1103
1420
  const key = keys[i];
1104
1421
  const held = drag?.key === key || kb === key;
1105
1422
  let shift = 0;
@@ -1108,7 +1425,7 @@ function SortableList({ items, getKey, onReorder, renderItem, getLabel = (i) =>
1108
1425
  if (drag.to < drag.from && i >= drag.to && i < drag.from) shift = h;
1109
1426
  }
1110
1427
  const transform = drag?.key === key ? `translateY(${drag.dy}px)` : shift ? `translateY(${shift}px)` : void 0;
1111
- return /* @__PURE__ */ React2.createElement(
1428
+ return /* @__PURE__ */ React3.createElement(
1112
1429
  "div",
1113
1430
  {
1114
1431
  key,
@@ -1130,14 +1447,14 @@ function SortableList({ items, getKey, onReorder, renderItem, getLabel = (i) =>
1130
1447
  onPointerCancel: onPointerUp,
1131
1448
  onKeyDown: (e) => onKeyDown(e, key, i)
1132
1449
  },
1133
- /* @__PURE__ */ React2.createElement("span", { className: "alt-sort-grip", "aria-hidden": "true" }, /* @__PURE__ */ React2.createElement("svg", { width: "12", height: "16", viewBox: "0 0 12 16", fill: "currentColor" }, /* @__PURE__ */ React2.createElement("circle", { cx: "3", cy: "3", r: "1.3" }), /* @__PURE__ */ React2.createElement("circle", { cx: "9", cy: "3", r: "1.3" }), /* @__PURE__ */ React2.createElement("circle", { cx: "3", cy: "8", r: "1.3" }), /* @__PURE__ */ React2.createElement("circle", { cx: "9", cy: "8", r: "1.3" }), /* @__PURE__ */ React2.createElement("circle", { cx: "3", cy: "13", r: "1.3" }), /* @__PURE__ */ React2.createElement("circle", { cx: "9", cy: "13", r: "1.3" }))),
1134
- /* @__PURE__ */ React2.createElement("div", { className: "alt-sort-body" }, renderItem(item, { held }))
1450
+ /* @__PURE__ */ React3.createElement("span", { className: "alt-sort-grip", "aria-hidden": "true" }, /* @__PURE__ */ React3.createElement("svg", { width: "12", height: "16", viewBox: "0 0 12 16", fill: "currentColor" }, /* @__PURE__ */ React3.createElement("circle", { cx: "3", cy: "3", r: "1.3" }), /* @__PURE__ */ React3.createElement("circle", { cx: "9", cy: "3", r: "1.3" }), /* @__PURE__ */ React3.createElement("circle", { cx: "3", cy: "8", r: "1.3" }), /* @__PURE__ */ React3.createElement("circle", { cx: "9", cy: "8", r: "1.3" }), /* @__PURE__ */ React3.createElement("circle", { cx: "3", cy: "13", r: "1.3" }), /* @__PURE__ */ React3.createElement("circle", { cx: "9", cy: "13", r: "1.3" }))),
1451
+ /* @__PURE__ */ React3.createElement("div", { className: "alt-sort-body" }, renderItem(item, { held }))
1135
1452
  );
1136
- }), /* @__PURE__ */ React2.createElement("span", { className: "alt-sr", "aria-live": "assertive" }, msg));
1453
+ }), /* @__PURE__ */ React3.createElement("span", { className: "alt-sr", "aria-live": "assertive" }, msg));
1137
1454
  }
1138
1455
 
1139
1456
  // project/components/src/pile.tsx
1140
- import * as React3 from "react";
1457
+ import * as React4 from "react";
1141
1458
  function Pile({
1142
1459
  count,
1143
1460
  interactive,
@@ -1159,15 +1476,15 @@ function Pile({
1159
1476
  const live = interactive || openable;
1160
1477
  const [isOpen, setOpen] = useControllable(open, defaultOpen, onOpenChange);
1161
1478
  const { mounted, state } = usePresence(openable && isOpen, 260);
1162
- const root = React3.useRef(null);
1163
- const top = React3.useRef(null);
1164
- const id = React3.useId();
1479
+ const root = React4.useRef(null);
1480
+ const top = React4.useRef(null);
1481
+ const id = React4.useId();
1165
1482
  const toggle = () => {
1166
1483
  if (openable) setOpen(!isOpen);
1167
1484
  };
1168
- const close = React3.useCallback(() => setOpen(false), [setOpen]);
1485
+ const close = React4.useCallback(() => setOpen(false), [setOpen]);
1169
1486
  useOutside(root, openable && isOpen, close);
1170
- return /* @__PURE__ */ React3.createElement(
1487
+ return /* @__PURE__ */ React4.createElement(
1171
1488
  "div",
1172
1489
  {
1173
1490
  ref: root,
@@ -1176,8 +1493,8 @@ function Pile({
1176
1493
  "data-open": openable && isOpen ? "" : void 0,
1177
1494
  ...rest
1178
1495
  },
1179
- Array.from({ length: sheets }, (_, i) => /* @__PURE__ */ React3.createElement("span", { key: i, className: "alt-pile-sheet", "aria-hidden": "true", style: { ["--i"]: i + 1 } })),
1180
- /* @__PURE__ */ React3.createElement(
1496
+ Array.from({ length: sheets }, (_, i) => /* @__PURE__ */ React4.createElement("span", { key: i, className: "alt-pile-sheet", "aria-hidden": "true", style: { ["--i"]: i + 1 } })),
1497
+ /* @__PURE__ */ React4.createElement(
1181
1498
  "div",
1182
1499
  {
1183
1500
  ref: top,
@@ -1196,8 +1513,8 @@ function Pile({
1196
1513
  },
1197
1514
  children
1198
1515
  ),
1199
- n > 1 && /* @__PURE__ */ React3.createElement("span", { className: "alt-pile-count", "aria-label": `${n} items` }, n),
1200
- openable && mounted && /* @__PURE__ */ React3.createElement(
1516
+ n > 1 && /* @__PURE__ */ React4.createElement("span", { className: "alt-pile-count", "aria-label": `${n} items` }, n),
1517
+ openable && mounted && /* @__PURE__ */ React4.createElement(
1201
1518
  "div",
1202
1519
  {
1203
1520
  className: "alt-pile-list",
@@ -1211,23 +1528,23 @@ function Pile({
1211
1528
  }
1212
1529
  }
1213
1530
  },
1214
- /* @__PURE__ */ React3.createElement("ul", { className: "alt-pile-list-inner", style: { maxHeight } }, items.map((it, i) => /* @__PURE__ */ React3.createElement("li", { key: getKey ? getKey(it, i) : i }, /* @__PURE__ */ React3.createElement("button", { type: "button", className: "alt-pile-item", style: { ["--i"]: Math.min(i, 10) }, onClick: () => onSelect?.(it, i) }, renderItem(it, { index: i })))))
1531
+ /* @__PURE__ */ React4.createElement("ul", { className: "alt-pile-list-inner", style: { maxHeight } }, items.map((it, i) => /* @__PURE__ */ React4.createElement("li", { key: getKey ? getKey(it, i) : i }, /* @__PURE__ */ React4.createElement("button", { type: "button", className: "alt-pile-item", style: { ["--i"]: Math.min(i, 10) }, onClick: () => onSelect?.(it, i) }, renderItem(it, { index: i })))))
1215
1532
  )
1216
1533
  );
1217
1534
  }
1218
1535
 
1219
1536
  // project/components/src/overlays.tsx
1220
- import * as React4 from "react";
1537
+ import * as React5 from "react";
1221
1538
  var EXIT_3 = 160;
1222
1539
  var EXIT_4 = 190;
1223
1540
  var EXIT_5 = 220;
1224
1541
  var lastTipClose = 0;
1225
1542
  var openCard = null;
1226
1543
  function Tooltip({ content, side = "top", delay = 450, defaultOpen = false, children }) {
1227
- const [open, setOpen] = React4.useState(defaultOpen);
1228
- const [warm, setWarm] = React4.useState(false);
1229
- const timer = React4.useRef(void 0);
1230
- const id = React4.useId();
1544
+ const [open, setOpen] = React5.useState(defaultOpen);
1545
+ const [warm, setWarm] = React5.useState(false);
1546
+ const timer = React5.useRef(void 0);
1547
+ const id = React5.useId();
1231
1548
  const { mounted, state } = usePresence(open, EXIT_3);
1232
1549
  const show = () => {
1233
1550
  const isWarm = Date.now() - lastTipClose < 400;
@@ -1242,8 +1559,8 @@ function Tooltip({ content, side = "top", delay = 450, defaultOpen = false, chil
1242
1559
  return false;
1243
1560
  });
1244
1561
  };
1245
- React4.useEffect(() => () => window.clearTimeout(timer.current), []);
1246
- return /* @__PURE__ */ React4.createElement(
1562
+ React5.useEffect(() => () => window.clearTimeout(timer.current), []);
1563
+ return /* @__PURE__ */ React5.createElement(
1247
1564
  "span",
1248
1565
  {
1249
1566
  className: "alt-tip-anchor",
@@ -1259,27 +1576,27 @@ function Tooltip({ content, side = "top", delay = 450, defaultOpen = false, chil
1259
1576
  if (e.key === "Escape") hide();
1260
1577
  }
1261
1578
  },
1262
- React4.cloneElement(children, { "aria-describedby": open ? id : void 0 }),
1263
- mounted && /* @__PURE__ */ React4.createElement("span", { role: "tooltip", id, className: "alt-tip", "data-side": side, "data-state": state, "data-warm": warm ? "" : void 0 }, content)
1579
+ React5.cloneElement(children, { "aria-describedby": open ? id : void 0 }),
1580
+ mounted && /* @__PURE__ */ React5.createElement("span", { role: "tooltip", id, className: "alt-tip", "data-side": side, "data-state": state, "data-warm": warm ? "" : void 0 }, content)
1264
1581
  );
1265
1582
  }
1266
1583
  function Popover({ trigger, children, open, defaultOpen = false, onOpenChange, side = "bottom", align = "start", className, ...rest }) {
1267
1584
  const [isOpen, set] = useControllable(open, defaultOpen, onOpenChange);
1268
- const ref = React4.useRef(null);
1269
- const panel = React4.useRef(null);
1270
- const id = React4.useId();
1585
+ const ref = React5.useRef(null);
1586
+ const panel = React5.useRef(null);
1587
+ const id = React5.useId();
1271
1588
  const { mounted, state } = usePresence(isOpen, EXIT_3);
1272
- const close = React4.useCallback(() => set(false), [set]);
1589
+ const close = React5.useCallback(() => set(false), [set]);
1273
1590
  useOutside(ref, isOpen, close);
1274
- React4.useEffect(() => {
1591
+ React5.useEffect(() => {
1275
1592
  if (state !== "open" || !panel.current) return;
1276
1593
  const f = panel.current.querySelector('input, textarea, select, button, [href], [tabindex]:not([tabindex="-1"])');
1277
1594
  (f || panel.current).focus({ preventScroll: true });
1278
1595
  }, [state]);
1279
- return /* @__PURE__ */ React4.createElement("span", { className: "alt-pop-anchor", ref }, React4.cloneElement(trigger, { "aria-expanded": isOpen, "aria-controls": id, "aria-haspopup": "dialog", onClick: (e) => {
1596
+ return /* @__PURE__ */ React5.createElement("span", { className: "alt-pop-anchor", ref }, React5.cloneElement(trigger, { "aria-expanded": isOpen, "aria-controls": id, "aria-haspopup": "dialog", onClick: (e) => {
1280
1597
  trigger.props.onClick?.(e);
1281
1598
  set(!isOpen);
1282
- } }), mounted && /* @__PURE__ */ React4.createElement(
1599
+ } }), mounted && /* @__PURE__ */ React5.createElement(
1283
1600
  "div",
1284
1601
  {
1285
1602
  ref: panel,
@@ -1303,15 +1620,15 @@ function Popover({ trigger, children, open, defaultOpen = false, onOpenChange, s
1303
1620
  ));
1304
1621
  }
1305
1622
  function DropdownMenu({ trigger, items, align = "start", side = "bottom", defaultOpen = false, className }) {
1306
- const [open, setOpen] = React4.useState(defaultOpen);
1307
- const [active, setActive] = React4.useState(-1);
1308
- const [hl, setHl] = React4.useState(null);
1309
- const anchor = React4.useRef(null);
1310
- const menu = React4.useRef(null);
1311
- const refs = React4.useRef([]);
1312
- const id = React4.useId();
1623
+ const [open, setOpen] = React5.useState(defaultOpen);
1624
+ const [active, setActive] = React5.useState(-1);
1625
+ const [hl, setHl] = React5.useState(null);
1626
+ const anchor = React5.useRef(null);
1627
+ const menu = React5.useRef(null);
1628
+ const refs = React5.useRef([]);
1629
+ const id = React5.useId();
1313
1630
  const { mounted, state } = usePresence(open, EXIT_3);
1314
- const close = React4.useCallback(() => {
1631
+ const close = React5.useCallback(() => {
1315
1632
  setOpen(false);
1316
1633
  setActive(-1);
1317
1634
  }, []);
@@ -1321,7 +1638,7 @@ function DropdownMenu({ trigger, items, align = "start", side = "bottom", defaul
1321
1638
  const el = active >= 0 ? refs.current[active] : null;
1322
1639
  setHl(el ? { y: el.offsetTop, h: el.offsetHeight } : null);
1323
1640
  }, [active, mounted]);
1324
- React4.useEffect(() => {
1641
+ React5.useEffect(() => {
1325
1642
  if (state === "open") menu.current?.focus({ preventScroll: true });
1326
1643
  }, [state]);
1327
1644
  const choose = (i) => {
@@ -1355,7 +1672,7 @@ function DropdownMenu({ trigger, items, align = "start", side = "bottom", defaul
1355
1672
  };
1356
1673
  let n = 0;
1357
1674
  const activeTone = active >= 0 ? items[active].tone : void 0;
1358
- return /* @__PURE__ */ React4.createElement("span", { className: "alt-pop-anchor", ref: anchor }, React4.cloneElement(trigger, {
1675
+ return /* @__PURE__ */ React5.createElement("span", { className: "alt-pop-anchor", ref: anchor }, React5.cloneElement(trigger, {
1359
1676
  "aria-haspopup": "menu",
1360
1677
  "aria-expanded": open,
1361
1678
  "aria-controls": id,
@@ -1370,7 +1687,7 @@ function DropdownMenu({ trigger, items, align = "start", side = "bottom", defaul
1370
1687
  setActive(enabled[0]);
1371
1688
  }
1372
1689
  }
1373
- }), mounted && /* @__PURE__ */ React4.createElement(
1690
+ }), mounted && /* @__PURE__ */ React5.createElement(
1374
1691
  "div",
1375
1692
  {
1376
1693
  ref: menu,
@@ -1386,7 +1703,7 @@ function DropdownMenu({ trigger, items, align = "start", side = "bottom", defaul
1386
1703
  onKeyDown,
1387
1704
  onPointerLeave: () => setActive(-1)
1388
1705
  },
1389
- /* @__PURE__ */ React4.createElement(
1706
+ /* @__PURE__ */ React5.createElement(
1390
1707
  "span",
1391
1708
  {
1392
1709
  className: "alt-menu-hl",
@@ -1396,10 +1713,10 @@ function DropdownMenu({ trigger, items, align = "start", side = "bottom", defaul
1396
1713
  }
1397
1714
  ),
1398
1715
  items.map((it, i) => {
1399
- if (it.type === "separator") return /* @__PURE__ */ React4.createElement("div", { key: i, className: "alt-menu-sep", role: "separator" });
1400
- if (it.type === "label") return /* @__PURE__ */ React4.createElement("div", { key: i, className: "alt-menu-label", style: { ["--i"]: n++ } }, it.label);
1716
+ if (it.type === "separator") return /* @__PURE__ */ React5.createElement("div", { key: i, className: "alt-menu-sep", role: "separator" });
1717
+ if (it.type === "label") return /* @__PURE__ */ React5.createElement("div", { key: i, className: "alt-menu-label", style: { ["--i"]: n++ } }, it.label);
1401
1718
  const item = it;
1402
- return /* @__PURE__ */ React4.createElement(
1719
+ return /* @__PURE__ */ React5.createElement(
1403
1720
  "div",
1404
1721
  {
1405
1722
  key: i,
@@ -1416,9 +1733,9 @@ function DropdownMenu({ trigger, items, align = "start", side = "bottom", defaul
1416
1733
  onPointerMove: () => !item.disabled && active !== i && setActive(i),
1417
1734
  onClick: () => choose(i)
1418
1735
  },
1419
- item.icon && /* @__PURE__ */ React4.createElement("span", { className: "alt-menu-icon" }, item.icon),
1420
- /* @__PURE__ */ React4.createElement("span", { className: "alt-menu-text" }, item.label),
1421
- item.shortcut && /* @__PURE__ */ React4.createElement("span", { className: "alt-menu-shortcut" }, item.shortcut)
1736
+ item.icon && /* @__PURE__ */ React5.createElement("span", { className: "alt-menu-icon" }, item.icon),
1737
+ /* @__PURE__ */ React5.createElement("span", { className: "alt-menu-text" }, item.label),
1738
+ item.shortcut && /* @__PURE__ */ React5.createElement("span", { className: "alt-menu-shortcut" }, item.shortcut)
1422
1739
  );
1423
1740
  })
1424
1741
  ));
@@ -1426,10 +1743,10 @@ function DropdownMenu({ trigger, items, align = "start", side = "bottom", defaul
1426
1743
  function HoverCard({ trigger, children, side = "bottom", align = "start", openDelay = 400, closeDelay = 250, open, defaultOpen = false, onOpenChange, className }) {
1427
1744
  const [isOpen, set] = useControllable(open, defaultOpen, onOpenChange);
1428
1745
  const { mounted, state } = usePresence(isOpen, EXIT_3);
1429
- const timer = React4.useRef(void 0);
1430
- const closeMe = React4.useRef(() => set(false));
1746
+ const timer = React5.useRef(void 0);
1747
+ const closeMe = React5.useRef(() => set(false));
1431
1748
  closeMe.current = () => set(false);
1432
- React4.useEffect(() => {
1749
+ React5.useEffect(() => {
1433
1750
  if (!isOpen) return;
1434
1751
  const mine = () => closeMe.current();
1435
1752
  if (openCard && openCard !== mine) {
@@ -1453,8 +1770,8 @@ function HoverCard({ trigger, children, side = "bottom", align = "start", openDe
1453
1770
  if (isOpen) lastTipClose = Date.now();
1454
1771
  }, delay);
1455
1772
  };
1456
- React4.useEffect(() => () => window.clearTimeout(timer.current), []);
1457
- return /* @__PURE__ */ React4.createElement(
1773
+ React5.useEffect(() => () => window.clearTimeout(timer.current), []);
1774
+ return /* @__PURE__ */ React5.createElement(
1458
1775
  "span",
1459
1776
  {
1460
1777
  className: "alt-pop-anchor alt-hovercard-anchor",
@@ -1478,7 +1795,7 @@ function HoverCard({ trigger, children, side = "bottom", align = "start", openDe
1478
1795
  }
1479
1796
  },
1480
1797
  trigger,
1481
- mounted && /* @__PURE__ */ React4.createElement(
1798
+ mounted && /* @__PURE__ */ React5.createElement(
1482
1799
  "div",
1483
1800
  {
1484
1801
  className: cx("alt-pop alt-hovercard", className),
@@ -1493,6 +1810,7 @@ function HoverCard({ trigger, children, side = "bottom", align = "start", openDe
1493
1810
  }
1494
1811
  var summits = 0;
1495
1812
  var summitTaken = () => summits > 0;
1813
+ var MODAL_FOCUS = "[data-autofocus], input, textarea, select";
1496
1814
  function useModal({
1497
1815
  open,
1498
1816
  onDismiss,
@@ -1502,12 +1820,13 @@ function useModal({
1502
1820
  dismissible = true,
1503
1821
  summit = false,
1504
1822
  autoFocus = true,
1505
- focusSelector = "[data-autofocus], input, textarea, select"
1823
+ focusSelector = MODAL_FOCUS,
1824
+ restoreFocus = autoFocus
1506
1825
  }) {
1507
1826
  const ctx = useAltitude();
1508
- const restore = React4.useRef(null);
1827
+ const restore = React5.useRef(null);
1509
1828
  const presence = usePresence(open, exitMs);
1510
- React4.useEffect(() => {
1829
+ React5.useEffect(() => {
1511
1830
  if (!open) return;
1512
1831
  restore.current = document.activeElement;
1513
1832
  const pop = modal ? ctx?.pushLayer() : void 0;
@@ -1518,10 +1837,10 @@ function useModal({
1518
1837
  pop?.();
1519
1838
  if (modal) document.body.style.overflow = prev;
1520
1839
  if (summit) summits--;
1521
- if (autoFocus) restore.current?.focus?.({ preventScroll: true });
1840
+ if (restoreFocus) restore.current?.focus?.({ preventScroll: true });
1522
1841
  };
1523
1842
  }, [open]);
1524
- React4.useEffect(() => {
1843
+ React5.useEffect(() => {
1525
1844
  if (presence.state !== "open" || !autoFocus) return;
1526
1845
  let raf = 0;
1527
1846
  const tryFocus = () => {
@@ -1554,15 +1873,39 @@ function useModal({
1554
1873
  };
1555
1874
  return { ...presence, onKeyDown };
1556
1875
  }
1557
- function Dialog({ open, defaultOpen = false, onOpenChange, trigger, title, description, children, footer, size = "md", dismissible = true, className }) {
1876
+ function Dialog({
1877
+ open,
1878
+ defaultOpen = false,
1879
+ onOpenChange,
1880
+ trigger,
1881
+ title,
1882
+ description,
1883
+ children,
1884
+ footer,
1885
+ size = "md",
1886
+ dismissible = true,
1887
+ initialFocus = "first-field",
1888
+ focusSelector = MODAL_FOCUS,
1889
+ className
1890
+ }) {
1558
1891
  const [isOpen, set] = useControllable(open, defaultOpen, onOpenChange);
1559
- const panel = React4.useRef(null);
1560
- const id = React4.useId();
1561
- const { mounted, state, onKeyDown } = useModal({ open: isOpen, onDismiss: () => set(false), exitMs: EXIT_5, panel, dismissible, summit: true });
1562
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, trigger && React4.cloneElement(trigger, { "aria-haspopup": "dialog", onClick: (e) => {
1892
+ const panel = React5.useRef(null);
1893
+ const id = React5.useId();
1894
+ const { mounted, state, onKeyDown } = useModal({
1895
+ open: isOpen,
1896
+ onDismiss: () => set(false),
1897
+ exitMs: EXIT_5,
1898
+ panel,
1899
+ dismissible,
1900
+ summit: true,
1901
+ autoFocus: initialFocus !== false,
1902
+ focusSelector: initialFocus === "title" ? ".alt-dialog-title" : focusSelector,
1903
+ restoreFocus: true
1904
+ });
1905
+ return /* @__PURE__ */ React5.createElement(React5.Fragment, null, trigger && React5.cloneElement(trigger, { "aria-haspopup": "dialog", onClick: (e) => {
1563
1906
  trigger.props.onClick?.(e);
1564
1907
  set(true);
1565
- } }), mounted && /* @__PURE__ */ React4.createElement(Layer, null, /* @__PURE__ */ React4.createElement("div", { className: "alt-dialog-root", "data-state": state, onKeyDown }, /* @__PURE__ */ React4.createElement("div", { className: "alt-scrim", onClick: () => dismissible && set(false) }), /* @__PURE__ */ React4.createElement(
1908
+ } }), mounted && /* @__PURE__ */ React5.createElement(Layer, null, /* @__PURE__ */ React5.createElement("div", { className: "alt-dialog-root", "data-state": state, onKeyDown }, /* @__PURE__ */ React5.createElement("div", { className: "alt-scrim", onClick: () => dismissible && set(false) }), /* @__PURE__ */ React5.createElement(
1566
1909
  "div",
1567
1910
  {
1568
1911
  ref: panel,
@@ -1574,10 +1917,10 @@ function Dialog({ open, defaultOpen = false, onOpenChange, trigger, title, descr
1574
1917
  className: cx("alt-dialog", className),
1575
1918
  "data-size": size
1576
1919
  },
1577
- /* @__PURE__ */ React4.createElement("div", { className: "alt-dialog-head" }, /* @__PURE__ */ React4.createElement("h2", { className: "alt-dialog-title", id: `${id}-t` }, title), description && /* @__PURE__ */ React4.createElement("p", { className: "alt-dialog-desc", id: `${id}-d` }, description)),
1578
- children && /* @__PURE__ */ React4.createElement("div", { className: "alt-dialog-body" }, children),
1579
- footer && /* @__PURE__ */ React4.createElement("div", { className: "alt-dialog-footer" }, footer),
1580
- dismissible && /* @__PURE__ */ React4.createElement(Button, { variant: "ghost", size: "sm", square: true, "aria-label": "Close", className: "alt-dialog-close", onClick: () => set(false) }, /* @__PURE__ */ React4.createElement(Icons.X, null))
1920
+ /* @__PURE__ */ React5.createElement("div", { className: "alt-dialog-head" }, /* @__PURE__ */ React5.createElement("h2", { className: "alt-dialog-title", id: `${id}-t`, tabIndex: initialFocus === "title" ? -1 : void 0 }, title), description && /* @__PURE__ */ React5.createElement("p", { className: "alt-dialog-desc", id: `${id}-d` }, description)),
1921
+ children && /* @__PURE__ */ React5.createElement("div", { className: "alt-dialog-body" }, children),
1922
+ footer && /* @__PURE__ */ React5.createElement("div", { className: "alt-dialog-footer" }, footer),
1923
+ dismissible && /* @__PURE__ */ React5.createElement(Button, { variant: "ghost", size: "sm", square: true, "aria-label": "Close", className: "alt-dialog-close", onClick: () => set(false) }, /* @__PURE__ */ React5.createElement(Icons.X, null))
1581
1924
  ))));
1582
1925
  }
1583
1926
  var toasts = [];
@@ -1607,16 +1950,16 @@ var toastIcon = { neutral: Icons.Info, positive: Icons.CircleCheck, caution: Ico
1607
1950
  var STACK = 3;
1608
1951
  var GAP = 8;
1609
1952
  function Toaster({ className }) {
1610
- const [, force] = React4.useReducer((n) => n + 1, 0);
1611
- const [expanded, setExpanded] = React4.useState(false);
1612
- const heights = React4.useRef(/* @__PURE__ */ new Map());
1613
- React4.useEffect(() => {
1953
+ const [, force] = React5.useReducer((n) => n + 1, 0);
1954
+ const [expanded, setExpanded] = React5.useState(false);
1955
+ const heights = React5.useRef(/* @__PURE__ */ new Map());
1956
+ React5.useEffect(() => {
1614
1957
  subs.add(force);
1615
1958
  return () => {
1616
1959
  subs.delete(force);
1617
1960
  };
1618
1961
  }, []);
1619
- React4.useEffect(() => {
1962
+ React5.useEffect(() => {
1620
1963
  if (expanded) return;
1621
1964
  const timers = toasts.filter((t) => !t.leaving && t.duration > 0).map((t) => setTimeout(() => toast.dismiss(t.id), t.duration));
1622
1965
  return () => timers.forEach(clearTimeout);
@@ -1625,7 +1968,7 @@ function Toaster({ className }) {
1625
1968
  const frontH = live[0] ? heights.current.get(live[0].id) || 64 : 64;
1626
1969
  let offset = 0;
1627
1970
  const total = live.slice(0, 5).reduce((a, t) => a + (heights.current.get(t.id) || 64) + GAP, 0);
1628
- return /* @__PURE__ */ React4.createElement(Layer, null, /* @__PURE__ */ React4.createElement(
1971
+ return /* @__PURE__ */ React5.createElement(Layer, null, /* @__PURE__ */ React5.createElement(
1629
1972
  "section",
1630
1973
  {
1631
1974
  "aria-label": "Notifications",
@@ -1667,7 +2010,7 @@ function Toaster({ className }) {
1667
2010
  }
1668
2011
  if (!t.leaving && i >= 0) offset += h + GAP;
1669
2012
  const I = toastIcon[t.tone || "neutral"];
1670
- return /* @__PURE__ */ React4.createElement(
2013
+ return /* @__PURE__ */ React5.createElement(
1671
2014
  "div",
1672
2015
  {
1673
2016
  key: t.id,
@@ -1685,28 +2028,28 @@ function Toaster({ className }) {
1685
2028
  },
1686
2029
  style: { transform: `translateY(${y}) scale(${s})`, opacity: o, boxShadow: sh, zIndex: 100 - Math.max(i, 0), height: behind ? frontH : void 0, pointerEvents: o ? void 0 : "none" }
1687
2030
  },
1688
- /* @__PURE__ */ React4.createElement("span", { className: "alt-toast-icon" }, /* @__PURE__ */ React4.createElement(I, { size: 18 })),
1689
- /* @__PURE__ */ React4.createElement("div", { className: "alt-toast-body" }, /* @__PURE__ */ React4.createElement("p", { className: "alt-toast-title" }, t.title), t.description && /* @__PURE__ */ React4.createElement("p", { className: "alt-toast-desc" }, t.description)),
1690
- t.action && /* @__PURE__ */ React4.createElement(Button, { size: "sm", variant: "secondary", className: "alt-toast-action", onClick: () => {
2031
+ /* @__PURE__ */ React5.createElement("span", { className: "alt-toast-icon" }, /* @__PURE__ */ React5.createElement(I, { size: 18 })),
2032
+ /* @__PURE__ */ React5.createElement("div", { className: "alt-toast-body" }, /* @__PURE__ */ React5.createElement("p", { className: "alt-toast-title" }, t.title), t.description && /* @__PURE__ */ React5.createElement("p", { className: "alt-toast-desc" }, t.description)),
2033
+ t.action && /* @__PURE__ */ React5.createElement(Button, { size: "sm", variant: "secondary", className: "alt-toast-action", onClick: () => {
1691
2034
  t.action.onClick();
1692
2035
  toast.dismiss(t.id);
1693
2036
  } }, t.action.label),
1694
- /* @__PURE__ */ React4.createElement("button", { type: "button", className: "alt-toast-close", "aria-label": "Dismiss", onClick: () => toast.dismiss(t.id) }, /* @__PURE__ */ React4.createElement(Icons.X, { size: 14 }))
2037
+ /* @__PURE__ */ React5.createElement("button", { type: "button", className: "alt-toast-close", "aria-label": "Dismiss", onClick: () => toast.dismiss(t.id) }, /* @__PURE__ */ React5.createElement(Icons.X, { size: 14 }))
1695
2038
  );
1696
2039
  })
1697
2040
  ));
1698
2041
  }
1699
2042
 
1700
2043
  // project/components/src/nav.tsx
1701
- import * as React5 from "react";
2044
+ import * as React6 from "react";
1702
2045
  function Drilldown({ root, className, ...rest }) {
1703
- const [path, setPath] = React5.useState([root]);
1704
- const [dir, setDir] = React5.useState("down");
1705
- const [out, setOut] = React5.useState(null);
1706
- const view = React5.useRef(null);
2046
+ const [path, setPath] = React6.useState([root]);
2047
+ const [dir, setDir] = React6.useState("down");
2048
+ const [out, setOut] = React6.useState(null);
2049
+ const view = React6.useRef(null);
1707
2050
  const depth = path.length - 1;
1708
2051
  const current = path[depth];
1709
- React5.useEffect(() => {
2052
+ React6.useEffect(() => {
1710
2053
  if (!out) return;
1711
2054
  const t = setTimeout(() => setOut(null), 220);
1712
2055
  return () => clearTimeout(t);
@@ -1722,18 +2065,18 @@ function Drilldown({ root, className, ...rest }) {
1722
2065
  setOut(current);
1723
2066
  setPath(path.slice(0, i + 1));
1724
2067
  };
1725
- React5.useEffect(() => {
2068
+ React6.useEffect(() => {
1726
2069
  view.current?.focus({ preventScroll: true });
1727
2070
  }, [current.id]);
1728
- const render = (node) => node.children?.length ? /* @__PURE__ */ React5.createElement("ul", { className: "alt-drill-list" }, node.children.map((c) => /* @__PURE__ */ React5.createElement("li", { key: c.id }, /* @__PURE__ */ React5.createElement("button", { type: "button", className: "alt-drill-row", onClick: () => go(c) }, /* @__PURE__ */ React5.createElement("span", { className: "alt-drill-row-text" }, /* @__PURE__ */ React5.createElement("span", { className: "alt-drill-row-title" }, c.title), c.description && /* @__PURE__ */ React5.createElement("span", { className: "alt-drill-row-desc" }, c.description)), c.children?.length ? /* @__PURE__ */ React5.createElement("span", { className: "alt-drill-count" }, c.children.length) : null, /* @__PURE__ */ React5.createElement(Icons.ChevronDown, { className: "alt-drill-chev", size: 16 }))))) : /* @__PURE__ */ React5.createElement("div", { className: "alt-drill-leaf" }, node.content);
2071
+ const render = (node) => node.children?.length ? /* @__PURE__ */ React6.createElement("ul", { className: "alt-drill-list" }, node.children.map((c) => /* @__PURE__ */ React6.createElement("li", { key: c.id }, /* @__PURE__ */ React6.createElement("button", { type: "button", className: "alt-drill-row", onClick: () => go(c) }, /* @__PURE__ */ React6.createElement("span", { className: "alt-drill-row-text" }, /* @__PURE__ */ React6.createElement("span", { className: "alt-drill-row-title" }, c.title), c.description && /* @__PURE__ */ React6.createElement("span", { className: "alt-drill-row-desc" }, c.description)), c.children?.length ? /* @__PURE__ */ React6.createElement("span", { className: "alt-drill-count" }, c.children.length) : null, /* @__PURE__ */ React6.createElement(Icons.ChevronDown, { className: "alt-drill-chev", size: 16 }))))) : /* @__PURE__ */ React6.createElement("div", { className: "alt-drill-leaf" }, node.content);
1729
2072
  const sheets = Math.min(depth, 3);
1730
- return /* @__PURE__ */ React5.createElement("div", { className: cx("alt-drill", className), "data-dir": dir, ...rest }, /* @__PURE__ */ React5.createElement("nav", { className: "alt-crumbs", "aria-label": "Location" }, /* @__PURE__ */ React5.createElement("ol", null, path.map((n, i) => /* @__PURE__ */ React5.createElement("li", { key: n.id, "data-d": Math.min(i, 3), style: { ["--d"]: i, zIndex: i + 1 }, "data-current": i === depth ? "" : void 0, "data-new": i === depth && dir === "down" && i > 0 ? "" : void 0 }, /* @__PURE__ */ React5.createElement("button", { type: "button", onClick: () => back(i), "aria-current": i === depth ? "location" : void 0 }, n.title))))), /* @__PURE__ */ React5.createElement("div", { className: "alt-pile alt-drill-pile", "data-sheets": sheets }, Array.from({ length: sheets }, (_, i) => /* @__PURE__ */ React5.createElement("span", { key: i, className: "alt-pile-sheet", "aria-hidden": "true", style: { ["--i"]: i + 1 } })), /* @__PURE__ */ React5.createElement("div", { className: "alt-pile-top alt-drill-stage" }, out && /* @__PURE__ */ React5.createElement("div", { key: "out-" + out.id, className: "alt-drill-view", "data-phase": "out", "aria-hidden": "true" }, render(out)), /* @__PURE__ */ React5.createElement("div", { key: current.id, ref: view, tabIndex: -1, className: "alt-drill-view", "data-phase": "in", "aria-label": typeof current.title === "string" ? current.title : void 0 }, render(current)))));
2073
+ return /* @__PURE__ */ React6.createElement("div", { className: cx("alt-drill", className), "data-dir": dir, ...rest }, /* @__PURE__ */ React6.createElement("nav", { className: "alt-crumbs", "aria-label": "Location" }, /* @__PURE__ */ React6.createElement("ol", null, path.map((n, i) => /* @__PURE__ */ React6.createElement("li", { key: n.id, "data-d": Math.min(i, 3), style: { ["--d"]: i, zIndex: i + 1 }, "data-current": i === depth ? "" : void 0, "data-new": i === depth && dir === "down" && i > 0 ? "" : void 0 }, /* @__PURE__ */ React6.createElement("button", { type: "button", onClick: () => back(i), "aria-current": i === depth ? "location" : void 0 }, n.title))))), /* @__PURE__ */ React6.createElement("div", { className: "alt-pile alt-drill-pile", "data-sheets": sheets }, Array.from({ length: sheets }, (_, i) => /* @__PURE__ */ React6.createElement("span", { key: i, className: "alt-pile-sheet", "aria-hidden": "true", style: { ["--i"]: i + 1 } })), /* @__PURE__ */ React6.createElement("div", { className: "alt-pile-top alt-drill-stage" }, out && /* @__PURE__ */ React6.createElement("div", { key: "out-" + out.id, className: "alt-drill-view", "data-phase": "out", "aria-hidden": "true" }, render(out)), /* @__PURE__ */ React6.createElement("div", { key: current.id, ref: view, tabIndex: -1, className: "alt-drill-view", "data-phase": "in", "aria-label": typeof current.title === "string" ? current.title : void 0 }, render(current)))));
1731
2074
  }
1732
2075
 
1733
2076
  // project/components/src/sheet.tsx
1734
- import * as React6 from "react";
2077
+ import * as React7 from "react";
1735
2078
  var EXIT_42 = 190;
1736
- var SheetCtx = React6.createContext(null);
2079
+ var SheetCtx = React7.createContext(null);
1737
2080
  function Sheet({
1738
2081
  open,
1739
2082
  defaultOpen = false,
@@ -1749,28 +2092,28 @@ function Sheet({
1749
2092
  ...rest
1750
2093
  }) {
1751
2094
  const [isOpen, set] = useControllable(open, defaultOpen, onOpenChange);
1752
- const panel = React6.useRef(null);
1753
- const scroller = React6.useRef(null);
1754
- const inner = React6.useRef(null);
1755
- const id = React6.useId();
1756
- const [titled, setTitled] = React6.useState(false);
1757
- const [described, setDescribed] = React6.useState(false);
1758
- const [edges, setEdges] = React6.useState({ top: false, bottom: false });
1759
- const [drag, setDrag] = React6.useState(null);
1760
- const pull = React6.useRef(null);
1761
- const [panelEl, setPanelEl] = React6.useState(null);
1762
- const panelRef = React6.useCallback((el) => {
2095
+ const panel = React7.useRef(null);
2096
+ const scroller = React7.useRef(null);
2097
+ const inner = React7.useRef(null);
2098
+ const id = React7.useId();
2099
+ const [titled, setTitled] = React7.useState(false);
2100
+ const [described, setDescribed] = React7.useState(false);
2101
+ const [edges, setEdges] = React7.useState({ top: false, bottom: false });
2102
+ const [drag, setDrag] = React7.useState(null);
2103
+ const pull = React7.useRef(null);
2104
+ const [panelEl, setPanelEl] = React7.useState(null);
2105
+ const panelRef = React7.useCallback((el) => {
1763
2106
  panel.current = el;
1764
2107
  setPanelEl(el);
1765
2108
  }, []);
1766
- const underSummit = React6.useMemo(() => isOpen && summitTaken(), [isOpen]);
1767
- const close = React6.useCallback(() => set(false), [set]);
2109
+ const underSummit = React7.useMemo(() => isOpen && summitTaken(), [isOpen]);
2110
+ const close = React7.useCallback(() => set(false), [set]);
1768
2111
  const { mounted, state, onKeyDown } = useModal({ open: isOpen, onDismiss: close, exitMs: EXIT_42, panel, modal, dismissible, autoFocus: !underSummit });
1769
2112
  useApproach(side === "bottom" && dismissible);
1770
- React6.useEffect(() => {
2113
+ React7.useEffect(() => {
1771
2114
  if (isOpen) setDrag(null);
1772
2115
  }, [isOpen]);
1773
- const measure = React6.useCallback(() => {
2116
+ const measure = React7.useCallback(() => {
1774
2117
  const el = scroller.current;
1775
2118
  if (!el) return;
1776
2119
  const top = el.scrollTop > 1, bottom = el.scrollTop + el.clientHeight < el.scrollHeight - 1;
@@ -1806,17 +2149,17 @@ function Sheet({
1806
2149
  close();
1807
2150
  } else setDrag(null);
1808
2151
  };
1809
- const ctx = React6.useMemo(() => ({ titleId: `${id}-t`, descId: `${id}-d`, setTitled, setDescribed }), [id]);
2152
+ const ctx = React7.useMemo(() => ({ titleId: `${id}-t`, descId: `${id}-d`, setTitled, setDescribed }), [id]);
1810
2153
  const dragging = !!drag && !drag.leaving && !!pull.current;
1811
2154
  const dragStyle = drag ? drag.leaving ? { transform: `translateY(${drag.dy + 24}px)` } : { transform: `translateY(${drag.dy}px)`, transition: dragging ? "none" : void 0 } : void 0;
1812
- return /* @__PURE__ */ React6.createElement(React6.Fragment, null, trigger && React6.cloneElement(trigger, {
2155
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, trigger && React7.cloneElement(trigger, {
1813
2156
  "aria-haspopup": "dialog",
1814
2157
  "aria-expanded": isOpen,
1815
2158
  onClick: (e) => {
1816
2159
  trigger.props.onClick?.(e);
1817
2160
  set(modal ? true : !isOpen);
1818
2161
  }
1819
- }), mounted && /* @__PURE__ */ React6.createElement(Layer, null, /* @__PURE__ */ React6.createElement(SheetCtx.Provider, { value: ctx }, /* @__PURE__ */ React6.createElement("div", { className: "alt-sheet-root", "data-state": state, "data-exit": !isOpen ? "" : void 0, "data-modal": modal ? "" : void 0, onKeyDown }, modal && /* @__PURE__ */ React6.createElement("div", { className: "alt-scrim", onClick: () => dismissible && close() }), /* @__PURE__ */ React6.createElement(
2162
+ }), mounted && /* @__PURE__ */ React7.createElement(Layer, null, /* @__PURE__ */ React7.createElement(SheetCtx.Provider, { value: ctx }, /* @__PURE__ */ React7.createElement("div", { className: "alt-sheet-root", "data-state": state, "data-exit": !isOpen ? "" : void 0, "data-modal": modal ? "" : void 0, onKeyDown }, modal && /* @__PURE__ */ React7.createElement("div", { className: "alt-scrim", onClick: () => dismissible && close() }), /* @__PURE__ */ React7.createElement(
1820
2163
  "div",
1821
2164
  {
1822
2165
  ref: panelRef,
@@ -1834,7 +2177,7 @@ function Sheet({
1834
2177
  style: { ...style, ...dragStyle },
1835
2178
  ...rest
1836
2179
  },
1837
- side === "bottom" && dismissible && /* @__PURE__ */ React6.createElement(
2180
+ side === "bottom" && dismissible && /* @__PURE__ */ React7.createElement(
1838
2181
  "span",
1839
2182
  {
1840
2183
  className: "alt-sheet-pull",
@@ -1846,35 +2189,35 @@ function Sheet({
1846
2189
  onPointerCancel: onPullUp
1847
2190
  }
1848
2191
  ),
1849
- /* @__PURE__ */ React6.createElement("div", { className: "alt-sheet-scroll", ref: scroller, onScroll: measure }, /* @__PURE__ */ React6.createElement("div", { className: "alt-sheet-inner", ref: inner }, children)),
1850
- dismissible && /* @__PURE__ */ React6.createElement(Button, { variant: "ghost", size: "sm", square: true, "aria-label": "Close", className: "alt-sheet-close", onClick: close }, /* @__PURE__ */ React6.createElement(Icons.X, null))
2192
+ /* @__PURE__ */ React7.createElement("div", { className: "alt-sheet-scroll", ref: scroller, onScroll: measure }, /* @__PURE__ */ React7.createElement("div", { className: "alt-sheet-inner", ref: inner }, children)),
2193
+ dismissible && /* @__PURE__ */ React7.createElement(Button, { variant: "ghost", size: "sm", square: true, "aria-label": "Close", className: "alt-sheet-close", onClick: close }, /* @__PURE__ */ React7.createElement(Icons.X, null))
1851
2194
  )))));
1852
2195
  }
1853
2196
  function SheetHeader({ className, ...p }) {
1854
- return /* @__PURE__ */ React6.createElement("div", { className: cx("alt-sheet-header", className), ...p });
2197
+ return /* @__PURE__ */ React7.createElement("div", { className: cx("alt-sheet-header", className), ...p });
1855
2198
  }
1856
2199
  function SheetTitle({ className, ...p }) {
1857
- const c = React6.useContext(SheetCtx);
1858
- React6.useEffect(() => {
2200
+ const c = React7.useContext(SheetCtx);
2201
+ React7.useEffect(() => {
1859
2202
  c?.setTitled(true);
1860
2203
  return () => c?.setTitled(false);
1861
2204
  }, [c]);
1862
- return /* @__PURE__ */ React6.createElement("h2", { id: c?.titleId, className: cx("alt-sheet-title", className), ...p });
2205
+ return /* @__PURE__ */ React7.createElement("h2", { id: c?.titleId, className: cx("alt-sheet-title", className), ...p });
1863
2206
  }
1864
2207
  function SheetDescription({ className, ...p }) {
1865
- const c = React6.useContext(SheetCtx);
1866
- React6.useEffect(() => {
2208
+ const c = React7.useContext(SheetCtx);
2209
+ React7.useEffect(() => {
1867
2210
  c?.setDescribed(true);
1868
2211
  return () => c?.setDescribed(false);
1869
2212
  }, [c]);
1870
- return /* @__PURE__ */ React6.createElement("p", { id: c?.descId, className: cx("alt-sheet-desc", className), ...p });
2213
+ return /* @__PURE__ */ React7.createElement("p", { id: c?.descId, className: cx("alt-sheet-desc", className), ...p });
1871
2214
  }
1872
2215
  function SheetFooter({ className, ...p }) {
1873
- return /* @__PURE__ */ React6.createElement("div", { className: cx("alt-sheet-footer", className), ...p });
2216
+ return /* @__PURE__ */ React7.createElement("div", { className: cx("alt-sheet-footer", className), ...p });
1874
2217
  }
1875
2218
 
1876
2219
  // project/components/src/command.tsx
1877
- import * as React7 from "react";
2220
+ import * as React8 from "react";
1878
2221
  var EXIT_52 = 220;
1879
2222
  function commandScore(text, query) {
1880
2223
  const t = text.toLowerCase(), q = query.toLowerCase().trim();
@@ -1925,18 +2268,18 @@ function matchRanges(label, query) {
1925
2268
  return out;
1926
2269
  }
1927
2270
  function Marked({ text, ranges }) {
1928
- if (!ranges.length) return /* @__PURE__ */ React7.createElement(React7.Fragment, null, text);
2271
+ if (!ranges.length) return /* @__PURE__ */ React8.createElement(React8.Fragment, null, text);
1929
2272
  const parts = [];
1930
2273
  let i = 0;
1931
2274
  ranges.forEach(([a, b], k) => {
1932
2275
  if (a > i) parts.push(text.slice(i, a));
1933
- parts.push(/* @__PURE__ */ React7.createElement("mark", { key: k, className: "alt-cmd-match" }, text.slice(a, b)));
2276
+ parts.push(/* @__PURE__ */ React8.createElement("mark", { key: k, className: "alt-cmd-match" }, text.slice(a, b)));
1934
2277
  i = b;
1935
2278
  });
1936
2279
  if (i < text.length) parts.push(text.slice(i));
1937
- return /* @__PURE__ */ React7.createElement(React7.Fragment, null, parts);
2280
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, parts);
1938
2281
  }
1939
- var SearchIcon = () => /* @__PURE__ */ React7.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", "aria-hidden": "true" }, /* @__PURE__ */ React7.createElement("circle", { cx: "11", cy: "11", r: "7" }), /* @__PURE__ */ React7.createElement("path", { d: "M20 20l-3.5-3.5" }));
2282
+ var SearchIcon = () => /* @__PURE__ */ React8.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", "aria-hidden": "true" }, /* @__PURE__ */ React8.createElement("circle", { cx: "11", cy: "11", r: "7" }), /* @__PURE__ */ React8.createElement("path", { d: "M20 20l-3.5-3.5" }));
1940
2283
  var ms = (cs, name, fallback) => parseFloat(cs.getPropertyValue(name)) || fallback;
1941
2284
  function CommandPalette({
1942
2285
  items,
@@ -1948,6 +2291,8 @@ function CommandPalette({
1948
2291
  filter,
1949
2292
  empty,
1950
2293
  shortcut = "k",
2294
+ query: queryProp,
2295
+ defaultQuery = "",
1951
2296
  onQueryChange,
1952
2297
  closeOnSelect = true,
1953
2298
  hints = true,
@@ -1955,26 +2300,30 @@ function CommandPalette({
1955
2300
  ...rest
1956
2301
  }) {
1957
2302
  const [isOpen, set] = useControllable(open, defaultOpen, onOpenChange);
1958
- const [query, setQuery] = React7.useState("");
1959
- const [active, setActive] = React7.useState(0);
1960
- const [onset, setOnset] = React7.useState(true);
1961
- const [said, setSaid] = React7.useState("");
1962
- const panel = React7.useRef(null);
1963
- const viewport = React7.useRef(null);
1964
- const list = React7.useRef(null);
1965
- const sizer = React7.useRef(null);
1966
- const rowEls = React7.useRef(/* @__PURE__ */ new Map());
1967
- const prevTops = React7.useRef(null);
1968
- const byKeyboard = React7.useRef(false);
1969
- const [panelEl, setPanelEl] = React7.useState(null);
1970
- const panelRef = React7.useCallback((el) => {
2303
+ const [innerQuery, setInnerQuery] = React8.useState(defaultQuery);
2304
+ const query = queryProp ?? innerQuery;
2305
+ const [active, setActive] = React8.useState(0);
2306
+ const [onset, setOnset] = React8.useState(true);
2307
+ const [said, setSaid] = React8.useState("");
2308
+ const panel = React8.useRef(null);
2309
+ const viewport = React8.useRef(null);
2310
+ const list = React8.useRef(null);
2311
+ const sizer = React8.useRef(null);
2312
+ const rowEls = React8.useRef(/* @__PURE__ */ new Map());
2313
+ const prevTops = React8.useRef(null);
2314
+ const byKeyboard = React8.useRef(false);
2315
+ const caretPlaced = React8.useRef(false);
2316
+ const seed = React8.useRef(defaultQuery);
2317
+ seed.current = defaultQuery;
2318
+ const [panelEl, setPanelEl] = React8.useState(null);
2319
+ const panelRef = React8.useCallback((el) => {
1971
2320
  panel.current = el;
1972
2321
  setPanelEl(el);
1973
2322
  }, []);
1974
- const id = React7.useId();
1975
- const close = React7.useCallback(() => set(false), [set]);
2323
+ const id = React8.useId();
2324
+ const close = React8.useCallback(() => set(false), [set]);
1976
2325
  const { mounted, state, onKeyDown } = useModal({ open: isOpen, onDismiss: close, exitMs: EXIT_52, panel, summit: true });
1977
- React7.useEffect(() => {
2326
+ React8.useEffect(() => {
1978
2327
  if (!shortcut) return;
1979
2328
  const key = shortcut.toLowerCase();
1980
2329
  const on = (e) => {
@@ -1990,13 +2339,17 @@ function CommandPalette({
1990
2339
  window.addEventListener("keydown", on);
1991
2340
  return () => window.removeEventListener("keydown", on);
1992
2341
  }, [shortcut, isOpen, set]);
1993
- React7.useEffect(() => {
2342
+ React8.useEffect(() => {
1994
2343
  if (isOpen) {
1995
- setQuery("");
2344
+ setInnerQuery(seed.current);
1996
2345
  setActive(0);
1997
2346
  setOnset(true);
2347
+ caretPlaced.current = false;
1998
2348
  }
1999
2349
  }, [isOpen]);
2350
+ React8.useEffect(() => {
2351
+ setActive(0);
2352
+ }, [query]);
2000
2353
  const q = query.trim();
2001
2354
  const score = filter ?? itemScore;
2002
2355
  const view = items.map((g, gi) => {
@@ -2060,14 +2413,14 @@ function CommandPalette({
2060
2413
  ro.disconnect();
2061
2414
  };
2062
2415
  }, [panelEl]);
2063
- const [hl, setHl] = React7.useState(null);
2416
+ const [hl, setHl] = React8.useState(null);
2064
2417
  useIsoLayoutEffect(() => {
2065
2418
  const el = activeRow ? rowEls.current.get(activeRow.key) : null;
2066
2419
  setHl(el ? { y: el.offsetTop, h: el.offsetHeight } : null);
2067
2420
  if (el && byKeyboard.current) el.scrollIntoView({ block: "nearest" });
2068
2421
  byKeyboard.current = false;
2069
2422
  }, [activeRow?.key, rowsKey, panelEl]);
2070
- React7.useEffect(() => {
2423
+ React8.useEffect(() => {
2071
2424
  if (!q) {
2072
2425
  setSaid("");
2073
2426
  return;
@@ -2097,7 +2450,7 @@ function CommandPalette({
2097
2450
  const label = rest["aria-label"] ?? "Command palette";
2098
2451
  const activeIndex = activeRow ? flat.indexOf(activeRow) : -1;
2099
2452
  let n = 0;
2100
- return /* @__PURE__ */ React7.createElement(Layer, null, /* @__PURE__ */ React7.createElement("div", { className: "alt-cmd-root", "data-state": state, onKeyDown }, /* @__PURE__ */ React7.createElement("div", { className: "alt-scrim", onClick: close }), /* @__PURE__ */ React7.createElement("div", { ref: panelRef, role: "dialog", "aria-modal": "true", "aria-label": label, tabIndex: -1, className: cx("alt-cmd", className), "data-ephemeral": ephemeral ? "" : void 0 }, /* @__PURE__ */ React7.createElement("div", { className: "alt-cmd-head" }, /* @__PURE__ */ React7.createElement(
2453
+ return /* @__PURE__ */ React8.createElement(Layer, null, /* @__PURE__ */ React8.createElement("div", { className: "alt-cmd-root", "data-state": state, onKeyDown }, /* @__PURE__ */ React8.createElement("div", { className: "alt-scrim", onClick: close }), /* @__PURE__ */ React8.createElement("div", { ref: panelRef, role: "dialog", "aria-modal": "true", "aria-label": label, tabIndex: -1, className: cx("alt-cmd", className), "data-ephemeral": ephemeral ? "" : void 0 }, /* @__PURE__ */ React8.createElement("div", { className: "alt-cmd-head" }, /* @__PURE__ */ React8.createElement(
2101
2454
  Input,
2102
2455
  {
2103
2456
  className: "alt-cmd-field",
@@ -2111,17 +2464,23 @@ function CommandPalette({
2111
2464
  "aria-controls": `${id}-list`,
2112
2465
  "aria-autocomplete": "list",
2113
2466
  "aria-activedescendant": activeIndex >= 0 ? `${id}-o-${activeIndex}` : void 0,
2114
- leading: /* @__PURE__ */ React7.createElement(SearchIcon, null),
2115
- trailing: /* @__PURE__ */ React7.createElement("span", { "aria-hidden": "true" }, /* @__PURE__ */ React7.createElement(Kbd, null, "esc")),
2467
+ leading: /* @__PURE__ */ React8.createElement(SearchIcon, null),
2468
+ trailing: /* @__PURE__ */ React8.createElement("span", { "aria-hidden": "true" }, /* @__PURE__ */ React8.createElement(Kbd, null, "esc")),
2116
2469
  onChange: (e) => {
2117
- setQuery(e.target.value);
2470
+ setInnerQuery(e.target.value);
2118
2471
  setActive(0);
2119
2472
  setOnset(false);
2120
2473
  onQueryChange?.(e.target.value);
2121
2474
  },
2475
+ onFocus: (e) => {
2476
+ if (caretPlaced.current) return;
2477
+ caretPlaced.current = true;
2478
+ const n2 = e.currentTarget.value.length;
2479
+ e.currentTarget.setSelectionRange(n2, n2);
2480
+ },
2122
2481
  onKeyDown: onInputKeyDown
2123
2482
  }
2124
- )), /* @__PURE__ */ React7.createElement("div", { className: "alt-cmd-viewport", ref: viewport }, /* @__PURE__ */ React7.createElement("div", { ref: sizer }, /* @__PURE__ */ React7.createElement("div", { className: "alt-cmd-list", ref: list, role: "listbox", id: `${id}-list`, "aria-label": "Results" }, /* @__PURE__ */ React7.createElement(
2483
+ )), /* @__PURE__ */ React8.createElement("div", { className: "alt-cmd-viewport", ref: viewport }, /* @__PURE__ */ React8.createElement("div", { ref: sizer }, /* @__PURE__ */ React8.createElement("div", { className: "alt-cmd-list", ref: list, role: "listbox", id: `${id}-list`, "aria-label": "Results" }, /* @__PURE__ */ React8.createElement(
2125
2484
  "span",
2126
2485
  {
2127
2486
  className: "alt-cmd-hl",
@@ -2132,10 +2491,10 @@ function CommandPalette({
2132
2491
  ), view.map((v) => {
2133
2492
  const labelId = `${id}-g-${v.gi}`;
2134
2493
  const groupPredicted = !!v.g.predicted || v.rows.every((r) => r.item.predicted);
2135
- return /* @__PURE__ */ React7.createElement("div", { key: v.gk, role: "group", "aria-labelledby": v.g.label ? labelId : void 0, className: "alt-cmd-group" }, v.g.label && /* @__PURE__ */ React7.createElement("div", { id: labelId, role: "presentation", className: "alt-cmd-label", "data-flip": "g:" + v.gk, "data-predicted": groupPredicted ? "" : void 0 }, v.g.label), v.rows.map(() => {
2494
+ return /* @__PURE__ */ React8.createElement("div", { key: v.gk, role: "group", "aria-labelledby": v.g.label ? labelId : void 0, className: "alt-cmd-group" }, v.g.label && /* @__PURE__ */ React8.createElement("div", { id: labelId, role: "presentation", className: "alt-cmd-label", "data-flip": "g:" + v.gk, "data-predicted": groupPredicted ? "" : void 0 }, v.g.label), v.rows.map(() => {
2136
2495
  const i = n++, r = flat[i], item = r.item;
2137
2496
  const on = r === activeRow;
2138
- return /* @__PURE__ */ React7.createElement(
2497
+ return /* @__PURE__ */ React8.createElement(
2139
2498
  "div",
2140
2499
  {
2141
2500
  key: r.key,
@@ -2156,16 +2515,16 @@ function CommandPalette({
2156
2515
  },
2157
2516
  onClick: () => choose(r)
2158
2517
  },
2159
- item.icon && /* @__PURE__ */ React7.createElement("span", { className: "alt-cmd-icon", "aria-hidden": "true" }, item.icon),
2160
- /* @__PURE__ */ React7.createElement("span", { className: "alt-cmd-text" }, /* @__PURE__ */ React7.createElement("span", { className: "alt-cmd-title" }, /* @__PURE__ */ React7.createElement(Marked, { text: item.label, ranges: matchRanges(item.label, q) })), item.description && /* @__PURE__ */ React7.createElement("span", { className: "alt-cmd-desc" }, item.description)),
2161
- item.shortcut && /* @__PURE__ */ React7.createElement("span", { className: "alt-cmd-keys" }, item.shortcut.map((k, j) => /* @__PURE__ */ React7.createElement(Kbd, { key: j }, k)))
2518
+ item.icon && /* @__PURE__ */ React8.createElement("span", { className: "alt-cmd-icon", "aria-hidden": "true" }, item.icon),
2519
+ /* @__PURE__ */ React8.createElement("span", { className: "alt-cmd-text" }, /* @__PURE__ */ React8.createElement("span", { className: "alt-cmd-title" }, /* @__PURE__ */ React8.createElement(Marked, { text: item.label, ranges: matchRanges(item.label, q) })), item.description && /* @__PURE__ */ React8.createElement("span", { className: "alt-cmd-desc" }, item.description)),
2520
+ item.shortcut && /* @__PURE__ */ React8.createElement("span", { className: "alt-cmd-keys" }, item.shortcut.map((k, j) => /* @__PURE__ */ React8.createElement(Kbd, { key: j }, k)))
2162
2521
  );
2163
2522
  }));
2164
- })), q && !flat.length && /* @__PURE__ */ React7.createElement("div", { className: "alt-cmd-empty" }, typeof empty === "function" ? empty(q) : empty ?? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement("b", null, "No results for \u201C", q, "\u201D"), "Try another word, or check the spelling.")))), hints && /* @__PURE__ */ React7.createElement("div", { className: "alt-cmd-foot", "aria-hidden": "true" }, /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement(Kbd, null, "\u2191"), /* @__PURE__ */ React7.createElement(Kbd, null, "\u2193"), "Move"), /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement(Kbd, null, "\u21B5"), "Choose"), /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement(Kbd, null, "esc"), "Close")), /* @__PURE__ */ React7.createElement("span", { className: "alt-sr", "aria-live": "polite" }, said))));
2523
+ })), q && !flat.length && /* @__PURE__ */ React8.createElement("div", { className: "alt-cmd-empty" }, typeof empty === "function" ? empty(q) : empty ?? /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement("b", null, "No results for \u201C", q, "\u201D"), "Try another word, or check the spelling.")))), hints && /* @__PURE__ */ React8.createElement("div", { className: "alt-cmd-foot", "aria-hidden": "true" }, /* @__PURE__ */ React8.createElement("span", null, /* @__PURE__ */ React8.createElement(Kbd, null, "\u2191"), /* @__PURE__ */ React8.createElement(Kbd, null, "\u2193"), "Move"), /* @__PURE__ */ React8.createElement("span", null, /* @__PURE__ */ React8.createElement(Kbd, null, "\u21B5"), "Choose"), /* @__PURE__ */ React8.createElement("span", null, /* @__PURE__ */ React8.createElement(Kbd, null, "esc"), "Close")), /* @__PURE__ */ React8.createElement("span", { className: "alt-sr", "aria-live": "polite" }, said))));
2165
2524
  }
2166
2525
 
2167
2526
  // project/components/src/select.tsx
2168
- import * as React8 from "react";
2527
+ import * as React9 from "react";
2169
2528
  var EXIT_32 = 160;
2170
2529
  function SelectItem(_) {
2171
2530
  return null;
@@ -2174,17 +2533,17 @@ var textOf = (o) => o.textValue ?? (typeof o.label === "string" || typeof o.labe
2174
2533
  function collect(items, children) {
2175
2534
  if (items) return items;
2176
2535
  const out = [];
2177
- React8.Children.forEach(children, (c) => {
2178
- if (!React8.isValidElement(c) || c.type !== SelectItem) return;
2536
+ React9.Children.forEach(children, (c) => {
2537
+ if (!React9.isValidElement(c) || c.type !== SelectItem) return;
2179
2538
  const p = c.props;
2180
2539
  out.push({ value: p.value, label: p.children, textValue: p.textValue, description: p.description, icon: p.icon, disabled: p.disabled });
2181
2540
  });
2182
2541
  return out;
2183
2542
  }
2184
- var Tick = () => /* @__PURE__ */ React8.createElement("svg", { className: "alt-select-tick", viewBox: "0 0 16 16", width: "15", height: "15", fill: "none", stroke: "currentColor", strokeWidth: "2.25", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" }, /* @__PURE__ */ React8.createElement("path", { d: "M3.5 8.5l3 3 6-6.5", pathLength: 16 }));
2185
- var Chevron = () => /* @__PURE__ */ React8.createElement(Icons.ChevronDown, { className: "alt-select-chevron", size: 16 });
2543
+ var Tick = () => /* @__PURE__ */ React9.createElement("svg", { className: "alt-select-tick", viewBox: "0 0 16 16", width: "15", height: "15", fill: "none", stroke: "currentColor", strokeWidth: "2.25", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" }, /* @__PURE__ */ React9.createElement("path", { d: "M3.5 8.5l3 3 6-6.5", pathLength: 16 }));
2544
+ var Chevron = () => /* @__PURE__ */ React9.createElement(Icons.ChevronDown, { className: "alt-select-chevron", size: 16 });
2186
2545
  function useSide(open, anchor, list) {
2187
- const [side, setSide] = React8.useState("bottom");
2546
+ const [side, setSide] = React9.useState("bottom");
2188
2547
  useIsoLayoutEffect(() => {
2189
2548
  if (!open || !anchor.current || !list.current) return;
2190
2549
  const a = anchor.current.getBoundingClientRect(), need = list.current.offsetHeight + 12;
@@ -2202,9 +2561,9 @@ function useSide(open, anchor, list) {
2202
2561
  return side;
2203
2562
  }
2204
2563
  function useGlow(value) {
2205
- const [glow, setGlow] = React8.useState(void 0);
2206
- const first = React8.useRef(true);
2207
- React8.useEffect(() => {
2564
+ const [glow, setGlow] = React9.useState(void 0);
2565
+ const first = React9.useRef(true);
2566
+ React9.useEffect(() => {
2208
2567
  if (first.current) {
2209
2568
  first.current = false;
2210
2569
  return;
@@ -2214,8 +2573,8 @@ function useGlow(value) {
2214
2573
  return glow;
2215
2574
  }
2216
2575
  function useLabelId(controlId, fallback) {
2217
- const [labelId, setLabelId] = React8.useState(void 0);
2218
- React8.useEffect(() => {
2576
+ const [labelId, setLabelId] = React9.useState(void 0);
2577
+ React9.useEffect(() => {
2219
2578
  const label = document.querySelector(`label[for="${CSS.escape(controlId)}"]`);
2220
2579
  if (!label) {
2221
2580
  setLabelId(void 0);
@@ -2227,8 +2586,8 @@ function useLabelId(controlId, fallback) {
2227
2586
  return labelId;
2228
2587
  }
2229
2588
  function OptionList({ id, options, active, value, state, side, query, empty, listRef, labelledBy, label, focusable, onActive, onChoose, onKeyDown }) {
2230
- const rows = React8.useRef([]);
2231
- const [hl, setHl] = React8.useState(null);
2589
+ const rows = React9.useRef([]);
2590
+ const [hl, setHl] = React9.useState(null);
2232
2591
  useIsoLayoutEffect(() => {
2233
2592
  const el = active >= 0 ? rows.current[active] : null;
2234
2593
  setHl(el ? { y: el.offsetTop, h: el.offsetHeight } : null);
@@ -2243,9 +2602,9 @@ function OptionList({ id, options, active, value, state, side, query, empty, lis
2243
2602
  if (!query || typeof o.label !== "string") return o.label;
2244
2603
  const i = t.toLowerCase().indexOf(query.toLowerCase());
2245
2604
  if (i < 0) return o.label;
2246
- return /* @__PURE__ */ React8.createElement(React8.Fragment, null, t.slice(0, i), /* @__PURE__ */ React8.createElement("mark", { className: "alt-cmd-match" }, t.slice(i, i + query.length)), t.slice(i + query.length));
2605
+ return /* @__PURE__ */ React9.createElement(React9.Fragment, null, t.slice(0, i), /* @__PURE__ */ React9.createElement("mark", { className: "alt-cmd-match" }, t.slice(i, i + query.length)), t.slice(i + query.length));
2247
2606
  };
2248
- return /* @__PURE__ */ React8.createElement(
2607
+ return /* @__PURE__ */ React9.createElement(
2249
2608
  "div",
2250
2609
  {
2251
2610
  ref: listRef,
@@ -2261,8 +2620,8 @@ function OptionList({ id, options, active, value, state, side, query, empty, lis
2261
2620
  onKeyDown,
2262
2621
  onMouseDown: (e) => e.preventDefault()
2263
2622
  },
2264
- /* @__PURE__ */ React8.createElement("span", { className: "alt-menu-hl", "aria-hidden": "true", style: hl ? { transform: `translateY(${hl.y}px)`, height: hl.h, opacity: 1 } : { opacity: 0 } }),
2265
- options.map((o, i) => /* @__PURE__ */ React8.createElement(
2623
+ /* @__PURE__ */ React9.createElement("span", { className: "alt-menu-hl", "aria-hidden": "true", style: hl ? { transform: `translateY(${hl.y}px)`, height: hl.h, opacity: 1 } : { opacity: 0 } }),
2624
+ options.map((o, i) => /* @__PURE__ */ React9.createElement(
2266
2625
  "div",
2267
2626
  {
2268
2627
  key: o.value,
@@ -2281,11 +2640,11 @@ function OptionList({ id, options, active, value, state, side, query, empty, lis
2281
2640
  },
2282
2641
  onClick: () => onChoose(i)
2283
2642
  },
2284
- o.icon && /* @__PURE__ */ React8.createElement("span", { className: "alt-menu-icon" }, o.icon),
2285
- /* @__PURE__ */ React8.createElement("span", { className: "alt-menu-text" }, marks(o), o.description && /* @__PURE__ */ React8.createElement("span", { className: "alt-select-desc" }, o.description)),
2286
- o.value === value && /* @__PURE__ */ React8.createElement(Tick, null)
2643
+ o.icon && /* @__PURE__ */ React9.createElement("span", { className: "alt-menu-icon" }, o.icon),
2644
+ /* @__PURE__ */ React9.createElement("span", { className: "alt-menu-text" }, marks(o), o.description && /* @__PURE__ */ React9.createElement("span", { className: "alt-select-desc" }, o.description)),
2645
+ o.value === value && /* @__PURE__ */ React9.createElement(Tick, null)
2287
2646
  )),
2288
- !options.length && /* @__PURE__ */ React8.createElement("div", { className: "alt-select-empty" }, empty)
2647
+ !options.length && /* @__PURE__ */ React9.createElement("div", { className: "alt-select-empty" }, empty)
2289
2648
  );
2290
2649
  }
2291
2650
  function Select({
@@ -2307,16 +2666,16 @@ function Select({
2307
2666
  }) {
2308
2667
  const options = collect(items, children);
2309
2668
  const [v, set] = useControllable(value, defaultValue, onValueChange);
2310
- const [open, setOpen] = React8.useState(defaultOpen);
2311
- const [active, setActive] = React8.useState(() => defaultOpen ? options.findIndex((o) => o.value === (value ?? defaultValue)) : -1);
2312
- const auto = React8.useId();
2669
+ const [open, setOpen] = React9.useState(defaultOpen);
2670
+ const [active, setActive] = React9.useState(() => defaultOpen ? options.findIndex((o) => o.value === (value ?? defaultValue)) : -1);
2671
+ const auto = React9.useId();
2313
2672
  const triggerId = id ?? auto + "-trigger";
2314
2673
  const listId = auto + "-list";
2315
- const root = React8.useRef(null);
2316
- const field = React8.useRef(null);
2317
- const trigger = React8.useRef(null);
2318
- const list = React8.useRef(null);
2319
- const typed = React8.useRef({ text: "", at: 0 });
2674
+ const root = React9.useRef(null);
2675
+ const field = React9.useRef(null);
2676
+ const trigger = React9.useRef(null);
2677
+ const list = React9.useRef(null);
2678
+ const typed = React9.useRef({ text: "", at: 0 });
2320
2679
  const { mounted, state } = usePresence(open, EXIT_32);
2321
2680
  const side = useSide(mounted, field, list);
2322
2681
  const glow = useGlow(v);
@@ -2325,12 +2684,12 @@ function Select({
2325
2684
  useKeyFocus();
2326
2685
  const chosen = options.find((o) => o.value === v);
2327
2686
  const enabled = options.map((o, i) => o.disabled ? -1 : i).filter((i) => i >= 0);
2328
- const close = React8.useCallback((refocus = true) => {
2687
+ const close = React9.useCallback((refocus = true) => {
2329
2688
  setOpen(false);
2330
2689
  if (refocus) trigger.current?.focus({ preventScroll: true });
2331
2690
  }, []);
2332
2691
  useOutside(root, open, () => close(false));
2333
- React8.useEffect(() => {
2692
+ React9.useEffect(() => {
2334
2693
  if (state === "open") list.current?.focus({ preventScroll: true });
2335
2694
  }, [state]);
2336
2695
  const openAt = (i) => {
@@ -2402,7 +2761,7 @@ function Select({
2402
2761
  }
2403
2762
  }
2404
2763
  };
2405
- return /* @__PURE__ */ React8.createElement("div", { ref: root, className: cx("alt-select", className), "data-open": open ? "" : void 0 }, /* @__PURE__ */ React8.createElement(
2764
+ return /* @__PURE__ */ React9.createElement("div", { ref: root, className: cx("alt-select", className), "data-open": open ? "" : void 0 }, /* @__PURE__ */ React9.createElement(
2406
2765
  "div",
2407
2766
  {
2408
2767
  ref: field,
@@ -2413,7 +2772,7 @@ function Select({
2413
2772
  "data-invalid": invalid ? "" : void 0,
2414
2773
  "data-disabled": disabled ? "" : void 0
2415
2774
  },
2416
- /* @__PURE__ */ React8.createElement(
2775
+ /* @__PURE__ */ React9.createElement(
2417
2776
  "button",
2418
2777
  {
2419
2778
  ref: trigger,
@@ -2430,10 +2789,10 @@ function Select({
2430
2789
  onClick: () => open ? close() : openAt(current()),
2431
2790
  onKeyDown: onTriggerKey
2432
2791
  },
2433
- /* @__PURE__ */ React8.createElement("span", { className: "alt-select-value", "data-placeholder": chosen ? void 0 : "", "data-glow": glow }, chosen ? /* @__PURE__ */ React8.createElement(React8.Fragment, null, chosen.icon && /* @__PURE__ */ React8.createElement("span", { className: "alt-select-icon" }, chosen.icon), chosen.label) : placeholder),
2434
- /* @__PURE__ */ React8.createElement(Chevron, null)
2792
+ /* @__PURE__ */ React9.createElement("span", { className: "alt-select-value", "data-placeholder": chosen ? void 0 : "", "data-glow": glow }, chosen ? /* @__PURE__ */ React9.createElement(React9.Fragment, null, chosen.icon && /* @__PURE__ */ React9.createElement("span", { className: "alt-select-icon" }, chosen.icon), chosen.label) : placeholder),
2793
+ /* @__PURE__ */ React9.createElement(Chevron, null)
2435
2794
  )
2436
- ), name && /* @__PURE__ */ React8.createElement("input", { type: "hidden", name, value: v }), mounted && /* @__PURE__ */ React8.createElement(
2795
+ ), name && /* @__PURE__ */ React9.createElement("input", { type: "hidden", name, value: v }), mounted && /* @__PURE__ */ React9.createElement(
2437
2796
  OptionList,
2438
2797
  {
2439
2798
  id: listId,
@@ -2472,24 +2831,24 @@ function Combobox({
2472
2831
  }) {
2473
2832
  const [v, set] = useControllable(value, defaultValue, onValueChange);
2474
2833
  const chosen = items.find((o) => o.value === v);
2475
- const [text, setText] = React8.useState(chosen ? textOf(chosen) : "");
2476
- const [typing, setTyping] = React8.useState(false);
2477
- const [open, setOpen] = React8.useState(defaultOpen);
2478
- const [active, setActive] = React8.useState(() => defaultOpen ? items.findIndex((o) => o.value === (value ?? defaultValue)) : -1);
2479
- const auto = React8.useId();
2834
+ const [text, setText] = React9.useState(chosen ? textOf(chosen) : "");
2835
+ const [typing, setTyping] = React9.useState(false);
2836
+ const [open, setOpen] = React9.useState(defaultOpen);
2837
+ const [active, setActive] = React9.useState(() => defaultOpen ? items.findIndex((o) => o.value === (value ?? defaultValue)) : -1);
2838
+ const auto = React9.useId();
2480
2839
  const inputId = id ?? auto + "-input";
2481
2840
  const listId = auto + "-list";
2482
- const root = React8.useRef(null);
2483
- const field = React8.useRef(null);
2484
- const input = React8.useRef(null);
2485
- const list = React8.useRef(null);
2841
+ const root = React9.useRef(null);
2842
+ const field = React9.useRef(null);
2843
+ const input = React9.useRef(null);
2844
+ const list = React9.useRef(null);
2486
2845
  const { mounted, state } = usePresence(open, EXIT_32);
2487
2846
  const side = useSide(mounted, field, list);
2488
2847
  const glow = useGlow(v);
2489
2848
  const labelId = useLabelId(inputId, auto + "-label");
2490
2849
  useApproach();
2491
2850
  useKeyFocus();
2492
- React8.useEffect(() => {
2851
+ React9.useEffect(() => {
2493
2852
  if (!typing) setText(chosen ? textOf(chosen) : "");
2494
2853
  }, [v]);
2495
2854
  const q = typing ? text.trim() : "";
@@ -2556,7 +2915,7 @@ function Combobox({
2556
2915
  if (!root.current?.contains(e.relatedTarget)) commit();
2557
2916
  };
2558
2917
  const filled = !!chosen && !typing;
2559
- return /* @__PURE__ */ React8.createElement("div", { ref: root, className: cx("alt-select alt-combobox", className), "data-open": open ? "" : void 0 }, /* @__PURE__ */ React8.createElement(
2918
+ return /* @__PURE__ */ React9.createElement("div", { ref: root, className: cx("alt-select alt-combobox", className), "data-open": open ? "" : void 0 }, /* @__PURE__ */ React9.createElement(
2560
2919
  "div",
2561
2920
  {
2562
2921
  ref: field,
@@ -2567,7 +2926,7 @@ function Combobox({
2567
2926
  "data-invalid": invalid ? "" : void 0,
2568
2927
  "data-disabled": disabled ? "" : void 0
2569
2928
  },
2570
- /* @__PURE__ */ React8.createElement(
2929
+ /* @__PURE__ */ React9.createElement(
2571
2930
  "input",
2572
2931
  {
2573
2932
  ref: input,
@@ -2597,7 +2956,7 @@ function Combobox({
2597
2956
  }
2598
2957
  }
2599
2958
  ),
2600
- /* @__PURE__ */ React8.createElement(
2959
+ /* @__PURE__ */ React9.createElement(
2601
2960
  "button",
2602
2961
  {
2603
2962
  type: "button",
@@ -2618,9 +2977,9 @@ function Combobox({
2618
2977
  input.current?.focus();
2619
2978
  }
2620
2979
  },
2621
- /* @__PURE__ */ React8.createElement(Chevron, null)
2980
+ /* @__PURE__ */ React9.createElement(Chevron, null)
2622
2981
  )
2623
- ), name && /* @__PURE__ */ React8.createElement("input", { type: "hidden", name, value: v }), mounted && /* @__PURE__ */ React8.createElement(
2982
+ ), name && /* @__PURE__ */ React9.createElement("input", { type: "hidden", name, value: v }), mounted && /* @__PURE__ */ React9.createElement(
2624
2983
  OptionList,
2625
2984
  {
2626
2985
  id: listId,
@@ -2642,30 +3001,30 @@ function Combobox({
2642
3001
  }
2643
3002
 
2644
3003
  // project/components/src/stepper.tsx
2645
- import * as React9 from "react";
2646
- var Tick2 = () => /* @__PURE__ */ React9.createElement("svg", { viewBox: "0 0 16 16", width: "13", height: "13", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" }, /* @__PURE__ */ React9.createElement("path", { d: "M3.5 8.5l3 3 6-6.5", pathLength: 16 }));
3004
+ import * as React10 from "react";
3005
+ var Tick2 = () => /* @__PURE__ */ React10.createElement("svg", { viewBox: "0 0 16 16", width: "13", height: "13", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" }, /* @__PURE__ */ React10.createElement("path", { d: "M3.5 8.5l3 3 6-6.5", pathLength: 16 }));
2647
3006
  var word = { done: "completed", current: "current", upcoming: "not started" };
2648
3007
  function Stepper({ steps, current, onStepChange, orientation = "horizontal", className, ...rest }) {
2649
- const [seen, setSeen] = React9.useState(current);
2650
- const [motion, setMotion] = React9.useState(null);
2651
- const [said, setSaid] = React9.useState("");
3008
+ const [seen, setSeen] = React10.useState(current);
3009
+ const [motion, setMotion] = React10.useState(null);
3010
+ const [said, setSaid] = React10.useState("");
2652
3011
  if (seen !== current) {
2653
3012
  setSeen(current);
2654
3013
  setMotion({ pressed: seen, risen: current, stamp: current > seen ? seen : -1, delay: (current > seen ? 150 : 60) + riseDelay(), key: (motion?.key ?? 0) + 1 });
2655
3014
  }
2656
- React9.useEffect(() => {
3015
+ React10.useEffect(() => {
2657
3016
  if (!motion) return;
2658
3017
  const t = steps[current];
2659
3018
  setSaid(t ? `Step ${current + 1} of ${steps.length}: ${typeof t.title === "string" ? t.title : ""}` : "All steps complete");
2660
3019
  const done = setTimeout(() => setMotion(null), 900);
2661
3020
  return () => clearTimeout(done);
2662
3021
  }, [motion?.key]);
2663
- return /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement("ol", { className: cx("alt-stepper", className), "data-orientation": orientation, "aria-label": rest["aria-label"] ?? "Progress", ...rest }, steps.map((s, i) => {
3022
+ return /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement("ol", { className: cx("alt-stepper", className), "data-orientation": orientation, "aria-label": rest["aria-label"] ?? "Progress", ...rest }, steps.map((s, i) => {
2664
3023
  const state = i < current ? "done" : i === current ? "current" : "upcoming";
2665
3024
  const back = state === "done" && !!onStepChange;
2666
3025
  const rising = motion && motion.risen === i;
2667
3026
  const stamped = motion && motion.stamp === i;
2668
- return /* @__PURE__ */ React9.createElement("li", { key: s.id ?? i, className: "alt-step-item", "data-state": state, "aria-current": state === "current" ? "step" : void 0 }, /* @__PURE__ */ React9.createElement(
3027
+ return /* @__PURE__ */ React10.createElement("li", { key: s.id ?? i, className: "alt-step-item", "data-state": state, "aria-current": state === "current" ? "step" : void 0 }, /* @__PURE__ */ React10.createElement(
2669
3028
  "div",
2670
3029
  {
2671
3030
  className: "alt-step",
@@ -2684,14 +3043,59 @@ function Stepper({ steps, current, onStepChange, orientation = "horizontal", cla
2684
3043
  } : {},
2685
3044
  style: rising ? { ["--alt-rise-delay"]: motion.delay + "ms" } : void 0
2686
3045
  },
2687
- /* @__PURE__ */ React9.createElement("span", { className: "alt-step-mark", "data-stamp": stamped ? motion.key % 2 ? "a" : "b" : void 0 }, state === "done" ? /* @__PURE__ */ React9.createElement(Tick2, null) : i + 1),
2688
- /* @__PURE__ */ React9.createElement("span", { className: "alt-step-text" }, /* @__PURE__ */ React9.createElement("span", { className: "alt-sr" }, "Step ", i + 1, " of ", steps.length, ", ", word[state], ": "), /* @__PURE__ */ React9.createElement("span", { className: "alt-step-title" }, s.title), s.description && /* @__PURE__ */ React9.createElement("span", { className: "alt-step-desc" }, s.description))
2689
- ), i < steps.length - 1 && /* @__PURE__ */ React9.createElement("span", { className: "alt-step-line", "aria-hidden": "true", "data-done": i < current ? "" : void 0 }));
2690
- })), /* @__PURE__ */ React9.createElement("span", { className: "alt-sr", "aria-live": "polite" }, said));
3046
+ /* @__PURE__ */ React10.createElement("span", { className: "alt-step-mark", "data-stamp": stamped ? motion.key % 2 ? "a" : "b" : void 0 }, state === "done" ? /* @__PURE__ */ React10.createElement(Tick2, null) : i + 1),
3047
+ /* @__PURE__ */ React10.createElement("span", { className: "alt-step-text" }, /* @__PURE__ */ React10.createElement("span", { className: "alt-sr" }, "Step ", i + 1, " of ", steps.length, ", ", word[state], ": "), /* @__PURE__ */ React10.createElement("span", { className: "alt-step-title" }, s.title), s.description && /* @__PURE__ */ React10.createElement("span", { className: "alt-step-desc" }, s.description))
3048
+ ), i < steps.length - 1 && /* @__PURE__ */ React10.createElement("span", { className: "alt-step-line", "aria-hidden": "true", "data-done": i < current ? "" : void 0 }));
3049
+ })), /* @__PURE__ */ React10.createElement("span", { className: "alt-sr", "aria-live": "polite" }, said));
3050
+ }
3051
+
3052
+ // project/components/src/empty.tsx
3053
+ import * as React11 from "react";
3054
+ function EmptyState({
3055
+ icon: icon2,
3056
+ title,
3057
+ description,
3058
+ action,
3059
+ secondary,
3060
+ size = "md",
3061
+ headingLevel = 3,
3062
+ announce,
3063
+ className,
3064
+ children,
3065
+ ...rest
3066
+ }) {
3067
+ const id = React11.useId();
3068
+ const H = `h${headingLevel}`;
3069
+ const words = typeof announce === "string" ? announce : announce && typeof title === "string" ? title : "";
3070
+ const [said, setSaid] = React11.useState("");
3071
+ React11.useEffect(() => {
3072
+ if (!words) {
3073
+ setSaid("");
3074
+ return;
3075
+ }
3076
+ const t = setTimeout(() => setSaid(words), 100);
3077
+ return () => clearTimeout(t);
3078
+ }, [words]);
3079
+ return /* @__PURE__ */ React11.createElement(
3080
+ "section",
3081
+ {
3082
+ className: cx("alt-empty", className),
3083
+ "data-size": size,
3084
+ "aria-labelledby": `${id}-t`,
3085
+ "aria-describedby": description ? `${id}-d` : void 0,
3086
+ ...rest
3087
+ },
3088
+ icon2 && /* @__PURE__ */ React11.createElement("span", { className: "alt-empty-icon", "aria-hidden": "true" }, icon2),
3089
+ /* @__PURE__ */ React11.createElement(H, { id: `${id}-t`, className: "alt-empty-title" }, title),
3090
+ description && /* @__PURE__ */ React11.createElement("p", { id: `${id}-d`, className: "alt-empty-desc" }, description),
3091
+ children,
3092
+ (action || secondary) && /* @__PURE__ */ React11.createElement("div", { className: "alt-empty-actions" }, action, secondary),
3093
+ announce && /* @__PURE__ */ React11.createElement("span", { className: "alt-sr", "aria-live": "polite" }, said)
3094
+ );
2691
3095
  }
2692
3096
 
2693
3097
  // project/components/src/collections.tsx
2694
- import * as React10 from "react";
3098
+ import * as React12 from "react";
2695
3099
  var dropSnapshots = /* @__PURE__ */ new WeakMap();
2696
3100
  var ms2 = (cs, name, fallback) => parseFloat(cs.getPropertyValue(name)) || fallback;
2697
3101
  function pagePlace(el) {
@@ -2713,7 +3117,7 @@ function placeIn(el, host) {
2713
3117
  return { x: a.x - b.x, y: a.y - b.y };
2714
3118
  }
2715
3119
  function useCarry(host, selector, attr, durToken = "--dur-travel-3") {
2716
- const prev = React10.useRef(null);
3120
+ const prev = React12.useRef(null);
2717
3121
  useIsoLayoutEffect(() => {
2718
3122
  const root = host.current;
2719
3123
  if (!root) return;
@@ -2742,12 +3146,12 @@ var moveItem = (arr, from, to) => {
2742
3146
  a.splice(to, 0, x);
2743
3147
  return a;
2744
3148
  };
2745
- var Table = React10.forwardRef(function Table2({ maxHeight, underlay, className, children, ...rest }, ref) {
2746
- const wrap = React10.useRef(null);
2747
- const table = React10.useRef(null);
2748
- React10.useImperativeHandle(ref, () => table.current);
2749
- const [edges, setEdges] = React10.useState({ top: false, bottom: false });
2750
- const measure = React10.useCallback(() => {
3149
+ var Table = React12.forwardRef(function Table2({ maxHeight, underlay, className, children, ...rest }, ref) {
3150
+ const wrap = React12.useRef(null);
3151
+ const table = React12.useRef(null);
3152
+ React12.useImperativeHandle(ref, () => table.current);
3153
+ const [edges, setEdges] = React12.useState({ top: false, bottom: false });
3154
+ const measure = React12.useCallback(() => {
2751
3155
  const el = wrap.current;
2752
3156
  if (!el) return;
2753
3157
  const top = el.scrollTop > 1, bottom = el.scrollTop + el.clientHeight < el.scrollHeight - 1;
@@ -2768,7 +3172,7 @@ var Table = React10.forwardRef(function Table2({ maxHeight, underlay, className,
2768
3172
  }, [measure]);
2769
3173
  useCarry(table, "tbody > tr[data-row]", "data-row");
2770
3174
  const scrolls = maxHeight !== void 0;
2771
- return /* @__PURE__ */ React10.createElement(
3175
+ return /* @__PURE__ */ React12.createElement(
2772
3176
  "div",
2773
3177
  {
2774
3178
  ref: wrap,
@@ -2780,27 +3184,27 @@ var Table = React10.forwardRef(function Table2({ maxHeight, underlay, className,
2780
3184
  ...scrolls ? { tabIndex: 0, role: "region", "aria-label": rest["aria-label"] } : {}
2781
3185
  },
2782
3186
  underlay,
2783
- /* @__PURE__ */ React10.createElement("table", { ref: table, className: cx("alt-table", className), ...rest }, children)
3187
+ /* @__PURE__ */ React12.createElement("table", { ref: table, className: cx("alt-table", className), ...rest }, children)
2784
3188
  );
2785
3189
  });
2786
- var TableHeader = ({ className, ...p }) => /* @__PURE__ */ React10.createElement("thead", { className: cx("alt-table-head", className), ...p });
2787
- var TableBody = React10.forwardRef(function TableBody2({ className, ...p }, ref) {
2788
- return /* @__PURE__ */ React10.createElement("tbody", { ref, className: cx("alt-table-body", className), ...p });
3190
+ var TableHeader = ({ className, ...p }) => /* @__PURE__ */ React12.createElement("thead", { className: cx("alt-table-head", className), ...p });
3191
+ var TableBody = React12.forwardRef(function TableBody2({ className, ...p }, ref) {
3192
+ return /* @__PURE__ */ React12.createElement("tbody", { ref, className: cx("alt-table-body", className), ...p });
2789
3193
  });
2790
- var TableFooter = ({ className, ...p }) => /* @__PURE__ */ React10.createElement("tfoot", { className: cx("alt-table-foot", className), ...p });
2791
- var TableCaption = ({ className, ...p }) => /* @__PURE__ */ React10.createElement("caption", { className: cx("alt-table-caption", className), ...p });
2792
- var TableRow = React10.forwardRef(function TableRow2({ rowId, selected, interactive, relevance, settle, held, className, style, ...rest }, ref) {
2793
- const [glow, setGlow] = React10.useState(void 0);
2794
- const [delay, setDelay] = React10.useState(0);
2795
- const first = React10.useRef(true);
2796
- React10.useEffect(() => {
3194
+ var TableFooter = ({ className, ...p }) => /* @__PURE__ */ React12.createElement("tfoot", { className: cx("alt-table-foot", className), ...p });
3195
+ var TableCaption = ({ className, ...p }) => /* @__PURE__ */ React12.createElement("caption", { className: cx("alt-table-caption", className), ...p });
3196
+ var TableRow = React12.forwardRef(function TableRow2({ rowId, selected, interactive, relevance, settle, held, className, style, ...rest }, ref) {
3197
+ const [glow, setGlow] = React12.useState(void 0);
3198
+ const [delay, setDelay] = React12.useState(0);
3199
+ const first = React12.useRef(true);
3200
+ React12.useEffect(() => {
2797
3201
  const wasFirst = first.current;
2798
3202
  first.current = false;
2799
3203
  if (settle === void 0 || settle === null || settle === false || wasFirst && settle !== true) return;
2800
3204
  setDelay(riseDelay());
2801
3205
  setGlow((g) => g === "a" ? "b" : "a");
2802
3206
  }, [settle]);
2803
- return /* @__PURE__ */ React10.createElement(
3207
+ return /* @__PURE__ */ React12.createElement(
2804
3208
  "tr",
2805
3209
  {
2806
3210
  ref,
@@ -2816,15 +3220,28 @@ var TableRow = React10.forwardRef(function TableRow2({ rowId, selected, interact
2816
3220
  }
2817
3221
  );
2818
3222
  });
2819
- var SortIcon = () => /* @__PURE__ */ React10.createElement("svg", { className: "alt-table-sort-icon", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" }, /* @__PURE__ */ React10.createElement("path", { d: "M6 15l6-6 6 6" }));
3223
+ var SortIcon = () => /* @__PURE__ */ React12.createElement("svg", { className: "alt-table-sort-icon", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true" }, /* @__PURE__ */ React12.createElement("path", { d: "M6 15l6-6 6 6" }));
2820
3224
  function TableHead({ align, sort, onSort, className, children, ...rest }) {
2821
- return /* @__PURE__ */ React10.createElement("th", { scope: "col", className: cx("alt-th", className), "data-align": align, "aria-sort": onSort ? sort ?? "none" : void 0, ...rest }, onSort ? /* @__PURE__ */ React10.createElement("button", { type: "button", className: "alt-table-sort", "data-sort": sort ?? "none", onClick: onSort }, children, /* @__PURE__ */ React10.createElement(SortIcon, null)) : children);
3225
+ return /* @__PURE__ */ React12.createElement("th", { scope: "col", className: cx("alt-th", className), "data-align": align, "aria-sort": onSort ? sort ?? "none" : void 0, ...rest }, onSort ? /* @__PURE__ */ React12.createElement("button", { type: "button", className: "alt-table-sort", "data-sort": sort ?? "none", onClick: onSort }, children, /* @__PURE__ */ React12.createElement(SortIcon, null)) : children);
2822
3226
  }
2823
3227
  function TableCell({ align, className, ...rest }) {
2824
- return /* @__PURE__ */ React10.createElement("td", { className: cx("alt-td", className), "data-align": align, ...rest });
2825
- }
2826
- var GripIcon = () => /* @__PURE__ */ React10.createElement("svg", { width: "12", height: "16", viewBox: "0 0 12 16", fill: "currentColor", "aria-hidden": "true" }, /* @__PURE__ */ React10.createElement("circle", { cx: "3", cy: "3", r: "1.3" }), /* @__PURE__ */ React10.createElement("circle", { cx: "9", cy: "3", r: "1.3" }), /* @__PURE__ */ React10.createElement("circle", { cx: "3", cy: "8", r: "1.3" }), /* @__PURE__ */ React10.createElement("circle", { cx: "9", cy: "8", r: "1.3" }), /* @__PURE__ */ React10.createElement("circle", { cx: "3", cy: "13", r: "1.3" }), /* @__PURE__ */ React10.createElement("circle", { cx: "9", cy: "13", r: "1.3" }));
2827
- function DataTable({
3228
+ return /* @__PURE__ */ React12.createElement("td", { className: cx("alt-td", className), "data-align": align, ...rest });
3229
+ }
3230
+ var GripIcon = () => /* @__PURE__ */ React12.createElement("svg", { width: "12", height: "16", viewBox: "0 0 12 16", fill: "currentColor", "aria-hidden": "true" }, /* @__PURE__ */ React12.createElement("circle", { cx: "3", cy: "3", r: "1.3" }), /* @__PURE__ */ React12.createElement("circle", { cx: "9", cy: "3", r: "1.3" }), /* @__PURE__ */ React12.createElement("circle", { cx: "3", cy: "8", r: "1.3" }), /* @__PURE__ */ React12.createElement("circle", { cx: "9", cy: "8", r: "1.3" }), /* @__PURE__ */ React12.createElement("circle", { cx: "3", cy: "13", r: "1.3" }), /* @__PURE__ */ React12.createElement("circle", { cx: "9", cy: "13", r: "1.3" }));
3231
+ function DataTable({ skeleton, ...props }) {
3232
+ const missing = skeleton !== false && props.rows === void 0;
3233
+ useReportWaiting(missing || skeleton !== false && isPromise(props.rows));
3234
+ const arrival = useArrival(missing);
3235
+ if (!useHasWaited(missing || isPromise(props.rows))) return /* @__PURE__ */ React12.createElement(DataTableFace, { ...props, rows: props.rows ?? [] });
3236
+ const { lines = 5 } = hint(skeleton);
3237
+ const { columns, selectable, toolbar, maxHeight, className } = props;
3238
+ return /* @__PURE__ */ React12.createElement(Await, { shape: "none", enabled: skeleton !== false, imprint: /* @__PURE__ */ React12.createElement("div", { className: cx("alt-data-table", className) }, (selectable || toolbar) && /* @__PURE__ */ React12.createElement("div", { className: "alt-table-tools" }, toolbar && /* @__PURE__ */ React12.createElement("div", { className: "alt-table-tools-end" }, toolbar)), /* @__PURE__ */ React12.createElement(Table, { maxHeight, "aria-label": props["aria-label"] }, /* @__PURE__ */ React12.createElement(TableHeader, null, /* @__PURE__ */ React12.createElement(TableRow, null, selectable && /* @__PURE__ */ React12.createElement(TableHead, { className: "alt-th-check" }, /* @__PURE__ */ React12.createElement("span", { className: "alt-skeleton alt-check-imprint" })), columns.map((c) => /* @__PURE__ */ React12.createElement(TableHead, { key: c.key, align: c.align, style: { width: c.width } }, c.header)))), /* @__PURE__ */ React12.createElement(TableBody, null, Array.from({ length: lines }, (_, i) => /* @__PURE__ */ React12.createElement(TableRow, { key: i }, selectable && /* @__PURE__ */ React12.createElement(TableCell, { className: "alt-td-check" }, /* @__PURE__ */ React12.createElement("span", { className: "alt-skeleton alt-check-imprint" })), columns.map((c, ci) => /* @__PURE__ */ React12.createElement(TableCell, { key: c.key, align: c.align }, /* @__PURE__ */ React12.createElement("span", { className: "alt-skeleton alt-cell-imprint", "data-shape": "text", style: { width: CELL_WIDTHS[(i + ci) % CELL_WIDTHS.length], ["--i"]: i } })))))))) }, /* @__PURE__ */ React12.createElement(Arrive, { when: arrival }, /* @__PURE__ */ React12.createElement(DataTableLanded, { ...props })));
3239
+ }
3240
+ var CELL_WIDTHS = ["72%", "54%", "86%", "63%", "78%"];
3241
+ function DataTableLanded(props) {
3242
+ return /* @__PURE__ */ React12.createElement(DataTableFace, { ...props, rows: readPromised(props.rows) ?? [] });
3243
+ }
3244
+ function DataTableFace({
2828
3245
  columns,
2829
3246
  rows,
2830
3247
  getRowId,
@@ -2848,11 +3265,11 @@ function DataTable({
2848
3265
  }) {
2849
3266
  const [sel, setSel] = useControllable(selected, defaultSelected, onSelectedChange);
2850
3267
  const [srt, setSrt] = useControllable(sort, defaultSort, onSortChange);
2851
- const [said, setSaid] = React10.useState("");
2852
- const table = React10.useRef(null);
2853
- const body = React10.useRef(null);
3268
+ const [said, setSaid] = React12.useState("");
3269
+ const table = React12.useRef(null);
3270
+ const body = React12.useRef(null);
2854
3271
  const name = (r) => getRowLabel?.(r) ?? getRowId(r);
2855
- const view = React10.useMemo(() => {
3272
+ const view = React12.useMemo(() => {
2856
3273
  const col = srt && columns.find((c) => c.key === srt.key);
2857
3274
  if (!srt || !col?.sortValue) return rows;
2858
3275
  const d = srt.direction === "descending" ? -1 : 1;
@@ -2869,9 +3286,9 @@ function DataTable({
2869
3286
  setSaid(next ? `Sorted by ${typeof c.header === "string" ? c.header : c.key}, ${next.direction}.` : "Sort cleared.");
2870
3287
  };
2871
3288
  const toggle = (id, on) => setSel(on ? [...sel.filter((x) => x !== id), id] : sel.filter((x) => x !== id));
2872
- const start = React10.useRef(null);
2873
- const [drag, setDrag] = React10.useState(null);
2874
- const [held, setHeld] = React10.useState(null);
3289
+ const start = React12.useRef(null);
3290
+ const [drag, setDrag] = React12.useState(null);
3291
+ const [held, setHeld] = React12.useState(null);
2875
3292
  const rowEls = () => Array.from(body.current?.querySelectorAll("tr[data-row]") ?? []);
2876
3293
  const snapshot = (at) => {
2877
3294
  if (!table.current) return;
@@ -2941,24 +3358,24 @@ function DataTable({
2941
3358
  setSaid(`Move cancelled; ${name(view[index])} is back at position ${held.origin + 1}.`);
2942
3359
  }
2943
3360
  };
2944
- React10.useEffect(() => {
3361
+ React12.useEffect(() => {
2945
3362
  if (!movable) setHeld(null);
2946
3363
  }, [movable]);
2947
3364
  const s = start.current;
2948
3365
  const h = drag && s ? s.hs[drag.from] : 0;
2949
3366
  const slotTop = drag && s ? drag.to <= drag.from ? s.tops[drag.to] : s.tops[drag.to] + s.hs[drag.to] - s.hs[drag.from] : 0;
2950
3367
  const span = columns.length + (selectable ? 1 : 0) + (movable ? 1 : 0);
2951
- return /* @__PURE__ */ React10.createElement("div", { className: cx("alt-data-table", className) }, (selectable || toolbar) && /* @__PURE__ */ React10.createElement("div", { className: "alt-table-tools" }, sel.length > 0 && /* @__PURE__ */ React10.createElement("div", { className: "alt-table-selection" }, /* @__PURE__ */ React10.createElement(Badge, { variant: "count", tone: "accent", "aria-hidden": "true" }, sel.length), /* @__PURE__ */ React10.createElement("span", null, "selected"), actions?.(sel), /* @__PURE__ */ React10.createElement(Button, { size: "sm", variant: "ghost", onClick: () => setSel([]) }, "Clear")), toolbar && /* @__PURE__ */ React10.createElement("div", { className: "alt-table-tools-end" }, toolbar)), /* @__PURE__ */ React10.createElement(
3368
+ return /* @__PURE__ */ React12.createElement("div", { className: cx("alt-data-table", className) }, (selectable || toolbar) && /* @__PURE__ */ React12.createElement("div", { className: "alt-table-tools" }, sel.length > 0 && /* @__PURE__ */ React12.createElement("div", { className: "alt-table-selection" }, /* @__PURE__ */ React12.createElement(Badge, { variant: "count", tone: "accent", "aria-hidden": "true" }, sel.length), /* @__PURE__ */ React12.createElement("span", null, "selected"), actions?.(sel), /* @__PURE__ */ React12.createElement(Button, { size: "sm", variant: "ghost", onClick: () => setSel([]) }, "Clear")), toolbar && /* @__PURE__ */ React12.createElement("div", { className: "alt-table-tools-end" }, toolbar)), /* @__PURE__ */ React12.createElement(
2952
3369
  Table,
2953
3370
  {
2954
3371
  ref: table,
2955
3372
  maxHeight,
2956
3373
  "aria-label": rest["aria-label"],
2957
3374
  "data-dragging": drag ? "" : void 0,
2958
- underlay: drag && s ? /* @__PURE__ */ React10.createElement("span", { className: "alt-table-slot", "aria-hidden": "true", style: { top: slotTop + (table.current?.offsetTop ?? 0), height: h } }) : null
3375
+ underlay: drag && s ? /* @__PURE__ */ React12.createElement("span", { className: "alt-table-slot", "aria-hidden": "true", style: { top: slotTop + (table.current?.offsetTop ?? 0), height: h } }) : null
2959
3376
  },
2960
- /* @__PURE__ */ React10.createElement(TableHeader, null, /* @__PURE__ */ React10.createElement(TableRow, null, movable && /* @__PURE__ */ React10.createElement(TableHead, { className: "alt-th-grip" }, /* @__PURE__ */ React10.createElement("span", { className: "alt-sr" }, "Move")), selectable && /* @__PURE__ */ React10.createElement(TableHead, { className: "alt-th-check" }, /* @__PURE__ */ React10.createElement(Checkbox, { "aria-label": "Select all rows", checked: all, indeterminate: some, onCheckedChange: (on) => setSel(on ? Array.from(/* @__PURE__ */ new Set([...sel, ...ids])) : sel.filter((x) => !ids.includes(x))) })), columns.map((c) => /* @__PURE__ */ React10.createElement(TableHead, { key: c.key, align: c.align, style: { width: c.width }, sort: srt?.key === c.key ? srt.direction : "none", onSort: c.sortValue ? () => cycle(c) : void 0 }, c.header)))),
2961
- /* @__PURE__ */ React10.createElement(TableBody, { ref: body }, !view.length && /* @__PURE__ */ React10.createElement("tr", null, /* @__PURE__ */ React10.createElement("td", { className: "alt-td alt-table-empty", colSpan: span }, empty)), view.map((r, i) => {
3377
+ /* @__PURE__ */ React12.createElement(TableHeader, null, /* @__PURE__ */ React12.createElement(TableRow, null, movable && /* @__PURE__ */ React12.createElement(TableHead, { className: "alt-th-grip" }, /* @__PURE__ */ React12.createElement("span", { className: "alt-sr" }, "Move")), selectable && /* @__PURE__ */ React12.createElement(TableHead, { className: "alt-th-check" }, /* @__PURE__ */ React12.createElement(Checkbox, { "aria-label": "Select all rows", checked: all, indeterminate: some, onCheckedChange: (on) => setSel(on ? Array.from(/* @__PURE__ */ new Set([...sel, ...ids])) : sel.filter((x) => !ids.includes(x))) })), columns.map((c) => /* @__PURE__ */ React12.createElement(TableHead, { key: c.key, align: c.align, style: { width: c.width }, sort: srt?.key === c.key ? srt.direction : "none", onSort: c.sortValue ? () => cycle(c) : void 0 }, c.header)))),
3378
+ /* @__PURE__ */ React12.createElement(TableBody, { ref: body }, !view.length && /* @__PURE__ */ React12.createElement("tr", null, /* @__PURE__ */ React12.createElement("td", { className: "alt-td alt-table-empty", colSpan: span }, empty)), view.map((r, i) => {
2962
3379
  const id = ids[i];
2963
3380
  let shift = 0;
2964
3381
  if (drag && id !== drag.id && h) {
@@ -2966,7 +3383,7 @@ function DataTable({
2966
3383
  if (drag.to < drag.from && i >= drag.to && i < drag.from) shift = h;
2967
3384
  }
2968
3385
  const following = drag?.id === id;
2969
- return /* @__PURE__ */ React10.createElement(
3386
+ return /* @__PURE__ */ React12.createElement(
2970
3387
  TableRow,
2971
3388
  {
2972
3389
  key: id,
@@ -2981,7 +3398,7 @@ function DataTable({
2981
3398
  if (!e.target.closest("button, a, input, label, select, textarea")) onRowClick(r);
2982
3399
  } : void 0
2983
3400
  },
2984
- movable && /* @__PURE__ */ React10.createElement(TableCell, { className: "alt-td-grip" }, /* @__PURE__ */ React10.createElement(
3401
+ movable && /* @__PURE__ */ React12.createElement(TableCell, { className: "alt-td-grip" }, /* @__PURE__ */ React12.createElement(
2985
3402
  "button",
2986
3403
  {
2987
3404
  type: "button",
@@ -2997,18 +3414,18 @@ function DataTable({
2997
3414
  if (held?.id === id && !drag) setTimeout(() => setHeld((x) => x?.id === id && document.activeElement?.closest(`tr[data-row="${CSS.escape(id)}"]`) === null ? null : x), 0);
2998
3415
  }
2999
3416
  },
3000
- /* @__PURE__ */ React10.createElement(GripIcon, null)
3417
+ /* @__PURE__ */ React12.createElement(GripIcon, null)
3001
3418
  )),
3002
- selectable && /* @__PURE__ */ React10.createElement(TableCell, { className: "alt-td-check" }, /* @__PURE__ */ React10.createElement(Checkbox, { "aria-label": `Select ${name(r)}`, checked: chosen.has(id), onCheckedChange: (on) => toggle(id, on) })),
3419
+ selectable && /* @__PURE__ */ React12.createElement(TableCell, { className: "alt-td-check" }, /* @__PURE__ */ React12.createElement(Checkbox, { "aria-label": `Select ${name(r)}`, checked: chosen.has(id), onCheckedChange: (on) => toggle(id, on) })),
3003
3420
  columns.map((c, ci) => {
3004
3421
  const content = c.cell ? c.cell(r) : String(r[c.key] ?? "");
3005
- return /* @__PURE__ */ React10.createElement(TableCell, { key: c.key, align: c.align }, onRowClick && ci === 0 ? /* @__PURE__ */ React10.createElement("button", { type: "button", className: "alt-table-rowbtn", onClick: () => onRowClick(r) }, content) : content);
3422
+ return /* @__PURE__ */ React12.createElement(TableCell, { key: c.key, align: c.align }, onRowClick && ci === 0 ? /* @__PURE__ */ React12.createElement("button", { type: "button", className: "alt-table-rowbtn", onClick: () => onRowClick(r) }, content) : content);
3006
3423
  })
3007
3424
  );
3008
3425
  }))
3009
- ), /* @__PURE__ */ React10.createElement("span", { className: "alt-sr", "aria-live": "polite" }, selectable && sel.length ? `${sel.length} selected. ` : "", said));
3426
+ ), /* @__PURE__ */ React12.createElement("span", { className: "alt-sr", "aria-live": "polite" }, selectable && sel.length ? `${sel.length} selected. ` : "", said));
3010
3427
  }
3011
- var BoardCtx = React10.createContext(null);
3428
+ var BoardCtx = React12.createContext(null);
3012
3429
  function readBoard(root) {
3013
3430
  return Array.from(root.querySelectorAll("[data-board-col]")).map((col) => {
3014
3431
  const list = col.querySelector(".alt-board-list");
@@ -3055,18 +3472,18 @@ function plan(cols, id, cx2, cy, h) {
3055
3472
  }
3056
3473
  return { to: { column: tc.id, index }, shifts, slotTop, gap: tc.gap };
3057
3474
  }
3058
- var Board = React10.forwardRef(function Board2({ onMove, className, children, ...rest }, ref) {
3059
- const root = React10.useRef(null);
3060
- React10.useImperativeHandle(ref, () => root.current);
3061
- const hintId = React10.useId();
3062
- const [carry, setCarry] = React10.useState(null);
3063
- const [kb, setKb] = React10.useState(null);
3064
- const [landing, setLanding] = React10.useState(null);
3065
- const [said, setSaid] = React10.useState("");
3066
- const start = React10.useRef(null);
3067
- const dragged = React10.useRef(false);
3475
+ var Board = React12.forwardRef(function Board2({ onMove, className, children, ...rest }, ref) {
3476
+ const root = React12.useRef(null);
3477
+ React12.useImperativeHandle(ref, () => root.current);
3478
+ const hintId = React12.useId();
3479
+ const [carry, setCarry] = React12.useState(null);
3480
+ const [kb, setKb] = React12.useState(null);
3481
+ const [landing, setLanding] = React12.useState(null);
3482
+ const [said, setSaid] = React12.useState("");
3483
+ const start = React12.useRef(null);
3484
+ const dragged = React12.useRef(false);
3068
3485
  useCarry(root, "[data-board-card]", "data-board-card");
3069
- React10.useEffect(() => {
3486
+ React12.useEffect(() => {
3070
3487
  if (!landing) return;
3071
3488
  const t = setTimeout(() => setLanding(null), 450);
3072
3489
  return () => clearTimeout(t);
@@ -3195,17 +3612,17 @@ var Board = React10.forwardRef(function Board2({ onMove, className, children, ..
3195
3612
  return d;
3196
3613
  };
3197
3614
  const ctx = { carry, kb, landing, hintId, onPointerDown, onPointerMove, onPointerUp, onKeyDown, onBlur, swallowClick };
3198
- return /* @__PURE__ */ React10.createElement(BoardCtx.Provider, { value: ctx }, /* @__PURE__ */ React10.createElement("div", { ref: root, role: "group", "aria-label": rest["aria-label"] ?? "Board", className: cx("alt-board", className), "data-carrying": carry || kb ? "" : void 0, ...rest }, children, /* @__PURE__ */ React10.createElement("span", { id: hintId, className: "alt-sr" }, "Press Space to pick up. While holding a card, use the arrow keys to move it, Space to drop it, Escape to cancel."), /* @__PURE__ */ React10.createElement("span", { className: "alt-sr", "aria-live": "assertive" }, said)));
3615
+ return /* @__PURE__ */ React12.createElement(BoardCtx.Provider, { value: ctx }, /* @__PURE__ */ React12.createElement("div", { ref: root, role: "group", "aria-label": rest["aria-label"] ?? "Board", className: cx("alt-board", className), "data-carrying": carry || kb ? "" : void 0, ...rest }, children, /* @__PURE__ */ React12.createElement("span", { id: hintId, className: "alt-sr" }, "Press Space to pick up. While holding a card, use the arrow keys to move it, Space to drop it, Escape to cancel."), /* @__PURE__ */ React12.createElement("span", { className: "alt-sr", "aria-live": "assertive" }, said)));
3199
3616
  });
3200
3617
  function BoardColumn({ id, title, collapsed, defaultCollapsed = false, onCollapsedChange, collapsible, className, children, ...rest }) {
3201
- const ctx = React10.useContext(BoardCtx);
3618
+ const ctx = React12.useContext(BoardCtx);
3202
3619
  const [isCollapsed, setCollapsed] = useControllable(collapsed, defaultCollapsed, onCollapsedChange);
3203
- const count = React10.Children.toArray(children).filter(React10.isValidElement).length;
3620
+ const count = React12.Children.toArray(children).filter(React12.isValidElement).length;
3204
3621
  const label = typeof title === "string" ? title : id;
3205
3622
  const carry = ctx?.carry;
3206
3623
  const over = carry ? carry.to.column === id : ctx?.kb?.at.column === id;
3207
3624
  const receiving = !!carry && carry.to.column === id && carry.from.column !== id && !isCollapsed;
3208
- return /* @__PURE__ */ React10.createElement(
3625
+ return /* @__PURE__ */ React12.createElement(
3209
3626
  "section",
3210
3627
  {
3211
3628
  className: cx("alt-board-col", className),
@@ -3216,7 +3633,7 @@ function BoardColumn({ id, title, collapsed, defaultCollapsed = false, onCollaps
3216
3633
  "data-over": over ? "" : void 0,
3217
3634
  ...rest
3218
3635
  },
3219
- /* @__PURE__ */ React10.createElement("header", { className: "alt-board-head" }, /* @__PURE__ */ React10.createElement("h3", { className: "alt-board-title" }, title), /* @__PURE__ */ React10.createElement("span", { className: "alt-board-count", "aria-label": `${count} ${count === 1 ? "card" : "cards"}` }, count), collapsible && /* @__PURE__ */ React10.createElement(
3636
+ /* @__PURE__ */ React12.createElement("header", { className: "alt-board-head" }, /* @__PURE__ */ React12.createElement("h3", { className: "alt-board-title" }, title), /* @__PURE__ */ React12.createElement("span", { className: "alt-board-count", "aria-label": `${count} ${count === 1 ? "card" : "cards"}` }, count), collapsible && /* @__PURE__ */ React12.createElement(
3220
3637
  Button,
3221
3638
  {
3222
3639
  variant: "ghost",
@@ -3228,20 +3645,20 @@ function BoardColumn({ id, title, collapsed, defaultCollapsed = false, onCollaps
3228
3645
  "data-collapsed": isCollapsed ? "" : void 0,
3229
3646
  onClick: () => setCollapsed(!isCollapsed)
3230
3647
  },
3231
- /* @__PURE__ */ React10.createElement(Icons.ChevronDown, null)
3648
+ /* @__PURE__ */ React12.createElement(Icons.ChevronDown, null)
3232
3649
  )),
3233
- isCollapsed ? /* @__PURE__ */ React10.createElement(Pile, { count: Math.max(count, 1), className: "alt-board-pile" }, /* @__PURE__ */ React10.createElement("div", { className: "alt-board-pile-face" }, /* @__PURE__ */ React10.createElement("b", null, title), /* @__PURE__ */ React10.createElement("span", null, count ? `${count} ${count === 1 ? "card" : "cards"}` : "No cards"))) : /* @__PURE__ */ React10.createElement("div", { className: "alt-board-list", style: receiving ? { paddingBottom: carry.h + carry.gap } : void 0 }, carry && carry.to.column === id && /* @__PURE__ */ React10.createElement("span", { className: "alt-board-slot", "aria-hidden": "true", style: { top: carry.slotTop, height: carry.h } }), children, !count && !carry && /* @__PURE__ */ React10.createElement("div", { className: "alt-board-empty" }, "No cards"))
3650
+ isCollapsed ? /* @__PURE__ */ React12.createElement(Pile, { count: Math.max(count, 1), className: "alt-board-pile" }, /* @__PURE__ */ React12.createElement("div", { className: "alt-board-pile-face" }, /* @__PURE__ */ React12.createElement("b", null, title), /* @__PURE__ */ React12.createElement("span", null, count ? `${count} ${count === 1 ? "card" : "cards"}` : "No cards"))) : /* @__PURE__ */ React12.createElement("div", { className: "alt-board-list", style: receiving ? { paddingBottom: carry.h + carry.gap } : void 0 }, carry && carry.to.column === id && /* @__PURE__ */ React12.createElement("span", { className: "alt-board-slot", "aria-hidden": "true", style: { top: carry.slotTop, height: carry.h } }), children, !count && !carry && /* @__PURE__ */ React12.createElement("div", { className: "alt-board-empty" }, "No cards"))
3234
3651
  );
3235
3652
  }
3236
- var BoardCard = React10.forwardRef(function BoardCard2({ id, label, heldBy, settle, className, style, onClickCapture, children, ...rest }, ref) {
3237
- const ctx = React10.useContext(BoardCtx);
3653
+ var BoardCard = React12.forwardRef(function BoardCard2({ id, label, heldBy, settle, className, style, onClickCapture, children, ...rest }, ref) {
3654
+ const ctx = React12.useContext(BoardCtx);
3238
3655
  const depth = useDepth({ heldBy, settle });
3239
3656
  const carry = ctx?.carry;
3240
3657
  const following = carry?.id === id;
3241
3658
  const carried = following || ctx?.kb?.id === id;
3242
3659
  const shift = carry?.shifts[id];
3243
3660
  const transform = following ? `translate(${carry.dx}px, ${carry.dy}px)` : shift ? `translateY(${shift}px)` : void 0;
3244
- return /* @__PURE__ */ React10.createElement(
3661
+ return /* @__PURE__ */ React12.createElement(
3245
3662
  "div",
3246
3663
  {
3247
3664
  ref,
@@ -3282,6 +3699,7 @@ export {
3282
3699
  AltitudeProvider,
3283
3700
  Avatar,
3284
3701
  AvatarGroup,
3702
+ Await,
3285
3703
  Badge,
3286
3704
  Board,
3287
3705
  BoardCard,
@@ -3301,6 +3719,7 @@ export {
3301
3719
  Drilldown,
3302
3720
  DropZone,
3303
3721
  DropdownMenu,
3722
+ EmptyState,
3304
3723
  Field,
3305
3724
  HoldButton,
3306
3725
  HoverCard,
@@ -3308,11 +3727,13 @@ export {
3308
3727
  Input,
3309
3728
  Kbd,
3310
3729
  Layer,
3730
+ LoadingScope,
3311
3731
  Pile,
3312
3732
  Popover,
3313
3733
  Progress,
3314
3734
  Radio,
3315
3735
  RadioGroup,
3736
+ RevealGroup,
3316
3737
  ScrollArea,
3317
3738
  Select,
3318
3739
  SelectItem,
@@ -3343,9 +3764,11 @@ export {
3343
3764
  Textarea,
3344
3765
  Toaster,
3345
3766
  Tooltip,
3767
+ checkScheme,
3346
3768
  commandScore,
3347
3769
  contrast,
3348
3770
  deriveAccent,
3771
+ readPromised,
3349
3772
  riseDelay,
3350
3773
  toast,
3351
3774
  useAltitude,