[object Object]

← back to Architecturalwallcoverings

revert ux-primitives auto-apply — coordinator gates fan-out (TK-12031)

1cc46af915bcaa6021a0f0534f32acd5f1d42118 · 2026-09-22 16:44:54 -0700 · front-page-steward

Files touched

Diff

commit 1cc46af915bcaa6021a0f0534f32acd5f1d42118
Author: front-page-steward <steve@designerwallcoverings.com>
Date:   Tue Sep 22 16:44:54 2026 -0700

    revert ux-primitives auto-apply — coordinator gates fan-out (TK-12031)
---
 public/index.html               |    3 -
 public/ux-primitives.bundle.css |  764 -------------------------
 public/ux-primitives.bundle.js  | 1207 ---------------------------------------
 3 files changed, 1974 deletions(-)

diff --git a/public/index.html b/public/index.html
index 2384960..5ee90a1 100644
--- a/public/index.html
+++ b/public/index.html
@@ -253,9 +253,6 @@ html.hf-sample  [data-f="sample"]  { display:none !important }
 <!-- noscript fallback is added by set-fb-pixel.sh on flip (omitted here to avoid unflipped img phone-home) -->
 <noscript><img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1431180262113856<!-- End Meta Pixel -->ev=PageView<!-- End Meta Pixel -->noscript=1"/></noscript>
 <!-- End Meta Pixel -->
-  <!-- ux-primitives.bundle v1.0.0#21023ffcfab3 (front-page-steward TK-12031) -->
-  <link rel="stylesheet" href="ux-primitives.bundle.css">
-  <script src="ux-primitives.bundle.js" defer></script>
 </head>
 <body>
 <h1 style="position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0">Architectural Wallcoverings</h1>
diff --git a/public/ux-primitives.bundle.css b/public/ux-primitives.bundle.css
deleted file mode 100644
index e6bb113..0000000
--- a/public/ux-primitives.bundle.css
+++ /dev/null
@@ -1,764 +0,0 @@
-/* ux-primitives.bundle.css — canonical Bundle-B UX primitives (generated 2026-09-22T21:06:28Z)
-   Shared ux-primitives.css tokens (md5 614018b) included ONCE, then each
-   primitive's own CSS. All selectors namespaced .ux-* / .ux-bento* / .ux-modal*
-   so nothing collides with corner-nav (cnav-*), hero-4grid, or site styles.
-   Regenerate via /Users/macstudio3/Projects/_shared/scripts/build-ux-primitives-bundle.sh */
-
-/* ===== shared tokens (ux-primitives.css) ===== */
-/* ============================================================================
-   ux-primitives.css — the SHARED token/base layer for the UX build-feature set
-   (toast-notify · skeleton-loader · empty-state · command-palette ·
-    copy-to-clipboard).
-
-   ONE cohesive design system, not N divergent conventions. Every component in
-   the set reads these `--ux-*` custom properties, so the whole set shares one
-   spacing scale, one radius scale, one color palette, one motion curve, and one
-   dark-mode approach. Load this file ONCE per page (before or after the
-   component CSS — cascade order does not matter for tokens) and every component
-   inherits the same look.
-
-   Resilience: every component ALSO hard-codes a literal fallback in each
-   `var(--ux-*, <fallback>)`, so a component still renders correctly even if this
-   file is not loaded. Loading it is what makes the set cohesive; not loading it
-   just falls back to sensible defaults.
-
-   Theme-agnostic: the tokens themselves fall back to the HOST page's own vars
-   where a page already defines them (--accent, --ink, --card, --line, …), so
-   dropping the set onto an existing themed page inherits that theme with no
-   config. Override any --ux-* on :root (or a subtree) to retheme the whole set.
-
-   Dark mode, three ways (in priority order, last wins):
-     1. default :root palette = LIGHT
-     2. @media (prefers-color-scheme: dark)      → auto dark by OS setting
-     3. [data-theme="dark"] / [data-theme="light"] on <html> → explicit override
-   ============================================================================ */
-
-:root {
-  /* ---- spacing scale (4px base) ---- */
-  --ux-space-0: 0;
-  --ux-space-1: 4px;
-  --ux-space-2: 8px;
-  --ux-space-3: 12px;
-  --ux-space-4: 16px;
-  --ux-space-5: 24px;
-  --ux-space-6: 32px;
-  --ux-space-7: 48px;
-
-  /* ---- radius scale ---- */
-  --ux-radius-sm: 6px;
-  --ux-radius-md: 10px;
-  --ux-radius-lg: 16px;
-  --ux-radius-pill: 999px;
-
-  /* ---- typography ---- */
-  --ux-font: inherit;                 /* inherit the host page's font stack     */
-  --ux-fs-xs: 11px;
-  --ux-fs-sm: 12.5px;
-  --ux-fs-md: 14px;
-  --ux-fs-lg: 16px;
-  --ux-fw-normal: 400;
-  --ux-fw-medium: 550;
-  --ux-fw-bold: 700;
-
-  /* ---- motion ---- */
-  --ux-ease: cubic-bezier(.4, 0, .2, 1);
-  --ux-dur-fast: 120ms;
-  --ux-dur: 200ms;
-  --ux-dur-slow: 320ms;
-
-  /* ---- z-index bands ---- */
-  --ux-z-toast: 2147483000;
-  --ux-z-palette: 2147482000;
-
-  /* ---- semantic colors (LIGHT palette; fall back to any host var first) ---- */
-  --ux-bg:          var(--bg, #ffffff);
-  --ux-surface:     var(--card, #ffffff);
-  --ux-surface-2:   var(--card2, #f3f4f6);
-  --ux-text:        var(--ink, #1a1d24);
-  --ux-text-dim:    var(--mut, var(--muted, #5c6470));
-  --ux-border:      var(--line, rgba(0,0,0,.12));
-  --ux-hover:       var(--hover, rgba(0,0,0,.04));
-  --ux-accent:      var(--accent, var(--blue, #2563eb));
-  --ux-accent-contrast: #ffffff;
-  --ux-focus:       var(--ux-accent, #2563eb);
-
-  /* skeleton shimmer track */
-  --ux-skel-base:   var(--card2, #e6e8ec);
-  --ux-skel-sheen:  rgba(255,255,255,.55);
-
-  /* status colors + subtle tinted backgrounds */
-  --ux-success:     #128a4b;
-  --ux-success-bg:  #e7f6ee;
-  --ux-error:       #c62b34;
-  --ux-error-bg:    #fdeaea;
-  --ux-warn:        #a5730a;
-  --ux-warn-bg:     #fbf1dc;
-  --ux-info:        #2563eb;
-  --ux-info-bg:     #e8effd;
-
-  /* elevation */
-  --ux-shadow-1: 0 1px 2px rgba(0,0,0,.08), 0 2px 8px rgba(0,0,0,.06);
-  --ux-shadow-2: 0 8px 24px rgba(0,0,0,.14), 0 2px 6px rgba(0,0,0,.10);
-
-  color-scheme: light;
-}
-
-/* ---- auto dark by OS, only when the page hasn't forced light ---- */
-@media (prefers-color-scheme: dark) {
-  :root:not([data-theme="light"]) {
-    --ux-bg:          var(--bg, #0d1017);
-    --ux-surface:     var(--card, #161b22);
-    --ux-surface-2:   var(--card2, #21262d);
-    --ux-text:        var(--ink, #e6edf3);
-    --ux-text-dim:    var(--mut, var(--muted, #8b949e));
-    --ux-border:      var(--line, rgba(255,255,255,.12));
-    --ux-hover:       var(--hover, rgba(120,160,255,.08));
-    --ux-accent:      var(--accent, var(--blue, #58a6ff));
-    --ux-accent-contrast: #08111f;
-
-    --ux-skel-base:   var(--card2, #21262d);
-    --ux-skel-sheen:  rgba(255,255,255,.10);
-
-    --ux-success:     #3fb950;  --ux-success-bg: #12281a;
-    --ux-error:       #f85149;  --ux-error-bg:   #2c1416;
-    --ux-warn:        #d29922;  --ux-warn-bg:    #2a2113;
-    --ux-info:        #58a6ff;  --ux-info-bg:    #10233f;
-
-    --ux-shadow-1: 0 1px 2px rgba(0,0,0,.4), 0 2px 8px rgba(0,0,0,.35);
-    --ux-shadow-2: 0 10px 30px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.4);
-
-    color-scheme: dark;
-  }
-}
-
-/* ---- explicit dark override (wins over OS + over light) ---- */
-:root[data-theme="dark"] {
-  --ux-bg:          var(--bg, #0d1017);
-  --ux-surface:     var(--card, #161b22);
-  --ux-surface-2:   var(--card2, #21262d);
-  --ux-text:        var(--ink, #e6edf3);
-  --ux-text-dim:    var(--mut, var(--muted, #8b949e));
-  --ux-border:      var(--line, rgba(255,255,255,.12));
-  --ux-hover:       var(--hover, rgba(120,160,255,.08));
-  --ux-accent:      var(--accent, var(--blue, #58a6ff));
-  --ux-accent-contrast: #08111f;
-
-  --ux-skel-base:   var(--card2, #21262d);
-  --ux-skel-sheen:  rgba(255,255,255,.10);
-
-  --ux-success:     #3fb950;  --ux-success-bg: #12281a;
-  --ux-error:       #f85149;  --ux-error-bg:   #2c1416;
-  --ux-warn:        #d29922;  --ux-warn-bg:    #2a2113;
-  --ux-info:        #58a6ff;  --ux-info-bg:    #10233f;
-
-  --ux-shadow-1: 0 1px 2px rgba(0,0,0,.4), 0 2px 8px rgba(0,0,0,.35);
-  --ux-shadow-2: 0 10px 30px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.4);
-
-  color-scheme: dark;
-}
-
-/* a shared focus ring every component can opt into with .ux-focusable */
-.ux-focusable:focus-visible {
-  outline: 2px solid var(--ux-focus, #2563eb);
-  outline-offset: 2px;
-}
-
-/* ===== toast-notify ===== */
-/* toast-notify.css — transient toast/notification stack.
- * Part of the UX build-feature set; inherits tokens from ux-primitives.css.
- * Every color/space reads a --ux-* token with a literal fallback, so it renders
- * fine standalone but themes cohesively when ux-primitives.css is loaded. */
-
-.ux-toast-region {
-  position: fixed;
-  z-index: var(--ux-z-toast, 2147483000);
-  display: flex;
-  flex-direction: column;
-  gap: var(--ux-space-2, 8px);
-  padding: var(--ux-space-4, 16px);
-  width: min(360px, calc(100vw - 24px));
-  max-height: 100vh;
-  overflow: hidden;
-  pointer-events: none;                 /* region is click-through; toasts opt back in */
-  box-sizing: border-box;
-}
-/* positions (safe-area aware) */
-.ux-toast-region[data-pos^="top"]    { top: 0;    padding-top: calc(var(--ux-space-4,16px) + env(safe-area-inset-top,0px)); }
-.ux-toast-region[data-pos^="bottom"] { bottom: 0; padding-bottom: calc(var(--ux-space-4,16px) + env(safe-area-inset-bottom,0px)); flex-direction: column-reverse; }
-.ux-toast-region[data-pos$="right"]  { right: 0;  align-items: flex-end; }
-.ux-toast-region[data-pos$="left"]   { left: 0;   align-items: flex-start; }
-.ux-toast-region[data-pos$="center"] { left: 50%; transform: translateX(-50%); align-items: center; }
-
-.ux-toast {
-  pointer-events: auto;
-  box-sizing: border-box;
-  width: 100%;
-  display: flex;
-  align-items: flex-start;
-  gap: var(--ux-space-3, 12px);
-  padding: var(--ux-space-3, 12px) var(--ux-space-4, 16px);
-  background: var(--ux-surface, #fff);
-  color: var(--ux-text, #1a1d24);
-  border: 1px solid var(--ux-border, rgba(0,0,0,.12));
-  border-left: 4px solid var(--ux-accent, #2563eb);
-  border-radius: var(--ux-radius-md, 10px);
-  box-shadow: var(--ux-shadow-2, 0 8px 24px rgba(0,0,0,.14));
-  font: var(--ux-fw-normal,400) var(--ux-fs-md,14px)/1.45 var(--ux-font, inherit);
-  transition: transform var(--ux-dur,200ms) var(--ux-ease, ease),
-              opacity var(--ux-dur,200ms) var(--ux-ease, ease);
-}
-/* enter/exit — direction depends on which edge the region sits on */
-.ux-toast[data-state="enter"] { opacity: 0; transform: translateY(-8px) scale(.98); }
-.ux-toast-region[data-pos^="bottom"] .ux-toast[data-state="enter"] { transform: translateY(8px) scale(.98); }
-.ux-toast[data-state="shown"] { opacity: 1; transform: none; }
-.ux-toast[data-state="leave"] { opacity: 0; transform: translateX(12px) scale(.98); }
-.ux-toast-region[data-pos$="left"] .ux-toast[data-state="leave"] { transform: translateX(-12px) scale(.98); }
-.ux-toast-region[data-pos$="center"] .ux-toast[data-state="leave"] { transform: scale(.96); }
-
-/* variant accents */
-.ux-toast--success { border-left-color: var(--ux-success, #128a4b); }
-.ux-toast--error   { border-left-color: var(--ux-error,   #c62b34); }
-.ux-toast--warn    { border-left-color: var(--ux-warn,    #a5730a); }
-.ux-toast--info    { border-left-color: var(--ux-info,    #2563eb); }
-
-.ux-toast__icon {
-  flex: 0 0 auto; width: 20px; height: 20px; margin-top: 1px;
-  display: grid; place-items: center; font-size: 14px; line-height: 1;
-}
-.ux-toast--success .ux-toast__icon { color: var(--ux-success, #128a4b); }
-.ux-toast--error   .ux-toast__icon { color: var(--ux-error,   #c62b34); }
-.ux-toast--warn    .ux-toast__icon { color: var(--ux-warn,    #a5730a); }
-.ux-toast--info    .ux-toast__icon { color: var(--ux-info,    #2563eb); }
-
-.ux-toast__body { flex: 1 1 auto; min-width: 0; }
-.ux-toast__title { font-weight: var(--ux-fw-medium, 550); margin: 0 0 2px; }
-.ux-toast__msg { color: var(--ux-text, #1a1d24); word-wrap: break-word; overflow-wrap: anywhere; }
-.ux-toast__title + .ux-toast__msg { color: var(--ux-text-dim, #5c6470); font-size: var(--ux-fs-sm, 12.5px); }
-
-.ux-toast__close {
-  flex: 0 0 auto;
-  appearance: none; border: 0; background: transparent; cursor: pointer;
-  color: var(--ux-text-dim, #5c6470);
-  font-size: 18px; line-height: 1; padding: 2px 4px; margin: -2px -4px 0 0;
-  border-radius: var(--ux-radius-sm, 6px);
-}
-.ux-toast__close:hover { background: var(--ux-hover, rgba(0,0,0,.06)); color: var(--ux-text, #1a1d24); }
-.ux-toast__close:focus-visible { outline: 2px solid var(--ux-focus, #2563eb); outline-offset: 2px; }
-
-/* auto-dismiss progress bar (thin, under the toast) */
-.ux-toast__bar { position: absolute; left: 0; bottom: 0; height: 2px; width: 100%;
-  background: currentColor; opacity: .35; transform-origin: left; }
-.ux-toast { position: relative; overflow: hidden; }
-
-@media (prefers-reduced-motion: reduce) {
-  .ux-toast { transition: opacity var(--ux-dur,200ms) linear; }
-  .ux-toast[data-state="enter"], .ux-toast[data-state="leave"] { transform: none; }
-  .ux-toast__bar { transition: none !important; }
-}
-
-/* ===== skeleton-loader ===== */
-/* skeleton-loader.css — content-placeholder shimmer skeletons.
- * Part of the UX build-feature set; inherits tokens from ux-primitives.css.
- * Standalone-safe: every --ux-* has a literal fallback. */
-
-.ux-skel {
-  display: block;
-  position: relative;
-  overflow: hidden;
-  background: var(--ux-skel-base, #e6e8ec);
-  border-radius: var(--ux-radius-sm, 6px);
-}
-/* the moving sheen */
-.ux-skel::after {
-  content: "";
-  position: absolute; inset: 0;
-  transform: translateX(-100%);
-  background: linear-gradient(90deg,
-    transparent 0,
-    var(--ux-skel-sheen, rgba(255,255,255,.55)) 50%,
-    transparent 100%);
-  animation: ux-skel-shimmer 1.3s var(--ux-ease, ease) infinite;
-}
-@keyframes ux-skel-shimmer { 100% { transform: translateX(100%); } }
-
-/* ---- primitives ---- */
-.ux-skel--text   { height: .8em; margin: .35em 0; border-radius: var(--ux-radius-sm, 6px); }
-.ux-skel--title  { height: 1.15em; width: 55%; margin: .2em 0 .6em; }
-.ux-skel--avatar { width: 44px; height: 44px; border-radius: var(--ux-radius-pill, 999px); flex: 0 0 auto; }
-.ux-skel--image  { width: 100%; aspect-ratio: 16 / 10; border-radius: var(--ux-radius-md, 10px); }
-.ux-skel--thumb  { width: 56px; height: 56px; border-radius: var(--ux-radius-md, 10px); flex: 0 0 auto; }
-.ux-skel--chip   { height: 22px; width: 64px; border-radius: var(--ux-radius-pill, 999px); }
-.ux-skel--btn    { height: 34px; width: 96px; border-radius: var(--ux-radius-md, 10px); }
-
-/* width helpers for text lines (last line short, like real paragraphs) */
-.ux-skel--w90 { width: 90%; } .ux-skel--w75 { width: 75%; }
-.ux-skel--w60 { width: 60%; } .ux-skel--w40 { width: 40%; }
-
-/* ---- composed blocks ---- */
-.ux-skel-lines { display: block; }
-
-.ux-skel-card {
-  display: block;
-  padding: var(--ux-space-4, 16px);
-  border: 1px solid var(--ux-border, rgba(0,0,0,.12));
-  border-radius: var(--ux-radius-lg, 16px);
-  background: var(--ux-surface, #fff);
-}
-
-.ux-skel-row {
-  display: flex; align-items: center; gap: var(--ux-space-3, 12px);
-  padding: var(--ux-space-3, 12px) 0;
-  border-bottom: 1px solid var(--ux-border, rgba(0,0,0,.10));
-}
-.ux-skel-row__body { flex: 1 1 auto; min-width: 0; }
-
-.ux-skel-media { display: flex; align-items: center; gap: var(--ux-space-3, 12px); }
-.ux-skel-media__body { flex: 1 1 auto; min-width: 0; }
-
-/* content-swap fade: real content fades in when ready */
-[data-ux-skel-host] { position: relative; }
-.ux-skel-in { animation: ux-skel-fadein var(--ux-dur-slow, 320ms) var(--ux-ease, ease) both; }
-@keyframes ux-skel-fadein { from { opacity: 0; } to { opacity: 1; } }
-
-@media (prefers-reduced-motion: reduce) {
-  .ux-skel::after { animation: none; opacity: .5; }
-  .ux-skel-in { animation: none; }
-}
-
-/* ===== empty-state ===== */
-/* empty-state.css — reusable empty / zero-results / error / offline block.
- * Part of the UX build-feature set; inherits tokens from ux-primitives.css.
- * Standalone-safe: every --ux-* has a literal fallback. */
-
-.ux-empty {
-  box-sizing: border-box;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  text-align: center;
-  gap: var(--ux-space-3, 12px);
-  max-width: 420px;
-  margin: 0 auto;
-  padding: var(--ux-space-7, 48px) var(--ux-space-4, 16px);
-  color: var(--ux-text, #1a1d24);
-  font: var(--ux-fw-normal,400) var(--ux-fs-md,14px)/1.5 var(--ux-font, inherit);
-}
-
-.ux-empty__icon {
-  width: 56px; height: 56px;
-  display: grid; place-items: center;
-  border-radius: var(--ux-radius-pill, 999px);
-  background: var(--ux-surface-2, #f3f4f6);
-  color: var(--ux-text-dim, #5c6470);
-  margin-bottom: var(--ux-space-1, 4px);
-}
-.ux-empty__icon svg { width: 28px; height: 28px; display: block; }
-
-/* variant icon tints */
-.ux-empty--error   .ux-empty__icon { background: var(--ux-error-bg,#fdeaea); color: var(--ux-error,#c62b34); }
-.ux-empty--offline .ux-empty__icon { background: var(--ux-warn-bg,#fbf1dc);  color: var(--ux-warn,#a5730a); }
-.ux-empty--no-results .ux-empty__icon,
-.ux-empty--no-data .ux-empty__icon { background: var(--ux-info-bg,#e8effd); color: var(--ux-info,#2563eb); }
-
-.ux-empty__title { margin: 0; font-size: var(--ux-fs-lg, 16px); font-weight: var(--ux-fw-bold, 700); }
-.ux-empty__text  { margin: 0; color: var(--ux-text-dim, #5c6470); }
-
-.ux-empty__actions {
-  display: flex; flex-wrap: wrap; gap: var(--ux-space-2, 8px);
-  justify-content: center; margin-top: var(--ux-space-2, 8px);
-}
-
-.ux-empty__btn {
-  appearance: none; cursor: pointer;
-  font: var(--ux-fw-medium,550) var(--ux-fs-md,14px)/1 var(--ux-font, inherit);
-  padding: 10px 18px;
-  border-radius: var(--ux-radius-md, 10px);
-  border: 1px solid var(--ux-border, rgba(0,0,0,.14));
-  background: var(--ux-surface, #fff);
-  color: var(--ux-text, #1a1d24);
-  text-decoration: none;
-  transition: background var(--ux-dur-fast,120ms) var(--ux-ease, ease),
-              border-color var(--ux-dur-fast,120ms) var(--ux-ease, ease);
-}
-.ux-empty__btn:hover { background: var(--ux-hover, rgba(0,0,0,.05)); }
-.ux-empty__btn:focus-visible { outline: 2px solid var(--ux-focus, #2563eb); outline-offset: 2px; }
-
-.ux-empty__btn--primary {
-  background: var(--ux-accent, #2563eb);
-  border-color: var(--ux-accent, #2563eb);
-  color: var(--ux-accent-contrast, #fff);
-}
-.ux-empty__btn--primary:hover { filter: brightness(1.06); background: var(--ux-accent, #2563eb); }
-
-@media (max-width: 420px) {
-  .ux-empty { padding: var(--ux-space-6, 32px) var(--ux-space-4, 16px); }
-  .ux-empty__actions { flex-direction: column; align-self: stretch; }
-  .ux-empty__btn { width: 100%; }
-}
-
-/* ===== copy-to-clipboard ===== */
-/* copy-to-clipboard.css — copy button + "Copied!" feedback.
- * Part of the UX build-feature set; inherits tokens from ux-primitives.css.
- * OPTIONAL: the JS works on any element; these styles just make a nice button
- * and the inline feedback pill. Standalone-safe: every --ux-* has a fallback. */
-
-.ux-copy {
-  display: inline-flex; align-items: center; gap: var(--ux-space-2, 8px);
-  appearance: none; cursor: pointer;
-  font: var(--ux-fw-medium,550) var(--ux-fs-sm,12.5px)/1 var(--ux-font, inherit);
-  padding: 7px 12px;
-  border-radius: var(--ux-radius-md, 10px);
-  border: 1px solid var(--ux-border, rgba(0,0,0,.14));
-  background: var(--ux-surface, #fff);
-  color: var(--ux-text, #1a1d24);
-  position: relative;
-  transition: background var(--ux-dur-fast,120ms) var(--ux-ease, ease),
-              border-color var(--ux-dur-fast,120ms) var(--ux-ease, ease);
-}
-.ux-copy:hover { background: var(--ux-hover, rgba(0,0,0,.05)); }
-.ux-copy:focus-visible { outline: 2px solid var(--ux-focus, #2563eb); outline-offset: 2px; }
-.ux-copy__ic { width: 15px; height: 15px; flex: 0 0 auto; }
-.ux-copy__ic svg { width: 15px; height: 15px; display: block; }
-
-/* success + error states (toggled briefly by the JS) */
-.ux-copy.is-copied { border-color: var(--ux-success, #128a4b); color: var(--ux-success, #128a4b); }
-.ux-copy.is-error  { border-color: var(--ux-error,   #c62b34); color: var(--ux-error,   #c62b34); }
-
-/* floating "Copied!" pill (inline feedback mode), anchored above the trigger */
-.ux-copy-pill {
-  position: absolute; z-index: var(--ux-z-toast, 2147483000);
-  transform: translate(-50%, -100%);
-  margin-top: -8px;
-  padding: 4px 9px;
-  border-radius: var(--ux-radius-pill, 999px);
-  background: var(--ux-text, #1a1d24);
-  color: var(--ux-bg, #fff);
-  font: var(--ux-fw-medium,550) var(--ux-fs-xs,11px)/1.3 var(--ux-font, inherit);
-  white-space: nowrap;
-  box-shadow: var(--ux-shadow-1, 0 2px 8px rgba(0,0,0,.2));
-  pointer-events: none;
-  opacity: 0; transition: opacity var(--ux-dur-fast,120ms) var(--ux-ease, ease),
-                          transform var(--ux-dur-fast,120ms) var(--ux-ease, ease);
-}
-.ux-copy-pill[data-show="true"] { opacity: 1; transform: translate(-50%, -100%) translateY(-2px); }
-.ux-copy-pill.is-error { background: var(--ux-error, #c62b34); color: #fff; }
-
-@media (prefers-reduced-motion: reduce) {
-  .ux-copy, .ux-copy-pill { transition: opacity var(--ux-dur-fast,120ms) linear; }
-}
-
-/* ===== command-palette ===== */
-/* command-palette.css — cmd-k / ctrl-k command palette.
- * Part of the UX build-feature set; inherits tokens from ux-primitives.css.
- * Standalone-safe: every --ux-* has a literal fallback. */
-
-.ux-cmdk-backdrop {
-  position: fixed; inset: 0;
-  z-index: var(--ux-z-palette, 2147482000);
-  background: rgba(10, 12, 18, .48);
-  backdrop-filter: blur(2px);
-  display: flex; justify-content: center;
-  align-items: flex-start;
-  padding: clamp(24px, 12vh, 140px) 16px 16px;
-  opacity: 0; transition: opacity var(--ux-dur-fast,120ms) var(--ux-ease, ease);
-}
-.ux-cmdk-backdrop[data-open="true"] { opacity: 1; }
-
-.ux-cmdk {
-  box-sizing: border-box;
-  width: min(620px, 100%);
-  max-height: 70vh;
-  display: flex; flex-direction: column;
-  background: var(--ux-surface, #fff);
-  color: var(--ux-text, #1a1d24);
-  border: 1px solid var(--ux-border, rgba(0,0,0,.14));
-  border-radius: var(--ux-radius-lg, 16px);
-  box-shadow: var(--ux-shadow-2, 0 18px 50px rgba(0,0,0,.35));
-  overflow: hidden;
-  transform: translateY(-6px) scale(.99);
-  transition: transform var(--ux-dur,200ms) var(--ux-ease, ease);
-  font: var(--ux-fw-normal,400) var(--ux-fs-md,14px)/1.4 var(--ux-font, inherit);
-}
-.ux-cmdk-backdrop[data-open="true"] .ux-cmdk { transform: none; }
-
-.ux-cmdk__head { display: flex; align-items: center; gap: var(--ux-space-3,12px);
-  padding: var(--ux-space-4,16px); border-bottom: 1px solid var(--ux-border, rgba(0,0,0,.10)); }
-.ux-cmdk__search-ic { flex: 0 0 auto; color: var(--ux-text-dim, #5c6470); display: grid; place-items: center; }
-.ux-cmdk__search-ic svg { width: 18px; height: 18px; display: block; }
-.ux-cmdk__input {
-  flex: 1 1 auto; min-width: 0;
-  appearance: none; border: 0; outline: 0; background: transparent;
-  color: var(--ux-text, #1a1d24);
-  font: var(--ux-fw-normal,400) var(--ux-fs-lg,16px)/1.2 var(--ux-font, inherit);
-}
-.ux-cmdk__input::placeholder { color: var(--ux-text-dim, #8b949e); }
-.ux-cmdk__kbd { flex: 0 0 auto; font-size: 11px; color: var(--ux-text-dim,#8b949e);
-  border: 1px solid var(--ux-border, rgba(0,0,0,.14)); border-radius: var(--ux-radius-sm,6px);
-  padding: 2px 6px; }
-
-.ux-cmdk__list { list-style: none; margin: 0; padding: var(--ux-space-2,8px);
-  overflow-y: auto; flex: 1 1 auto; -webkit-overflow-scrolling: touch; }
-.ux-cmdk__group { padding: var(--ux-space-3,12px) var(--ux-space-3,12px) var(--ux-space-1,4px);
-  font-size: var(--ux-fs-xs,11px); text-transform: uppercase; letter-spacing: .06em;
-  color: var(--ux-text-dim, #8b949e); font-weight: var(--ux-fw-medium,550); }
-
-.ux-cmdk__opt {
-  display: flex; align-items: center; gap: var(--ux-space-3,12px);
-  padding: 10px var(--ux-space-3,12px);
-  border-radius: var(--ux-radius-md, 10px);
-  cursor: pointer; scroll-margin: 8px;
-}
-.ux-cmdk__opt[aria-selected="true"] { background: var(--ux-accent, #2563eb); color: var(--ux-accent-contrast,#fff); }
-.ux-cmdk__opt[aria-selected="true"] .ux-cmdk__sub { color: var(--ux-accent-contrast,#fff); opacity: .85; }
-.ux-cmdk__opt[aria-selected="true"] .ux-cmdk__ic  { color: var(--ux-accent-contrast,#fff); }
-.ux-cmdk__ic { flex: 0 0 auto; width: 20px; text-align: center; color: var(--ux-text-dim,#5c6470); }
-.ux-cmdk__opt-body { flex: 1 1 auto; min-width: 0; }
-.ux-cmdk__title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
-.ux-cmdk__sub { font-size: var(--ux-fs-sm,12.5px); color: var(--ux-text-dim,#8b949e);
-  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
-.ux-cmdk__hint { flex: 0 0 auto; font-size: 11px; color: var(--ux-text-dim,#8b949e); }
-.ux-cmdk__opt[aria-selected="true"] .ux-cmdk__hint { color: var(--ux-accent-contrast,#fff); opacity: .85; }
-
-.ux-cmdk__empty { padding: var(--ux-space-6,32px); text-align: center; color: var(--ux-text-dim,#8b949e); }
-
-@media (max-width: 420px) {
-  .ux-cmdk-backdrop { padding-top: 24px; }
-  .ux-cmdk { max-height: 82vh; }
-  .ux-cmdk__kbd { display: none; }
-}
-@media (prefers-reduced-motion: reduce) {
-  .ux-cmdk-backdrop, .ux-cmdk { transition: opacity var(--ux-dur-fast,120ms) linear; }
-  .ux-cmdk { transform: none; }
-}
-
-/* ===== modal-rig ===== */
-/* ============================================================================
-   modal-rig.css — token-driven styling for ModalRig modals/panels.
-   Part of the UX build-feature set (shares ux-primitives.css `--ux-*` tokens).
-
-   modal-rig.js works with ZERO css (it hard-codes structural inline styles as a
-   fallback), but loading this file makes the modal theme cohesively with the rest
-   of the set and inherit the host page's dark-mode + accent. Every rule below is
-   namespaced `.ux-modal*` so it cannot clobber existing site styles.
-   ============================================================================ */
-
-.ux-modal-backdrop {
-  position: fixed;
-  inset: 0;
-  z-index: var(--ux-z-palette, 2147482000);
-  background: rgba(0, 0, 0, .5);
-}
-
-.ux-modal {
-  display: flex;
-  flex-direction: column;
-  min-width: 340px;
-  min-height: 180px;
-  background: var(--ux-surface, #fff);
-  color: var(--ux-text, #1a1d24);
-  border: 1px solid var(--ux-border, rgba(0, 0, 0, .12));
-  border-radius: var(--ux-radius-md, 10px);
-  box-shadow: var(--ux-shadow-2, 0 16px 56px rgba(0, 0, 0, .6));
-  font: var(--ux-font, inherit);
-}
-
-.ux-modal__head {
-  flex: 0 0 auto;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  gap: var(--ux-space-2, 8px);
-  padding: var(--ux-space-3, 12px) var(--ux-space-4, 16px);
-  border-bottom: 1px solid var(--ux-border, rgba(0, 0, 0, .12));
-  background: var(--ux-surface-2, #f3f4f6);
-  border-radius: var(--ux-radius-md, 10px) var(--ux-radius-md, 10px) 0 0;
-}
-
-.ux-modal__title {
-  font-weight: var(--ux-fw-medium, 550);
-  font-size: var(--ux-fs-sm, 12.5px);
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.ux-modal__btns {
-  flex: 0 0 auto;
-  display: flex;
-  align-items: center;
-}
-
-.ux-modal__btn {
-  cursor: pointer;
-  opacity: .7;
-  line-height: 1;
-  margin-left: var(--ux-space-2, 8px);
-  background: none;
-  border: 0;
-  color: inherit;
-  font-size: 14px;
-  transition: opacity var(--ux-dur-fast, 120ms) var(--ux-ease, ease);
-}
-.ux-modal__btn:hover { opacity: 1; }
-.ux-modal__close { font-size: 18px; }
-
-.ux-modal__body {
-  flex: 1 1 auto;
-  overflow: auto;
-  padding: var(--ux-space-4, 16px) var(--ux-space-5, 24px);
-}
-
-/* the corner resize grip is native (resize:both); nudge its color for visibility */
-.ux-modal { resize: both; }
-
-@media (prefers-reduced-motion: reduce) {
-  .ux-modal__btn { transition: none; }
-}
-
-/* ===== bento-grid ===== */
-/* ============================================================================
-   bento-grid.css — a zero-dependency editorial "bento box" layout system.
-   Namespaced .ux-bento / .ux-bento-item so it can't clobber existing site CSS.
-   Part of the UX build-feature set — its knobs default to ux-primitives.css
-   `--ux-*` tokens (with literal fallbacks), so it themes with the rest of the set
-   and inherits the host page's dark mode. Nothing here is !important.
-
-   Add class="ux-bento" to a container, class="ux-bento-item" + a size on each
-   child (data-span="CxR", or .is-wide/.is-tall/.is-big/.is-hero). Multi-column
-   spans collapse to full width on narrow viewports.
-   ============================================================================ */
-
-.ux-bento {
-  --ux-bento-cols: 4;
-  --ux-bento-gap: var(--ux-space-4, 16px);
-  --ux-bento-row: 180px;
-  --ux-bento-radius: var(--ux-radius-lg, 18px);
-  --ux-bento-pad: var(--ux-space-5, 20px);
-  --ux-bento-bg: var(--ux-surface, #14161d);
-  --ux-bento-fg: var(--ux-text, #e7e9f0);
-  --ux-bento-dim: var(--ux-text-dim, #98a1b3);
-  --ux-bento-border: var(--ux-border, rgba(255, 255, 255, .08));
-  --ux-bento-accent: var(--ux-accent, #c9a227);
-  --ux-bento-lift: var(--ux-shadow-2, 0 10px 30px rgba(0, 0, 0, .35));
-
-  display: grid;
-  grid-template-columns: repeat(var(--ux-bento-cols), minmax(0, 1fr));
-  grid-auto-rows: var(--ux-bento-row);
-  grid-auto-flow: row dense;
-  gap: var(--ux-bento-gap);
-  align-items: stretch;
-  font: var(--ux-font, inherit);
-}
-
-.ux-bento-item {
-  position: relative;
-  display: flex;
-  flex-direction: column;
-  justify-content: flex-end;
-  gap: 6px;
-  padding: var(--ux-bento-pad);
-  border-radius: var(--ux-bento-radius);
-  background: var(--ux-bento-bg);
-  color: var(--ux-bento-fg);
-  border: 1px solid var(--ux-bento-border);
-  overflow: hidden;
-  text-decoration: none;
-  isolation: isolate;
-  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
-}
-
-a.ux-bento-item,
-.ux-bento-item[data-href] { cursor: pointer; }
-
-a.ux-bento-item:hover,
-.ux-bento-item[data-href]:hover {
-  transform: translateY(-3px);
-  box-shadow: var(--ux-bento-lift);
-  border-color: color-mix(in srgb, var(--ux-bento-accent) 55%, transparent);
-}
-
-.ux-bento-item:focus-visible {
-  outline: 2px solid var(--ux-bento-accent);
-  outline-offset: 2px;
-}
-
-.ux-bento-item.has-image::before {
-  content: "";
-  position: absolute; inset: 0; z-index: -1;
-  background-image: var(--ux-bento-img);
-  background-size: cover;
-  background-position: center;
-  transform: scale(1.001);
-  transition: transform .4s ease;
-}
-a.ux-bento-item:hover.has-image::before { transform: scale(1.06); }
-
-.ux-bento-item.has-image::after {
-  content: "";
-  position: absolute; inset: 0; z-index: -1;
-  background: linear-gradient(180deg, transparent 30%, rgba(0, 0, 0, .66) 100%);
-}
-
-.ux-bento-item .eyebrow {
-  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
-  color: var(--ux-bento-accent); font-weight: 600;
-}
-.ux-bento-item .title  { font-size: 18px; font-weight: 650; line-height: 1.2; margin: 0; }
-.ux-bento-item .desc   { font-size: 13px; color: var(--ux-bento-dim); margin: 0;
-                         display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
-.ux-bento-item .cta    { font-size: 13px; font-weight: 600; color: var(--ux-bento-accent); margin-top: 2px; }
-
-.ux-bento-item.is-stat { justify-content: center; align-items: flex-start; }
-.ux-bento-item.is-stat .stat  { font-size: clamp(30px, 5vw, 52px); font-weight: 750; line-height: 1; }
-.ux-bento-item.is-stat .label { font-size: 13px; color: var(--ux-bento-dim); }
-
-.ux-bento-item.is-accent {
-  background:
-    radial-gradient(120% 140% at 0% 0%,
-      color-mix(in srgb, var(--ux-bento-accent) 26%, transparent), transparent 60%),
-    var(--ux-bento-bg);
-  border-color: color-mix(in srgb, var(--ux-bento-accent) 35%, transparent);
-}
-
-/* ---- SPANS ---- */
-.ux-bento-item.is-wide { grid-column: span 2; }
-.ux-bento-item.is-tall { grid-row: span 2; }
-.ux-bento-item.is-big  { grid-column: span 2; grid-row: span 2; }
-.ux-bento-item.is-hero { grid-column: span 3; grid-row: span 2; }
-
-.ux-bento-item[data-span="2x1"] { grid-column: span 2; grid-row: span 1; }
-.ux-bento-item[data-span="1x2"] { grid-column: span 1; grid-row: span 2; }
-.ux-bento-item[data-span="2x2"] { grid-column: span 2; grid-row: span 2; }
-.ux-bento-item[data-span="3x1"] { grid-column: span 3; grid-row: span 1; }
-.ux-bento-item[data-span="3x2"] { grid-column: span 3; grid-row: span 2; }
-.ux-bento-item[data-span="4x1"] { grid-column: span 4; grid-row: span 1; }
-.ux-bento-item[data-span="2x3"] { grid-column: span 2; grid-row: span 3; }
-
-/* ---- RESPONSIVE ---- */
-@media (max-width: 960px) {
-  .ux-bento { --ux-bento-cols: 3; }
-  .ux-bento-item.is-hero,
-  .ux-bento-item[data-span="4x1"],
-  .ux-bento-item[data-span="3x2"],
-  .ux-bento-item[data-span="3x1"] { grid-column: span 3; }
-}
-@media (max-width: 640px) {
-  .ux-bento { --ux-bento-cols: 2; --ux-bento-row: 150px; }
-  .ux-bento-item[data-span],
-  .ux-bento-item.is-wide,
-  .ux-bento-item.is-big,
-  .ux-bento-item.is-hero { grid-column: span 2; }
-  .ux-bento-item.is-tall,
-  .ux-bento-item[data-span="1x2"] { grid-row: span 2; grid-column: span 1; }
-}
-@media (max-width: 420px) {
-  .ux-bento { --ux-bento-cols: 1; }
-  .ux-bento-item,
-  .ux-bento-item[data-span],
-  .ux-bento-item.is-wide,
-  .ux-bento-item.is-big,
-  .ux-bento-item.is-hero { grid-column: span 1; }
-}
-@media (prefers-reduced-motion: reduce) {
-  .ux-bento-item, .ux-bento-item::before { transition: none; }
-}
diff --git a/public/ux-primitives.bundle.js b/public/ux-primitives.bundle.js
deleted file mode 100644
index f074f36..0000000
--- a/public/ux-primitives.bundle.js
+++ /dev/null
@@ -1,1207 +0,0 @@
-/* ux-primitives.bundle.js — canonical Bundle-B UX primitives (generated 2026-09-22T21:06:28Z)
-   7 zero-dependency IIFE primitives (window globals Toast, Skeleton, EmptyState,
-   Copy, CommandPalette, ModalRig, Bento) + ONE idempotent declarative auto-init
-   (UXPrimitives.init). No-ops on a page using none of them. Globals are distinct
-   from corner-nav (CornerNavConfig) + hero-4grid (Hero4GridConfig).
-   Regenerate via /Users/macstudio3/Projects/_shared/scripts/build-ux-primitives-bundle.sh */
-
-/* ===== toast-notify.js ===== */
-/* toast-notify.js — transient toast/notification stack. Zero dependencies.
- *
- * Part of the UX build-feature set (shares ux-primitives.css tokens).
- *
- *   Toast.show({ message, title?, variant, duration?, position?, dismissible?, onClose? }) -> handle
- *   Toast.success(message, opts?)   Toast.error(...)   Toast.info(...)   Toast.warn(...)
- *   Toast.setPosition('top-right')  // persists per-viewer in localStorage
- *   Toast.clear()                   // dismiss everything
- *
- *   variant   : 'success' | 'error' | 'info' | 'warn'   (default 'info')
- *   duration  : ms before auto-dismiss; 0 = sticky (default 4500; errors 7000)
- *   position  : 'top-right'|'top-left'|'top-center'|'bottom-right'|'bottom-left'|'bottom-center'
- *   handle    : { close() }
- *
- * a11y: each position has ONE ARIA live region. success/info are polite
- * (role=status), error/warn are assertive (role=alert). Auto-dismiss pauses on
- * hover/focus. Manual close button is keyboard reachable and labelled.
- */
-(function (global) {
-  var LS_KEY = 'ux:toast:pos';
-  var DEFAULT_POS = 'top-right';
-  var regions = {};                       // pos -> element
-
-  var ICONS = {
-    success: '✓',                    // ✓
-    error:   '✕',                    // ✕
-    warn:    '⚠',                    // ⚠
-    info:    'ℹ'                     // ℹ
-  };
-
-  function lsGet(k) { try { return localStorage.getItem(k); } catch (e) { return null; } }
-  function lsSet(k, v) { try { localStorage.setItem(k, v); } catch (e) {} }
-
-  function prefPos() { return lsGet(LS_KEY) || DEFAULT_POS; }
-
-  function reduceMotion() {
-    try { return matchMedia('(prefers-reduced-motion: reduce)').matches; } catch (e) { return false; }
-  }
-
-  function region(pos) {
-    if (regions[pos] && document.body.contains(regions[pos])) return regions[pos];
-    var el = document.createElement('div');
-    el.className = 'ux-toast-region';
-    el.setAttribute('data-pos', pos);
-    // polite live region; assertive toasts set their own role=alert which overrides
-    el.setAttribute('aria-live', 'polite');
-    el.setAttribute('aria-atomic', 'false');
-    document.body.appendChild(el);
-    regions[pos] = el;
-    return el;
-  }
-
-  function show(opts) {
-    opts = opts || {};
-    if (typeof opts === 'string') opts = { message: opts };
-    var variant = opts.variant || 'info';
-    var pos = opts.position || prefPos();
-    var assertive = (variant === 'error' || variant === 'warn');
-    var duration = opts.duration == null
-      ? (variant === 'error' ? 7000 : 4500)
-      : opts.duration;
-    var dismissible = opts.dismissible !== false;
-
-    var reg = region(pos);
-
-    var t = document.createElement('div');
-    t.className = 'ux-toast ux-toast--' + variant;
-    t.setAttribute('role', assertive ? 'alert' : 'status');
-    t.setAttribute('data-state', 'enter');
-
-    var icon = document.createElement('span');
-    icon.className = 'ux-toast__icon';
-    icon.setAttribute('aria-hidden', 'true');
-    icon.textContent = ICONS[variant] || ICONS.info;
-    t.appendChild(icon);
-
-    var body = document.createElement('div');
-    body.className = 'ux-toast__body';
-    if (opts.title) {
-      var h = document.createElement('div');
-      h.className = 'ux-toast__title';
-      h.textContent = opts.title;
-      body.appendChild(h);
-    }
-    var m = document.createElement('div');
-    m.className = 'ux-toast__msg';
-    m.textContent = opts.message == null ? '' : String(opts.message);
-    body.appendChild(m);
-    t.appendChild(body);
-
-    if (dismissible) {
-      var btn = document.createElement('button');
-      btn.className = 'ux-toast__close';
-      btn.type = 'button';
-      btn.setAttribute('aria-label', 'Dismiss notification');
-      btn.innerHTML = '&times;';
-      btn.addEventListener('click', function () { close(); });
-      t.appendChild(btn);
-    }
-
-    var timer = null, closed = false, remaining = duration, startedAt = 0;
-    var bar = null;
-
-    function clearTimer() {
-      if (timer) { clearTimeout(timer); timer = null; }
-      if (bar) { var w = 0; try { w = bar.getBoundingClientRect().width; } catch (e) {}
-        var pw = t.getBoundingClientRect().width || 1;
-        bar.style.transition = 'none';
-        bar.style.transform = 'scaleX(' + Math.max(0, w / pw) + ')';
-      }
-    }
-    function startTimer() {
-      if (!duration) return;
-      startedAt = Date.now();
-      timer = setTimeout(close, remaining);
-      if (bar && !reduceMotion()) {
-        // animate the progress bar to 0 over the remaining time
-        bar.style.transition = 'none';
-        bar.style.transform = 'scaleX(1)';
-        // force reflow so the next transition takes effect
-        void bar.offsetWidth;
-        bar.style.transition = 'transform ' + remaining + 'ms linear';
-        bar.style.transform = 'scaleX(0)';
-      }
-    }
-    function pause() {
-      if (!duration || closed) return;
-      remaining -= (Date.now() - startedAt);
-      clearTimer();
-    }
-    function resume() {
-      if (!duration || closed) return;
-      if (remaining <= 0) { close(); return; }
-      startTimer();
-    }
-    function close() {
-      if (closed) return;
-      closed = true;
-      if (timer) clearTimeout(timer);
-      t.setAttribute('data-state', 'leave');
-      var done = function () {
-        if (t.parentNode) t.parentNode.removeChild(t);
-        if (reg && !reg.children.length && reg.parentNode) reg.parentNode.removeChild(reg);
-        delete regions[pos];
-        try { if (typeof opts.onClose === 'function') opts.onClose(); } catch (e) {}
-      };
-      if (reduceMotion()) { done(); }
-      else { var t2 = setTimeout(done, 260); t.addEventListener('transitionend', function () { clearTimeout(t2); done(); }, { once: true }); }
-    }
-
-    if (duration) {
-      bar = document.createElement('div');
-      bar.className = 'ux-toast__bar';
-      t.appendChild(bar);
-      t.addEventListener('mouseenter', pause);
-      t.addEventListener('mouseleave', resume);
-      t.addEventListener('focusin', pause);
-      t.addEventListener('focusout', resume);
-    }
-
-    reg.appendChild(t);
-    // animate in
-    requestAnimationFrame(function () {
-      t.setAttribute('data-state', 'shown');
-      startTimer();
-    });
-
-    return { close: close, el: t };
-  }
-
-  function clear() {
-    Object.keys(regions).forEach(function (p) {
-      var r = regions[p];
-      if (r) Array.prototype.slice.call(r.querySelectorAll('.ux-toast__close')).forEach(function (b) { b.click(); });
-    });
-  }
-
-  function setPosition(pos) { lsSet(LS_KEY, pos); return pos; }
-
-  var API = {
-    show: show,
-    clear: clear,
-    setPosition: setPosition,
-    getPosition: prefPos,
-    success: function (msg, o) { return show(Object.assign({ message: msg, variant: 'success' }, o || {})); },
-    error:   function (msg, o) { return show(Object.assign({ message: msg, variant: 'error'   }, o || {})); },
-    info:    function (msg, o) { return show(Object.assign({ message: msg, variant: 'info'    }, o || {})); },
-    warn:    function (msg, o) { return show(Object.assign({ message: msg, variant: 'warn'    }, o || {})); }
-  };
-
-  global.Toast = API;
-  if (typeof module !== 'undefined' && module.exports) module.exports = API;
-})(typeof window !== 'undefined' ? window : this);
-
-/* ===== skeleton-loader.js ===== */
-/* skeleton-loader.js — content-placeholder shimmer skeletons. Zero dependencies.
- *
- * Part of the UX build-feature set (shares ux-primitives.css tokens).
- *
- *   Skeleton.render(mount, { variant, count?, ...opts })  // fill a container
- *   Skeleton.html(spec)                                   // -> HTML string
- *   Skeleton.swap(mount, realNodeOrHtml)                  // replace skeleton, fade in
- *   Skeleton.wrap(mount, promise, spec)                   // show skeleton until promise settles
- *
- *   variant : 'text' | 'card' | 'list-row' | 'image' | 'avatar' | 'media'
- *   count   : repeat the block N times (default 1; text uses `lines`)
- *
- * a11y: the mount is marked aria-busy="true" while skeletons show; the skeleton
- * nodes are aria-hidden so screen readers announce nothing until real content
- * lands. swap()/wrap() clear aria-busy and fade the real content in.
- */
-(function (global) {
-  function resolve(m) { return typeof m === 'string' ? document.querySelector(m) : m; }
-
-  function lines(n, opts) {
-    n = n || 3;
-    var out = '';
-    var widths = ['', '', 'ux-skel--w90', 'ux-skel--w75', 'ux-skel--w60'];
-    for (var i = 0; i < n; i++) {
-      var last = (i === n - 1);
-      var w = last ? 'ux-skel--w60' : (widths[i % widths.length] || '');
-      out += '<span class="ux-skel ux-skel--text ' + w + '"></span>';
-    }
-    return '<div class="ux-skel-lines" role="presentation">' + out + '</div>';
-  }
-
-  var BLOCKS = {
-    text: function (o) {
-      return (o.title ? '<span class="ux-skel ux-skel--title"></span>' : '') + lines(o.lines || 3, o);
-    },
-    image: function () { return '<span class="ux-skel ux-skel--image"></span>'; },
-    avatar: function () { return '<span class="ux-skel ux-skel--avatar"></span>'; },
-    media: function (o) {
-      return '<div class="ux-skel-media">'
-        + '<span class="ux-skel ux-skel--thumb"></span>'
-        + '<div class="ux-skel-media__body"><span class="ux-skel ux-skel--title" style="width:60%"></span>'
-        + lines(o.lines || 2, o) + '</div></div>';
-    },
-    card: function (o) {
-      return '<div class="ux-skel-card">'
-        + '<span class="ux-skel ux-skel--image"></span>'
-        + '<span class="ux-skel ux-skel--title" style="margin-top:14px"></span>'
-        + lines(o.lines || 2, o)
-        + '<div style="display:flex;gap:8px;margin-top:12px">'
-        + '<span class="ux-skel ux-skel--chip"></span><span class="ux-skel ux-skel--chip"></span></div>'
-        + '</div>';
-    },
-    'list-row': function (o) {
-      return '<div class="ux-skel-row">'
-        + '<span class="ux-skel ux-skel--thumb"></span>'
-        + '<div class="ux-skel-row__body">'
-        + '<span class="ux-skel ux-skel--text ux-skel--w60"></span>'
-        + '<span class="ux-skel ux-skel--text ux-skel--w40"></span></div>'
-        + '<span class="ux-skel ux-skel--btn"></span>'
-        + '</div>';
-    }
-  };
-
-  function html(spec) {
-    spec = spec || {};
-    if (typeof spec === 'string') spec = { variant: spec };
-    var v = spec.variant || 'text';
-    var block = BLOCKS[v] || BLOCKS.text;
-    var count = spec.count || 1;
-    var out = '';
-    for (var i = 0; i < count; i++) out += block(spec);
-    return out;
-  }
-
-  function render(mount, spec) {
-    var el = resolve(mount);
-    if (!el) { console.warn('[skeleton-loader] mount not found:', mount); return null; }
-    el.setAttribute('data-ux-skel-host', '');
-    el.setAttribute('aria-busy', 'true');
-    var wrap = document.createElement('div');
-    wrap.setAttribute('aria-hidden', 'true');
-    wrap.setAttribute('data-ux-skel', '');
-    wrap.innerHTML = html(spec);
-    el.innerHTML = '';
-    el.appendChild(wrap);
-    return el;
-  }
-
-  function swap(mount, real) {
-    var el = resolve(mount);
-    if (!el) return null;
-    el.removeAttribute('aria-busy');
-    el.innerHTML = '';
-    if (real == null) return el;
-    if (typeof real === 'string') el.innerHTML = real;
-    else if (real.nodeType) el.appendChild(real);
-    // fade the fresh content in
-    var target = el.firstElementChild || el;
-    if (target && target.classList) {
-      target.classList.add('ux-skel-in');
-      target.addEventListener('animationend', function () { target.classList.remove('ux-skel-in'); }, { once: true });
-    }
-    return el;
-  }
-
-  function wrap(mount, promise, spec) {
-    render(mount, spec);
-    return Promise.resolve(promise).then(
-      function (v) { return v; },
-      function (err) { swap(mount, ''); throw err; }
-    );
-    // caller decides what to swap in on success: wrap(...).then(data => Skeleton.swap(mount, view(data)))
-  }
-
-  var API = { render: render, html: html, swap: swap, wrap: wrap };
-  global.Skeleton = API;
-  if (typeof module !== 'undefined' && module.exports) module.exports = API;
-})(typeof window !== 'undefined' ? window : this);
-
-/* ===== empty-state.js ===== */
-/* empty-state.js — reusable empty / zero-results / error / offline block.
- * Zero dependencies. Part of the UX build-feature set (shares ux-primitives.css).
- *
- *   EmptyState.render(mount, {
- *     variant,        // 'no-results' | 'no-data' | 'error' | 'offline'  (default 'no-data')
- *     icon,           // optional: raw SVG/HTML string OR emoji; overrides the built-in
- *     title,          // headline (falls back to a per-variant default)
- *     text,           // subtext (optional)
- *     primary,        // { label, onClick } or { label, href }  (optional)
- *     secondary       // { label, onClick } or { label, href }  (optional)
- *   }) -> element
- *
- *   EmptyState.html(opts)  // -> HTML string (for your own templating)
- *
- * a11y: informational variants use role="status" (aria-live polite); error/offline
- * use role="alert". CTAs are real <button>/<a> (keyboard + focus ring). Built-in
- * icons are aria-hidden decorative SVG.
- */
-(function (global) {
-  function resolve(m) { return typeof m === 'string' ? document.querySelector(m) : m; }
-  function esc(s) {
-    return String(s == null ? '' : s)
-      .replace(/&/g, '&amp;').replace(/</g, '&lt;')
-      .replace(/>/g, '&gt;').replace(/"/g, '&quot;');
-  }
-
-  // inline decorative SVGs (currentColor)
-  var SVG = {
-    'no-results': '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="7"></circle><path d="M21 21l-3.5-3.5"></path></svg>',
-    'no-data':    '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 7l9-4 9 4-9 4-9-4z"></path><path d="M3 7v10l9 4 9-4V7"></path><path d="M12 11v10"></path></svg>',
-    'error':      '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"></circle><path d="M12 8v5"></path><path d="M12 16h.01"></path></svg>',
-    'offline':    '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3l18 18"></path><path d="M8.5 8.5a7 7 0 0 0-3 2"></path><path d="M2 8.8a11 11 0 0 1 5-3"></path><path d="M16.7 11.3A7 7 0 0 1 18.5 12.5"></path><path d="M22 8.8a11 11 0 0 0-6.3-3.2"></path><path d="M12 20h.01"></path></svg>'
-  };
-  var DEFAULT_TITLE = {
-    'no-results': 'No results found',
-    'no-data':    'Nothing here yet',
-    'error':      'Something went wrong',
-    'offline':    'You’re offline'
-  };
-
-  function actionHtml(a, primary) {
-    if (!a || !a.label) return '';
-    var cls = 'ux-empty__btn' + (primary ? ' ux-empty__btn--primary' : '') + ' ux-focusable';
-    if (a.href) return '<a class="' + cls + '" href="' + esc(a.href) + '">' + esc(a.label) + '</a>';
-    return '<button type="button" class="' + cls + '" data-ux-empty-act="' + (primary ? 'primary' : 'secondary') + '">' + esc(a.label) + '</button>';
-  }
-
-  function html(o) {
-    o = o || {};
-    var v = o.variant || 'no-data';
-    var icon = o.icon != null ? o.icon : (SVG[v] || SVG['no-data']);
-    var title = o.title != null ? o.title : (DEFAULT_TITLE[v] || DEFAULT_TITLE['no-data']);
-    var actions = actionHtml(o.primary, true) + actionHtml(o.secondary, false);
-    return '<div class="ux-empty__icon">' + icon + '</div>'
-      + '<p class="ux-empty__title">' + esc(title) + '</p>'
-      + (o.text ? '<p class="ux-empty__text">' + esc(o.text) + '</p>' : '')
-      + (actions ? '<div class="ux-empty__actions">' + actions + '</div>' : '');
-  }
-
-  function render(mount, o) {
-    o = o || {};
-    var el = resolve(mount);
-    if (!el) { console.warn('[empty-state] mount not found:', mount); return null; }
-    var v = o.variant || 'no-data';
-    var alertish = (v === 'error' || v === 'offline');
-    el.classList.add('ux-empty', 'ux-empty--' + v);
-    el.setAttribute('role', alertish ? 'alert' : 'status');
-    el.setAttribute('aria-live', alertish ? 'assertive' : 'polite');
-    el.innerHTML = html(o);
-    // wire button callbacks (links navigate on their own)
-    if (o.primary && typeof o.primary.onClick === 'function') {
-      var pb = el.querySelector('[data-ux-empty-act="primary"]');
-      if (pb) pb.addEventListener('click', o.primary.onClick);
-    }
-    if (o.secondary && typeof o.secondary.onClick === 'function') {
-      var sb = el.querySelector('[data-ux-empty-act="secondary"]');
-      if (sb) sb.addEventListener('click', o.secondary.onClick);
-    }
-    return el;
-  }
-
-  var API = { render: render, html: html };
-  global.EmptyState = API;
-  if (typeof module !== 'undefined' && module.exports) module.exports = API;
-})(typeof window !== 'undefined' ? window : this);
-
-/* ===== copy-to-clipboard.js ===== */
-/* copy-to-clipboard.js — one-liner copy behavior. Zero dependencies.
- *
- * Part of the UX build-feature set (shares ux-primitives.css tokens). Integrates
- * with toast-notify if Toast is present, otherwise shows inline feedback.
- *
- *   Copy.copy(text)                    // -> Promise<boolean>  (clipboard API + execCommand fallback)
- *   Copy.attach(el, opts)              // wire one trigger element
- *   Copy.init(root=document)           // auto-wire every [data-copy] under root
- *
- * Data-attribute auto-wiring (no JS needed beyond loading this file):
- *   <button data-copy="DWK-32014">Copy SKU</button>
- *   <button data-copy data-copy-target="#snippet">Copy code</button>   <!-- copies that node's text/value -->
- *   optional: data-copy-feedback="toast|inline|both"  data-copy-label="Copy"  data-copy-copied="Copied!"
- *
- * a11y: feedback is announced via an aria-live="polite" region; the button keeps
- * an aria-label; the icon is decorative.
- */
-(function (global) {
-  var COPY_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="11" height="11" rx="2"></rect><path d="M5 15V5a2 2 0 0 1 2-2h10"></path></svg>';
-
-  var liveRegion = null;
-  function announce(msg) {
-    if (!liveRegion) {
-      liveRegion = document.createElement('div');
-      liveRegion.setAttribute('aria-live', 'polite');
-      liveRegion.setAttribute('role', 'status');
-      liveRegion.style.cssText = 'position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;';
-      document.body.appendChild(liveRegion);
-    }
-    liveRegion.textContent = '';
-    // reassign next tick so repeat messages are re-announced
-    setTimeout(function () { liveRegion.textContent = msg; }, 30);
-  }
-
-  function copy(text) {
-    text = text == null ? '' : String(text);
-    // modern path (needs secure context + focus; may reject)
-    if (global.navigator && navigator.clipboard && navigator.clipboard.writeText) {
-      return navigator.clipboard.writeText(text).then(function () { return true; }, function () { return legacy(text); });
-    }
-    return Promise.resolve(legacy(text));
-  }
-
-  function legacy(text) {
-    try {
-      var ta = document.createElement('textarea');
-      ta.value = text;
-      ta.setAttribute('readonly', '');
-      ta.style.cssText = 'position:fixed;top:0;left:0;opacity:0;pointer-events:none;';
-      document.body.appendChild(ta);
-      ta.select();
-      ta.setSelectionRange(0, text.length);
-      var ok = document.execCommand('copy');
-      document.body.removeChild(ta);
-      return !!ok;
-    } catch (e) { return false; }
-  }
-
-  function targetText(el) {
-    // explicit literal wins
-    var lit = el.getAttribute('data-copy');
-    if (lit) return lit;
-    var sel = el.getAttribute('data-copy-target');
-    if (sel) {
-      var t = document.querySelector(sel);
-      if (t) return ('value' in t && t.value != null && t.tagName !== undefined && /^(INPUT|TEXTAREA|SELECT)$/.test(t.tagName)) ? t.value : t.textContent.trim();
-    }
-    return '';
-  }
-
-  function pill(el, msg, isError) {
-    var p = document.createElement('span');
-    p.className = 'ux-copy-pill' + (isError ? ' is-error' : '');
-    p.textContent = msg;
-    p.setAttribute('aria-hidden', 'true');
-    // anchor relative to the trigger
-    var host = el;
-    var cs = global.getComputedStyle ? getComputedStyle(host) : null;
-    if (cs && cs.position === 'static') host.style.position = 'relative';
-    host.appendChild(p);
-    var r = el.getBoundingClientRect();
-    p.style.left = (el.offsetWidth / 2) + 'px';
-    p.style.top = '0px';
-    requestAnimationFrame(function () { p.setAttribute('data-show', 'true'); });
-    setTimeout(function () {
-      p.setAttribute('data-show', 'false');
-      setTimeout(function () { if (p.parentNode) p.parentNode.removeChild(p); }, 200);
-    }, 1200);
-  }
-
-  function feedback(el, mode, ok, copiedLabel) {
-    var msg = ok ? (copiedLabel || 'Copied!') : 'Copy failed';
-    announce(msg);
-    if (mode === 'toast' || mode === 'both') {
-      if (global.Toast) { ok ? Toast.success(msg) : Toast.error(msg); }
-      else if (mode === 'toast') { pill(el, msg, !ok); } // graceful fallback if Toast absent
-    }
-    if (mode === 'inline' || mode === 'both') {
-      el.classList.add(ok ? 'is-copied' : 'is-error');
-      pill(el, msg, !ok);
-      setTimeout(function () { el.classList.remove('is-copied', 'is-error'); }, 1300);
-    }
-  }
-
-  function attach(el, opts) {
-    if (!el || el.__uxCopyBound) return el;
-    opts = opts || {};
-    el.__uxCopyBound = true;
-
-    // decorate a bare .ux-copy button with an icon + label if empty
-    if (el.classList && el.classList.contains('ux-copy') && !el.children.length && !el.textContent.trim()) {
-      el.innerHTML = '<span class="ux-copy__ic">' + COPY_SVG + '</span><span>' + (opts.label || el.getAttribute('data-copy-label') || 'Copy') + '</span>';
-    }
-    if (el.tagName === 'BUTTON' && !el.getAttribute('type')) el.setAttribute('type', 'button');
-    if (!el.getAttribute('aria-label')) el.setAttribute('aria-label', opts.label || el.getAttribute('data-copy-label') || 'Copy to clipboard');
-
-    var mode = opts.feedback || el.getAttribute('data-copy-feedback') || (global.Toast ? 'toast' : 'inline');
-    var copiedLabel = opts.copiedLabel || el.getAttribute('data-copy-copied') || 'Copied!';
-
-    el.addEventListener('click', function () {
-      var text = (typeof opts.text === 'function') ? opts.text(el)
-               : (opts.text != null ? opts.text : targetText(el));
-      copy(text).then(function (ok) {
-        feedback(el, mode, ok, copiedLabel);
-        try { if (typeof opts.onCopy === 'function') opts.onCopy(ok, text, el); } catch (e) {}
-      });
-    });
-    return el;
-  }
-
-  function init(root) {
-    root = root || document;
-    var els = root.querySelectorAll('[data-copy], [data-copy-target]');
-    Array.prototype.forEach.call(els, function (el) { attach(el); });
-    return els.length;
-  }
-
-  var API = { copy: copy, attach: attach, init: init };
-  global.Copy = API;
-  if (typeof module !== 'undefined' && module.exports) module.exports = API;
-
-  // auto-wire declarative triggers once the DOM is ready
-  if (typeof document !== 'undefined') {
-    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', function () { init(document); });
-    else init(document);
-  }
-})(typeof window !== 'undefined' ? window : this);
-
-/* ===== command-palette.js ===== */
-/* command-palette.js — cmd-k / ctrl-k command palette. Zero dependencies.
- *
- * Part of the UX build-feature set (shares ux-primitives.css tokens).
- *
- *   var palette = CommandPalette.create({
- *     commands: [
- *       { id:'new',  title:'New collection', section:'Actions', subtitle:'Create a curated set',
- *         keywords:'add create', icon:'⊕', hint:'C', run(){ ... } },
- *       ...
- *     ],
- *     placeholder: 'Type a command…',
- *     hotkey: true,            // bind Cmd/Ctrl+K globally (default true)
- *     recentKey: 'ux:cmdk:recent',   // localStorage key for recents (default this)
- *     maxRecent: 5,
- *     onSelect: cmd => {}      // optional; runs after cmd.run()
- *   });
- *   palette.open();  palette.close();  palette.setCommands([...]);  palette.destroy();
- *
- * Fuzzy subsequence filter over title + subtitle + keywords + section. Keyboard:
- * up/down (wrap), Enter runs the selected command, Esc closes. Recents float to a
- * "Recent" group when the query is empty. ARIA combobox: input role=combobox with
- * aria-expanded/aria-controls/aria-activedescendant; results are a role=listbox of
- * role=option. Focus is trapped in the dialog and restored to the prior element on
- * close.
- */
-(function (global) {
-  var uid = 0;
-
-  function lsGet(k) { try { return JSON.parse(localStorage.getItem(k) || '[]'); } catch (e) { return []; } }
-  function lsSet(k, v) { try { localStorage.setItem(k, JSON.stringify(v)); } catch (e) {} }
-  function esc(s) {
-    return String(s == null ? '' : s)
-      .replace(/&/g, '&amp;').replace(/</g, '&lt;')
-      .replace(/>/g, '&gt;').replace(/"/g, '&quot;');
-  }
-
-  // subsequence fuzzy match; returns a score (higher = better) or -1 for no match
-  function fuzzy(needle, hay) {
-    needle = needle.toLowerCase(); hay = hay.toLowerCase();
-    if (!needle) return 0;
-    var n = 0, score = 0, streak = 0, lastIdx = -1;
-    for (var i = 0; i < hay.length && n < needle.length; i++) {
-      if (hay[i] === needle[n]) {
-        score += 1 + streak;                       // reward consecutive hits
-        if (lastIdx === i - 1) streak++; else streak = 1;
-        if (i === 0 || /\s|[-_/]/.test(hay[i - 1])) score += 3; // word-boundary bonus
-        lastIdx = i; n++;
-      }
-    }
-    return n === needle.length ? score : -1;
-  }
-
-  var SEARCH_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="7"></circle><path d="M21 21l-3.5-3.5"></path></svg>';
-
-  function create(cfg) {
-    cfg = cfg || {};
-    var commands = (cfg.commands || []).slice();
-    var recentKey = cfg.recentKey || 'ux:cmdk:recent';
-    var maxRecent = cfg.maxRecent || 5;
-    var listId = 'ux-cmdk-list-' + (++uid);
-
-    var backdrop = document.createElement('div');
-    backdrop.className = 'ux-cmdk-backdrop';
-    backdrop.setAttribute('data-open', 'false');
-    backdrop.hidden = true;
-
-    backdrop.innerHTML =
-      '<div class="ux-cmdk" role="dialog" aria-modal="true" aria-label="Command palette">'
-      + '<div class="ux-cmdk__head">'
-      +   '<span class="ux-cmdk__search-ic">' + SEARCH_SVG + '</span>'
-      +   '<input class="ux-cmdk__input" type="text" role="combobox" autocomplete="off" '
-      +          'spellcheck="false" aria-expanded="true" aria-controls="' + listId + '" '
-      +          'aria-autocomplete="list" placeholder="' + esc(cfg.placeholder || 'Type a command…') + '">'
-      +   '<span class="ux-cmdk__kbd">esc</span>'
-      + '</div>'
-      + '<ul class="ux-cmdk__list" id="' + listId + '" role="listbox" aria-label="Commands"></ul>'
-      + '</div>';
-
-    var panel = backdrop.querySelector('.ux-cmdk');
-    var input = backdrop.querySelector('.ux-cmdk__input');
-    var list  = backdrop.querySelector('.ux-cmdk__list');
-
-    var results = [];        // flat, in display order (excludes group headers)
-    var selected = 0;
-    var lastFocus = null;
-    var mounted = false;
-
-    function recents() { return lsGet(recentKey); }
-    function pushRecent(id) {
-      var r = recents().filter(function (x) { return x !== id; });
-      r.unshift(id); r = r.slice(0, maxRecent); lsSet(recentKey, r);
-    }
-
-    function compute(q) {
-      q = (q || '').trim();
-      if (!q) {
-        // empty query: Recent group (if any) then everything by section
-        var recIds = recents();
-        var recCmds = recIds.map(function (id) {
-          return commands.filter(function (c) { return c.id === id; })[0];
-        }).filter(Boolean);
-        var groups = [];
-        if (recCmds.length) groups.push({ name: 'Recent', items: recCmds });
-        bySection(commands).forEach(function (g) { groups.push(g); });
-        return groups;
-      }
-      var scored = commands.map(function (c) {
-        var hay = [c.title, c.subtitle, c.keywords, c.section].filter(Boolean).join(' ');
-        return { c: c, s: fuzzy(q, hay) };
-      }).filter(function (x) { return x.s >= 0; })
-        .sort(function (a, b) { return b.s - a.s; })
-        .map(function (x) { return x.c; });
-      return scored.length ? [{ name: 'Results', items: scored }] : [];
-    }
-
-    function bySection(cmds) {
-      var order = [], map = {};
-      cmds.forEach(function (c) {
-        var s = c.section || 'Commands';
-        if (!map[s]) { map[s] = { name: s, items: [] }; order.push(map[s]); }
-        map[s].items.push(c);
-      });
-      return order;
-    }
-
-    function draw(q) {
-      var groups = compute(q);
-      results = [];
-      if (!groups.length) {
-        list.innerHTML = '<li class="ux-cmdk__empty" role="presentation">No matching commands</li>';
-        input.setAttribute('aria-activedescendant', '');
-        return;
-      }
-      var html = '';
-      groups.forEach(function (g) {
-        html += '<li class="ux-cmdk__group" role="presentation">' + esc(g.name) + '</li>';
-        g.items.forEach(function (c) {
-          var idx = results.length;
-          results.push(c);
-          var oid = 'ux-cmdk-opt-' + uid + '-' + idx;
-          html += '<li class="ux-cmdk__opt" role="option" id="' + oid + '" data-i="' + idx + '" aria-selected="false">'
-            + (c.icon ? '<span class="ux-cmdk__ic" aria-hidden="true">' + esc(c.icon) + '</span>' : '<span class="ux-cmdk__ic"></span>')
-            + '<span class="ux-cmdk__opt-body"><span class="ux-cmdk__title">' + esc(c.title) + '</span>'
-            + (c.subtitle ? '<span class="ux-cmdk__sub">' + esc(c.subtitle) + '</span>' : '') + '</span>'
-            + (c.hint ? '<span class="ux-cmdk__hint">' + esc(c.hint) + '</span>' : '')
-            + '</li>';
-        });
-      });
-      list.innerHTML = html;
-      selected = 0;
-      highlight();
-    }
-
-    function optEls() { return list.querySelectorAll('.ux-cmdk__opt'); }
-
-    function highlight() {
-      var els = optEls();
-      els.forEach(function (el, i) {
-        var on = (i === selected);
-        el.setAttribute('aria-selected', on ? 'true' : 'false');
-        if (on) {
-          input.setAttribute('aria-activedescendant', el.id);
-          el.scrollIntoView({ block: 'nearest' });
-        }
-      });
-      if (!els.length) input.setAttribute('aria-activedescendant', '');
-    }
-
-    function move(delta) {
-      var n = results.length;
-      if (!n) return;
-      selected = (selected + delta + n) % n;
-      highlight();
-    }
-
-    function run(i) {
-      var c = results[i];
-      if (!c) return;
-      pushRecent(c.id);
-      close();
-      try { if (typeof c.run === 'function') c.run(c); } catch (e) { console.error('[command-palette] run failed', e); }
-      if (typeof cfg.onSelect === 'function') cfg.onSelect(c);
-    }
-
-    function onKey(e) {
-      if (e.key === 'ArrowDown') { e.preventDefault(); move(1); }
-      else if (e.key === 'ArrowUp') { e.preventDefault(); move(-1); }
-      else if (e.key === 'Enter') { e.preventDefault(); run(selected); }
-      else if (e.key === 'Escape') { e.preventDefault(); close(); }
-      else if (e.key === 'Tab') { e.preventDefault(); move(e.shiftKey ? -1 : 1); } // trap: cycle options
-    }
-
-    function onListClick(e) {
-      var opt = e.target.closest('.ux-cmdk__opt');
-      if (opt) run(+opt.dataset.i);
-    }
-    function onListMove(e) {
-      var opt = e.target.closest('.ux-cmdk__opt');
-      if (opt) { selected = +opt.dataset.i; highlight(); }
-    }
-    function onBackdrop(e) { if (e.target === backdrop) close(); }
-
-    function mount() {
-      if (mounted) return;
-      document.body.appendChild(backdrop);
-      input.addEventListener('input', function () { draw(input.value); });
-      input.addEventListener('keydown', onKey);
-      list.addEventListener('click', onListClick);
-      list.addEventListener('mousemove', onListMove);
-      backdrop.addEventListener('mousedown', onBackdrop);
-      mounted = true;
-    }
-
-    function open() {
-      mount();
-      lastFocus = document.activeElement;
-      backdrop.hidden = false;
-      input.value = '';
-      draw('');
-      requestAnimationFrame(function () {
-        backdrop.setAttribute('data-open', 'true');
-        input.focus();
-      });
-    }
-
-    function close() {
-      backdrop.setAttribute('data-open', 'false');
-      var done = function () { backdrop.hidden = true; };
-      var t = setTimeout(done, 180);
-      backdrop.addEventListener('transitionend', function () { clearTimeout(t); done(); }, { once: true });
-      if (lastFocus && lastFocus.focus) { try { lastFocus.focus(); } catch (e) {} }
-    }
-
-    function toggle() { (backdrop.hidden) ? open() : close(); }
-
-    // global hotkey Cmd/Ctrl+K
-    var hotkeyHandler = null;
-    if (cfg.hotkey !== false) {
-      hotkeyHandler = function (e) {
-        if ((e.metaKey || e.ctrlKey) && (e.key === 'k' || e.key === 'K')) {
-          e.preventDefault(); toggle();
-        }
-      };
-      document.addEventListener('keydown', hotkeyHandler);
-    }
-
-    function setCommands(next) { commands = (next || []).slice(); if (!backdrop.hidden) draw(input.value); }
-
-    function destroy() {
-      if (hotkeyHandler) document.removeEventListener('keydown', hotkeyHandler);
-      if (backdrop.parentNode) backdrop.parentNode.removeChild(backdrop);
-      mounted = false;
-    }
-
-    return { open: open, close: close, toggle: toggle, setCommands: setCommands, destroy: destroy, el: backdrop };
-  }
-
-  var API = { create: create, fuzzy: fuzzy };
-  global.CommandPalette = API;
-  if (typeof module !== 'undefined' && module.exports) module.exports = API;
-})(typeof window !== 'undefined' ? window : this);
-
-/* ===== modal-rig.js ===== */
-/*!
- * modal-rig.js — make any modal/panel "fully done": drag-to-rearrange,
- * stretch/resize, collapsible sections, maximize, all persisted to localStorage.
- * Vanilla JS, zero deps, framework-agnostic. Exposes window.ModalRig.
- *
- * Part of the UX build-feature set (themes via ux-primitives.css + modal-rig.css;
- * still renders correctly with neither loaded — structural styles are inlined).
- *
- *   ModalRig.rig(panelEl, { key:'mynote' })            // enhance an existing panel
- *   ModalRig.section(headerEl, bodyEl, 'mynote:links')  // collapsible section
- *   var m = ModalRig.open({ key:'mynote', title:'Note', bodyHtml:'<p>…</p>' })
- *   ModalRig.init(root=document)                        // wire declarative hooks (idempotent)
- *
- * Declarative auto-wiring (no JS needed beyond loading this file):
- *   <div data-ux-modal-rig data-ux-modal-key="panel1"> … </div>   // rig an in-DOM panel
- *   <button data-ux-modal-open="#tmpl" data-ux-modal-title="Details">Open</button>
- *      where #tmpl is a <template> (or any element) whose innerHTML becomes the body.
- */
-(function (global) {
-  function lsGet(k) { try { return JSON.parse(localStorage.getItem(k) || 'null'); } catch (e) { return null; } }
-  function lsSet(k, v) { try { localStorage.setItem(k, JSON.stringify(v)); } catch (e) {} }
-  function px(n) { return Math.round(n) + 'px'; }
-
-  function applyRect(panel, key, opts) {
-    var w = opts.width || 760;
-    var h = opts.height || Math.min(620, Math.round(window.innerHeight * 0.8));
-    var r = lsGet('modalrig:' + key);
-    if (r && r.w) {
-      panel.style.left = px(r.left || 0); panel.style.top = px(r.top || 0);
-      panel.style.width = px(r.w); panel.style.height = px(r.h);
-    } else {
-      panel.style.left = px(Math.max(0, (window.innerWidth - w) / 2));
-      panel.style.top = px(Math.max(0, (window.innerHeight - h) / 2));
-      panel.style.width = px(w); panel.style.height = px(h);
-    }
-  }
-
-  function saveRect(panel, key) {
-    if (panel.getAttribute('data-rig-max') === '1') return; // don't persist the maximized state
-    lsSet('modalrig:' + key, {
-      left: parseInt(panel.style.left) || 0, top: parseInt(panel.style.top) || 0,
-      w: panel.offsetWidth, h: panel.offsetHeight
-    });
-  }
-
-  function startDrag(e, panel, key) {
-    if (e.target.closest && e.target.closest('[data-rig-btn]')) return; // not when clicking header buttons
-    if (panel.getAttribute('data-rig-max') === '1') unmaximize(panel, key); // dragging exits maximize
-    var box = panel.getBoundingClientRect();
-    var dx = e.clientX - box.left, dy = e.clientY - box.top;
-    function move(ev) {
-      panel.style.left = px(Math.max(0, Math.min(window.innerWidth - 80, ev.clientX - dx)));
-      panel.style.top = px(Math.max(0, Math.min(window.innerHeight - 40, ev.clientY - dy)));
-    }
-    function up() { document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', up); saveRect(panel, key); }
-    document.addEventListener('mousemove', move); document.addEventListener('mouseup', up);
-    e.preventDefault();
-  }
-
-  function maximize(panel) {
-    panel.setAttribute('data-rig-pre', JSON.stringify({ left: panel.style.left, top: panel.style.top, w: panel.style.width, h: panel.style.height }));
-    panel.setAttribute('data-rig-max', '1');
-    panel.style.left = '2vw'; panel.style.top = '2vh'; panel.style.width = '96vw'; panel.style.height = '96vh';
-  }
-  function unmaximize(panel, key) {
-    var pre = null;
-    try { pre = JSON.parse(panel.getAttribute('data-rig-pre') || 'null'); } catch (e) { pre = null; }
-    panel.removeAttribute('data-rig-max');
-    if (pre) { panel.style.left = pre.left; panel.style.top = pre.top; panel.style.width = pre.w; panel.style.height = pre.h; }
-  }
-  function toggleMax(panel, key, btn) {
-    if (panel.getAttribute('data-rig-max') === '1') { unmaximize(panel, key); if (btn) btn.textContent = '⤢'; }
-    else { maximize(panel); if (btn) btn.textContent = '⤡'; }
-  }
-
-  function injectMaxBtn(handle, panel, key) {
-    if (handle.querySelector('[data-rig-max-btn]')) return;
-    var b = document.createElement('button');
-    b.type = 'button';
-    b.className = 'ux-modal__btn ux-modal__max';
-    b.setAttribute('data-rig-btn', '1'); b.setAttribute('data-rig-max-btn', '1');
-    b.title = 'maximize / restore'; b.textContent = '⤢';
-    b.addEventListener('click', function (e) { e.stopPropagation(); toggleMax(panel, key, b); });
-    handle.appendChild(b);
-  }
-
-  // Enhance an already-in-DOM panel. Idempotent per panel (won't double-bind).
-  function rig(panel, opts) {
-    if (!panel || panel.__uxRigBound) return panel;
-    opts = opts || {};
-    var key = opts.key || 'default';
-    panel.__uxRigBound = true;
-    panel.classList.add('ux-modal');
-    panel.style.position = 'absolute';
-    if (opts.resizable !== false) { panel.style.resize = 'both'; if (!panel.style.overflow) panel.style.overflow = 'hidden'; }
-    applyRect(panel, key, opts);
-    var handle = typeof opts.handle === 'string' ? panel.querySelector(opts.handle) : (opts.handle || panel.firstElementChild);
-    if (handle) {
-      handle.style.cursor = 'move'; handle.style.userSelect = 'none';
-      handle.addEventListener('mousedown', function (e) { startDrag(e, panel, key); });
-      if (opts.maximizable !== false) injectMaxBtn(handle, panel, key);
-    }
-    panel.addEventListener('mouseup', function () { saveRect(panel, key); });
-    if (opts.onResize && window.ResizeObserver) {
-      var ro = new ResizeObserver(function () { try { opts.onResize(panel); } catch (e) {} });
-      ro.observe(panel);
-    }
-    return panel;
-  }
-
-  // Collapsible section: clicking headerEl toggles bodyEl; state persists under key.
-  function section(headerEl, bodyEl, key) {
-    if (!headerEl || !bodyEl || headerEl.__uxRigSection) return;
-    headerEl.__uxRigSection = true;
-    var collapsed = lsGet('modalrig-sec:' + key) === true;
-    var caret = document.createElement('span');
-    caret.textContent = collapsed ? '▸ ' : '▾ ';
-    headerEl.insertBefore(caret, headerEl.firstChild);
-    headerEl.style.cursor = 'pointer'; headerEl.style.userSelect = 'none';
-    bodyEl.style.display = collapsed ? 'none' : '';
-    headerEl.addEventListener('click', function () {
-      var nowOpen = bodyEl.style.display === 'none';
-      bodyEl.style.display = nowOpen ? '' : 'none';
-      caret.textContent = nowOpen ? '▾ ' : '▸ ';
-      lsSet('modalrig-sec:' + key, !nowOpen);
-    });
-  }
-
-  // Build a complete modal (backdrop + panel + header) and rig it. Returns
-  // { backdrop, panel, body, close }. Closes on backdrop click, ×, and Esc.
-  function open(o) {
-    o = o || {};
-    var key = o.key || 'modal';
-    var old = document.getElementById('modalrig-bd-' + key); if (old) old.remove();
-    var bd = document.createElement('div');
-    bd.id = 'modalrig-bd-' + key;
-    bd.className = 'ux-modal-backdrop';
-    // structural fallback so it works with no CSS loaded:
-    bd.style.cssText = 'position:fixed;inset:0;z-index:' + (o.z || 'var(--ux-z-palette,2147482000)') + ';background:rgba(0,0,0,.5);';
-    var panel = document.createElement('div');
-    panel.className = 'ux-modal';
-    panel.style.cssText = 'display:flex;flex-direction:column;min-width:340px;min-height:180px;';
-    panel.addEventListener('click', function (e) { e.stopPropagation(); });
-    var head = document.createElement('div');
-    head.className = 'ux-modal__head';
-    head.style.cssText = 'flex:0 0 auto;display:flex;justify-content:space-between;align-items:center;gap:8px;';
-    var title = document.createElement('span');
-    title.className = 'ux-modal__title';
-    title.textContent = o.title || '';
-    var btns = document.createElement('span'); btns.className = 'ux-modal__btns'; btns.style.cssText = 'flex:0 0 auto;display:flex;align-items:center;';
-    var x = document.createElement('button');
-    x.type = 'button'; x.className = 'ux-modal__btn ux-modal__close';
-    x.setAttribute('data-rig-btn', '1'); x.textContent = '×'; x.title = 'close (Esc)';
-    x.setAttribute('aria-label', 'Close');
-    var body = document.createElement('div');
-    body.className = 'ux-modal__body';
-    body.style.cssText = 'flex:1 1 auto;overflow:auto;';
-    if (o.bodyHtml != null) body.innerHTML = o.bodyHtml; else if (o.bodyEl) body.appendChild(o.bodyEl);
-    btns.appendChild(x); head.appendChild(title); head.appendChild(btns);
-    panel.appendChild(head); panel.appendChild(body); bd.appendChild(panel); document.body.appendChild(bd);
-    function close() { bd.remove(); if (o.onClose) o.onClose(); }
-    bd.addEventListener('click', close); x.addEventListener('click', close);
-    if (!window.__modalRigEsc) { window.__modalRigEsc = true; document.addEventListener('keydown', function (e) { if (e.key === 'Escape') { var t = document.querySelector('[id^="modalrig-bd-"]'); if (t) t.remove(); } }); }
-    rig(panel, { key: key, handle: head, resizable: o.resizable, maximizable: o.maximizable, width: o.width, height: o.height, onResize: o.onResize });
-    return { backdrop: bd, panel: panel, body: body, close: close };
-  }
-
-  // Declarative wiring — idempotent; safe to call on a page that uses none.
-  function init(root) {
-    root = root || (typeof document !== 'undefined' ? document : null);
-    if (!root) return 0;
-    var n = 0;
-    Array.prototype.forEach.call(root.querySelectorAll('[data-ux-modal-rig]'), function (el) {
-      if (el.__uxRigBound) return;
-      rig(el, { key: el.getAttribute('data-ux-modal-key') || ('rig-' + (++n)) });
-    });
-    Array.prototype.forEach.call(root.querySelectorAll('[data-ux-modal-open]'), function (btn) {
-      if (btn.__uxRigOpenBound) return;
-      btn.__uxRigOpenBound = true;
-      btn.addEventListener('click', function () {
-        var sel = btn.getAttribute('data-ux-modal-open');
-        var src = sel ? document.querySelector(sel) : null;
-        var html = src ? (src.tagName === 'TEMPLATE' ? src.innerHTML : src.innerHTML) : '';
-        open({ key: btn.getAttribute('data-ux-modal-key') || sel || 'modal', title: btn.getAttribute('data-ux-modal-title') || '', bodyHtml: html });
-      });
-    });
-    return n;
-  }
-
-  global.ModalRig = { rig: rig, section: section, open: open, init: init };
-  if (typeof module !== 'undefined' && module.exports) module.exports = global.ModalRig;
-})(typeof window !== 'undefined' ? window : this);
-
-/* ===== bento-grid.js ===== */
-/* ============================================================================
-   bento-grid.js — editorial "bento box" tile layout. Zero dependencies.
-   Part of the UX build-feature set (IIFE window.Bento, shares ux-primitives.css).
-
-   Converted from the original ES-module so it concatenates cleanly into the
-   ux-primitives.bundle.js classic script alongside the other primitives.
-
-     Bento.render(container, items, opts)   // render tiles from a data array
-     Bento.tile(item, i)                     // build ONE tile element
-     Bento.init(root=document)               // auto-wire [data-ux-bento] containers
-                                             //   whose JSON items live in a
-                                             //   <script type="application/json">
-   Each item:
-     { span?, variant?, eyebrow?, title?, desc?, cta?, image?, stat?, label?,
-       href?, accent?, bg? }
-   Markup is namespaced .ux-bento / .ux-bento-item so it can't clobber site CSS.
-   ============================================================================ */
-(function (global) {
-  var NAMED = { feature: 'is-accent', stat: 'is-stat', accent: 'is-accent', plain: '' };
-
-  function esc(s) {
-    return String(s == null ? '' : s)
-      .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
-      .replace(/"/g, '&quot;');
-  }
-
-  function autoSpan(item, i) {
-    if (item.span) return item.span;
-    if (item.variant === 'feature') return '2x2';
-    if (item.variant === 'stat') return '1x1';
-    if (i % 5 === 0) return '2x1';
-    return '1x1';
-  }
-
-  function tile(item, i) {
-    item = item || {}; i = i || 0;
-    var span = autoSpan(item, i);
-    var el = document.createElement(item.href ? 'a' : 'div');
-    el.className = 'ux-bento-item ' + (NAMED[item.variant] || '');
-    if (span && span !== '1x1') el.setAttribute('data-span', span);
-    if (item.href) { el.href = item.href; el.setAttribute('data-href', item.href); }
-    if (item.image) { el.classList.add('has-image'); el.style.setProperty('--ux-bento-img', 'url("' + item.image + '")'); }
-    if (item.accent) el.style.setProperty('--ux-bento-accent', item.accent);
-    if (item.bg) el.style.setProperty('--ux-bento-bg', item.bg);
-
-    var html = '';
-    if (item.variant === 'stat') {
-      html += '<div class="stat">' + esc(item.stat) + '</div>';
-      if (item.label) html += '<div class="label">' + esc(item.label) + '</div>';
-    } else {
-      if (item.eyebrow) html += '<div class="eyebrow">' + esc(item.eyebrow) + '</div>';
-      if (item.title) html += '<p class="title">' + esc(item.title) + '</p>';
-      if (item.desc) html += '<p class="desc">' + esc(item.desc) + '</p>';
-      if (item.cta) html += '<div class="cta">' + esc(item.cta) + ' ›</div>';
-    }
-    el.innerHTML = html;
-    return el;
-  }
-
-  function render(container, items, opts) {
-    if (!container) { console.warn('[bento-grid] container required'); return null; }
-    items = items || []; opts = opts || {};
-    container.classList.add('ux-bento');
-    container.innerHTML = '';
-    if (opts.vars) Object.keys(opts.vars).forEach(function (k) { container.style.setProperty(k, opts.vars[k]); });
-
-    var frag = document.createDocumentFragment();
-    items.forEach(function (item, i) { var t = tile(item, i); t._item = item; frag.appendChild(t); });
-    container.appendChild(frag);
-
-    var onClick = null;
-    if (typeof opts.onTileClick === 'function') {
-      onClick = function (ev) {
-        var t = ev.target.closest('.ux-bento-item');
-        if (!t || !container.contains(t)) return;
-        if (opts.onTileClick(t._item, ev) === false) ev.preventDefault();
-      };
-      container.addEventListener('click', onClick);
-    }
-    return {
-      el: container, items: items,
-      destroy: function () {
-        if (onClick) container.removeEventListener('click', onClick);
-        container.innerHTML = ''; container.classList.remove('ux-bento');
-      }
-    };
-  }
-
-  // Declarative: <div data-ux-bento><script type="application/json">[ … ]</script></div>
-  // Idempotent; no-ops if nothing on the page uses it.
-  function init(root) {
-    root = root || (typeof document !== 'undefined' ? document : null);
-    if (!root) return 0;
-    var n = 0;
-    Array.prototype.forEach.call(root.querySelectorAll('[data-ux-bento]'), function (el) {
-      if (el.__uxBentoBound) return;
-      el.__uxBentoBound = true;
-      var src = el.querySelector('script[type="application/json"]');
-      if (!src) return;
-      var items = [];
-      try { items = JSON.parse(src.textContent || '[]'); } catch (e) { console.warn('[bento-grid] bad JSON', e); return; }
-      render(el, items);
-      n++;
-    });
-    return n;
-  }
-
-  global.Bento = { render: render, tile: tile, init: init };
-  if (typeof module !== 'undefined' && module.exports) module.exports = global.Bento;
-})(typeof window !== 'undefined' ? window : this);
-
-/* ============================================================================
-   ux-primitives.bundle — declarative auto-init (idempotent).
-   Scans the DOM for data-attributes and activates the matching primitive.
-   Every block is wrapped in try/catch and guarded so a page that uses NONE of
-   them is a silent no-op, and a missing primitive never breaks the others.
-   Re-callable as UXPrimitives.init(root) after injecting new DOM.
-   ============================================================================ */
-(function (global) {
-  var doc = global.document;
-  if (!doc) return;
-  function each(list, fn) { Array.prototype.forEach.call(list || [], fn); }
-  function ready(fn) {
-    if (doc.readyState === 'loading') doc.addEventListener('DOMContentLoaded', fn, { once: true });
-    else fn();
-  }
-
-  function initAll(root) {
-    root = root || doc;
-
-    try { if (global.Copy && Copy.init) Copy.init(root); } catch (e) { console.warn('[ux-primitives] copy', e); }
-    try { if (global.ModalRig && ModalRig.init) ModalRig.init(root); } catch (e) { console.warn('[ux-primitives] modal-rig', e); }
-    try { if (global.Bento && Bento.init) Bento.init(root); } catch (e) { console.warn('[ux-primitives] bento', e); }
-
-    try {
-      if (global.Skeleton) each(root.querySelectorAll('[data-ux-skeleton]'), function (el) {
-        if (el.__uxSkelBound) return; el.__uxSkelBound = true;
-        var lines = +(el.getAttribute('data-ux-skeleton-lines') || 0);
-        Skeleton.render(el, {
-          variant: el.getAttribute('data-ux-skeleton') || 'text',
-          count: +(el.getAttribute('data-ux-skeleton-count') || 1),
-          lines: lines || undefined
-        });
-      });
-    } catch (e) { console.warn('[ux-primitives] skeleton', e); }
-
-    try {
-      if (global.EmptyState) each(root.querySelectorAll('[data-ux-empty]'), function (el) {
-        if (el.__uxEmptyBound) return; el.__uxEmptyBound = true;
-        EmptyState.render(el, {
-          variant: el.getAttribute('data-ux-empty') || 'no-data',
-          title: el.getAttribute('data-ux-empty-title') || undefined,
-          text: el.getAttribute('data-ux-empty-text') || undefined
-        });
-      });
-    } catch (e) { console.warn('[ux-primitives] empty-state', e); }
-
-    try {
-      if (global.Toast) each(root.querySelectorAll('[data-ux-toast]'), function (el) {
-        if (el.__uxToastBound) return; el.__uxToastBound = true;
-        var fire = function () {
-          Toast.show({ message: el.getAttribute('data-ux-toast') || 'Done',
-                       variant: el.getAttribute('data-ux-toast-variant') || 'info' });
-        };
-        if (el.hasAttribute('data-ux-toast-onload')) fire();
-        else el.addEventListener('click', fire);
-      });
-    } catch (e) { console.warn('[ux-primitives] toast', e); }
-
-    try {
-      if (global.CommandPalette) each(root.querySelectorAll('[data-ux-cmdk]'), function (el) {
-        if (el.__uxCmdkBound) return; el.__uxCmdkBound = true;
-        var src = el.querySelector('script[type="application/json"]');
-        var cmds = [];
-        if (src) { try { cmds = JSON.parse(src.textContent || '[]'); } catch (e2) {} }
-        cmds = cmds.map(function (c) { if (!c.run && c.href) { var h = c.href; c.run = function () { location.href = h; }; } return c; });
-        var p = CommandPalette.create({ commands: cmds, hotkey: el.getAttribute('data-ux-cmdk') !== 'no-hotkey' });
-        el.__uxCmdk = p;
-        each(root.querySelectorAll('[data-ux-cmdk-open]'), function (btn) {
-          if (btn.__uxCmdkOpenBound) return; btn.__uxCmdkOpenBound = true;
-          btn.addEventListener('click', function () { p.open(); });
-        });
-      });
-    } catch (e) { console.warn('[ux-primitives] command-palette', e); }
-
-    return true;
-  }
-
-  global.UXPrimitives = { init: initAll, version: '1.0.0' };
-  ready(function () { if (global.__uxPrimitivesAutoInit === false) return; try { initAll(doc); } catch (e) { console.warn('[ux-primitives] auto-init', e); } });
-})(typeof window !== 'undefined' ? window : this);

← ff5b502 front-page-steward: ux-primitives bundle (silent) TK-12031  ·  back to Architecturalwallcoverings  ·  front-page-steward: ux-primitives bundle (grid) TK-12031 8355df7 →