@realiizlabs/admin 0.11.2 → 0.13.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.
Files changed (39) hide show
  1. package/dist/Sidebar-CNuphww6.d.cts +60 -0
  2. package/dist/Sidebar-CNuphww6.d.ts +60 -0
  3. package/dist/auth/index.d.cts +5 -127
  4. package/dist/auth/index.d.ts +5 -127
  5. package/dist/auth-ui/index.js +124 -1
  6. package/dist/auth-ui/index.js.map +1 -1
  7. package/dist/forms/index.js +287 -1
  8. package/dist/forms/index.js.map +1 -1
  9. package/dist/forms-ui/index.js +355 -6
  10. package/dist/forms-ui/index.js.map +1 -1
  11. package/dist/git/index.cjs.map +1 -1
  12. package/dist/git/index.d.cts +3 -77
  13. package/dist/git/index.d.ts +3 -77
  14. package/dist/git/index.js.map +1 -1
  15. package/dist/members-nhbRSYyr.d.cts +106 -0
  16. package/dist/members-nhbRSYyr.d.ts +106 -0
  17. package/dist/roles-BjWuj2_v.d.cts +25 -0
  18. package/dist/roles-Dnwj-DAm.d.ts +25 -0
  19. package/dist/shell/index.d.cts +3 -58
  20. package/dist/shell/index.d.ts +3 -58
  21. package/dist/studio/index.cjs +1150 -0
  22. package/dist/studio/index.cjs.map +1 -0
  23. package/dist/studio/index.d.cts +325 -0
  24. package/dist/studio/index.d.ts +325 -0
  25. package/dist/studio/index.js +1131 -0
  26. package/dist/studio/index.js.map +1 -0
  27. package/dist/studio-ui/index.cjs +3931 -0
  28. package/dist/studio-ui/index.cjs.map +1 -0
  29. package/dist/studio-ui/index.d.cts +375 -0
  30. package/dist/studio-ui/index.d.ts +375 -0
  31. package/dist/studio-ui/index.js +3900 -0
  32. package/dist/studio-ui/index.js.map +1 -0
  33. package/dist/types-BP5G1myE.d.cts +78 -0
  34. package/dist/types-BP5G1myE.d.ts +78 -0
  35. package/package.json +20 -2
  36. package/dist/chunk-2GSYBARR.js +0 -126
  37. package/dist/chunk-2GSYBARR.js.map +0 -1
  38. package/dist/chunk-JLR5K6RP.js +0 -289
  39. package/dist/chunk-JLR5K6RP.js.map +0 -1
@@ -1,9 +1,235 @@
1
1
  "use client";
2
- import { walkSchema, titlecase } from '../chunk-JLR5K6RP.js';
3
- import { FORM_CSS } from '../chunk-2GSYBARR.js';
4
2
  import { useState, useRef, useId, useEffect, useCallback, useMemo } from 'react';
5
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
4
 
5
+ // src/forms-ui/ContentForm.tsx
6
+
7
+ // src/forms/internals.ts
8
+ function asNode(schema, what = "schema") {
9
+ const n = schema;
10
+ if (!n || typeof n !== "object" || !n._zod?.def?.type) {
11
+ throw new TypeError(`walkSchema: ${what} is not a zod 4 schema`);
12
+ }
13
+ return n;
14
+ }
15
+ function checkMessage(def) {
16
+ const e = def.error;
17
+ if (!e) return void 0;
18
+ if (typeof e === "string") return e;
19
+ const out = e({});
20
+ if (typeof out === "string") return out;
21
+ return out?.message;
22
+ }
23
+
24
+ // src/forms/checks.ts
25
+ function readChecks(node) {
26
+ const constraints = {};
27
+ const messages = {};
28
+ for (const c of node._zod.def.checks ?? []) {
29
+ const d = c._zod.def;
30
+ const msg = checkMessage(d);
31
+ let key;
32
+ switch (d.check) {
33
+ case "min_length":
34
+ constraints.min = d.minimum;
35
+ key = "min_length";
36
+ break;
37
+ case "max_length":
38
+ constraints.max = d.maximum;
39
+ key = "max_length";
40
+ break;
41
+ case "length_equals":
42
+ constraints.exact = d.length;
43
+ key = "length_equals";
44
+ break;
45
+ case "greater_than":
46
+ constraints.min = d.inclusive ? d.value : (d.value ?? 0) + 1;
47
+ key = "greater_than";
48
+ break;
49
+ case "less_than":
50
+ constraints.max = d.inclusive ? d.value : (d.value ?? 0) - 1;
51
+ key = "less_than";
52
+ break;
53
+ case "string_format":
54
+ if (d.format === "regex" && d.pattern) {
55
+ constraints.pattern = d.pattern.source;
56
+ constraints.format = "regex";
57
+ key = "regex";
58
+ } else if (d.format === "url" || d.format === "email") {
59
+ constraints.format = d.format;
60
+ key = d.format;
61
+ } else {
62
+ key = d.format;
63
+ }
64
+ break;
65
+ case "number_format":
66
+ if (d.format === "safeint" || d.format === "int32") {
67
+ constraints.format = "int";
68
+ key = "int";
69
+ }
70
+ break;
71
+ case "custom":
72
+ key = "custom";
73
+ break;
74
+ default:
75
+ key = d.check;
76
+ }
77
+ if (key && msg) messages[key] = msg;
78
+ }
79
+ return { constraints, messages };
80
+ }
81
+
82
+ // src/forms/unwrap.ts
83
+ function unwrap(start) {
84
+ let node = start;
85
+ let required = true;
86
+ for (let i = 0; i < 16; i++) {
87
+ const def = node._zod.def;
88
+ if (def.type === "optional" || def.type === "nullable" || def.type === "default") {
89
+ required = false;
90
+ if (!def.innerType) break;
91
+ node = def.innerType;
92
+ } else if (def.type === "pipe") {
93
+ const next = def.out ?? def.in;
94
+ if (!next) break;
95
+ node = next;
96
+ } else {
97
+ break;
98
+ }
99
+ }
100
+ return { node, type: node._zod.def.type, required };
101
+ }
102
+
103
+ // src/forms/inputs.ts
104
+ var TEXTAREA_MIN_MAX = 120;
105
+ function inputFor(node) {
106
+ const def = node._zod.def;
107
+ const { constraints, messages } = readChecks(node);
108
+ switch (def.type) {
109
+ case "string": {
110
+ if (constraints.format === "url") return { input: "url", constraints, messages };
111
+ const long = (constraints.max ?? 0) > TEXTAREA_MIN_MAX;
112
+ return { input: long ? "textarea" : "text", constraints, messages };
113
+ }
114
+ case "date":
115
+ return { input: "date", constraints, messages };
116
+ case "number":
117
+ case "int":
118
+ return { input: "number", constraints, messages };
119
+ case "boolean":
120
+ return { input: "boolean", constraints, messages };
121
+ case "enum":
122
+ case "literal": {
123
+ const options = Object.values(def.entries ?? {}).map(String);
124
+ return { input: "select", constraints, messages, options };
125
+ }
126
+ case "array": {
127
+ if (def.element) {
128
+ const item = unwrap(def.element);
129
+ const inner = readChecks(item.node);
130
+ constraints.item = inner;
131
+ }
132
+ return { input: "tags", constraints, messages };
133
+ }
134
+ default:
135
+ return { input: "text", constraints, messages };
136
+ }
137
+ }
138
+
139
+ // src/forms/labels.ts
140
+ function readMeta(schema) {
141
+ const s = schema;
142
+ const raw = typeof s.meta === "function" ? s.meta() ?? {} : {};
143
+ const pick = (k) => typeof raw[k] === "string" ? raw[k] : void 0;
144
+ const rec = raw.recommended;
145
+ const recommended = Array.isArray(rec) && rec.length === 2 && rec.every((n) => typeof n === "number") ? [rec[0], rec[1]] : void 0;
146
+ const INPUTS = ["text", "textarea", "date", "number", "boolean", "select", "tags", "image", "url", "time"];
147
+ const input = typeof raw.input === "string" && INPUTS.includes(raw.input) ? raw.input : void 0;
148
+ return {
149
+ label: pick("label"),
150
+ placeholder: pick("placeholder"),
151
+ description: pick("description") ?? (typeof s.description === "string" ? s.description : void 0),
152
+ recommended,
153
+ suffix: pick("suffix"),
154
+ help: pick("help"),
155
+ input
156
+ };
157
+ }
158
+ function inputOverrideFor(name, schema, entry) {
159
+ return entry?.inputs?.[name] ?? readMeta(schema).input;
160
+ }
161
+ function recommendedFor(name, schema, entry) {
162
+ return entry?.recommended?.[name] ?? readMeta(schema).recommended;
163
+ }
164
+ function titlecase(name) {
165
+ const words = name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").toLowerCase().trim();
166
+ return words.charAt(0).toUpperCase() + words.slice(1);
167
+ }
168
+ function labelFor(name, schema, entry) {
169
+ const fromRegistry = entry?.labels?.[name];
170
+ if (fromRegistry) return fromRegistry;
171
+ const meta = readMeta(schema);
172
+ return meta.label ?? meta.description ?? titlecase(name);
173
+ }
174
+ function placeholderFor(name, schema, entry) {
175
+ return entry?.placeholders?.[name] ?? readMeta(schema).placeholder;
176
+ }
177
+ function helpFor(name, schema, entry) {
178
+ return entry?.help?.[name] ?? readMeta(schema).help;
179
+ }
180
+
181
+ // src/forms/walk.ts
182
+ function walkSchema(schema, entry = {}) {
183
+ const root = asNode(schema);
184
+ const shape = shapeOf(root);
185
+ const names = Object.keys(shape);
186
+ const specs = names.map((name) => {
187
+ const raw = shape[name];
188
+ const { node, required } = unwrap(raw);
189
+ const info = inputFor(node);
190
+ const role = roleFor(name, entry);
191
+ return {
192
+ name,
193
+ label: labelFor(name, raw, entry),
194
+ input: role === "image" ? "image" : inputOverrideFor(name, raw, entry) ?? info.input,
195
+ required,
196
+ constraints: info.constraints,
197
+ messages: info.messages,
198
+ placeholder: placeholderFor(name, raw, entry),
199
+ recommended: recommendedFor(name, raw, entry),
200
+ suffix: readMeta(raw).suffix,
201
+ help: helpFor(name, raw, entry),
202
+ order: 0,
203
+ role,
204
+ options: entry.options?.[name] ?? info.options
205
+ };
206
+ });
207
+ return applyOrder(specs, entry.order ?? []);
208
+ }
209
+ function shapeOf(root) {
210
+ let node = root;
211
+ for (let i = 0; i < 8 && !node._zod.def.shape; i++) {
212
+ const def = node._zod.def;
213
+ const next = def.innerType ?? def.in;
214
+ if (!next) break;
215
+ node = next;
216
+ }
217
+ const shape = node._zod.def.shape;
218
+ if (!shape) throw new TypeError(`walkSchema: expected an object schema, got "${root._zod.def.type}"`);
219
+ return shape;
220
+ }
221
+ function roleFor(name, entry) {
222
+ if (entry.hidden?.includes(name)) return "hidden";
223
+ if (entry.body === name) return "body";
224
+ if (entry.images?.includes(name)) return "image";
225
+ return "field";
226
+ }
227
+ function applyOrder(specs, order) {
228
+ const rank = new Map(order.map((n, i) => [n, i]));
229
+ const named = specs.filter((s) => rank.has(s.name)).sort((a, b) => rank.get(a.name) - rank.get(b.name));
230
+ const rest = specs.filter((s) => !rank.has(s.name));
231
+ return [...named, ...rest].map((s, i) => ({ ...s, order: i }));
232
+ }
7
233
  function ChipsInput({ id, name, value, onChange, onBlur, placeholder, invalid, max }) {
8
234
  const [draft, setDraft] = useState("");
9
235
  const commit = () => {
@@ -48,7 +274,7 @@ function ChipsInput({ id, name, value, onChange, onBlur, placeholder, invalid, m
48
274
  ] })
49
275
  ] });
50
276
  }
51
- function labelFor(value, labels) {
277
+ function labelFor2(value, labels) {
52
278
  if (labels?.[value]) return labels[value];
53
279
  return value ? titlecase(value) : "\u2014";
54
280
  }
@@ -122,7 +348,7 @@ function SelectInput(p) {
122
348
  default: {
123
349
  if (e.key.length === 1 && /\S/.test(e.key)) {
124
350
  const k = e.key.toLowerCase();
125
- const idx = choices.findIndex((c) => labelFor(c, p.labels).toLowerCase().startsWith(k));
351
+ const idx = choices.findIndex((c) => labelFor2(c, p.labels).toLowerCase().startsWith(k));
126
352
  if (idx >= 0) setActive(idx);
127
353
  }
128
354
  }
@@ -146,7 +372,7 @@ function SelectInput(p) {
146
372
  disabled: p.disabled,
147
373
  onClick: () => open ? close() : setOpen(true),
148
374
  children: [
149
- /* @__PURE__ */ jsx("span", { className: p.value ? void 0 : "realiiz-select__placeholder", children: labelFor(p.value, p.labels) }),
375
+ /* @__PURE__ */ jsx("span", { className: p.value ? void 0 : "realiiz-select__placeholder", children: labelFor2(p.value, p.labels) }),
150
376
  /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6" }) })
151
377
  ]
152
378
  }
@@ -163,7 +389,7 @@ function SelectInput(p) {
163
389
  onClick: () => pick(c),
164
390
  children: [
165
391
  /* @__PURE__ */ jsx("span", { className: "realiiz-select__check", "aria-hidden": "true", children: c === p.value ? "\u2713" : "" }),
166
- /* @__PURE__ */ jsx("span", { children: labelFor(c, p.labels) })
392
+ /* @__PURE__ */ jsx("span", { children: labelFor2(c, p.labels) })
167
393
  ]
168
394
  },
169
395
  c || "__empty"
@@ -1082,6 +1308,129 @@ function groupIssues(list) {
1082
1308
  return { byField, formLevel };
1083
1309
  }
1084
1310
 
1311
+ // src/forms-ui/styles.ts
1312
+ var FORM_CSS = `
1313
+ .realiiz-form{
1314
+ --_fg:var(--realiiz-form-fg,#111);
1315
+ --_muted:var(--realiiz-form-muted,#666);
1316
+ --_border:var(--realiiz-form-border,#cfcfcf);
1317
+ --_accent:var(--realiiz-form-accent,#111);
1318
+ --_accent-fg:var(--realiiz-form-accent-fg,#fff);
1319
+ --_danger:var(--realiiz-form-danger,#b3261e);
1320
+ --_radius:var(--realiiz-form-radius,6px);
1321
+ --_font:var(--realiiz-form-font,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif);
1322
+ --_ring:var(--realiiz-form-focus-ring,0 0 0 3px rgba(0,0,0,.15));
1323
+ box-sizing:border-box;max-width:100%;color:var(--_fg);font-family:var(--_font);font-size:15px;line-height:1.4;
1324
+ }
1325
+ .realiiz-form *,.realiiz-form *::before,.realiiz-form *::after{box-sizing:inherit}
1326
+ .realiiz-form fieldset{border:0;margin:0 0 20px;padding:0;min-width:0}
1327
+ .realiiz-form legend{font-weight:600;font-size:13px;letter-spacing:.02em;text-transform:uppercase;color:var(--_muted);margin-bottom:12px;padding:0}
1328
+ .realiiz-form__field{display:block;margin:0 0 16px}
1329
+ .realiiz-form__label{display:block;font-weight:500;margin-bottom:6px}
1330
+ .realiiz-form__required{color:var(--_danger);margin-left:3px}
1331
+ .realiiz-form__control{display:block;width:100%;max-width:100%;font:inherit;color:inherit;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius);padding:9px 11px;min-height:40px}
1332
+ .realiiz-form__control:focus{outline:none;border-color:var(--_accent);box-shadow:var(--_ring)}
1333
+ .realiiz-form__control--textarea{min-height:110px;resize:vertical}
1334
+ .realiiz-form__control--body{min-height:280px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px}
1335
+ .realiiz-form__control--invalid{border-color:var(--_danger)}
1336
+ .realiiz-select{position:relative}
1337
+ .realiiz-select__btn{display:flex;align-items:center;justify-content:space-between;gap:10px;text-align:left;cursor:pointer;background:#fff}
1338
+ .realiiz-select__btn svg{flex-shrink:0;color:var(--_muted);transition:transform .15s}
1339
+ .realiiz-select__btn--open{border-color:var(--_accent);box-shadow:var(--_ring)}
1340
+ .realiiz-select__btn--open svg{transform:rotate(180deg)}
1341
+ .realiiz-select__btn:disabled{opacity:.6;cursor:default}
1342
+ .realiiz-select__placeholder{color:var(--_muted)}
1343
+ .realiiz-select__menu{position:absolute;left:0;right:0;top:calc(100% + 6px);margin:0;padding:6px 0;list-style:none;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius);box-shadow:0 8px 24px rgba(14,23,38,.14);max-height:260px;overflow:auto;z-index:40}
1344
+ .realiiz-select__item{display:flex;align-items:center;gap:8px;padding:8px 12px;font-size:14px;color:var(--_fg);cursor:pointer}
1345
+ .realiiz-select__item--active{background:var(--realiiz-form-hover,rgba(0,0,0,.05))}
1346
+ .realiiz-select__item--selected{font-weight:600}
1347
+ .realiiz-select__check{width:1em;flex-shrink:0;color:var(--_accent);font-weight:700}
1348
+ .realiiz-form__check{display:flex;align-items:center;gap:8px;font-weight:500}
1349
+ .realiiz-form__check input{width:18px;height:18px;margin:0}
1350
+ .realiiz-form__helper{display:flex;justify-content:space-between;gap:12px;font-size:12px;color:var(--_muted);margin-top:4px;min-height:1em}
1351
+ .realiiz-form__count{margin-left:auto;font-variant-numeric:tabular-nums}
1352
+ .realiiz-form__error{color:var(--_danger);font-size:13px;margin-top:4px}
1353
+ .realiiz-image{border:1px dashed var(--_border);border-radius:var(--_radius);padding:16px 18px;background:#fff;outline:none;transition:border-color .15s}
1354
+ .realiiz-image--over{border-color:var(--_accent);border-style:solid}
1355
+ .realiiz-image--invalid{border-color:var(--_danger)}
1356
+ .realiiz-image--busy{opacity:.7}
1357
+ .realiiz-image__empty{display:flex;align-items:center;gap:14px;flex-wrap:wrap;color:var(--_muted)}
1358
+ .realiiz-image__icon{flex-shrink:0;color:var(--_muted)}
1359
+ .realiiz-image__or{font-size:13px}
1360
+ .realiiz-image__has{display:flex;align-items:flex-start;gap:16px}
1361
+ .realiiz-image__thumb{display:block;max-height:160px;max-width:min(320px,55%);width:auto;object-fit:cover;border-radius:8px;border:1px solid var(--_border);background:#f6f8fa}
1362
+ .realiiz-image__meta{display:flex;flex-direction:column;gap:10px;min-width:0}
1363
+ .realiiz-image__detail{font-size:13px;color:var(--_muted);word-break:break-all}
1364
+ .realiiz-image__actions{display:flex;align-items:center;gap:14px}
1365
+ .realiiz-image__remove{font:inherit;font-size:13px;background:none;border:0;padding:0;color:var(--_muted);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
1366
+ .realiiz-image__remove:hover{color:var(--_danger)}
1367
+ .realiiz-image__hint{font-size:12px;color:var(--_muted);margin-top:10px}
1368
+ .realiiz-image .realiiz-form__error{margin-top:8px}
1369
+ @media (max-width:720px){.realiiz-image__has{flex-direction:column}.realiiz-image__thumb{max-width:100%}}
1370
+ .realiiz-form__alert{border:1px solid var(--_danger);border-radius:var(--_radius);padding:12px 14px;margin:0 0 20px;color:var(--_danger)}
1371
+ .realiiz-form__alert ul{margin:6px 0 0;padding-left:18px}
1372
+ .realiiz-form__actions{display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap;margin-top:8px}
1373
+ .realiiz-form__help{text-decoration:underline dotted;text-decoration-color:color-mix(in srgb,currentColor 45%,transparent);text-underline-offset:4px;cursor:help}
1374
+ .realiiz-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
1375
+ .realiiz-form__footer{max-width:920px}
1376
+ .realiiz-form__bar{display:flex;align-items:center;gap:10px;margin-top:16px;padding:12px 0;border-top:1px solid var(--_border);background:#fff}
1377
+ .realiiz-form__status{margin-right:auto;font-size:.85rem;color:var(--_muted)}
1378
+ .realiiz-form__bar[data-dirty] .realiiz-form__status{color:var(--_fg)}
1379
+ .realiiz-form__button{font:inherit;font-weight:600;border-radius:var(--_radius);padding:10px 16px;border:1px solid var(--_border);background:#fff;color:var(--_fg);cursor:pointer;min-height:40px}
1380
+ .realiiz-form__button--primary{background:var(--_accent);color:var(--_accent-fg);border-color:var(--_accent)}
1381
+ .realiiz-form__button:disabled{opacity:.6;cursor:default}
1382
+ .realiiz-md{--_md-head:#fafbfd;--_md-hover:#f4f8fd;--_md-hover-line:#bcd0ea;--_md-on:#eef4fb;--_md-tip:#1f2933;position:relative}
1383
+ .realiiz-md__mode{display:inline-flex;align-self:flex-start;width:max-content;gap:2px;padding:3px;background:color-mix(in srgb,var(--_border) 40%,transparent);border-radius:8px;margin-bottom:8px}
1384
+ .realiiz-md__mode button{font:inherit;font-size:.8rem;padding:5px 13px;border:0;border-radius:6px;background:transparent;color:var(--_muted);cursor:pointer}
1385
+ .realiiz-md__mode button[aria-selected="true"]{background:#fff;color:var(--_fg);box-shadow:0 1px 2px rgba(0,0,0,.12)}
1386
+ .realiiz-md__panel{position:relative;z-index:0;display:flex;flex-direction:column;border:1px solid var(--_border);border-radius:10px;background:#fff;overflow:hidden}
1387
+ .realiiz-md__panel:focus-within{border-color:var(--_md-hover-line)}
1388
+ .realiiz-md__head{position:relative;z-index:5;display:flex;align-items:center;gap:2px;flex-wrap:wrap;padding:5px 7px;background:var(--_md-head);border-bottom:1px solid var(--_border);flex-shrink:0}
1389
+ .realiiz-md__tools{display:flex;align-items:center;gap:3px;flex-wrap:wrap}
1390
+ .realiiz-md__spacer{flex:1}
1391
+ .realiiz-md__head button{position:relative;min-width:31px;height:28px;padding:0 9px;display:inline-flex;align-items:center;justify-content:center;background:#fff;border:1px solid var(--_border);border-radius:6px;font-family:inherit;font-size:.82rem;color:var(--_fg);cursor:pointer;line-height:1}
1392
+ .realiiz-md__head button:hover:not(:disabled){border-color:var(--_md-hover-line);background:var(--_md-hover)}
1393
+ .realiiz-md__head button:active{background:var(--_md-on)}
1394
+ .realiiz-md__head button.on{background:var(--_md-on);border-color:var(--_accent);color:var(--_accent);font-weight:600}
1395
+ .realiiz-md__ico{width:15px;height:15px;display:block}
1396
+ .realiiz-md__dot{font-size:1.05rem;line-height:1}
1397
+ .realiiz-md__sep{width:1px;height:17px;background:var(--_border);margin:0 5px}
1398
+ .realiiz-md__insert{display:inline-flex;align-items:center;gap:3px;border-left:1px solid var(--_border);padding-left:8px;margin-left:6px}
1399
+ .realiiz-md__insert button{background:#f6f8fa;color:var(--_muted);padding:0;width:31px}
1400
+ .realiiz-md__insert button:hover{color:var(--_accent)}
1401
+ .realiiz-md__lab{font-size:.74rem;color:var(--_muted);margin-right:3px}
1402
+ .realiiz-md__head button[data-tip]::after{content:attr(data-tip);position:absolute;top:calc(100% + 6px);left:0;background:var(--_md-tip);color:#fff;font-size:.72rem;padding:4px 8px;border-radius:5px;white-space:nowrap;opacity:0;pointer-events:none;transition:opacity .12s;z-index:20}
1403
+ .realiiz-md__head button[data-tip]:hover::after,.realiiz-md__head button[data-tip]:focus-visible::after{opacity:1}
1404
+ .realiiz-md__expand[data-tip]::after{left:auto;right:0}
1405
+ .realiiz-md__tgwrap{position:relative;display:inline-flex}
1406
+ .realiiz-md__tgrid{position:absolute;top:calc(100% + 6px);left:0;background:#fff;border:1px solid var(--_border);border-radius:9px;padding:9px;box-shadow:0 10px 28px rgba(0,0,0,.14);z-index:7;display:block}
1407
+ .realiiz-md__tgcells{display:grid;grid-template-columns:repeat(6,17px);gap:3px}
1408
+ .realiiz-md__tgcells i{width:17px;height:15px;border:1px solid var(--_border);border-radius:2px;background:#fff;cursor:pointer;display:block}
1409
+ .realiiz-md__tgcells i.hot{background:#dbe9fb;border-color:var(--_accent)}
1410
+ .realiiz-md__tglab{display:block;margin-top:8px;font-size:.74rem;color:var(--_muted);text-align:center;white-space:nowrap}
1411
+ .realiiz-md .realiiz-md__ta{flex:1 1 auto;border:0;border-radius:0;resize:vertical;background:#fff;max-width:none;padding:16px 18px;line-height:1.65}
1412
+ .realiiz-md .realiiz-md__ta:focus{outline:none;box-shadow:none}
1413
+ .realiiz-md__preview{padding:20px 24px;background:#fff}
1414
+ .realiiz-md__note{padding:4px 2px}
1415
+ .realiiz-md--fs{position:fixed;inset:0;z-index:60;background:#fff;padding:14px 22px 22px;overflow:auto;display:flex;flex-direction:column}
1416
+ .realiiz-md--fs .realiiz-md__panel{flex:1;min-height:0}
1417
+ .realiiz-md--fs .realiiz-md__ta,.realiiz-md--fs .realiiz-md__preview{flex:1;min-height:0;overflow:auto;resize:none}
1418
+ .realiiz-prose{max-width:68ch;line-height:1.65}
1419
+ .realiiz-chips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;min-height:40px;padding:5px 8px;background:#fff;border:1px solid var(--_border);border-radius:var(--_radius)}
1420
+ .realiiz-chips:focus-within{border-color:var(--_accent);box-shadow:var(--_ring)}
1421
+ .realiiz-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 9px;border:1px solid var(--_border);border-radius:999px;font-size:.8rem}
1422
+ .realiiz-chip button{font:inherit;line-height:1;width:18px;height:18px;border-radius:50%;border:0;background:transparent;color:var(--_muted);cursor:pointer}
1423
+ .realiiz-chips__input{flex:1;min-width:120px;border:0;background:transparent;font:inherit;color:inherit;outline:none;padding:4px}
1424
+ .realiiz-chips__count{margin-left:auto;color:var(--_muted);font-size:.75rem}
1425
+ .realiiz-gauge{display:inline-flex;align-items:center;gap:10px;font-size:.75rem;color:var(--_muted)}
1426
+ .realiiz-gauge__bar{position:relative;width:140px;height:6px;border-radius:3px;background:var(--_border);overflow:hidden}
1427
+ .realiiz-gauge__zone{position:absolute;top:0;bottom:0;background:rgba(21,128,61,.28)}
1428
+ .realiiz-gauge__fill{position:absolute;top:0;bottom:0;left:0;background:var(--_muted);border-radius:3px;transition:width .12s}
1429
+ .realiiz-gauge__text b{font-weight:600;color:inherit}
1430
+ .realiiz-gauge--ok{color:#15803d}.realiiz-gauge--ok .realiiz-gauge__fill{background:#15803d}
1431
+ .realiiz-gauge--over{color:var(--_danger)}.realiiz-gauge--over .realiiz-gauge__fill{background:var(--_danger)}
1432
+ `;
1433
+
1085
1434
  // src/forms-ui/values.ts
1086
1435
  function toControl(spec, raw) {
1087
1436
  if (raw === void 0 || raw === null) return spec.input === "boolean" ? false : "";