streetui 2.5.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "2.5.0";
2
+ var VERSION = "2.7.0";
3
3
 
4
4
  // ../state/src/signal.ts
5
5
  var _activeConsumer = null;
@@ -402,13 +402,13 @@ var HttpError = class extends Error {
402
402
  statusText;
403
403
  url;
404
404
  body;
405
- constructor(status, statusText, url, body) {
405
+ constructor(status, statusText, url, body2) {
406
406
  super(`HTTP ${status} ${statusText} for ${url}`);
407
407
  this.name = "HttpError";
408
408
  this.status = status;
409
409
  this.statusText = statusText;
410
410
  this.url = url;
411
- this.body = body;
411
+ this.body = body2;
412
412
  }
413
413
  };
414
414
  function joinUrl(baseUrl, path) {
@@ -426,20 +426,20 @@ function withQuery(url, query) {
426
426
  return url.includes("?") ? `${url}&${qs}` : `${url}?${qs}`;
427
427
  }
428
428
  function createClient(config = {}) {
429
- const doFetch = config.fetch ?? ((input, init) => {
429
+ const doFetch = config.fetch ?? ((input2, init) => {
430
430
  if (typeof fetch === "undefined") {
431
431
  throw new Error("createClient: no global fetch; pass { fetch } explicitly");
432
432
  }
433
- return fetch(input, init);
433
+ return fetch(input2, init);
434
434
  });
435
- async function request(method, path, body, reqConfig = {}) {
435
+ async function request(method, path, body2, reqConfig = {}) {
436
436
  const url = withQuery(joinUrl(config.baseUrl, path), reqConfig.query);
437
437
  const headers = { ...config.headers, ...reqConfig.headers };
438
438
  const init = { method, headers };
439
439
  if (reqConfig.signal !== void 0) init.signal = reqConfig.signal;
440
- if (body !== void 0) {
440
+ if (body2 !== void 0) {
441
441
  if (headers["Content-Type"] === void 0) headers["Content-Type"] = "application/json";
442
- init.body = JSON.stringify(body);
442
+ init.body = JSON.stringify(body2);
443
443
  }
444
444
  const response = await doFetch(url, init);
445
445
  const parsed = await parseBody(response);
@@ -466,17 +466,17 @@ function createClient(config = {}) {
466
466
  };
467
467
  }
468
468
  async function parseBody(response) {
469
- const text = await response.text();
470
- if (text === "") return void 0;
469
+ const text2 = await response.text();
470
+ if (text2 === "") return void 0;
471
471
  const type = response.headers.get("content-type") ?? "";
472
472
  if (type.includes("application/json")) {
473
473
  try {
474
- return JSON.parse(text);
474
+ return JSON.parse(text2);
475
475
  } catch {
476
- return text;
476
+ return text2;
477
477
  }
478
478
  }
479
- return text;
479
+ return text2;
480
480
  }
481
481
 
482
482
  // ../state/src/auth.ts
@@ -707,14 +707,14 @@ var DiagnosticCollector = class {
707
707
  get hasWarnings() {
708
708
  return this._diagnostics.some((d) => d.severity === "warning");
709
709
  }
710
- error(code, message, location, cause) {
711
- this._diagnostics.push({ severity: "error", code, message, location: location ?? void 0, cause: cause ?? void 0 });
710
+ error(code2, message, location, cause) {
711
+ this._diagnostics.push({ severity: "error", code: code2, message, location: location ?? void 0, cause: cause ?? void 0 });
712
712
  }
713
- warn(code, message, location) {
714
- this._diagnostics.push({ severity: "warning", code, message, location: location ?? void 0, cause: void 0 });
713
+ warn(code2, message, location) {
714
+ this._diagnostics.push({ severity: "warning", code: code2, message, location: location ?? void 0, cause: void 0 });
715
715
  }
716
- info(code, message, location) {
717
- this._diagnostics.push({ severity: "info", code, message, location: location ?? void 0, cause: void 0 });
716
+ info(code2, message, location) {
717
+ this._diagnostics.push({ severity: "info", code: code2, message, location: location ?? void 0, cause: void 0 });
718
718
  }
719
719
  merge(other) {
720
720
  for (const d of other.diagnostics) {
@@ -855,11 +855,11 @@ function safeStringify(value) {
855
855
  if (typeof value === "string") return value;
856
856
  if (value === null) return "null";
857
857
  if (value === void 0) return "undefined";
858
- const t = typeof value;
859
- if (t === "number" || t === "boolean" || t === "bigint" || t === "symbol") {
858
+ const t6 = typeof value;
859
+ if (t6 === "number" || t6 === "boolean" || t6 === "bigint" || t6 === "symbol") {
860
860
  return String(value);
861
861
  }
862
- const ctor = t === "object" && value !== null ? value.constructor?.name ?? "Object" : t;
862
+ const ctor = t6 === "object" && value !== null ? value.constructor?.name ?? "Object" : t6;
863
863
  return `[non-Error ${ctor}]`;
864
864
  }
865
865
  function describeError(error, context, options = {}) {
@@ -871,6 +871,884 @@ function reportError(sink, error, context, options = {}) {
871
871
  return report;
872
872
  }
873
873
 
874
+ // ../core/src/styling/canonical.ts
875
+ var LENGTH_PROPS = /* @__PURE__ */ new Set([
876
+ "inset",
877
+ "top",
878
+ "right",
879
+ "bottom",
880
+ "left",
881
+ "width",
882
+ "minWidth",
883
+ "maxWidth",
884
+ "height",
885
+ "minHeight",
886
+ "maxHeight",
887
+ "margin",
888
+ "marginTop",
889
+ "marginRight",
890
+ "marginBottom",
891
+ "marginLeft",
892
+ "padding",
893
+ "paddingTop",
894
+ "paddingRight",
895
+ "paddingBottom",
896
+ "paddingLeft",
897
+ "gap",
898
+ "rowGap",
899
+ "columnGap",
900
+ "flexBasis",
901
+ "borderWidth",
902
+ "borderRadius",
903
+ "fontSize",
904
+ "letterSpacing"
905
+ ]);
906
+ function cssPropName(camel) {
907
+ if (camel.startsWith("--")) return camel;
908
+ return camel.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
909
+ }
910
+ function cssValue(prop, value) {
911
+ if (typeof value === "number") {
912
+ if (value === 0) return "0";
913
+ return LENGTH_PROPS.has(prop) ? `${value}px` : String(value);
914
+ }
915
+ return value;
916
+ }
917
+ function sortDeep(value) {
918
+ if (Array.isArray(value)) return value.map(sortDeep);
919
+ if (value !== null && typeof value === "object") {
920
+ const out = {};
921
+ for (const key of Object.keys(value).sort()) {
922
+ const v = value[key];
923
+ if (v === void 0) continue;
924
+ out[key] = sortDeep(v);
925
+ }
926
+ return out;
927
+ }
928
+ return value;
929
+ }
930
+ function canonicalize(def) {
931
+ return JSON.stringify(sortDeep(def));
932
+ }
933
+ function hashIdentity(canonical) {
934
+ let h1 = 2166136261;
935
+ let h2 = 16777619 ^ canonical.length;
936
+ for (let i = 0; i < canonical.length; i++) {
937
+ const c = canonical.charCodeAt(i);
938
+ h1 ^= c;
939
+ h1 = Math.imul(h1, 16777619);
940
+ h2 = Math.imul(h2 ^ c, 2246822507);
941
+ }
942
+ const a = (h1 >>> 0).toString(36);
943
+ const b = (h2 >>> 0).toString(36);
944
+ return `s-${a}${b}`;
945
+ }
946
+ function identityOf(def) {
947
+ const canonical = canonicalize(def);
948
+ return { canonical, id: hashIdentity(canonical) };
949
+ }
950
+
951
+ // ../core/src/styling/registry.ts
952
+ var BAND_ORDER = ["tokens", "base", "responsive", "state", "variant"];
953
+ var StyleRegistry = class {
954
+ _entries = /* @__PURE__ */ new Map();
955
+ _seq = 0;
956
+ /** True once the registry has adopted a server-emitted stylesheet (§12). */
957
+ _adopted = false;
958
+ /**
959
+ * Register (idempotently) the CSS for a style identity. Returns the identity so
960
+ * callers can chain. Re-registering an existing id with the same css is a no-op;
961
+ * with different css it keeps the first registration (identity is content-derived,
962
+ * so this cannot happen for honest input and signals a hash collision if it does).
963
+ */
964
+ register(id, band, css) {
965
+ const existing = this._entries.get(id);
966
+ if (existing !== void 0) return id;
967
+ this._entries.set(id, { id, band, css, seq: this._seq++ });
968
+ return id;
969
+ }
970
+ /** Whether an identity is already present (server-adopted or locally registered). */
971
+ has(id) {
972
+ return this._entries.has(id);
973
+ }
974
+ /** Number of distinct rules held (bounded by source diversity, not instances). */
975
+ get size() {
976
+ return this._entries.size;
977
+ }
978
+ /**
979
+ * Seed the registry from identities a server stylesheet already shipped (§12).
980
+ * We only need the *keys* to avoid re-emitting duplicates; the rule text is
981
+ * already in the adopted `<style>` element, so a placeholder css is stored.
982
+ */
983
+ adoptServerIdentities(ids) {
984
+ for (const id of ids) {
985
+ if (!this._entries.has(id)) {
986
+ this._entries.set(id, { id, band: "base", css: "", seq: this._seq++ });
987
+ }
988
+ }
989
+ this._adopted = true;
990
+ }
991
+ get adopted() {
992
+ return this._adopted;
993
+ }
994
+ /** Serialize all rules to a single CSS string in deterministic band order. */
995
+ serializeCSS() {
996
+ if (this._entries.size === 0) return "";
997
+ const byBand = {
998
+ tokens: [],
999
+ base: [],
1000
+ responsive: [],
1001
+ state: [],
1002
+ variant: []
1003
+ };
1004
+ for (const e of this._entries.values()) {
1005
+ if (e.css.length > 0) byBand[e.band].push(e);
1006
+ }
1007
+ let out = "";
1008
+ for (const band of BAND_ORDER) {
1009
+ const list2 = byBand[band].sort((a, b) => a.seq - b.seq);
1010
+ for (const e of list2) out += e.css;
1011
+ }
1012
+ return out;
1013
+ }
1014
+ /** The ordered list of identities present (for the `data-streetui-css-keys` attr). */
1015
+ identities() {
1016
+ return [...this._entries.values()].sort((a, b) => a.seq - b.seq).map((e) => e.id);
1017
+ }
1018
+ /** Clear everything — test isolation and per-process reset only. */
1019
+ reset() {
1020
+ this._entries.clear();
1021
+ this._seq = 0;
1022
+ this._adopted = false;
1023
+ }
1024
+ };
1025
+ var styleRegistry = new StyleRegistry();
1026
+
1027
+ // ../core/src/styling/css.ts
1028
+ var BREAKPOINTS = {
1029
+ sm: 480,
1030
+ md: 768,
1031
+ lg: 1024,
1032
+ xl: 1280
1033
+ };
1034
+ var PSEUDO_SELECTOR = {
1035
+ hover: ":hover",
1036
+ focus: ":focus",
1037
+ focusVisible: ":focus-visible",
1038
+ focusWithin: ":focus-within",
1039
+ active: ":active",
1040
+ disabled: ":disabled",
1041
+ checked: ":checked",
1042
+ firstChild: ":first-child",
1043
+ lastChild: ":last-child"
1044
+ };
1045
+ function stateAttr(state) {
1046
+ return `data-${state}`;
1047
+ }
1048
+ function isResponsiveObject(v) {
1049
+ return v !== null && typeof v === "object";
1050
+ }
1051
+ function splitResponsive(props) {
1052
+ const base = [];
1053
+ const media = { sm: [], md: [], lg: [], xl: [] };
1054
+ for (const key of Object.keys(props).sort()) {
1055
+ if (key === "vars") {
1056
+ const vars = props.vars;
1057
+ if (vars) for (const vk of Object.keys(vars).sort()) base.push([vk, vars[vk]]);
1058
+ continue;
1059
+ }
1060
+ const raw = props[key];
1061
+ if (raw === void 0) continue;
1062
+ if (isResponsiveObject(raw)) {
1063
+ const r = raw;
1064
+ if (r.base !== void 0) base.push([key, r.base]);
1065
+ for (const bp of ["sm", "md", "lg", "xl"]) {
1066
+ if (r[bp] !== void 0) media[bp].push([key, r[bp]]);
1067
+ }
1068
+ } else {
1069
+ base.push([key, raw]);
1070
+ }
1071
+ }
1072
+ return { base, media };
1073
+ }
1074
+ function declBody(pairs) {
1075
+ let out = "";
1076
+ for (const [prop, val] of pairs) out += `${cssPropName(prop)}:${cssValue(prop, val)};`;
1077
+ return out;
1078
+ }
1079
+ function flatBody(props) {
1080
+ const pairs = [];
1081
+ for (const key of Object.keys(props).sort()) {
1082
+ if (key === "vars") {
1083
+ const vars = props.vars;
1084
+ if (vars) for (const vk of Object.keys(vars).sort()) pairs.push([vk, vars[vk]]);
1085
+ continue;
1086
+ }
1087
+ const raw = props[key];
1088
+ if (raw === void 0) continue;
1089
+ if (isResponsiveObject(raw)) {
1090
+ const b = raw.base;
1091
+ if (b !== void 0) pairs.push([key, b]);
1092
+ } else {
1093
+ pairs.push([key, raw]);
1094
+ }
1095
+ }
1096
+ return declBody(pairs);
1097
+ }
1098
+ function generateCSS(id, def) {
1099
+ const sel = `.${id}`;
1100
+ const { base, media } = splitResponsive(def);
1101
+ let baseCss = "";
1102
+ const baseBody = declBody(base);
1103
+ if (baseBody.length > 0) baseCss += `${sel}{${baseBody}}`;
1104
+ let hasResponsive = false;
1105
+ for (const bp of ["sm", "md", "lg", "xl"]) {
1106
+ if (media[bp].length > 0) {
1107
+ hasResponsive = true;
1108
+ baseCss += `@media (min-width:${BREAKPOINTS[bp]}px){${sel}{${declBody(media[bp])}}}`;
1109
+ }
1110
+ }
1111
+ let stateCss = "";
1112
+ if (def.on) {
1113
+ for (const ps of Object.keys(def.on).sort()) {
1114
+ const block = def.on[ps];
1115
+ if (!block) continue;
1116
+ const body2 = flatBody(block);
1117
+ if (body2.length > 0) stateCss += `${sel}${PSEUDO_SELECTOR[ps]}{${body2}}`;
1118
+ }
1119
+ }
1120
+ if (def.when) {
1121
+ for (const st of Object.keys(def.when).sort()) {
1122
+ const block = def.when[st];
1123
+ if (!block) continue;
1124
+ const body2 = flatBody(block);
1125
+ if (body2.length > 0) stateCss += `${sel}[${stateAttr(st)}]{${body2}}`;
1126
+ }
1127
+ }
1128
+ return { base: baseCss, state: stateCss, hasResponsive };
1129
+ }
1130
+
1131
+ // ../core/src/styling/tokens.ts
1132
+ function kebab(seg) {
1133
+ return seg.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
1134
+ }
1135
+ function isLeaf(v) {
1136
+ return typeof v === "string" || typeof v === "number";
1137
+ }
1138
+ function walkTokens(tree, path, visit) {
1139
+ for (const key of Object.keys(tree).sort()) {
1140
+ const v = tree[key];
1141
+ const next = [...path, kebab(key)];
1142
+ if (isLeaf(v)) visit(`--${next.join("-")}`, v);
1143
+ else walkTokens(v, next, visit);
1144
+ }
1145
+ }
1146
+ function buildRefs(tree, path) {
1147
+ const out = {};
1148
+ for (const key of Object.keys(tree)) {
1149
+ const v = tree[key];
1150
+ const next = [...path, kebab(key)];
1151
+ out[key] = isLeaf(v) ? `var(--${next.join("-")})` : buildRefs(v, next);
1152
+ }
1153
+ return out;
1154
+ }
1155
+ function tokenIdentity(def) {
1156
+ const json = JSON.stringify({ light: def.light, dark: def.dark ?? null });
1157
+ let h = 2166136261;
1158
+ for (let i = 0; i < json.length; i++) {
1159
+ h ^= json.charCodeAt(i);
1160
+ h = Math.imul(h, 16777619);
1161
+ }
1162
+ return `t-${(h >>> 0).toString(36)}`;
1163
+ }
1164
+ function createThemeTokens(def) {
1165
+ const id = tokenIdentity(def);
1166
+ let root = "";
1167
+ walkTokens(def.light, [], (name, value) => {
1168
+ root += `${name}:${value};`;
1169
+ });
1170
+ let dark = "";
1171
+ if (def.dark) walkTokens(def.dark, [], (name, value) => {
1172
+ dark += `${name}:${value};`;
1173
+ });
1174
+ let css = root.length > 0 ? `:root{${root}}` : "";
1175
+ if (dark.length > 0) css += `[data-theme="dark"]{${dark}}`;
1176
+ styleRegistry.register(id, "tokens", css);
1177
+ return {
1178
+ ref: buildRefs(def.light, []),
1179
+ css,
1180
+ id
1181
+ };
1182
+ }
1183
+ var DEFAULT_TOKENS = {
1184
+ surface: { background: "#ffffff", raised: "#f7f7f8", sunken: "#eeeef1", overlay: "rgba(17,17,20,0.55)" },
1185
+ content: { primary: "#17171a", secondary: "#55555f", muted: "#666672", inverse: "#ffffff" },
1186
+ border: { default: "#e3e3e8", strong: "#c9c9d1", subtle: "#f0f0f3" },
1187
+ accent: { primary: "#4f46e5", hover: "#4338ca", contrast: "#ffffff" },
1188
+ focus: { ring: "#6366f1" },
1189
+ danger: { surface: "#fef2f2", border: "#fecaca", content: "#b91c1c", solid: "#dc2626" },
1190
+ success: { content: "#15803d", solid: "#16a34a" },
1191
+ space: { "0": "0", "1": "4px", "2": "8px", "3": "12px", "4": "16px", "5": "24px", "6": "32px", "8": "48px", "10": "64px" },
1192
+ radius: { sm: "4px", md: "8px", lg: "12px", xl: "16px", full: "9999px" },
1193
+ font: {
1194
+ sans: "ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif",
1195
+ mono: "ui-monospace,SFMono-Regular,Menlo,Consolas,monospace"
1196
+ },
1197
+ size: { xs: "12px", sm: "14px", md: "16px", lg: "18px", xl: "24px", "2xl": "32px", "3xl": "44px" },
1198
+ weight: { normal: "400", medium: "500", semibold: "600", bold: "700" },
1199
+ leading: { tight: "1.2", normal: "1.5", relaxed: "1.7" },
1200
+ shadow: {
1201
+ sm: "0 1px 2px rgba(17,17,20,0.08)",
1202
+ md: "0 4px 12px rgba(17,17,20,0.1)",
1203
+ lg: "0 12px 32px rgba(17,17,20,0.16)"
1204
+ },
1205
+ z: { base: "0", dropdown: "1000", overlay: "1100", toast: "1200" },
1206
+ duration: { fast: "120ms", base: "200ms", slow: "320ms" },
1207
+ easing: { standard: "cubic-bezier(0.2,0,0,1)", emphasized: "cubic-bezier(0.3,0,0,1)" }
1208
+ };
1209
+ var DARK_OVERRIDES = {
1210
+ surface: { background: "#0f0f12", raised: "#17171c", sunken: "#0a0a0d", overlay: "rgba(0,0,0,0.6)" },
1211
+ content: { primary: "#f4f4f6", secondary: "#b4b4bf", muted: "#7c7c88", inverse: "#17171a" },
1212
+ border: { default: "#2a2a31", strong: "#3a3a44", subtle: "#1e1e24" },
1213
+ accent: { primary: "#818cf8", hover: "#a5b4fc", contrast: "#0f0f12" },
1214
+ focus: { ring: "#a5b4fc" },
1215
+ danger: { surface: "#2a1416", border: "#5b1d1d", content: "#fca5a5", solid: "#ef4444" },
1216
+ success: { content: "#4ade80", solid: "#22c55e" }
1217
+ };
1218
+ var tokens = createThemeTokens({ light: DEFAULT_TOKENS, dark: DARK_OVERRIDES });
1219
+
1220
+ // ../core/src/styling/style.ts
1221
+ function style(def) {
1222
+ const { id } = identityOf(def);
1223
+ if (!styleRegistry.has(id)) {
1224
+ const gen = generateCSS(id, def);
1225
+ styleRegistry.register(id, gen.hasResponsive ? "responsive" : "base", gen.base);
1226
+ if (gen.state.length > 0) {
1227
+ styleRegistry.register(`${id}~state`, "state", gen.state);
1228
+ }
1229
+ }
1230
+ return id;
1231
+ }
1232
+ function cx(...parts) {
1233
+ let out = "";
1234
+ for (const p of parts) {
1235
+ if (!p) continue;
1236
+ out = out.length === 0 ? p : `${out} ${p}`;
1237
+ }
1238
+ return out;
1239
+ }
1240
+ function styleVariants(cfg) {
1241
+ const baseClass = cfg.base ? style(cfg.base) : "";
1242
+ const groupClasses = {};
1243
+ for (const group of Object.keys(cfg.variants)) {
1244
+ const values = cfg.variants[group];
1245
+ const map = {};
1246
+ for (const value of Object.keys(values)) map[value] = style(values[value]);
1247
+ groupClasses[group] = map;
1248
+ }
1249
+ const defaults = cfg.defaultVariants ?? {};
1250
+ return (selection) => {
1251
+ const parts = [];
1252
+ if (baseClass) parts.push(baseClass);
1253
+ for (const group of Object.keys(groupClasses)) {
1254
+ const chosen = selection?.[group] ?? defaults[group];
1255
+ if (chosen === void 0) continue;
1256
+ const cls = groupClasses[group][chosen];
1257
+ if (cls) parts.push(cls);
1258
+ }
1259
+ return cx(...parts);
1260
+ };
1261
+ }
1262
+
1263
+ // ../core/src/styling/reactive.ts
1264
+ function reactiveVarName(prop) {
1265
+ return `--s-${cssPropName(prop)}`;
1266
+ }
1267
+ function styleWithVars(staticDef, reactiveProps) {
1268
+ const vars = {};
1269
+ const bind = {};
1270
+ const dynamic = {};
1271
+ for (const prop of reactiveProps) {
1272
+ const varName = reactiveVarName(prop);
1273
+ vars[prop] = varName;
1274
+ bind[prop] = `style.${varName}`;
1275
+ dynamic[prop] = `var(${varName})`;
1276
+ }
1277
+ const merged = { ...staticDef, ...dynamic };
1278
+ return { class: style(merged), vars, bind };
1279
+ }
1280
+ function reactiveVarValue(prop, value) {
1281
+ return cssValue(prop, value);
1282
+ }
1283
+
1284
+ // ../core/src/styling/layout.ts
1285
+ var space = (k) => tokens.ref.space[k];
1286
+ function container(opts = {}) {
1287
+ const def = {
1288
+ width: "100%",
1289
+ maxWidth: opts.max ?? 1120,
1290
+ paddingLeft: space(opts.padX ?? "4"),
1291
+ paddingRight: space(opts.padX ?? "4"),
1292
+ ...opts.center === false ? {} : { marginLeft: "auto", marginRight: "auto" }
1293
+ };
1294
+ return style(def);
1295
+ }
1296
+ var ALIGN = {
1297
+ start: "flex-start",
1298
+ center: "center",
1299
+ end: "flex-end",
1300
+ stretch: "stretch"
1301
+ };
1302
+ var JUSTIFY = {
1303
+ start: "flex-start",
1304
+ center: "center",
1305
+ end: "flex-end",
1306
+ between: "space-between",
1307
+ around: "space-around"
1308
+ };
1309
+ function stack(opts = {}) {
1310
+ return style({
1311
+ display: "flex",
1312
+ flexDirection: "column",
1313
+ gap: space(opts.gap ?? "4"),
1314
+ ...opts.align ? { alignItems: ALIGN[opts.align] } : {},
1315
+ ...opts.justify ? { justifyContent: JUSTIFY[opts.justify] } : {}
1316
+ });
1317
+ }
1318
+ function row(opts = {}) {
1319
+ return style({
1320
+ display: "flex",
1321
+ flexDirection: "row",
1322
+ gap: space(opts.gap ?? "4"),
1323
+ alignItems: opts.align ? ALIGN[opts.align] : "center",
1324
+ ...opts.justify ? { justifyContent: JUSTIFY[opts.justify] } : {},
1325
+ ...opts.wrap ? { flexWrap: "wrap" } : {}
1326
+ });
1327
+ }
1328
+ function grid(opts = {}) {
1329
+ const columns = opts.columns ?? "auto";
1330
+ const min = typeof opts.min === "number" ? `${opts.min}px` : opts.min ?? "220px";
1331
+ const template = columns === "auto" ? `repeat(auto-fill, minmax(${min}, 1fr))` : `repeat(${columns}, minmax(0, 1fr))`;
1332
+ return style({ display: "grid", gridTemplateColumns: template, gap: space(opts.gap ?? "4") });
1333
+ }
1334
+ function center(opts = {}) {
1335
+ return style({
1336
+ display: opts.inline ? "inline-flex" : "flex",
1337
+ alignItems: "center",
1338
+ justifyContent: "center",
1339
+ ...opts.minHeight !== void 0 ? { minHeight: opts.minHeight } : {}
1340
+ });
1341
+ }
1342
+ function spacer(opts = {}) {
1343
+ return opts.size !== void 0 ? style({ flex: "0 0 auto", width: opts.size, height: opts.size }) : style({ flex: "1 1 0%" });
1344
+ }
1345
+ var layout = { container, stack, row, grid, center, spacer };
1346
+
1347
+ // ../core/src/styling/typography.ts
1348
+ var t = tokens.ref;
1349
+ var HEADING_SIZE = {
1350
+ 1: t.size["3xl"],
1351
+ 2: t.size["2xl"],
1352
+ 3: t.size.xl,
1353
+ 4: t.size.lg,
1354
+ 5: t.size.md,
1355
+ 6: t.size.sm
1356
+ };
1357
+ function heading(opts = {}) {
1358
+ const level = opts.level ?? 2;
1359
+ return style({
1360
+ fontFamily: t.font.sans,
1361
+ fontSize: HEADING_SIZE[level],
1362
+ fontWeight: level <= 2 ? t.weight.bold : t.weight.semibold,
1363
+ lineHeight: t.leading.tight,
1364
+ color: t.content.primary,
1365
+ letterSpacing: level <= 2 ? "-0.02em" : "-0.01em"
1366
+ });
1367
+ }
1368
+ function body(opts = {}) {
1369
+ const def = {
1370
+ fontFamily: t.font.sans,
1371
+ fontSize: t.size.md,
1372
+ fontWeight: t.weight.normal,
1373
+ lineHeight: t.leading.normal,
1374
+ color: opts.muted ? t.content.secondary : t.content.primary
1375
+ };
1376
+ return style(opts.measure !== void 0 ? { ...def, maxWidth: opts.measure } : def);
1377
+ }
1378
+ function label() {
1379
+ return style({
1380
+ fontFamily: t.font.sans,
1381
+ fontSize: t.size.sm,
1382
+ fontWeight: t.weight.medium,
1383
+ lineHeight: t.leading.normal,
1384
+ color: t.content.primary
1385
+ });
1386
+ }
1387
+ function caption() {
1388
+ return style({
1389
+ fontFamily: t.font.sans,
1390
+ fontSize: t.size.xs,
1391
+ fontWeight: t.weight.normal,
1392
+ lineHeight: t.leading.normal,
1393
+ color: t.content.muted
1394
+ });
1395
+ }
1396
+ function link() {
1397
+ return style({
1398
+ color: t.accent.primary,
1399
+ textDecoration: "underline",
1400
+ cursor: "pointer",
1401
+ borderRadius: t.radius.sm,
1402
+ on: {
1403
+ hover: { color: t.accent.hover },
1404
+ focusVisible: { outline: `2px solid ${t.focus.ring}` }
1405
+ }
1406
+ });
1407
+ }
1408
+ function code() {
1409
+ return style({
1410
+ fontFamily: t.font.mono,
1411
+ fontSize: "0.9em",
1412
+ background: t.surface.sunken,
1413
+ color: t.content.primary,
1414
+ borderRadius: t.radius.sm,
1415
+ paddingLeft: t.space["1"],
1416
+ paddingRight: t.space["1"],
1417
+ borderWidth: 1,
1418
+ borderStyle: "solid",
1419
+ borderColor: t.border.subtle
1420
+ });
1421
+ }
1422
+ function pre() {
1423
+ return style({
1424
+ fontFamily: t.font.mono,
1425
+ fontSize: t.size.sm,
1426
+ lineHeight: t.leading.relaxed,
1427
+ background: t.surface.sunken,
1428
+ color: t.content.primary,
1429
+ borderRadius: t.radius.md,
1430
+ borderWidth: 1,
1431
+ borderStyle: "solid",
1432
+ borderColor: t.border.subtle,
1433
+ padding: t.space["4"],
1434
+ overflowX: "auto",
1435
+ whiteSpace: "pre"
1436
+ });
1437
+ }
1438
+ function blockquote() {
1439
+ return style({
1440
+ fontFamily: t.font.sans,
1441
+ fontSize: t.size.lg,
1442
+ lineHeight: t.leading.relaxed,
1443
+ color: t.content.secondary,
1444
+ borderStyle: "solid",
1445
+ borderColor: t.accent.primary,
1446
+ paddingLeft: t.space["4"],
1447
+ marginLeft: 0
1448
+ });
1449
+ }
1450
+ function list() {
1451
+ return style({
1452
+ fontFamily: t.font.sans,
1453
+ fontSize: t.size.md,
1454
+ lineHeight: t.leading.normal,
1455
+ color: t.content.primary,
1456
+ display: "flex",
1457
+ flexDirection: "column",
1458
+ gap: t.space["2"]
1459
+ });
1460
+ }
1461
+ var text = { heading, body, label, caption, link, code, pre, blockquote, list };
1462
+
1463
+ // ../core/src/styling/a11y.ts
1464
+ var t2 = tokens.ref;
1465
+ function focusRing(opts = {}) {
1466
+ const color = opts.color ?? t2.focus.ring;
1467
+ const width = opts.width ?? 2;
1468
+ const offset = opts.offset ?? 2;
1469
+ return style({
1470
+ outline: "2px solid transparent",
1471
+ // reserve space; real ring shown on focus
1472
+ on: {
1473
+ focusVisible: {
1474
+ outline: `${width}px solid ${color}`,
1475
+ outlineOffset: offset
1476
+ }
1477
+ }
1478
+ });
1479
+ }
1480
+ function visuallyHidden() {
1481
+ return style({
1482
+ position: "absolute",
1483
+ width: 1,
1484
+ height: 1,
1485
+ padding: 0,
1486
+ margin: -1,
1487
+ overflow: "hidden",
1488
+ whiteSpace: "nowrap",
1489
+ border: 0,
1490
+ // clip to a zero-area rect so the node occupies no visual space
1491
+ clipPath: "inset(50%)"
1492
+ });
1493
+ }
1494
+ function skipLink() {
1495
+ return style({
1496
+ position: "absolute",
1497
+ left: t2.space["2"],
1498
+ top: -40,
1499
+ background: t2.surface.raised,
1500
+ color: t2.content.primary,
1501
+ padding: t2.space["2"],
1502
+ borderRadius: t2.radius.md,
1503
+ boxShadow: t2.shadow.md,
1504
+ transition: `top ${t2.duration.fast} ${t2.easing.standard}`,
1505
+ on: {
1506
+ focusVisible: { top: t2.space["2"], outline: `2px solid ${t2.focus.ring}`, outlineOffset: 2 }
1507
+ }
1508
+ });
1509
+ }
1510
+ var a11y = { focusRing, visuallyHidden, skipLink };
1511
+
1512
+ // ../core/src/styling/forms.ts
1513
+ var t3 = tokens.ref;
1514
+ var CONTROL_BASE = {
1515
+ fontFamily: t3.font.sans,
1516
+ fontSize: t3.size.md,
1517
+ lineHeight: t3.leading.normal,
1518
+ color: t3.content.primary,
1519
+ background: t3.surface.background,
1520
+ borderWidth: 1,
1521
+ borderStyle: "solid",
1522
+ borderColor: t3.border.strong,
1523
+ borderRadius: t3.radius.md,
1524
+ paddingTop: t3.space["2"],
1525
+ paddingBottom: t3.space["2"],
1526
+ paddingLeft: t3.space["3"],
1527
+ paddingRight: t3.space["3"],
1528
+ width: "100%",
1529
+ appearance: "none",
1530
+ transition: `border-color ${t3.duration.fast} ${t3.easing.standard}, box-shadow ${t3.duration.fast} ${t3.easing.standard}`,
1531
+ on: {
1532
+ focusVisible: { outline: "none", borderColor: t3.accent.primary, boxShadow: `0 0 0 3px ${t3.focus.ring}` },
1533
+ disabled: { opacity: 0.55, cursor: "not-allowed", background: t3.surface.sunken }
1534
+ },
1535
+ when: {
1536
+ invalid: { borderColor: t3.danger.border, boxShadow: `0 0 0 3px ${t3.danger.surface}` }
1537
+ }
1538
+ };
1539
+ function input() {
1540
+ return style(CONTROL_BASE);
1541
+ }
1542
+ function field() {
1543
+ return style({ display: "flex", flexDirection: "column", gap: t3.space["2"] });
1544
+ }
1545
+ function fieldLabel() {
1546
+ return style({
1547
+ fontFamily: t3.font.sans,
1548
+ fontSize: t3.size.sm,
1549
+ fontWeight: t3.weight.medium,
1550
+ color: t3.content.primary
1551
+ });
1552
+ }
1553
+ function fieldHelp() {
1554
+ return style({ fontFamily: t3.font.sans, fontSize: t3.size.xs, color: t3.content.muted });
1555
+ }
1556
+ function fieldError() {
1557
+ return style({
1558
+ fontFamily: t3.font.sans,
1559
+ fontSize: t3.size.xs,
1560
+ fontWeight: t3.weight.medium,
1561
+ color: t3.danger.content
1562
+ });
1563
+ }
1564
+ function button() {
1565
+ return style({
1566
+ fontFamily: t3.font.sans,
1567
+ fontSize: t3.size.md,
1568
+ fontWeight: t3.weight.semibold,
1569
+ lineHeight: t3.leading.normal,
1570
+ color: t3.accent.contrast,
1571
+ background: t3.accent.primary,
1572
+ borderWidth: 0,
1573
+ borderStyle: "solid",
1574
+ borderRadius: t3.radius.md,
1575
+ paddingTop: t3.space["2"],
1576
+ paddingBottom: t3.space["2"],
1577
+ paddingLeft: t3.space["4"],
1578
+ paddingRight: t3.space["4"],
1579
+ cursor: "pointer",
1580
+ appearance: "none",
1581
+ transition: `background ${t3.duration.fast} ${t3.easing.standard}`,
1582
+ on: {
1583
+ hover: { background: t3.accent.hover },
1584
+ focusVisible: { outline: "none", boxShadow: `0 0 0 3px ${t3.focus.ring}` },
1585
+ disabled: { opacity: 0.55, cursor: "not-allowed" }
1586
+ }
1587
+ });
1588
+ }
1589
+ var form = { field, input, label: fieldLabel, help: fieldHelp, error: fieldError, button };
1590
+
1591
+ // ../core/src/styling/overlays.ts
1592
+ var t4 = tokens.ref;
1593
+ function backdrop() {
1594
+ return style({
1595
+ position: "fixed",
1596
+ inset: 0,
1597
+ background: t4.surface.overlay,
1598
+ zIndex: t4.z.overlay
1599
+ });
1600
+ }
1601
+ function dialog() {
1602
+ return style({
1603
+ position: "relative",
1604
+ background: t4.surface.background,
1605
+ color: t4.content.primary,
1606
+ borderRadius: t4.radius.lg,
1607
+ boxShadow: t4.shadow.lg,
1608
+ borderWidth: 1,
1609
+ borderStyle: "solid",
1610
+ borderColor: t4.border.default,
1611
+ padding: t4.space["5"],
1612
+ maxWidth: "min(560px, calc(100vw - 32px))",
1613
+ width: "100%",
1614
+ zIndex: t4.z.overlay
1615
+ });
1616
+ }
1617
+ function popover() {
1618
+ return style({
1619
+ position: "absolute",
1620
+ background: t4.surface.raised,
1621
+ color: t4.content.primary,
1622
+ borderRadius: t4.radius.md,
1623
+ boxShadow: t4.shadow.md,
1624
+ borderWidth: 1,
1625
+ borderStyle: "solid",
1626
+ borderColor: t4.border.default,
1627
+ padding: t4.space["3"],
1628
+ zIndex: t4.z.dropdown
1629
+ });
1630
+ }
1631
+ function tooltip() {
1632
+ return style({
1633
+ position: "absolute",
1634
+ background: t4.content.primary,
1635
+ color: t4.surface.background,
1636
+ fontFamily: t4.font.sans,
1637
+ fontSize: t4.size.xs,
1638
+ lineHeight: t4.leading.tight,
1639
+ borderRadius: t4.radius.sm,
1640
+ paddingTop: t4.space["1"],
1641
+ paddingBottom: t4.space["1"],
1642
+ paddingLeft: t4.space["2"],
1643
+ paddingRight: t4.space["2"],
1644
+ maxWidth: 240,
1645
+ zIndex: t4.z.overlay,
1646
+ pointerEvents: "none"
1647
+ });
1648
+ }
1649
+ var MENU_BASE = {
1650
+ position: "absolute",
1651
+ background: t4.surface.background,
1652
+ color: t4.content.primary,
1653
+ borderRadius: t4.radius.md,
1654
+ boxShadow: t4.shadow.md,
1655
+ borderWidth: 1,
1656
+ borderStyle: "solid",
1657
+ borderColor: t4.border.default,
1658
+ paddingTop: t4.space["1"],
1659
+ paddingBottom: t4.space["1"],
1660
+ minWidth: 180,
1661
+ zIndex: t4.z.dropdown
1662
+ };
1663
+ function dropdown() {
1664
+ return style(MENU_BASE);
1665
+ }
1666
+ function dropdownItem() {
1667
+ return style({
1668
+ display: "flex",
1669
+ alignItems: "center",
1670
+ gap: t4.space["2"],
1671
+ fontFamily: t4.font.sans,
1672
+ fontSize: t4.size.sm,
1673
+ color: t4.content.primary,
1674
+ paddingTop: t4.space["2"],
1675
+ paddingBottom: t4.space["2"],
1676
+ paddingLeft: t4.space["3"],
1677
+ paddingRight: t4.space["3"],
1678
+ cursor: "pointer",
1679
+ on: {
1680
+ hover: { background: t4.surface.raised },
1681
+ disabled: { opacity: 0.5, cursor: "not-allowed" }
1682
+ },
1683
+ when: { selected: { background: t4.surface.sunken, fontWeight: t4.weight.medium } }
1684
+ });
1685
+ }
1686
+ function toast() {
1687
+ return style({
1688
+ background: t4.surface.raised,
1689
+ color: t4.content.primary,
1690
+ borderRadius: t4.radius.md,
1691
+ boxShadow: t4.shadow.lg,
1692
+ borderWidth: 1,
1693
+ borderStyle: "solid",
1694
+ borderColor: t4.border.default,
1695
+ padding: t4.space["3"],
1696
+ minWidth: 240,
1697
+ maxWidth: 420,
1698
+ zIndex: t4.z.toast
1699
+ });
1700
+ }
1701
+ var overlay = {
1702
+ backdrop,
1703
+ dialog,
1704
+ popover,
1705
+ tooltip,
1706
+ dropdown,
1707
+ dropdownItem,
1708
+ toast
1709
+ };
1710
+
1711
+ // ../core/src/styling/animation.ts
1712
+ var t5 = tokens.ref;
1713
+ var KEYFRAMES = {
1714
+ "streetui-fade-in": "from{opacity:0}to{opacity:1}",
1715
+ "streetui-fade-out": "from{opacity:1}to{opacity:0}",
1716
+ "streetui-scale-in": "from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}",
1717
+ "streetui-scale-out": "from{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.96)}",
1718
+ "streetui-slide-in-up": "from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}",
1719
+ "streetui-slide-out-down": "from{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(8px)}",
1720
+ "streetui-spin": "to{transform:rotate(360deg)}"
1721
+ };
1722
+ function ensureKeyframes(name) {
1723
+ const id = `kf-${name}`;
1724
+ if (!styleRegistry.has(id)) {
1725
+ styleRegistry.register(id, "base", `@keyframes ${name}{${KEYFRAMES[name]}}`);
1726
+ }
1727
+ }
1728
+ function animate(name, opts = {}) {
1729
+ ensureKeyframes(name);
1730
+ const duration = t5.duration[opts.duration ?? "base"];
1731
+ const easing = t5.easing[opts.easing ?? "standard"];
1732
+ const iterations = opts.iterations ?? 1;
1733
+ const fill = opts.fill ?? "both";
1734
+ return style({
1735
+ animationName: name,
1736
+ animationDuration: duration,
1737
+ animationTimingFunction: easing,
1738
+ animationFillMode: fill,
1739
+ animationIterationCount: String(iterations),
1740
+ ...opts.delay !== void 0 ? { animationDelay: opts.delay } : {}
1741
+ });
1742
+ }
1743
+ function transition(properties, opts = {}) {
1744
+ const props = typeof properties === "string" ? [properties] : properties;
1745
+ const duration = t5.duration[opts.duration ?? "base"];
1746
+ const easing = t5.easing[opts.easing ?? "standard"];
1747
+ const delay = opts.delay !== void 0 ? ` ${typeof opts.delay === "number" ? `${opts.delay}ms` : opts.delay}` : "";
1748
+ return props.map((p) => `${p} ${duration} ${easing}${delay}`).join(", ");
1749
+ }
1750
+ var animation = { animate, transition, keyframes: KEYFRAMES };
1751
+
874
1752
  // ../graph/src/graph-node.ts
875
1753
  var GraphNode = class _GraphNode {
876
1754
  id;
@@ -1404,13 +2282,13 @@ var ContentBuilderBase = class {
1404
2282
  this._node = _node;
1405
2283
  this._graph = _graph;
1406
2284
  }
1407
- heading(text, options = {}) {
2285
+ heading(text2, options = {}) {
1408
2286
  const props = { level: options.level ?? 1 };
1409
2287
  if (options.class !== void 0) props["class"] = options.class;
1410
2288
  if (options.id !== void 0) props["id"] = options.id;
1411
2289
  applyA11yProps(props, options);
1412
2290
  const node = this._graph.createNode("heading", { parent: this._node, props });
1413
- const resolved = bindValue(this._graph, node, "text", text);
2291
+ const resolved = bindValue(this._graph, node, "text", text2);
1414
2292
  node.setProp("text", resolved);
1415
2293
  }
1416
2294
  text(content, options = {}) {
@@ -1422,13 +2300,13 @@ var ContentBuilderBase = class {
1422
2300
  const resolved = bindValue(this._graph, node, "text", content);
1423
2301
  node.setProp("text", resolved);
1424
2302
  }
1425
- button(label, options = {}) {
2303
+ button(label2, options = {}) {
1426
2304
  const props = {};
1427
2305
  if (options.class !== void 0) props["class"] = options.class;
1428
2306
  if (options.id !== void 0) props["id"] = options.id;
1429
2307
  applyA11yProps(props, options);
1430
2308
  const node = this._graph.createNode("button", { parent: this._node, props });
1431
- const resolved = bindValue(this._graph, node, "label", label);
2309
+ const resolved = bindValue(this._graph, node, "label", label2);
1432
2310
  node.setProp("label", resolved);
1433
2311
  if (options.disabled !== void 0) {
1434
2312
  const resolvedDisabled = bindValue(this._graph, node, "disabled", options.disabled);
@@ -1492,7 +2370,7 @@ var ContentBuilderBase = class {
1492
2370
  if (options.id !== void 0) nodeOpts.key = options.id;
1493
2371
  this._graph.createNode("image", nodeOpts);
1494
2372
  }
1495
- link(label, options) {
2373
+ link(label2, options) {
1496
2374
  const props = {
1497
2375
  href: options.href,
1498
2376
  external: options.external ?? false
@@ -1501,7 +2379,7 @@ var ContentBuilderBase = class {
1501
2379
  if (options.id !== void 0) props["id"] = options.id;
1502
2380
  applyA11yProps(props, options);
1503
2381
  const node = this._graph.createNode("link", { parent: this._node, props });
1504
- const resolved = bindValue(this._graph, node, "label", label);
2382
+ const resolved = bindValue(this._graph, node, "label", label2);
1505
2383
  node.setProp("label", resolved);
1506
2384
  if (options.onClick !== void 0) {
1507
2385
  const handlerKey = `click:${node.id}`;
@@ -1509,6 +2387,16 @@ var ContentBuilderBase = class {
1509
2387
  node.addEvent({ type: "click", handlerKey });
1510
2388
  }
1511
2389
  }
2390
+ code(source, options = {}) {
2391
+ const props = {};
2392
+ if (options.language !== void 0) props["data-language"] = options.language;
2393
+ if (options.class !== void 0) props["class"] = options.class;
2394
+ if (options.id !== void 0) props["id"] = options.id;
2395
+ applyA11yProps(props, options);
2396
+ const node = this._graph.createNode("code", { parent: this._node, props });
2397
+ const resolved = bindValue(this._graph, node, "text", source);
2398
+ node.setProp("text", resolved);
2399
+ }
1512
2400
  };
1513
2401
  var ContainerBuilderBase = class extends ContentBuilderBase {
1514
2402
  section(key, builder, options = {}) {
@@ -1675,9 +2563,9 @@ var ContainerBuilderBase = class extends ContentBuilderBase {
1675
2563
  options.fallback(fb, currentError, retry);
1676
2564
  },
1677
2565
  // Healthy state → body, guarded against synchronous build throws.
1678
- (body) => {
2566
+ (body2) => {
1679
2567
  try {
1680
- builder(body);
2568
+ builder(body2);
1681
2569
  } catch (err) {
1682
2570
  queueMicrotask(() => localError.set(err));
1683
2571
  }
@@ -1960,8 +2848,8 @@ function validateGraph(graph) {
1960
2848
  function validateNode(node, dc) {
1961
2849
  switch (node.type) {
1962
2850
  case "heading": {
1963
- const text = node.getProp("text");
1964
- if (text === void 0 || text === "") {
2851
+ const text2 = node.getProp("text");
2852
+ if (text2 === void 0 || text2 === "") {
1965
2853
  dc.warn("COMPILER_EMPTY_HEADING", `Heading node "${node.id}" has no text content`, {
1966
2854
  nodeId: node.id
1967
2855
  });
@@ -2241,11 +3129,11 @@ var Runtime = class {
2241
3129
  /**
2242
3130
  * Mount the compiled application into the given DOM container.
2243
3131
  */
2244
- mount(compiled, container) {
3132
+ mount(compiled, container2) {
2245
3133
  if (this._mounted) {
2246
3134
  throw new Error("[Runtime] Already mounted. Call unmount() first.");
2247
3135
  }
2248
- this._renderHandle = this._renderer.mount(compiled, container);
3136
+ this._renderHandle = this._renderer.mount(compiled, container2);
2249
3137
  this._mounted = true;
2250
3138
  this._bindSignals(compiled.graph);
2251
3139
  const self2 = this;
@@ -2274,11 +3162,11 @@ var Runtime = class {
2274
3162
  * cannot hydrate. Signal binding is identical to `mount`, so the live client
2275
3163
  * lifecycle is established the same way.
2276
3164
  */
2277
- hydrate(compiled, container) {
3165
+ hydrate(compiled, container2) {
2278
3166
  if (this._mounted) {
2279
3167
  throw new Error("[Runtime] Already mounted. Call unmount() first.");
2280
3168
  }
2281
- this._renderHandle = this._renderer.hydrate !== void 0 ? this._renderer.hydrate(compiled, container) : this._renderer.mount(compiled, container);
3169
+ this._renderHandle = this._renderer.hydrate !== void 0 ? this._renderer.hydrate(compiled, container2) : this._renderer.mount(compiled, container2);
2282
3170
  this._mounted = true;
2283
3171
  this._bindSignals(compiled.graph);
2284
3172
  const self2 = this;
@@ -2453,8 +3341,8 @@ var BrowserDOMAdapter = class {
2453
3341
  setProperty(element, name, value) {
2454
3342
  element[name] = value;
2455
3343
  }
2456
- setTextContent(node, text) {
2457
- node.textContent = text;
3344
+ setTextContent(node, text2) {
3345
+ node.textContent = text2;
2458
3346
  }
2459
3347
  getTextContent(node) {
2460
3348
  return node.textContent;
@@ -2694,9 +3582,9 @@ function serializeAttributes(el) {
2694
3582
  }
2695
3583
  }
2696
3584
  }
2697
- const style = el._style;
2698
- if (style !== null && !style.isEmpty && !el.attributes.has("style")) {
2699
- parts.push(` style="${escapeHtmlAttr(style.toCss())}"`);
3585
+ const style2 = el._style;
3586
+ if (style2 !== null && !style2.isEmpty && !el.attributes.has("style")) {
3587
+ parts.push(` style="${escapeHtmlAttr(style2.toCss())}"`);
2700
3588
  }
2701
3589
  return parts.join("");
2702
3590
  }
@@ -2819,16 +3707,16 @@ var ServerDOMAdapter = class {
2819
3707
  setProperty(element, name, value) {
2820
3708
  element.properties.set(name, value);
2821
3709
  }
2822
- setTextContent(node, text) {
3710
+ setTextContent(node, text2) {
2823
3711
  const n = asServer(node);
2824
3712
  if (n.kind === "element" || n.kind === "fragment") {
2825
3713
  const el = n;
2826
3714
  el.children.length = 0;
2827
- const t = new ServerText(text);
2828
- t.parent = el;
2829
- el.children.push(t);
3715
+ const t6 = new ServerText(text2);
3716
+ t6.parent = el;
3717
+ el.children.push(t6);
2830
3718
  } else if (n.kind === "text") {
2831
- n.data = text;
3719
+ n.data = text2;
2832
3720
  }
2833
3721
  }
2834
3722
  getTextContent(node) {
@@ -2933,14 +3821,14 @@ function focusById(dom, root, id) {
2933
3821
  dom.focus(el);
2934
3822
  return true;
2935
3823
  }
2936
- function focusFirst(dom, container, selector = FOCUSABLE_SELECTOR) {
2937
- const el = dom.querySelector(container, selector);
3824
+ function focusFirst(dom, container2, selector = FOCUSABLE_SELECTOR) {
3825
+ const el = dom.querySelector(container2, selector);
2938
3826
  if (el === null) return false;
2939
3827
  dom.focus(el);
2940
3828
  return true;
2941
3829
  }
2942
- function getFocusable(dom, container, selector = FOCUSABLE_SELECTOR) {
2943
- return Array.from(dom.querySelectorAll(container, selector)).filter(
3830
+ function getFocusable(dom, container2, selector = FOCUSABLE_SELECTOR) {
3831
+ return Array.from(dom.querySelectorAll(container2, selector)).filter(
2944
3832
  (el) => dom.matches(el, selector)
2945
3833
  );
2946
3834
  }
@@ -2950,14 +3838,14 @@ function saveFocus(dom) {
2950
3838
  function restoreFocus(dom, saved) {
2951
3839
  if (saved !== null) dom.focus(saved);
2952
3840
  }
2953
- function focusInitial(dom, container, initialFocusId) {
2954
- if (initialFocusId !== void 0 && focusById(dom, container, initialFocusId)) return;
2955
- focusFirst(dom, container);
3841
+ function focusInitial(dom, container2, initialFocusId) {
3842
+ if (initialFocusId !== void 0 && focusById(dom, container2, initialFocusId)) return;
3843
+ focusFirst(dom, container2);
2956
3844
  }
2957
- function trapFocus(dom, container) {
3845
+ function trapFocus(dom, container2) {
2958
3846
  const onKeydown = (event) => {
2959
3847
  if (event.key !== "Tab") return;
2960
- const items = getFocusable(dom, container);
3848
+ const items = getFocusable(dom, container2);
2961
3849
  if (items.length === 0) {
2962
3850
  event.preventDefault();
2963
3851
  return;
@@ -2965,7 +3853,7 @@ function trapFocus(dom, container) {
2965
3853
  const first = items[0];
2966
3854
  const last = items[items.length - 1];
2967
3855
  const active = dom.activeElement();
2968
- if (active === null || !dom.contains(container, active)) {
3856
+ if (active === null || !dom.contains(container2, active)) {
2969
3857
  event.preventDefault();
2970
3858
  dom.focus(first);
2971
3859
  } else if (event.shiftKey && active === first) {
@@ -2976,26 +3864,26 @@ function trapFocus(dom, container) {
2976
3864
  dom.focus(first);
2977
3865
  }
2978
3866
  };
2979
- dom.addEventListener(container, "keydown", onKeydown);
2980
- return () => dom.removeEventListener(container, "keydown", onKeydown);
3867
+ dom.addEventListener(container2, "keydown", onKeydown);
3868
+ return () => dom.removeEventListener(container2, "keydown", onKeydown);
2981
3869
  }
2982
3870
  var containmentStack = [];
2983
- function containFocus(dom, container) {
2984
- const body = dom.body();
2985
- if (body === null) return () => {
3871
+ function containFocus(dom, container2) {
3872
+ const body2 = dom.body();
3873
+ if (body2 === null) return () => {
2986
3874
  };
2987
- containmentStack.push(container);
3875
+ containmentStack.push(container2);
2988
3876
  const onFocusIn = (event) => {
2989
- if (containmentStack[containmentStack.length - 1] !== container) return;
3877
+ if (containmentStack[containmentStack.length - 1] !== container2) return;
2990
3878
  const target = event.target;
2991
- if (target !== null && !dom.contains(container, target)) {
2992
- focusFirst(dom, container);
3879
+ if (target !== null && !dom.contains(container2, target)) {
3880
+ focusFirst(dom, container2);
2993
3881
  }
2994
3882
  };
2995
- dom.addEventListener(body, "focusin", onFocusIn);
3883
+ dom.addEventListener(body2, "focusin", onFocusIn);
2996
3884
  return () => {
2997
- dom.removeEventListener(body, "focusin", onFocusIn);
2998
- const index = containmentStack.lastIndexOf(container);
3885
+ dom.removeEventListener(body2, "focusin", onFocusIn);
3886
+ const index = containmentStack.lastIndexOf(container2);
2999
3887
  if (index !== -1) containmentStack.splice(index, 1);
3000
3888
  };
3001
3889
  }
@@ -3006,13 +3894,13 @@ function onEscape(dom, target, handler) {
3006
3894
  dom.addEventListener(target, "keydown", onKeydown);
3007
3895
  return () => dom.removeEventListener(target, "keydown", onKeydown);
3008
3896
  }
3009
- function rovingMenu(dom, container, selector = FOCUSABLE_SELECTOR) {
3897
+ function rovingMenu(dom, container2, selector = FOCUSABLE_SELECTOR) {
3010
3898
  const onKeydown = (event) => {
3011
3899
  const key = event.key;
3012
3900
  const isActivate = key === "Enter" || key === " " || key === "Spacebar";
3013
3901
  const isMove = key === "ArrowDown" || key === "ArrowUp" || key === "Home" || key === "End";
3014
3902
  if (!isActivate && !isMove) return;
3015
- const items = getFocusable(dom, container, selector);
3903
+ const items = getFocusable(dom, container2, selector);
3016
3904
  if (items.length === 0) return;
3017
3905
  const active = dom.activeElement();
3018
3906
  const index = active === null ? -1 : items.indexOf(active);
@@ -3030,8 +3918,8 @@ function rovingMenu(dom, container, selector = FOCUSABLE_SELECTOR) {
3030
3918
  else next = index <= 0 ? items.length - 1 : index - 1;
3031
3919
  dom.focus(items[next]);
3032
3920
  };
3033
- dom.addEventListener(container, "keydown", onKeydown);
3034
- return () => dom.removeEventListener(container, "keydown", onKeydown);
3921
+ dom.addEventListener(container2, "keydown", onKeydown);
3922
+ return () => dom.removeEventListener(container2, "keydown", onKeydown);
3035
3923
  }
3036
3924
 
3037
3925
  // ../dom/src/live-region.ts
@@ -3046,8 +3934,8 @@ function makeRegion(dom, politeness) {
3046
3934
  return el;
3047
3935
  }
3048
3936
  function createAnnouncer(dom) {
3049
- const body = dom.body();
3050
- if (body === null) {
3937
+ const body2 = dom.body();
3938
+ if (body2 === null) {
3051
3939
  return { announce() {
3052
3940
  }, clear() {
3053
3941
  }, destroy() {
@@ -3055,8 +3943,8 @@ function createAnnouncer(dom) {
3055
3943
  }
3056
3944
  const polite = makeRegion(dom, "polite");
3057
3945
  const assertive = makeRegion(dom, "assertive");
3058
- dom.appendChild(body, polite);
3059
- dom.appendChild(body, assertive);
3946
+ dom.appendChild(body2, polite);
3947
+ dom.appendChild(body2, assertive);
3060
3948
  let destroyed = false;
3061
3949
  const write = (region, message) => {
3062
3950
  dom.setTextContent(region, "");
@@ -3086,12 +3974,12 @@ function createAnnouncer(dom) {
3086
3974
  }
3087
3975
 
3088
3976
  // ../renderer/src/render-context.ts
3089
- function createRenderContext(dom, graph, container, hydrationDiagnostics, staticHTML) {
3977
+ function createRenderContext(dom, graph, container2, hydrationDiagnostics, staticHTML) {
3090
3978
  return {
3091
3979
  dom,
3092
3980
  graph,
3093
3981
  instances: /* @__PURE__ */ new Map(),
3094
- container,
3982
+ container: container2,
3095
3983
  ...hydrationDiagnostics !== void 0 ? { hydrationDiagnostics } : {},
3096
3984
  ...staticHTML !== void 0 ? { staticHTML } : {}
3097
3985
  };
@@ -3189,6 +4077,13 @@ function applyProp(dom, element, name, value) {
3189
4077
  }
3190
4078
  return;
3191
4079
  }
4080
+ if (name.startsWith("style.")) {
4081
+ const el = element;
4082
+ const prop = name.slice("style.".length);
4083
+ if (value === null || value === void 0) el.style.removeProperty(prop);
4084
+ else el.style.setProperty(prop, String(value));
4085
+ return;
4086
+ }
3192
4087
  if (value === null || value === void 0 || value === false) {
3193
4088
  dom.removeAttribute(element, name);
3194
4089
  return;
@@ -3208,8 +4103,8 @@ function wireEvents(dom, graph, node, element, instance) {
3208
4103
  if (handler === void 0) continue;
3209
4104
  const domListener = (domEvent) => {
3210
4105
  if (eventDesc.type === "input" || eventDesc.type === "change") {
3211
- const input = domEvent.target;
3212
- handler(input.value);
4106
+ const input2 = domEvent.target;
4107
+ handler(input2.value);
3213
4108
  } else if (eventDesc.type === "submit") {
3214
4109
  domEvent.preventDefault();
3215
4110
  handler(domEvent);
@@ -3239,6 +4134,11 @@ var TAG_MAP = {
3239
4134
  "list-item": "li",
3240
4135
  image: "img",
3241
4136
  link: "a",
4137
+ // A `code()` node renders as a semantic `<pre>` outer element; the mount/
4138
+ // hydrate branches add a single inner `<code>` holding the escaped source
4139
+ // (mirrors how `text` renders `<span>` + an inner text node). One graph
4140
+ // node → one outer element preserves positional hydration.
4141
+ code: "pre",
3242
4142
  component: "div",
3243
4143
  slot: "div",
3244
4144
  fragment: "div",
@@ -3548,7 +4448,7 @@ function nextFrame(cb) {
3548
4448
  function splitClass(value) {
3549
4449
  if (value === null) return [];
3550
4450
  const out = [];
3551
- for (const t of value.split(/\s+/)) if (t.length > 0) out.push(t);
4451
+ for (const t6 of value.split(/\s+/)) if (t6.length > 0) out.push(t6);
3552
4452
  return out;
3553
4453
  }
3554
4454
  function addClasses(dom, el, classes2) {
@@ -3930,9 +4830,9 @@ function mountNode(ctx, graphNode, parentDom) {
3930
4830
  return instance2;
3931
4831
  }
3932
4832
  if (graphNode.type === "text") {
3933
- const text = String(graphNode.getProp("text") ?? "");
4833
+ const text2 = String(graphNode.getProp("text") ?? "");
3934
4834
  const el2 = dom.createElement("span");
3935
- const textNode = dom.createTextNode(text);
4835
+ const textNode = dom.createTextNode(text2);
3936
4836
  dom.appendChild(el2, textNode);
3937
4837
  applyNodeProps(ctx, graphNode, el2);
3938
4838
  const instance2 = new NodeInstance(graphNode, el2);
@@ -3948,8 +4848,8 @@ function mountNode(ctx, graphNode, parentDom) {
3948
4848
  const level = graphNode.getProp("level") ?? 1;
3949
4849
  const tag2 = `h${level}`;
3950
4850
  const el2 = dom.createElement(tag2);
3951
- const text = String(graphNode.getProp("text") ?? "");
3952
- dom.setTextContent(el2, text);
4851
+ const text2 = String(graphNode.getProp("text") ?? "");
4852
+ dom.setTextContent(el2, text2);
3953
4853
  applyNodeProps(ctx, graphNode, el2);
3954
4854
  const instance2 = new NodeInstance(graphNode, el2);
3955
4855
  ctx.instances.set(graphNode.id, instance2);
@@ -3994,13 +4894,30 @@ function mountNode(ctx, graphNode, parentDom) {
3994
4894
  dom.appendChild(parentDom, el2);
3995
4895
  return instance2;
3996
4896
  }
4897
+ if (graphNode.type === "code") {
4898
+ const source = String(graphNode.getProp("text") ?? "");
4899
+ const pre2 = dom.createElement("pre");
4900
+ const codeEl = dom.createElement("code");
4901
+ const textNode = dom.createTextNode(source);
4902
+ dom.appendChild(codeEl, textNode);
4903
+ dom.appendChild(pre2, codeEl);
4904
+ applyNodeProps(ctx, graphNode, pre2);
4905
+ const instance2 = new NodeInstance(graphNode, pre2);
4906
+ ctx.instances.set(graphNode.id, instance2);
4907
+ wireEvents(dom, graph, graphNode, pre2, instance2);
4908
+ if (graphNode.stateRefs.length !== 0) {
4909
+ wireSignalBindings(ctx, graphNode, instance2, textUpdate(dom, pre2, textNode));
4910
+ }
4911
+ dom.appendChild(parentDom, pre2);
4912
+ return instance2;
4913
+ }
3997
4914
  if (graphNode.type === "link") {
3998
4915
  const el2 = dom.createElement("a");
3999
4916
  const href = graphNode.getProp("href");
4000
- const label = graphNode.getProp("label");
4917
+ const label2 = graphNode.getProp("label");
4001
4918
  const external = graphNode.getProp("external");
4002
4919
  if (href !== void 0) dom.setAttribute(el2, "href", String(href));
4003
- if (label !== void 0) dom.setTextContent(el2, String(label));
4920
+ if (label2 !== void 0) dom.setTextContent(el2, String(label2));
4004
4921
  if (external === true) {
4005
4922
  dom.setAttribute(el2, "target", "_blank");
4006
4923
  dom.setAttribute(el2, "rel", "noopener noreferrer");
@@ -4017,8 +4934,8 @@ function mountNode(ctx, graphNode, parentDom) {
4017
4934
  }
4018
4935
  if (graphNode.type === "button") {
4019
4936
  const el2 = dom.createElement("button");
4020
- const label = graphNode.getProp("label");
4021
- if (label !== void 0) dom.setTextContent(el2, String(label));
4937
+ const label2 = graphNode.getProp("label");
4938
+ if (label2 !== void 0) dom.setTextContent(el2, String(label2));
4022
4939
  const disabled = graphNode.getProp("disabled");
4023
4940
  if (disabled === true) dom.setAttribute(el2, "disabled", "");
4024
4941
  applyNodeProps(ctx, graphNode, el2);
@@ -4051,13 +4968,13 @@ function mountNode(ctx, graphNode, parentDom) {
4051
4968
  applyNodeProps(ctx, graphNode, anchor);
4052
4969
  const instance2 = new NodeInstance(graphNode, anchor);
4053
4970
  ctx.instances.set(graphNode.id, instance2);
4054
- const body = dom.body();
4971
+ const body2 = dom.body();
4055
4972
  let target = anchor;
4056
- if (body !== null) {
4973
+ if (body2 !== null) {
4057
4974
  const portalContainer = dom.createElement("div");
4058
4975
  dom.setAttribute(portalContainer, "data-streetui-portal-container", "");
4059
- dom.appendChild(body, portalContainer);
4060
- instance2.trackCleanup(() => dom.removeChild(body, portalContainer));
4976
+ dom.appendChild(body2, portalContainer);
4977
+ instance2.trackCleanup(() => dom.removeChild(body2, portalContainer));
4061
4978
  target = portalContainer;
4062
4979
  }
4063
4980
  for (const child of graphNode.children) {
@@ -4296,6 +5213,173 @@ function wireComponentBehavior(ctx, graphNode, instance) {
4296
5213
  for (const cleanup of fn()) instance.trackCleanup(cleanup);
4297
5214
  }
4298
5215
 
5216
+ // ../renderer/src/styling-transitions.ts
5217
+ var DURATION_MS = { fast: 120, base: 200, slow: 320 };
5218
+ function activeClass(props, duration, easing) {
5219
+ return style({ transition: transition(props, { duration, easing }) });
5220
+ }
5221
+ function fadeTransition(opts = {}) {
5222
+ const duration = opts.duration ?? "base";
5223
+ const easing = opts.easing ?? "standard";
5224
+ const active = activeClass(["opacity"], duration, easing);
5225
+ const hidden = style({ opacity: 0 });
5226
+ const shown = style({ opacity: 1 });
5227
+ return {
5228
+ enterActive: [active],
5229
+ enterFrom: [hidden],
5230
+ enterTo: [shown],
5231
+ leaveActive: [active],
5232
+ leaveFrom: [shown],
5233
+ leaveTo: [hidden],
5234
+ appear: opts.appear ?? false,
5235
+ duration: DURATION_MS[duration]
5236
+ };
5237
+ }
5238
+ function scaleTransition(opts = {}) {
5239
+ const duration = opts.duration ?? "base";
5240
+ const easing = opts.easing ?? "emphasized";
5241
+ const active = activeClass(["opacity", "transform"], duration, easing);
5242
+ const hidden = style({ opacity: 0, transform: "scale(.96)" });
5243
+ const shown = style({ opacity: 1, transform: "scale(1)" });
5244
+ return {
5245
+ enterActive: [active],
5246
+ enterFrom: [hidden],
5247
+ enterTo: [shown],
5248
+ leaveActive: [active],
5249
+ leaveFrom: [shown],
5250
+ leaveTo: [hidden],
5251
+ appear: opts.appear ?? false,
5252
+ duration: DURATION_MS[duration]
5253
+ };
5254
+ }
5255
+ function slideTransition(opts = {}) {
5256
+ const duration = opts.duration ?? "base";
5257
+ const easing = opts.easing ?? "standard";
5258
+ const active = activeClass(["opacity", "transform"], duration, easing);
5259
+ const hidden = style({ opacity: 0, transform: "translateY(8px)" });
5260
+ const shown = style({ opacity: 1, transform: "translateY(0)" });
5261
+ return {
5262
+ enterActive: [active],
5263
+ enterFrom: [hidden],
5264
+ enterTo: [shown],
5265
+ leaveActive: [active],
5266
+ leaveFrom: [shown],
5267
+ leaveTo: [hidden],
5268
+ appear: opts.appear ?? false,
5269
+ duration: DURATION_MS[duration]
5270
+ };
5271
+ }
5272
+ var transitions = { fadeTransition, scaleTransition, slideTransition };
5273
+
5274
+ // ../renderer/src/styles.ts
5275
+ var CSS_MARKER = "data-streetui-css";
5276
+ var CSS_KEYS = "data-streetui-css-keys";
5277
+ function renderStyles(options = {}) {
5278
+ const registry = options.registry ?? styleRegistry;
5279
+ const css = registry.serializeCSS();
5280
+ if (css.length === 0) return "";
5281
+ const keys = registry.identities().join(" ");
5282
+ return `<style ${CSS_MARKER} ${CSS_KEYS}="${keys}">${css}</style>`;
5283
+ }
5284
+ function adoptServerStyles(dom, root, options = {}) {
5285
+ const registry = options.registry ?? styleRegistry;
5286
+ const el = findStyleBlock(dom, root);
5287
+ if (el === null) return 0;
5288
+ const keysAttr = dom.getAttribute(el, CSS_KEYS);
5289
+ if (keysAttr === null || keysAttr.length === 0) {
5290
+ registry.adoptServerIdentities([]);
5291
+ return 0;
5292
+ }
5293
+ const ids = keysAttr.split(" ").filter((s) => s.length > 0);
5294
+ registry.adoptServerIdentities(ids);
5295
+ return ids.length;
5296
+ }
5297
+ function findStyleBlock(dom, root) {
5298
+ const head = dom.head();
5299
+ const scope = root ?? head;
5300
+ if (scope === null) return null;
5301
+ return searchDescendants(dom, scope);
5302
+ }
5303
+ function searchDescendants(dom, el) {
5304
+ if (dom.isElement(el) && dom.getAttribute(el, CSS_MARKER) !== null) return el;
5305
+ for (const child of dom.childNodes(el)) {
5306
+ if (!dom.isElement(child)) continue;
5307
+ const found = searchDescendants(dom, child);
5308
+ if (found !== null) return found;
5309
+ }
5310
+ return null;
5311
+ }
5312
+
5313
+ // ../renderer/src/theme.ts
5314
+ var DEFAULT_STORAGE_KEY = "streetui-theme";
5315
+ var CHOICES = ["light", "dark", "system"];
5316
+ function defaultThemeStorage(key = DEFAULT_STORAGE_KEY) {
5317
+ try {
5318
+ if (typeof localStorage !== "undefined") {
5319
+ return {
5320
+ read() {
5321
+ const v = localStorage.getItem(key);
5322
+ return v === "light" || v === "dark" || v === "system" ? v : null;
5323
+ },
5324
+ write(choice) {
5325
+ try {
5326
+ localStorage.setItem(key, choice);
5327
+ } catch {
5328
+ }
5329
+ }
5330
+ };
5331
+ }
5332
+ } catch {
5333
+ }
5334
+ let mem = null;
5335
+ return { read: () => mem, write: (c) => {
5336
+ mem = c;
5337
+ } };
5338
+ }
5339
+ function systemPrefersDark() {
5340
+ try {
5341
+ return typeof matchMedia !== "undefined" && matchMedia("(prefers-color-scheme: dark)").matches;
5342
+ } catch {
5343
+ return false;
5344
+ }
5345
+ }
5346
+ function createTheme(options = {}) {
5347
+ const storage = options.storage ?? defaultThemeStorage();
5348
+ const choice = signal(storage.read() ?? options.initial ?? "system");
5349
+ const resolved = derived(() => {
5350
+ const c = choice.get();
5351
+ if (c === "system") return systemPrefersDark() ? "dark" : "light";
5352
+ return c;
5353
+ });
5354
+ const label2 = derived(() => {
5355
+ const c = choice.get();
5356
+ return c === "light" ? "Theme: Light" : c === "dark" ? "Theme: Dark" : "Theme: System";
5357
+ });
5358
+ const root = options.root ?? (typeof document !== "undefined" ? document.documentElement : null);
5359
+ const stop = root !== null ? effect(() => {
5360
+ root.setAttribute("data-theme", resolved.get());
5361
+ }) : () => {
5362
+ };
5363
+ return {
5364
+ choice,
5365
+ resolved,
5366
+ label: label2,
5367
+ set(next) {
5368
+ choice.set(next);
5369
+ storage.write(next);
5370
+ },
5371
+ cycle() {
5372
+ const i = CHOICES.indexOf(choice.get());
5373
+ const next = CHOICES[(i + 1) % CHOICES.length];
5374
+ choice.set(next);
5375
+ storage.write(next);
5376
+ },
5377
+ dispose() {
5378
+ stop();
5379
+ }
5380
+ };
5381
+ }
5382
+
4299
5383
  // ../renderer/src/hydration-diagnostics.ts
4300
5384
  function formatHydrationDiagnostic(d) {
4301
5385
  const at = ` at ${d.path}`;
@@ -4382,6 +5466,27 @@ function hydrateNode(ctx, graphNode, domNode, path) {
4382
5466
  }
4383
5467
  return instance;
4384
5468
  }
5469
+ case "code": {
5470
+ let codeEl = dom.firstChild(domNode);
5471
+ if (codeEl === null || dom.isTextNode(codeEl)) {
5472
+ const createdCode = dom.createElement("code");
5473
+ dom.appendChild(domNode, createdCode);
5474
+ codeEl = createdCode;
5475
+ }
5476
+ let textNode = dom.firstChild(codeEl);
5477
+ if (textNode === null || !dom.isTextNode(textNode)) {
5478
+ const created = dom.createTextNode(String(graphNode.getProp("text") ?? ""));
5479
+ dom.appendChild(codeEl, created);
5480
+ textNode = created;
5481
+ }
5482
+ const instance = new NodeInstance(graphNode, domNode);
5483
+ ctx.instances.set(graphNode.id, instance);
5484
+ wireEvents(dom, graph, graphNode, domNode, instance);
5485
+ if (graphNode.stateRefs.length !== 0) {
5486
+ wireSignalBindings(ctx, graphNode, instance, textUpdate(dom, domNode, textNode));
5487
+ }
5488
+ return instance;
5489
+ }
4385
5490
  case "image":
4386
5491
  case "link": {
4387
5492
  const instance = new NodeInstance(graphNode, domNode);
@@ -4405,16 +5510,16 @@ function hydrateNode(ctx, graphNode, domNode, path) {
4405
5510
  case "portal": {
4406
5511
  const instance = new NodeInstance(graphNode, domNode);
4407
5512
  ctx.instances.set(graphNode.id, instance);
4408
- const body = dom.body();
5513
+ const body2 = dom.body();
4409
5514
  let target = domNode;
4410
- if (body !== null) {
5515
+ if (body2 !== null) {
4411
5516
  const portalContainer = dom.createElement("div");
4412
5517
  dom.setAttribute(portalContainer, "data-streetui-portal-container", "");
4413
5518
  for (const child of dom.childNodes(domNode)) {
4414
5519
  dom.appendChild(portalContainer, child);
4415
5520
  }
4416
- dom.appendChild(body, portalContainer);
4417
- instance.trackCleanup(() => dom.removeChild(body, portalContainer));
5521
+ dom.appendChild(body2, portalContainer);
5522
+ instance.trackCleanup(() => dom.removeChild(body2, portalContainer));
4418
5523
  target = portalContainer;
4419
5524
  }
4420
5525
  hydrateChildren(ctx, graphNode, instance, target, path);
@@ -4533,6 +5638,8 @@ function expectedTag(ctx, graphNode) {
4533
5638
  return "img";
4534
5639
  case "link":
4535
5640
  return "a";
5641
+ case "code":
5642
+ return "pre";
4536
5643
  case "button":
4537
5644
  return "button";
4538
5645
  default:
@@ -4557,9 +5664,9 @@ var StreetRenderHandle = class {
4557
5664
  this._disposed = true;
4558
5665
  this._rootInstance.dispose();
4559
5666
  const dom = this._ctx.dom;
4560
- const container = this._ctx.container;
4561
- for (const child of dom.childNodes(container)) {
4562
- dom.removeChild(container, child);
5667
+ const container2 = this._ctx.container;
5668
+ for (const child of dom.childNodes(container2)) {
5669
+ dom.removeChild(container2, child);
4563
5670
  }
4564
5671
  this._ctx.instances.clear();
4565
5672
  }
@@ -4575,8 +5682,8 @@ var StreetRendererImpl = class {
4575
5682
  this._hydrationDiagnostics = options.hydrationDiagnostics;
4576
5683
  }
4577
5684
  }
4578
- mount(compiled, container) {
4579
- const ctx = createRenderContext(this._dom, compiled.graph, container);
5685
+ mount(compiled, container2) {
5686
+ const ctx = createRenderContext(this._dom, compiled.graph, container2);
4580
5687
  const rootInstance = mountGraph(ctx);
4581
5688
  this._wireSignals(ctx, rootInstance);
4582
5689
  return new StreetRenderHandle(ctx, rootInstance);
@@ -4588,11 +5695,11 @@ var StreetRendererImpl = class {
4588
5695
  * behavior (events + signal subscriptions). Mismatched subtrees are locally
4589
5696
  * replaced. Returns the same handle type as `mount`.
4590
5697
  */
4591
- hydrate(compiled, container) {
5698
+ hydrate(compiled, container2) {
4592
5699
  const ctx = createRenderContext(
4593
5700
  this._dom,
4594
5701
  compiled.graph,
4595
- container,
5702
+ container2,
4596
5703
  this._hydrationDiagnostics
4597
5704
  );
4598
5705
  const rootInstance = hydrateGraph(ctx);
@@ -4611,12 +5718,12 @@ var STATE_MARKER_ATTR = "data-streetui-state";
4611
5718
  function escapeForScript(json) {
4612
5719
  let out = "";
4613
5720
  for (const ch of json) {
4614
- const code = ch.charCodeAt(0);
5721
+ const code2 = ch.charCodeAt(0);
4615
5722
  if (ch === "<") out += "\\u003c";
4616
5723
  else if (ch === ">") out += "\\u003e";
4617
5724
  else if (ch === "&") out += "\\u0026";
4618
- else if (code === 8232) out += "\\u2028";
4619
- else if (code === 8233) out += "\\u2029";
5725
+ else if (code2 === 8232) out += "\\u2028";
5726
+ else if (code2 === 8233) out += "\\u2029";
4620
5727
  else out += ch;
4621
5728
  }
4622
5729
  return out;
@@ -4629,10 +5736,10 @@ function serializeState(state) {
4629
5736
  function readState(dom, root) {
4630
5737
  const el = dom.querySelector(root, `script[${STATE_MARKER_ATTR}]`);
4631
5738
  if (el === null) return {};
4632
- const text = dom.getTextContent(el);
4633
- if (text === null || text.length === 0) return {};
5739
+ const text2 = dom.getTextContent(el);
5740
+ if (text2 === null || text2.length === 0) return {};
4634
5741
  try {
4635
- const parsed = JSON.parse(text);
5742
+ const parsed = JSON.parse(text2);
4636
5743
  if (parsed !== null && typeof parsed === "object") {
4637
5744
  return parsed;
4638
5745
  }
@@ -4717,10 +5824,10 @@ function collectMaximalStaticRoots(graph) {
4717
5824
  return roots;
4718
5825
  }
4719
5826
  function serializeStaticSubtree(dom, graph, root) {
4720
- const container = dom.createElement("div");
4721
- const ctx = createRenderContext(dom, graph, container);
4722
- const instance = mountNode(ctx, root, container);
4723
- const html = dom.serializeInner(container);
5827
+ const container2 = dom.createElement("div");
5828
+ const ctx = createRenderContext(dom, graph, container2);
5829
+ const instance = mountNode(ctx, root, container2);
5830
+ const html = dom.serializeInner(container2);
4724
5831
  instance.dispose();
4725
5832
  ctx.instances.clear();
4726
5833
  return html;
@@ -4751,10 +5858,10 @@ function renderToString(compiled, options = {}) {
4751
5858
  const dom = options.domAdapter ?? new ServerDOMAdapter();
4752
5859
  const plan = options.staticPlan === null ? void 0 : options.staticPlan ?? getStaticSSRPlan(compiled);
4753
5860
  const staticHTML = plan !== void 0 && plan.size > 0 ? plan : void 0;
4754
- const container = dom.createElement("div");
4755
- const ctx = createRenderContext(dom, compiled.graph, container, void 0, staticHTML);
5861
+ const container2 = dom.createElement("div");
5862
+ const ctx = createRenderContext(dom, compiled.graph, container2, void 0, staticHTML);
4756
5863
  const rootInstance = mountGraph(ctx);
4757
- const html = dom.serializeInner(container);
5864
+ const html = dom.serializeInner(container2);
4758
5865
  rootInstance.dispose();
4759
5866
  ctx.instances.clear();
4760
5867
  return html;
@@ -4869,20 +5976,20 @@ function createMemoryHistory(initial = "/") {
4869
5976
  if (qIndex < 0) return buildLocation(entry, "");
4870
5977
  return buildLocation(entry.slice(0, qIndex), entry.slice(qIndex + 1));
4871
5978
  };
4872
- const stack = [initial];
5979
+ const stack2 = [initial];
4873
5980
  let index = 0;
4874
5981
  return {
4875
5982
  location() {
4876
- return parse(stack[index]);
5983
+ return parse(stack2[index]);
4877
5984
  },
4878
5985
  push(pathname, search) {
4879
- stack.splice(index + 1);
4880
- stack.push(toUrl(pathname, search));
4881
- index = stack.length - 1;
5986
+ stack2.splice(index + 1);
5987
+ stack2.push(toUrl(pathname, search));
5988
+ index = stack2.length - 1;
4882
5989
  notify();
4883
5990
  },
4884
5991
  replace(pathname, search) {
4885
- stack[index] = toUrl(pathname, search);
5992
+ stack2[index] = toUrl(pathname, search);
4886
5993
  notify();
4887
5994
  },
4888
5995
  back() {
@@ -4892,7 +5999,7 @@ function createMemoryHistory(initial = "/") {
4892
5999
  }
4893
6000
  },
4894
6001
  forward() {
4895
- if (index < stack.length - 1) {
6002
+ if (index < stack2.length - 1) {
4896
6003
  index++;
4897
6004
  notify();
4898
6005
  }
@@ -4982,8 +6089,9 @@ function createRouter(options) {
4982
6089
 
4983
6090
  // ../router/src/mount-router.ts
4984
6091
  var ROUTER_OUTLET_ID = "streetui-router-outlet";
6092
+ var ROUTER_OUTLET_KEY = "router-outlet";
4985
6093
  function routerOutlet(scope, id = ROUTER_OUTLET_ID) {
4986
- scope.container("router-outlet", () => {
6094
+ scope.container(ROUTER_OUTLET_KEY, () => {
4987
6095
  }, { id });
4988
6096
  }
4989
6097
  function isExternalHref(href) {
@@ -4991,7 +6099,7 @@ function isExternalHref(href) {
4991
6099
  href.startsWith("//");
4992
6100
  }
4993
6101
  function mountRouter(router, options) {
4994
- const { container } = options;
6102
+ const { container: container2 } = options;
4995
6103
  const renderer = options.renderer ?? createRenderer();
4996
6104
  const outletId = options.outletId ?? ROUTER_OUTLET_ID;
4997
6105
  const interceptLinks = options.interceptLinks ?? true;
@@ -5009,8 +6117,8 @@ function mountRouter(router, options) {
5009
6117
  node.setProp("_hydrationBoundary", true);
5010
6118
  }
5011
6119
  }
5012
- shellMounted = hydrateMode ? shellRuntime.hydrate(shellCompiled, container) : shellRuntime.mount(shellCompiled, container);
5013
- const found = container.querySelector(`[id="${outletId}"]`);
6120
+ shellMounted = hydrateMode ? shellRuntime.hydrate(shellCompiled, container2) : shellRuntime.mount(shellCompiled, container2);
6121
+ const found = container2.querySelector(`[id="${outletId}"]`);
5014
6122
  if (found === null) {
5015
6123
  throw new Error(
5016
6124
  `[Router] The shell must contain a route outlet. Call routerOutlet(scope) (or add a container with id="${outletId}") inside your shell builder.`
@@ -5018,7 +6126,7 @@ function mountRouter(router, options) {
5018
6126
  }
5019
6127
  outlet = found;
5020
6128
  } else {
5021
- outlet = container;
6129
+ outlet = container2;
5022
6130
  }
5023
6131
  const routeTransition = options.transition !== void 0 ? resolveTransition(options.transition) : void 0;
5024
6132
  const txDom = routeTransition !== void 0 ? new BrowserDOMAdapter() : void 0;
@@ -5131,12 +6239,12 @@ function mountRouter(router, options) {
5131
6239
  router.navigate(href);
5132
6240
  };
5133
6241
  if (interceptLinks) {
5134
- container.addEventListener("click", onClick);
6242
+ container2.addEventListener("click", onClick);
5135
6243
  }
5136
6244
  return {
5137
6245
  outlet,
5138
6246
  unmount() {
5139
- if (interceptLinks) container.removeEventListener("click", onClick);
6247
+ if (interceptLinks) container2.removeEventListener("click", onClick);
5140
6248
  stopRouteSub();
5141
6249
  for (const [route, run] of pendingLeaves) {
5142
6250
  run.cancel();
@@ -5169,8 +6277,8 @@ function pattern(regex, message = "Invalid format") {
5169
6277
  }
5170
6278
  function runValidators(value, validators) {
5171
6279
  if (validators === void 0) return void 0;
5172
- const list = Array.isArray(validators) ? validators : [validators];
5173
- for (const validate of list) {
6280
+ const list2 = Array.isArray(validators) ? validators : [validators];
6281
+ for (const validate of list2) {
5174
6282
  const error = validate(value);
5175
6283
  if (error !== void 0) return error;
5176
6284
  }
@@ -5222,31 +6330,31 @@ function createForm(config) {
5222
6330
  };
5223
6331
  fields.set(name, { api, value, touched, error, valid: valid2, dirty: dirty2, initial, unsub });
5224
6332
  }
5225
- const field = (name) => {
6333
+ const field2 = (name) => {
5226
6334
  const f = fields.get(name);
5227
6335
  if (f === void 0) throw new Error(`Unknown form field: ${name}`);
5228
6336
  return f;
5229
6337
  };
5230
6338
  const values = derived(() => {
5231
6339
  const out = {};
5232
- for (const name of names) out[name] = field(name).value.get();
6340
+ for (const name of names) out[name] = field2(name).value.get();
5233
6341
  return out;
5234
6342
  });
5235
6343
  const errors = derived(() => {
5236
6344
  const out = {};
5237
6345
  for (const name of names) {
5238
- const e = field(name).error.get();
6346
+ const e = field2(name).error.get();
5239
6347
  if (e !== void 0) out[name] = e;
5240
6348
  }
5241
6349
  return out;
5242
6350
  });
5243
6351
  const touchedMap = derived(() => {
5244
6352
  const out = {};
5245
- for (const name of names) out[name] = field(name).touched.get();
6353
+ for (const name of names) out[name] = field2(name).touched.get();
5246
6354
  return out;
5247
6355
  });
5248
- const dirty = derived(() => names.some((n) => field(n).dirty.get()));
5249
- const valid = derived(() => names.every((n) => field(n).valid.get()));
6356
+ const dirty = derived(() => names.some((n) => field2(n).dirty.get()));
6357
+ const valid = derived(() => names.every((n) => field2(n).valid.get()));
5250
6358
  const status = signal("idle");
5251
6359
  const submitting = derived(() => status.get() === "submitting");
5252
6360
  const submitted = derived(() => status.get() === "success");
@@ -5257,7 +6365,7 @@ function createForm(config) {
5257
6365
  batch(() => {
5258
6366
  for (const name of names) {
5259
6367
  const next = partial[name];
5260
- if (next !== void 0) field(name).value.set(next);
6368
+ if (next !== void 0) field2(name).value.set(next);
5261
6369
  }
5262
6370
  });
5263
6371
  } finally {
@@ -5269,7 +6377,7 @@ function createForm(config) {
5269
6377
  try {
5270
6378
  batch(() => {
5271
6379
  for (const name of names) {
5272
- const f = field(name);
6380
+ const f = field2(name);
5273
6381
  f.value.set(f.initial);
5274
6382
  f.touched.set(false);
5275
6383
  }
@@ -5282,7 +6390,7 @@ function createForm(config) {
5282
6390
  }
5283
6391
  async function submit() {
5284
6392
  batch(() => {
5285
- for (const name of names) field(name).touched.set(true);
6393
+ for (const name of names) field2(name).touched.set(true);
5286
6394
  });
5287
6395
  if (!valid.peek()) {
5288
6396
  return;
@@ -5322,7 +6430,7 @@ function createForm(config) {
5322
6430
  submitted,
5323
6431
  status,
5324
6432
  submitError,
5325
- field: (name) => field(name).api,
6433
+ field: (name) => field2(name).api,
5326
6434
  setValues,
5327
6435
  submit,
5328
6436
  reset,
@@ -5333,23 +6441,23 @@ function createForm(config) {
5333
6441
  // ../context/src/context.ts
5334
6442
  function createContext(defaultValue, description) {
5335
6443
  const id = Symbol(description ?? "streetui.context");
5336
- const stack = [];
6444
+ const stack2 = [];
5337
6445
  return {
5338
6446
  id,
5339
6447
  defaultValue,
5340
6448
  provide(value, run) {
5341
- stack.push(value);
6449
+ stack2.push(value);
5342
6450
  try {
5343
6451
  return run();
5344
6452
  } finally {
5345
- stack.pop();
6453
+ stack2.pop();
5346
6454
  }
5347
6455
  },
5348
6456
  consume() {
5349
- return stack.length > 0 ? stack[stack.length - 1] : defaultValue;
6457
+ return stack2.length > 0 ? stack2[stack2.length - 1] : defaultValue;
5350
6458
  },
5351
6459
  hasProvider() {
5352
- return stack.length > 0;
6460
+ return stack2.length > 0;
5353
6461
  }
5354
6462
  };
5355
6463
  }
@@ -5469,7 +6577,7 @@ function inspectComponents(graph) {
5469
6577
  }
5470
6578
  function inspectInteractions(graph) {
5471
6579
  const overlays = [];
5472
- const transitions = [];
6580
+ const transitions2 = [];
5473
6581
  graph.walk((node, depth) => {
5474
6582
  const overlayFn = graph.getHandler(`__overlay__${node.id}`);
5475
6583
  if (overlayFn !== void 0) {
@@ -5488,18 +6596,18 @@ function inspectInteractions(graph) {
5488
6596
  }
5489
6597
  const transitionFn = graph.getHandler(`__transition__${node.id}`);
5490
6598
  if (transitionFn !== void 0) {
5491
- const t = transitionFn();
5492
- transitions.push({
6599
+ const t6 = transitionFn();
6600
+ transitions2.push({
5493
6601
  id: node.id,
5494
6602
  key: node.key,
5495
6603
  nodeType: node.type,
5496
- duration: t.duration,
5497
- appear: t.appear,
6604
+ duration: t6.duration,
6605
+ appear: t6.appear,
5498
6606
  depth
5499
6607
  });
5500
6608
  }
5501
6609
  });
5502
- return { overlays, transitions };
6610
+ return { overlays, transitions: transitions2 };
5503
6611
  }
5504
6612
 
5505
6613
  // ../devtools/src/application.ts
@@ -5567,39 +6675,39 @@ var DEFAULT_PERF_THRESHOLDS = {
5567
6675
  maxSignals: 1e3
5568
6676
  };
5569
6677
  function diagnosePerformance(compiled, thresholds = {}) {
5570
- const t = { ...DEFAULT_PERF_THRESHOLDS, ...thresholds };
6678
+ const t6 = { ...DEFAULT_PERF_THRESHOLDS, ...thresholds };
5571
6679
  const { perf } = inspectApplication(compiled);
5572
6680
  const out = [];
5573
- if (perf.totalNodes > t.maxNodes) {
6681
+ if (perf.totalNodes > t6.maxNodes) {
5574
6682
  out.push({
5575
6683
  code: "large-graph",
5576
- message: `Graph has ${perf.totalNodes} nodes (> ${t.maxNodes}); consider splitting the view or paginating.`,
6684
+ message: `Graph has ${perf.totalNodes} nodes (> ${t6.maxNodes}); consider splitting the view or paginating.`,
5577
6685
  observed: perf.totalNodes,
5578
- threshold: t.maxNodes
6686
+ threshold: t6.maxNodes
5579
6687
  });
5580
6688
  }
5581
- if (perf.maxDepth > t.maxDepth) {
6689
+ if (perf.maxDepth > t6.maxDepth) {
5582
6690
  out.push({
5583
6691
  code: "deep-tree",
5584
- message: `Graph nests ${perf.maxDepth} levels deep (> ${t.maxDepth}); deep trees slow mount and reconciliation.`,
6692
+ message: `Graph nests ${perf.maxDepth} levels deep (> ${t6.maxDepth}); deep trees slow mount and reconciliation.`,
5585
6693
  observed: perf.maxDepth,
5586
- threshold: t.maxDepth
6694
+ threshold: t6.maxDepth
5587
6695
  });
5588
6696
  }
5589
- if (perf.largestChildCount > t.maxChildCount) {
6697
+ if (perf.largestChildCount > t6.maxChildCount) {
5590
6698
  out.push({
5591
6699
  code: "large-list",
5592
- message: `A single node has ${perf.largestChildCount} children (> ${t.maxChildCount}); large un-windowed lists dominate DOM cost.`,
6700
+ message: `A single node has ${perf.largestChildCount} children (> ${t6.maxChildCount}); large un-windowed lists dominate DOM cost.`,
5593
6701
  observed: perf.largestChildCount,
5594
- threshold: t.maxChildCount
6702
+ threshold: t6.maxChildCount
5595
6703
  });
5596
6704
  }
5597
- if (perf.distinctSignals > t.maxSignals) {
6705
+ if (perf.distinctSignals > t6.maxSignals) {
5598
6706
  out.push({
5599
6707
  code: "high-signal-fanout",
5600
- message: `${perf.distinctSignals} distinct signals are bound (> ${t.maxSignals}); heavy reactive fan-out increases update overhead.`,
6708
+ message: `${perf.distinctSignals} distinct signals are bound (> ${t6.maxSignals}); heavy reactive fan-out increases update overhead.`,
5601
6709
  observed: perf.distinctSignals,
5602
- threshold: t.maxSignals
6710
+ threshold: t6.maxSignals
5603
6711
  });
5604
6712
  }
5605
6713
  return out;
@@ -5672,10 +6780,10 @@ function inspectRouter(router) {
5672
6780
  isFallback: match.isFallback === true
5673
6781
  };
5674
6782
  }
5675
- function inspectForm(form, options = {}) {
5676
- const values = form.values.peek();
5677
- const errorsRaw = form.errors.peek();
5678
- const touchedRaw = form.touched.peek();
6783
+ function inspectForm(form2, options = {}) {
6784
+ const values = form2.values.peek();
6785
+ const errorsRaw = form2.errors.peek();
6786
+ const touchedRaw = form2.touched.peek();
5679
6787
  const errors = {};
5680
6788
  for (const [k, v] of Object.entries(errorsRaw)) if (v !== void 0) errors[k] = v;
5681
6789
  const touched = {};
@@ -5684,9 +6792,9 @@ function inspectForm(form, options = {}) {
5684
6792
  fields: Object.keys(values),
5685
6793
  errors,
5686
6794
  touched,
5687
- dirty: form.dirty.peek(),
5688
- valid: form.valid.peek(),
5689
- status: form.status.peek()
6795
+ dirty: form2.dirty.peek(),
6796
+ valid: form2.valid.peek(),
6797
+ status: form2.status.peek()
5690
6798
  };
5691
6799
  if (options.includeValues !== true) return base;
5692
6800
  return { ...base, values: { ...values } };
@@ -5715,8 +6823,8 @@ function inspectEvents(graph) {
5715
6823
  graph.walk((node, depth) => {
5716
6824
  if (node.events.length === 0) return;
5717
6825
  const types = node.events.map((e) => e.type);
5718
- for (const t of types) {
5719
- byType[t] = (byType[t] ?? 0) + 1;
6826
+ for (const t6 of types) {
6827
+ byType[t6] = (byType[t6] ?? 0) + 1;
5720
6828
  totalHandlers += 1;
5721
6829
  }
5722
6830
  nodes.push({
@@ -5832,8 +6940,8 @@ function capture(compiled, sources, options) {
5832
6940
  };
5833
6941
  const live = {};
5834
6942
  if (sources.signals !== void 0) {
5835
- for (const [label, sig] of Object.entries(sources.signals)) {
5836
- live[label] = inspectSignal(
6943
+ for (const [label2, sig] of Object.entries(sources.signals)) {
6944
+ live[label2] = inspectSignal(
5837
6945
  sig,
5838
6946
  options.redactSignals !== void 0 ? { redact: options.redactSignals } : {}
5839
6947
  );
@@ -5885,7 +6993,7 @@ function capture(compiled, sources, options) {
5885
6993
  }
5886
6994
  function mapInspect(source, inspect) {
5887
6995
  const out = {};
5888
- for (const [label, value] of Object.entries(source)) out[label] = inspect(value);
6996
+ for (const [label2, value] of Object.entries(source)) out[label2] = inspect(value);
5889
6997
  return out;
5890
6998
  }
5891
6999
  function findNode(node, id) {
@@ -5907,8 +7015,8 @@ function formatSnapshot(s) {
5907
7015
  ` signals ${app.signalCount} \xB7 handlers ${app.eventHandlers} \xB7 bindings ${app.stateBindings} \xB7 errors ${app.errors} \xB7 warnings ${app.warnings}`
5908
7016
  );
5909
7017
  lines.push(`Signals: ${s.signals.boundSignalIds.length} bound in graph`);
5910
- for (const [label, sig] of Object.entries(s.signals.live)) {
5911
- lines.push(` ${label} [${sig.kind}] = ${format(sig.value)} \xB7 observers ${sig.observerCount ?? "?"}`);
7018
+ for (const [label2, sig] of Object.entries(s.signals.live)) {
7019
+ lines.push(` ${label2} [${sig.kind}] = ${format(sig.value)} \xB7 observers ${sig.observerCount ?? "?"}`);
5912
7020
  }
5913
7021
  if (s.components.length > 0) {
5914
7022
  lines.push(`Components: ${s.components.length}`);
@@ -5925,8 +7033,8 @@ function formatSnapshot(s) {
5925
7033
  }
5926
7034
  if (s.transitions.length > 0) {
5927
7035
  lines.push(`Transitions: ${s.transitions.length}`);
5928
- for (const t of s.transitions) {
5929
- lines.push(` ${t.key ?? t.id} on <${t.nodeType}> \xB7 ${t.duration}ms${t.appear ? " \xB7 appear" : ""}`);
7036
+ for (const t6 of s.transitions) {
7037
+ lines.push(` ${t6.key ?? t6.id} on <${t6.nodeType}> \xB7 ${t6.duration}ms${t6.appear ? " \xB7 appear" : ""}`);
5930
7038
  }
5931
7039
  }
5932
7040
  if (s.router !== void 0) {
@@ -5934,26 +7042,26 @@ function formatSnapshot(s) {
5934
7042
  }
5935
7043
  if (s.resources !== void 0) {
5936
7044
  lines.push("Resources:");
5937
- for (const [label, r] of Object.entries(s.resources)) {
5938
- lines.push(` ${label}: ${r.status}${r.loading ? " (loading)" : ""}${r.hasError ? ` !${r.errorName}` : ""}`);
7045
+ for (const [label2, r] of Object.entries(s.resources)) {
7046
+ lines.push(` ${label2}: ${r.status}${r.loading ? " (loading)" : ""}${r.hasError ? ` !${r.errorName}` : ""}`);
5939
7047
  }
5940
7048
  }
5941
7049
  if (s.mutations !== void 0) {
5942
7050
  lines.push("Mutations:");
5943
- for (const [label, m] of Object.entries(s.mutations)) {
5944
- lines.push(` ${label}: ${m.status}${m.pending ? " (pending)" : ""}${m.hasError ? ` !${m.errorName}` : ""}`);
7051
+ for (const [label2, m] of Object.entries(s.mutations)) {
7052
+ lines.push(` ${label2}: ${m.status}${m.pending ? " (pending)" : ""}${m.hasError ? ` !${m.errorName}` : ""}`);
5945
7053
  }
5946
7054
  }
5947
7055
  if (s.forms !== void 0) {
5948
7056
  lines.push("Forms:");
5949
- for (const [label, f] of Object.entries(s.forms)) {
5950
- lines.push(` ${label}: ${f.valid ? "valid" : "invalid"} \xB7 ${f.status} \xB7 fields ${f.fields.length}`);
7057
+ for (const [label2, f] of Object.entries(s.forms)) {
7058
+ lines.push(` ${label2}: ${f.valid ? "valid" : "invalid"} \xB7 ${f.status} \xB7 fields ${f.fields.length}`);
5951
7059
  }
5952
7060
  }
5953
7061
  if (s.contexts !== void 0) {
5954
7062
  lines.push("Contexts:");
5955
- for (const [label, c] of Object.entries(s.contexts)) {
5956
- lines.push(` ${label} (${c.description}): ${c.hasProvider ? "provided" : "no provider"}`);
7063
+ for (const [label2, c] of Object.entries(s.contexts)) {
7064
+ lines.push(` ${label2} (${c.description}): ${c.hasProvider ? "provided" : "no provider"}`);
5957
7065
  }
5958
7066
  }
5959
7067
  if (s.i18n !== void 0) {
@@ -5975,7 +7083,7 @@ function formatSnapshot(s) {
5975
7083
  lines.push(` ${m}`);
5976
7084
  }
5977
7085
  lines.push(
5978
- `Events: ${s.events.nodes.length} node(s), ${s.events.totalHandlers} handler(s)` + (Object.keys(s.events.byType).length > 0 ? ` \xB7 ${Object.entries(s.events.byType).map(([t, n]) => `${t}\xD7${n}`).join(", ")}` : "")
7086
+ `Events: ${s.events.nodes.length} node(s), ${s.events.totalHandlers} handler(s)` + (Object.keys(s.events.byType).length > 0 ? ` \xB7 ${Object.entries(s.events.byType).map(([t6, n]) => `${t6}\xD7${n}`).join(", ")}` : "")
5979
7087
  );
5980
7088
  lines.push(
5981
7089
  `Signal graph: ${s.signalGraph.signals.length} signal(s), ${s.signalGraph.edges.length} binding edge(s)`
@@ -6016,9 +7124,9 @@ function stringifyValue(value) {
6016
7124
  }
6017
7125
  return String(value);
6018
7126
  }
6019
- function section(title, count, body) {
7127
+ function section(title, count, body2) {
6020
7128
  const badge = count === void 0 ? "" : ` <span class="st-count">${count}</span>`;
6021
- return `<section class="st-panel"><h2>${escapeHtml(title)}${badge}</h2>${body}</section>`;
7129
+ return `<section class="st-panel"><h2>${escapeHtml(title)}${badge}</h2>${body2}</section>`;
6022
7130
  }
6023
7131
  function ul(items) {
6024
7132
  if (items.length === 0) return '<p class="st-empty">(none)</p>';
@@ -6052,7 +7160,7 @@ function renderDevToolsHTML(s) {
6052
7160
  s.signals.boundSignalIds.length,
6053
7161
  `<p class="st-dim">${s.signals.boundSignalIds.length} bound in graph \xB7 effects shown as observer counts (no global effect registry)</p>` + ul(
6054
7162
  Object.entries(s.signals.live).map(
6055
- ([label, sig]) => `<code>${escapeHtml(label)}</code> <span class="st-key">[${escapeHtml(sig.kind)}]</span> = <code>${escapeHtml(sig.value)}</code> <span class="st-dim">observers ${escapeHtml(sig.observerCount ?? "?")}</span>`
7163
+ ([label2, sig]) => `<code>${escapeHtml(label2)}</code> <span class="st-key">[${escapeHtml(sig.kind)}]</span> = <code>${escapeHtml(sig.value)}</code> <span class="st-dim">observers ${escapeHtml(sig.observerCount ?? "?")}</span>`
6056
7164
  )
6057
7165
  )
6058
7166
  )
@@ -6073,7 +7181,7 @@ function renderDevToolsHTML(s) {
6073
7181
  Object.keys(s.resources).length,
6074
7182
  ul(
6075
7183
  Object.entries(s.resources).map(
6076
- ([label, r]) => `<code>${escapeHtml(label)}</code>: ${escapeHtml(r.status)}` + (r.loading ? ' <span class="st-dim">(loading)</span>' : "") + (r.hasError ? ` <span class="st-err">!${escapeHtml(r.errorName)}</span>` : "")
7184
+ ([label2, r]) => `<code>${escapeHtml(label2)}</code>: ${escapeHtml(r.status)}` + (r.loading ? ' <span class="st-dim">(loading)</span>' : "") + (r.hasError ? ` <span class="st-err">!${escapeHtml(r.errorName)}</span>` : "")
6077
7185
  )
6078
7186
  )
6079
7187
  )
@@ -6097,7 +7205,7 @@ function renderDevToolsHTML(s) {
6097
7205
  s.transitions.length,
6098
7206
  ul(
6099
7207
  s.transitions.map(
6100
- (t) => `<code>${escapeHtml(t.key ?? t.id)}</code> on <code>&lt;${escapeHtml(t.nodeType)}&gt;</code> <span class="st-dim">${t.duration}ms${t.appear ? " \xB7 appear" : ""}</span>`
7208
+ (t6) => `<code>${escapeHtml(t6.key ?? t6.id)}</code> on <code>&lt;${escapeHtml(t6.nodeType)}&gt;</code> <span class="st-dim">${t6.duration}ms${t6.appear ? " \xB7 appear" : ""}</span>`
6101
7209
  )
6102
7210
  )
6103
7211
  )
@@ -6109,7 +7217,7 @@ function renderDevToolsHTML(s) {
6109
7217
  Object.keys(s.forms).length,
6110
7218
  ul(
6111
7219
  Object.entries(s.forms).map(
6112
- ([label, f]) => `<code>${escapeHtml(label)}</code>: ${f.valid ? "valid" : "invalid"} \xB7 ${escapeHtml(f.status)} \xB7 ${f.fields.length} field(s)`
7220
+ ([label2, f]) => `<code>${escapeHtml(label2)}</code>: ${f.valid ? "valid" : "invalid"} \xB7 ${escapeHtml(f.status)} \xB7 ${f.fields.length} field(s)`
6113
7221
  )
6114
7222
  )
6115
7223
  )
@@ -6188,8 +7296,8 @@ var DEVTOOLS_TABS = [
6188
7296
  var EMBED_ESCAPE = new RegExp("[<\\u2028\\u2029]", "g");
6189
7297
  function embedJson(snapshot) {
6190
7298
  return JSON.stringify(snapshot).replace(EMBED_ESCAPE, (ch) => {
6191
- const code = ch.charCodeAt(0).toString(16).padStart(4, "0");
6192
- return `\\u${code}`;
7299
+ const code2 = ch.charCodeAt(0).toString(16).padStart(4, "0");
7300
+ return `\\u${code2}`;
6193
7301
  });
6194
7302
  }
6195
7303
  function renderInteractiveDevTools(snapshot, options = {}) {
@@ -6197,7 +7305,7 @@ function renderInteractiveDevTools(snapshot, options = {}) {
6197
7305
  const title = options.title ?? `StreetUI DevTools \u2014 ${app.identity.name}`;
6198
7306
  const initialTab = options.initialTab ?? DEVTOOLS_TABS[0].id;
6199
7307
  const tabButtons = DEVTOOLS_TABS.map(
6200
- (t) => `<button type="button" role="tab" class="st-tab" data-tab="${escapeHtml(t.id)}"${t.id === initialTab ? ' aria-selected="true"' : ' aria-selected="false"'}>${escapeHtml(t.label)}</button>`
7308
+ (t6) => `<button type="button" role="tab" class="st-tab" data-tab="${escapeHtml(t6.id)}"${t6.id === initialTab ? ' aria-selected="true"' : ' aria-selected="false"'}>${escapeHtml(t6.label)}</button>`
6201
7309
  ).join("");
6202
7310
  return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${escapeHtml(title)}</title><style>${INTERACTIVE_CSS}</style></head><body class="st-dt"><header class="st-top"><h1>${escapeHtml(title)} <span class="st-dim">v${escapeHtml(app.identity.version)}</span></h1><button type="button" id="st-refresh" class="st-refresh">&#8635; Refresh</button></header><nav class="st-tabs" role="tablist" aria-label="DevTools panels">${tabButtons}</nav><main id="st-panel" class="st-body" role="tabpanel" aria-live="polite"></main><footer class="st-foot"><span class="st-dim">Structural inspection over one compiled graph. Not a production profiler; browser/AT conformance not claimed (gates BLOCKED).</span></footer><script type="application/json" id="st-data">${embedJson(snapshot)}</script><script>${CONTROLLER_JS.replace("__INITIAL_TAB__", JSON.stringify(initialTab))}</script></body></html>`;
6203
7311
  }
@@ -6385,11 +7493,13 @@ export {
6385
7493
  AppBuilder,
6386
7494
  Application,
6387
7495
  ApplicationGraph,
7496
+ BREAKPOINTS,
6388
7497
  BaseNode,
6389
7498
  BrowserDOMAdapter,
6390
7499
  CleanupRegistry,
6391
7500
  ContainerBuilderImpl,
6392
7501
  DEFAULT_PERF_THRESHOLDS,
7502
+ DEFAULT_TOKENS,
6393
7503
  DEVTOOLS_TABS,
6394
7504
  DerivedSignal,
6395
7505
  DiagnosticCollector,
@@ -6407,6 +7517,7 @@ export {
6407
7517
  NodeInstance,
6408
7518
  PageBuilderImpl,
6409
7519
  ROUTER_OUTLET_ID,
7520
+ ROUTER_OUTLET_KEY,
6410
7521
  Runtime,
6411
7522
  RuntimeNodeInstance,
6412
7523
  STATE_MARKER_ATTR,
@@ -6425,21 +7536,35 @@ export {
6425
7536
  StreetFrameworkError,
6426
7537
  StreetRenderHandle,
6427
7538
  StreetRendererImpl,
7539
+ StyleRegistry,
6428
7540
  TransitionController,
6429
7541
  VERSION,
7542
+ a11y,
6430
7543
  a11yIds,
7544
+ adoptServerStyles,
7545
+ animate,
7546
+ animation,
6431
7547
  applyNodeProps,
6432
7548
  applyProp,
7549
+ backdrop,
6433
7550
  batch,
6434
7551
  bindDomEvent,
7552
+ blockquote,
7553
+ body,
6435
7554
  browserDOMAdapter,
7555
+ button,
6436
7556
  buttonUpdate,
7557
+ canonicalize,
7558
+ caption,
7559
+ center,
7560
+ code,
6437
7561
  compile,
6438
7562
  compileGraph,
6439
7563
  component,
6440
7564
  consoleDiagnosticSink,
6441
7565
  consoleHydrationDiagnosticSink,
6442
7566
  containFocus,
7567
+ container,
6443
7568
  createAnnouncer,
6444
7569
  createApplication,
6445
7570
  createAuthSession,
@@ -6458,31 +7583,53 @@ export {
6458
7583
  createRuntime,
6459
7584
  createStore,
6460
7585
  createStreetEvent,
7586
+ createTheme,
7587
+ createThemeTokens,
7588
+ cssPropName,
7589
+ cssValue,
7590
+ cx,
7591
+ defaultThemeStorage,
6461
7592
  defineConfig,
6462
7593
  derived,
6463
7594
  describeError,
6464
7595
  diagnosePerformance,
7596
+ dialog,
7597
+ dropdown,
7598
+ dropdownItem,
6465
7599
  effect,
6466
7600
  email,
6467
7601
  environment,
6468
7602
  escapeHtml,
6469
7603
  escapeHtmlAttr,
6470
7604
  escapeHtmlText,
7605
+ fadeTransition,
7606
+ field,
7607
+ fieldError,
7608
+ fieldHelp,
7609
+ fieldLabel,
6471
7610
  flushSync,
6472
7611
  focusById,
6473
7612
  focusFirst,
6474
7613
  focusInitial,
7614
+ focusRing,
7615
+ form,
6475
7616
  formatDiagnostic,
6476
7617
  formatDiagnosticContext,
6477
7618
  formatHydrationDiagnostic,
6478
7619
  frameworkError,
6479
7620
  generateApplicationId,
7621
+ generateCSS,
6480
7622
  generateNodeId,
6481
7623
  getFocusable,
6482
7624
  getResolvedTransition,
6483
7625
  globalEventBus,
7626
+ grid,
7627
+ hashIdentity,
7628
+ heading,
6484
7629
  headingUpdate,
6485
7630
  hydrateGraph,
7631
+ identityOf,
7632
+ input,
6486
7633
  inputUpdate,
6487
7634
  inspectApplication,
6488
7635
  inspectComponents,
@@ -6503,7 +7650,11 @@ export {
6503
7650
  isComponentDefinition,
6504
7651
  isHeadContribution,
6505
7652
  isTransitionConfig,
7653
+ label,
7654
+ layout,
7655
+ link,
6506
7656
  linkUpdate,
7657
+ list,
6507
7658
  matchPattern,
6508
7659
  matchRoutes,
6509
7660
  maxLength,
@@ -6518,13 +7669,18 @@ export {
6518
7669
  normalizePath,
6519
7670
  observerCount,
6520
7671
  onEscape,
7672
+ overlay,
6521
7673
  patchNode,
6522
7674
  patchProp,
6523
7675
  pattern,
7676
+ popover,
7677
+ pre,
6524
7678
  printDiagnostics,
6525
7679
  printGraph,
6526
7680
  reactiveListItemKey,
6527
7681
  reactiveListItemSignature,
7682
+ reactiveVarName,
7683
+ reactiveVarValue,
6528
7684
  readState,
6529
7685
  reconcileChildren,
6530
7686
  reconcileChildrenByPlan,
@@ -6532,6 +7688,7 @@ export {
6532
7688
  renderDevToolsReport,
6533
7689
  renderHead,
6534
7690
  renderInteractiveDevTools,
7691
+ renderStyles,
6535
7692
  renderToString,
6536
7693
  reportDiagnostic,
6537
7694
  reportError,
@@ -6544,9 +7701,11 @@ export {
6544
7701
  restoreFocus,
6545
7702
  routerOutlet,
6546
7703
  rovingMenu,
7704
+ row,
6547
7705
  runElementTransition,
6548
7706
  runValidators,
6549
7707
  saveFocus,
7708
+ scaleTransition,
6550
7709
  scheduleImmediate,
6551
7710
  scheduleUpdate,
6552
7711
  scheduler,
@@ -6556,13 +7715,29 @@ export {
6556
7715
  serverDOMAdapter,
6557
7716
  signal,
6558
7717
  signalKind,
7718
+ skipLink,
7719
+ slideTransition,
7720
+ spacer,
6559
7721
  splitTarget,
7722
+ stack,
7723
+ stateAttr,
6560
7724
  streetui,
7725
+ style,
7726
+ styleRegistry,
7727
+ styleVariants,
7728
+ styleWithVars,
7729
+ text,
6561
7730
  textUpdate,
6562
7731
  toIdToken,
7732
+ toast,
7733
+ tokens,
7734
+ tooltip,
6563
7735
  transformGraph,
7736
+ transition,
7737
+ transitions,
6564
7738
  trapFocus,
6565
7739
  validateGraph,
7740
+ visuallyHidden,
6566
7741
  wireComponentBehavior,
6567
7742
  wireEvents,
6568
7743
  wireHeadBehavior,