@declarion/react 0.6.2 → 0.6.5
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataTableStyles-BwnbXviH.js","names":["#items","#index"],"sources":["../src/components/primitives/cx.ts","../src/components/primitives/Icons.tsx","../src/components/primitives/Btn.tsx","../src/components/primitives/IconBtn.tsx","../src/components/primitives/Pill.tsx","../src/components/primitives/Kbd.tsx","../src/components/primitives/Avatar.tsx","../src/components/primitives/BrandGlyph.tsx","../src/components/primitives/Dropdown.tsx","../src/components/primitives/HoverCard.tsx","../src/components/primitives/Chip.tsx","../src/components/primitives/SectionCard.tsx","../src/components/primitives/RecordIdBadge.tsx","../src/components/primitives/RowField.tsx","../src/components/primitives/BoolToggle.tsx","../src/components/primitives/MenuItem.tsx","../src/components/primitives/Check.tsx","../src/components/primitives/Spinner.tsx","../src/components/primitives/ClassifiedFieldLocked.tsx","../src/components/primitives/Fields.tsx","../src/types/ordmap.ts","../src/types/schema.ts","../src/api/schema.ts","../src/api/auth.ts","../src/stores/auth.ts","../src/hooks/useSchema.ts","../src/stores/appearance.ts","../src/components/shared/DynamicIcon.tsx","../src/api/data.ts","../src/components/shared/Markdown.tsx","../src/types/fieldType.ts","../src/components/shared/CopyButton.tsx","../src/components/fields/StringField.tsx","../src/components/fields/TextField.tsx","../src/components/fields/EnumField.tsx","../src/components/fields/EmailField.tsx","../src/components/fields/UrlField.tsx","../src/components/fields/PhoneField.tsx","../src/lib/timestamp.ts","../src/components/fields/TimestampField.tsx","../src/components/fields/BoolField.tsx","../src/components/fields/NumberField.tsx","../src/hooks/useEntityData.ts","../src/hooks/useEntity.ts","../src/components/fields/RefField.tsx","../src/components/fields/JsonField.tsx","../src/components/fields/MultilangField.tsx","../src/components/fields/MultilangTextField.tsx","../src/components/fields/StructureField.tsx","../src/components/fields/SecretField.tsx","../src/components/fields/PasswordField.tsx","../src/components/fields/StringArrayField.tsx","../src/components/fields/IntArrayField.tsx","../src/components/file-widgets/registry.ts","../src/components/file-widgets/cropper.ts","../src/components/file-widgets/ImageWidget.tsx","../src/components/file-widgets/SquareImage.tsx","../src/components/file-widgets/CircleImage.tsx","../src/components/file-widgets/WideBanner.tsx","../src/components/file-widgets/GridLazy.tsx","../src/components/file-widgets/DocumentCard.tsx","../src/components/file-widgets/FileList.tsx","../src/components/file-widgets/LabeledSlots.tsx","../src/components/file-widgets/builtins.ts","../src/components/file-widgets/host.tsx","../src/components/file-widgets/payload.ts","../src/components/file-widgets/index.ts","../src/components/fields/RichTextField.tsx","../src/components/fields/cells/factories/text.ts","../src/components/fields/cells/factories/boolPill.tsx","../src/components/fields/cells/factories/badge.tsx","../src/components/fields/cells/factories/statusPill.tsx","../src/components/fields/cells/factories/tagList.tsx","../src/components/fields/cells/factories/timestamp.tsx","../src/components/fields/cells/factories/nextRun.tsx","../src/components/fields/cells/factories/money.ts","../src/components/fields/cells/factories/refLink.tsx","../src/components/fields/cells/factories/url-helpers.ts","../src/components/fields/cells/factories/host-icons.tsx","../src/components/fields/cells/factories/emptyCell.tsx","../src/components/fields/cells/factories/url.tsx","../src/components/fields/cells/factories/email.tsx","../src/components/fields/cells/factories/phone.tsx","../src/components/fields/cells/factories/number.tsx","../src/components/fields/cells/factories/code.tsx","../src/components/fields/cells/factories/link.tsx","../src/components/fields/cells/factories/json.tsx","../src/components/fields/cells/factories/markdownPreview.ts","../src/components/fields/cells/factories/markdown.tsx","../src/components/fields/cells/factories/passwordMask.tsx","../src/components/fields/cells/factories/richTextPreview.tsx","../src/components/fields/cells/factories/multilangInline.tsx","../src/components/fields/cells/registry.ts","../src/components/fields/index.tsx","../src/hooks/useUserLocale.ts","../src/components/primitives/dataTableStyles.ts"],"sourcesContent":["export function cx(...a: Array<string | false | null | undefined>): string {\n return a.filter(Boolean).join(\" \");\n}\n","// Minimal, crisp icon set matching Lucide-style stroke (1.5) — all 14px/16px friendly.\n// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/icons.jsx.\nimport type { CSSProperties, ReactNode, FC } from \"react\";\n\nexport type IconProps = {\n\tsize?: number;\n\tcls?: string;\n\tstyle?: CSSProperties;\n};\n\nconst I = (path: ReactNode, opts: { sw?: number } = {}): FC<IconProps> => {\n\tconst Component: FC<IconProps> = ({ size = 14, cls = \"\", style = {} }) => (\n\t\t<svg\n\t\t\twidth={size}\n\t\t\theight={size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth={opts.sw ?? 1.5}\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tclassName={cls}\n\t\t\tstyle={style}\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t{path}\n\t\t</svg>\n\t);\n\treturn Component;\n};\n\nexport const Icon = {\n\t// App rail\n\thome: I(\n\t\t<>\n\t\t\t<path d=\"M3 10.5 12 3l9 7.5\" />\n\t\t\t<path d=\"M5 9.5V20a1 1 0 0 0 1 1h4v-6h4v6h4a1 1 0 0 0 1-1V9.5\" />\n\t\t</>,\n\t),\n\tinbox: I(\n\t\t<>\n\t\t\t<path d=\"M4 13v5a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5\" />\n\t\t\t<path d=\"M4 13h5l1 2h4l1-2h5\" />\n\t\t\t<path d=\"M4 13 7 5a2 2 0 0 1 2-1h6a2 2 0 0 1 2 1l3 8\" />\n\t\t</>,\n\t),\n\tflow: I(\n\t\t<>\n\t\t\t<circle cx=\"6\" cy=\"6\" r=\"2\" />\n\t\t\t<circle cx=\"18\" cy=\"6\" r=\"2\" />\n\t\t\t<circle cx=\"6\" cy=\"18\" r=\"2\" />\n\t\t\t<circle cx=\"18\" cy=\"18\" r=\"2\" />\n\t\t\t<path d=\"M8 6h8M6 8v8M18 8v8M8 18h8\" />\n\t\t</>,\n\t),\n\tpipeline: I(\n\t\t<>\n\t\t\t<path d=\"M3 6h13l5 3-5 3H3z\" />\n\t\t\t<path d=\"M3 13h9\" />\n\t\t\t<path d=\"M3 18h13\" />\n\t\t</>,\n\t),\n\tleads: I(\n\t\t<>\n\t\t\t<circle cx=\"9\" cy=\"8\" r=\"3\" />\n\t\t\t<path d=\"M3 20c0-3 3-5 6-5s6 2 6 5\" />\n\t\t\t<path d=\"M17 10l2 2 4-4\" />\n\t\t</>,\n\t),\n\tcompany: I(\n\t\t<>\n\t\t\t<path d=\"M4 21V6a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v15\" />\n\t\t\t<path d=\"M15 21V11h4a1 1 0 0 1 1 1v9\" />\n\t\t\t<path d=\"M7 9h2M7 13h2M7 17h2M11 9h1M11 13h1M11 17h1\" />\n\t\t</>,\n\t),\n\tactivity: I(\n\t\t<>\n\t\t\t<path d=\"M3 12h4l3-8 4 16 3-8h4\" />\n\t\t</>,\n\t),\n\tusers: I(\n\t\t<>\n\t\t\t<circle cx=\"9\" cy=\"8\" r=\"3\" />\n\t\t\t<path d=\"M2 21c0-3.5 3-6 7-6s7 2.5 7 6\" />\n\t\t\t<path d=\"M16 3.5a3 3 0 0 1 0 6\" />\n\t\t\t<path d=\"M22 20c0-2.5-1.5-5-4-6\" />\n\t\t</>,\n\t),\n\ttenant: I(\n\t\t<>\n\t\t\t<path d=\"M3 21V9l6-4 6 4M3 21h18\" />\n\t\t\t<path d=\"M15 21V9\" />\n\t\t\t<path d=\"M19 21V13l2-2\" />\n\t\t\t<path d=\"M7 13h2M7 17h2M11 13h1M11 17h1\" />\n\t\t</>,\n\t),\n\tshield: I(\n\t\t<>\n\t\t\t<path d=\"M12 3 4 6v6c0 4.5 3.5 8 8 9 4.5-1 8-4.5 8-9V6z\" />\n\t\t</>,\n\t),\n\tkey: I(\n\t\t<>\n\t\t\t<circle cx=\"8\" cy=\"14\" r=\"4\" />\n\t\t\t<path d=\"m11 11 9-9M17 5l3 3M15 7l3 3\" />\n\t\t</>,\n\t),\n\tgroup: I(\n\t\t<>\n\t\t\t<circle cx=\"8\" cy=\"10\" r=\"3\" />\n\t\t\t<circle cx=\"17\" cy=\"8\" r=\"2\" />\n\t\t\t<path d=\"M2 20c0-3 2.5-5 6-5s6 2 6 5\" />\n\t\t\t<path d=\"M15 16c2-1 4-1 6 0\" />\n\t\t</>,\n\t),\n\tidp: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n\t\t\t<path d=\"M3 10h18\" />\n\t\t\t<path d=\"M7 15h4\" />\n\t\t</>,\n\t),\n\taudit: I(\n\t\t<>\n\t\t\t<path d=\"M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z\" />\n\t\t\t<path d=\"M14 3v6h6\" />\n\t\t\t<path d=\"M8 13h8M8 17h5\" />\n\t\t</>,\n\t),\n\tlog: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n\t\t\t<path d=\"M7 9h10M7 13h10M7 17h6\" />\n\t\t</>,\n\t),\n\thandlers: I(\n\t\t<>\n\t\t\t<path d=\"M10 4 4 8v8l6 4 6-4\" />\n\t\t\t<path d=\"M16 4l4 2.5v8L16 17\" />\n\t\t\t<path d=\"m10 12 6-3.5\" />\n\t\t</>,\n\t),\n\tjobs: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"6\" width=\"18\" height=\"13\" rx=\"2\" />\n\t\t\t<path d=\"M8 6V4h8v2\" />\n\t\t\t<path d=\"M12 10v5\" />\n\t\t\t<path d=\"M10 12h4\" />\n\t\t</>,\n\t),\n\tsched: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"13\" r=\"8\" />\n\t\t\t<path d=\"M12 9v4l3 2\" />\n\t\t\t<path d=\"M9 3h6\" />\n\t\t</>,\n\t),\n\tentity: I(\n\t\t<>\n\t\t\t<ellipse cx=\"12\" cy=\"6\" rx=\"8\" ry=\"3\" />\n\t\t\t<path d=\"M4 6v6c0 1.7 3.6 3 8 3s8-1.3 8-3V6\" />\n\t\t\t<path d=\"M4 12v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6\" />\n\t\t</>,\n\t),\n\tfield: I(\n\t\t<>\n\t\t\t<path d=\"M4 6h16M4 12h10M4 18h16\" />\n\t\t</>,\n\t),\n\taction: I(\n\t\t<>\n\t\t\t<path d=\"M13 3 4 14h6l-1 7 9-11h-6z\" />\n\t\t</>,\n\t),\n\tcode: I(\n\t\t<>\n\t\t\t<path d=\"m8 8-4 4 4 4M16 8l4 4-4 4M14 4l-4 16\" />\n\t\t</>,\n\t),\n\n\t// Toolbar\n\tsearch: I(\n\t\t<>\n\t\t\t<circle cx=\"11\" cy=\"11\" r=\"7\" />\n\t\t\t<path d=\"m20 20-3.5-3.5\" />\n\t\t</>,\n\t),\n\tfilter: I(\n\t\t<>\n\t\t\t<path d=\"M3 5h18l-7 9v6l-4-2v-4z\" />\n\t\t</>,\n\t),\n\tcolumns: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"1\" />\n\t\t\t<path d=\"M9 4v16M15 4v16\" />\n\t\t</>,\n\t),\n\tplus: I(\n\t\t<>\n\t\t\t<path d=\"M12 5v14M5 12h14\" />\n\t\t</>,\n\t),\n\tminus: I(\n\t\t<>\n\t\t\t<path d=\"M5 12h14\" />\n\t\t</>,\n\t),\n\tsort: I(\n\t\t<>\n\t\t\t<path d=\"M8 4v16l-3-3M8 4l3 3\" />\n\t\t\t<path d=\"M16 20V4l-3 3M16 20l3-3\" />\n\t\t</>,\n\t),\n\tmore: I(\n\t\t<>\n\t\t\t<circle cx=\"5\" cy=\"12\" r=\"1.2\" />\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"1.2\" />\n\t\t\t<circle cx=\"19\" cy=\"12\" r=\"1.2\" />\n\t\t</>,\n\t\t{ sw: 2 },\n\t),\n\tx: I(\n\t\t<>\n\t\t\t<path d=\"M18 6 6 18M6 6l12 12\" />\n\t\t</>,\n\t),\n\tcheck: I(\n\t\t<>\n\t\t\t<path d=\"m5 12 5 5L20 7\" />\n\t\t</>,\n\t\t{ sw: 2 },\n\t),\n\tdown: I(\n\t\t<>\n\t\t\t<path d=\"m6 9 6 6 6-6\" />\n\t\t</>,\n\t),\n\tup: I(\n\t\t<>\n\t\t\t<path d=\"m6 15 6-6 6 6\" />\n\t\t</>,\n\t),\n\tright: I(\n\t\t<>\n\t\t\t<path d=\"m9 6 6 6-6 6\" />\n\t\t</>,\n\t),\n\tleft: I(\n\t\t<>\n\t\t\t<path d=\"m15 6-6 6 6 6\" />\n\t\t</>,\n\t),\n\tcheveron: I(\n\t\t<>\n\t\t\t<path d=\"m8 10 4 4 4-4\" />\n\t\t</>,\n\t),\n\tback: I(\n\t\t<>\n\t\t\t<path d=\"M19 12H5M12 19l-7-7 7-7\" />\n\t\t</>,\n\t),\n\n\t// Fields / actions\n\tcalendar: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" />\n\t\t\t<path d=\"M3 10h18\" />\n\t\t\t<path d=\"M8 3v4M16 3v4\" />\n\t\t</>,\n\t),\n\tclock: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M12 7v5l3 2\" />\n\t\t</>,\n\t),\n\tlock: I(\n\t\t<>\n\t\t\t<rect x=\"5\" y=\"11\" width=\"14\" height=\"9\" rx=\"2\" />\n\t\t\t<path d=\"M8 11V8a4 4 0 0 1 8 0v3\" />\n\t\t</>,\n\t),\n\temail: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n\t\t\t<path d=\"m3 7 9 6 9-6\" />\n\t\t</>,\n\t),\n\tlink: I(\n\t\t<>\n\t\t\t<path d=\"M10 14a5 5 0 0 0 7 0l3-3a5 5 0 1 0-7-7l-1 1\" />\n\t\t\t<path d=\"M14 10a5 5 0 0 0-7 0l-3 3a5 5 0 1 0 7 7l1-1\" />\n\t\t</>,\n\t),\n\thash: I(\n\t\t<>\n\t\t\t<path d=\"M5 9h14M5 15h14M10 3 8 21M16 3l-2 18\" />\n\t\t</>,\n\t),\n\teye: I(\n\t\t<>\n\t\t\t<path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z\" />\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"3\" />\n\t\t</>,\n\t),\n\teyeOff: I(\n\t\t<>\n\t\t\t<path d=\"M3 3l18 18\" />\n\t\t\t<path d=\"M10.6 6.2A10 10 0 0 1 12 6c6.5 0 10 6 10 6a17 17 0 0 1-3.6 4.3M6.4 6.4A17 17 0 0 0 2 12s3.5 6 10 6c1.3 0 2.5-.2 3.6-.6\" />\n\t\t\t<path d=\"M9.9 9.9a3 3 0 0 0 4.2 4.2\" />\n\t\t</>,\n\t),\n\tcopy: I(\n\t\t<>\n\t\t\t<rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" />\n\t\t\t<path d=\"M5 15V5a2 2 0 0 1 2-2h10\" />\n\t\t</>,\n\t),\n\ttrash: I(\n\t\t<>\n\t\t\t<path d=\"M4 7h16M9 7V4h6v3M6 7l1 13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-13\" />\n\t\t</>,\n\t),\n\tedit: I(\n\t\t<>\n\t\t\t<path d=\"M4 20h4l11-11-4-4L4 16z\" />\n\t\t\t<path d=\"m13 6 4 4\" />\n\t\t</>,\n\t),\n\tsave: I(\n\t\t<>\n\t\t\t<path d=\"M4 5a2 2 0 0 1 2-2h10l4 4v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2z\" />\n\t\t\t<path d=\"M7 3v5h8V3M8 15h8v6H8z\" />\n\t\t</>,\n\t),\n\trefresh: I(\n\t\t<>\n\t\t\t<path d=\"M3 12a9 9 0 0 1 15-6.7L21 8\" />\n\t\t\t<path d=\"M21 3v5h-5\" />\n\t\t\t<path d=\"M21 12a9 9 0 0 1-15 6.7L3 16\" />\n\t\t\t<path d=\"M3 21v-5h5\" />\n\t\t</>,\n\t),\n\tdownload: I(\n\t\t<>\n\t\t\t<path d=\"M12 3v12\" />\n\t\t\t<path d=\"m7 10 5 5 5-5\" />\n\t\t\t<path d=\"M5 20h14\" />\n\t\t</>,\n\t),\n\tupload: I(\n\t\t<>\n\t\t\t<path d=\"M12 15V3\" />\n\t\t\t<path d=\"m7 8 5-5 5 5\" />\n\t\t\t<path d=\"M5 20h14\" />\n\t\t</>,\n\t),\n\tpaperclip: I(\n\t\t<>\n\t\t\t<path d=\"m21 10-9.2 9.2a5 5 0 1 1-7-7L14 3a3.5 3.5 0 0 1 5 5L9.8 17.2a2 2 0 1 1-3-3L15 6\" />\n\t\t</>,\n\t),\n\ttag: I(\n\t\t<>\n\t\t\t<path d=\"M4 4h7l9 9-7 7-9-9z\" />\n\t\t\t<circle cx=\"8\" cy=\"8\" r=\"1.5\" />\n\t\t</>,\n\t),\n\tbolt: I(\n\t\t<>\n\t\t\t<path d=\"M13 3 4 14h6l-1 7 9-11h-6z\" />\n\t\t</>,\n\t),\n\tbell: I(\n\t\t<>\n\t\t\t<path d=\"M18 16v-5a6 6 0 0 0-12 0v5l-2 3h16z\" />\n\t\t\t<path d=\"M10 20a2 2 0 0 0 4 0\" />\n\t\t</>,\n\t),\n\tai: I(\n\t\t<>\n\t\t\t<path d=\"M12 3v3M12 18v3M3 12h3M18 12h3M5.5 5.5l2 2M16.5 16.5l2 2M18.5 5.5l-2 2M7.5 16.5l-2 2\" />\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"3.5\" />\n\t\t</>,\n\t),\n\tsparkle: I(\n\t\t<>\n\t\t\t<path d=\"M12 3v4M12 17v4M3 12h4M17 12h4\" />\n\t\t\t<path d=\"m7 7 2 2M15 15l2 2M17 7l-2 2M9 15l-2 2\" />\n\t\t</>,\n\t),\n\tcommand: I(\n\t\t<>\n\t\t\t<path d=\"M9 3a3 3 0 1 1-3 3v12a3 3 0 1 1 3-3h6a3 3 0 1 1 3 3V6a3 3 0 1 1-3 3H9\" />\n\t\t</>,\n\t),\n\tmenu: I(\n\t\t<>\n\t\t\t<path d=\"M4 6h16M4 12h16M4 18h16\" />\n\t\t</>,\n\t),\n\tdot: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"4\" fill=\"currentColor\" />\n\t\t</>,\n\t),\n\tglobe: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M3 12h18M12 3c3 3 3 15 0 18-3-3-3-15 0-18\" />\n\t\t</>,\n\t),\n\tfolder: I(\n\t\t<>\n\t\t\t<path d=\"M3 6a1 1 0 0 1 1-1h5l2 2h8a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z\" />\n\t\t</>,\n\t),\n\tfile: I(\n\t\t<>\n\t\t\t<path d=\"M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z\" />\n\t\t\t<path d=\"M14 3v6h6\" />\n\t\t</>,\n\t),\n\tbranch: I(\n\t\t<>\n\t\t\t<circle cx=\"6\" cy=\"6\" r=\"2\" />\n\t\t\t<circle cx=\"6\" cy=\"18\" r=\"2\" />\n\t\t\t<circle cx=\"18\" cy=\"8\" r=\"2\" />\n\t\t\t<path d=\"M6 8v8\" />\n\t\t\t<path d=\"M18 10c0 4-4 4-6 6\" />\n\t\t</>,\n\t),\n\tsun: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"4\" />\n\t\t\t<path d=\"M12 3v2M12 19v2M3 12h2M19 12h2M5.6 5.6l1.4 1.4M17 17l1.4 1.4M18.4 5.6 17 7M7 17l-1.4 1.4\" />\n\t\t</>,\n\t),\n\tmoon: I(\n\t\t<>\n\t\t\t<path d=\"M20 14A8 8 0 0 1 10 4a8 8 0 1 0 10 10z\" />\n\t\t</>,\n\t),\n\tsettings: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"3\" />\n\t\t\t<path d=\"M19 12a7 7 0 0 0-.2-1.7l2-1.5-2-3.4-2.3.9a7 7 0 0 0-3-1.7L13 2h-4l-.5 2.6a7 7 0 0 0-3 1.7L3.2 5.4l-2 3.4 2 1.5A7 7 0 0 0 3 12c0 .6.1 1.2.2 1.7l-2 1.5 2 3.4 2.3-.9a7 7 0 0 0 3 1.7L9 22h4l.5-2.6a7 7 0 0 0 3-1.7l2.3.9 2-3.4-2-1.5c.1-.5.2-1.1.2-1.7z\" />\n\t\t</>,\n\t),\n\tlogout: I(\n\t\t<>\n\t\t\t<path d=\"M14 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\" />\n\t\t\t<path d=\"M10 17 5 12l5-5\" />\n\t\t\t<path d=\"M5 12h12\" />\n\t\t</>,\n\t),\n\tloader: I(\n\t\t<>\n\t\t\t<path d=\"M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M18.4 5.6l-2.8 2.8M8.4 15.6l-2.8 2.8\" />\n\t\t</>,\n\t),\n\tgrid: I(\n\t\t<>\n\t\t\t<rect x=\"4\" y=\"4\" width=\"7\" height=\"7\" rx=\"1\" />\n\t\t\t<rect x=\"13\" y=\"4\" width=\"7\" height=\"7\" rx=\"1\" />\n\t\t\t<rect x=\"4\" y=\"13\" width=\"7\" height=\"7\" rx=\"1\" />\n\t\t\t<rect x=\"13\" y=\"13\" width=\"7\" height=\"7\" rx=\"1\" />\n\t\t</>,\n\t),\n\tstar: I(\n\t\t<>\n\t\t\t<path d=\"m12 3 3 6 6 1-4.5 4.5 1 6.5L12 18l-5.5 3 1-6.5L3 10l6-1z\" />\n\t\t</>,\n\t),\n\twarning: I(\n\t\t<>\n\t\t\t<path d=\"m12 3 10 18H2z\" />\n\t\t\t<path d=\"M12 10v5M12 18v.5\" />\n\t\t</>,\n\t),\n\tinfo: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M12 11v6M12 8v.5\" />\n\t\t</>,\n\t),\n\tbuilding: I(\n\t\t<>\n\t\t\t<path d=\"M4 21V3h12v18M4 21h16\" />\n\t\t\t<path d=\"M16 9h4v12\" />\n\t\t\t<path d=\"M7 6h2M7 10h2M7 14h2M11 6h2M11 10h2M11 14h2\" />\n\t\t</>,\n\t),\n\tdevice: I(\n\t\t<>\n\t\t\t<rect x=\"5\" y=\"3\" width=\"14\" height=\"18\" rx=\"2\" />\n\t\t\t<path d=\"M10 18h4\" />\n\t\t</>,\n\t),\n\tarrowUp: I(\n\t\t<>\n\t\t\t<path d=\"M12 19V5M5 12l7-7 7 7\" />\n\t\t</>,\n\t),\n\tarrowDown: I(\n\t\t<>\n\t\t\t<path d=\"M12 5v14M5 12l7 7 7-7\" />\n\t\t</>,\n\t),\n\texternal: I(\n\t\t<>\n\t\t\t<path d=\"M14 4h6v6\" />\n\t\t\t<path d=\"M20 4 10 14\" />\n\t\t\t<path d=\"M20 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5\" />\n\t\t</>,\n\t),\n\tdbtable: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"1\" />\n\t\t\t<path d=\"M3 9h18M3 13h18M9 9v10M15 9v10\" />\n\t\t</>,\n\t),\n\n\t// Kebab-case aliases used by YAML schemas (entity.display.icon, screen.display.icon, nav icons).\n\t// Kept as string keys so lookups via Icon[name] match the YAML value directly.\n\t\"users-round\": I(\n\t\t<>\n\t\t\t<circle cx=\"10\" cy=\"8\" r=\"5\" />\n\t\t\t<path d=\"M2 21a8 8 0 0 1 16 0\" />\n\t\t\t<path d=\"M17 4a5 5 0 0 1 0 8\" />\n\t\t\t<path d=\"M22 21a6 6 0 0 0-4-5.6\" />\n\t\t</>,\n\t),\n\tuser: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"7\" r=\"4\" />\n\t\t\t<path d=\"M6 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2\" />\n\t\t</>,\n\t),\n\t\"user-plus\": I(\n\t\t<>\n\t\t\t<circle cx=\"9\" cy=\"7\" r=\"4\" />\n\t\t\t<path d=\"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\" />\n\t\t\t<path d=\"M19 8v6M22 11h-6\" />\n\t\t</>,\n\t),\n\t\"shield-check\": I(\n\t\t<>\n\t\t\t<path d=\"M12 3 4 6v6c0 4.5 3.5 8 8 9 4.5-1 8-4.5 8-9V6z\" />\n\t\t\t<path d=\"m9 12 2 2 4-4\" />\n\t\t</>,\n\t),\n\t\"shield-plus\": I(\n\t\t<>\n\t\t\t<path d=\"M12 3 4 6v6c0 4.5 3.5 8 8 9 4.5-1 8-4.5 8-9V6z\" />\n\t\t\t<path d=\"M9 12h6M12 9v6\" />\n\t\t</>,\n\t),\n\t\"key-round\": I(\n\t\t<>\n\t\t\t<path d=\"M2 18v3c0 .6.4 1 1 1h4v-3h3v-3h2l1.4-1.4a6.5 6.5 0 1 0-4-4z\" />\n\t\t\t<circle cx=\"16.5\" cy=\"7.5\" r=\"0.5\" fill=\"currentColor\" />\n\t\t</>,\n\t),\n\t\"list-checks\": I(\n\t\t<>\n\t\t\t<path d=\"m3 17 2 2 4-4\" />\n\t\t\t<path d=\"m3 7 2 2 4-4\" />\n\t\t\t<path d=\"M13 6h8M13 12h8M13 18h8\" />\n\t\t</>,\n\t),\n\tlist: I(\n\t\t<>\n\t\t\t<path d=\"M8 6h13M8 12h13M8 18h13\" />\n\t\t\t<circle cx=\"3.5\" cy=\"6\" r=\"0.5\" fill=\"currentColor\" />\n\t\t\t<circle cx=\"3.5\" cy=\"12\" r=\"0.5\" fill=\"currentColor\" />\n\t\t\t<circle cx=\"3.5\" cy=\"18\" r=\"0.5\" fill=\"currentColor\" />\n\t\t</>,\n\t),\n\t\"play-circle\": I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M10 8.5v7L16 12z\" />\n\t\t</>,\n\t),\n\tplay: I(\n\t\t<>\n\t\t\t<path d=\"M6 3 20 12 6 21z\" />\n\t\t</>,\n\t),\n\tlayers: I(\n\t\t<>\n\t\t\t<path d=\"M12 2 2 7l10 5 10-5z\" />\n\t\t\t<path d=\"m2 12 10 5 10-5\" />\n\t\t\t<path d=\"m2 17 10 5 10-5\" />\n\t\t</>,\n\t),\n\tlayout: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n\t\t\t<path d=\"M3 9h18\" />\n\t\t\t<path d=\"M9 21V9\" />\n\t\t</>,\n\t),\n\t\"layout-dashboard\": I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"3\" width=\"7\" height=\"9\" rx=\"1\" />\n\t\t\t<rect x=\"14\" y=\"3\" width=\"7\" height=\"5\" rx=\"1\" />\n\t\t\t<rect x=\"14\" y=\"12\" width=\"7\" height=\"9\" rx=\"1\" />\n\t\t\t<rect x=\"3\" y=\"16\" width=\"7\" height=\"5\" rx=\"1\" />\n\t\t</>,\n\t),\n\tdatabase: I(\n\t\t<>\n\t\t\t<ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" />\n\t\t\t<path d=\"M3 5v14c0 1.7 4 3 9 3s9-1.3 9-3V5\" />\n\t\t\t<path d=\"M3 12c0 1.7 4 3 9 3s9-1.3 9-3\" />\n\t\t</>,\n\t),\n\tzap: I(\n\t\t<>\n\t\t\t<path d=\"M13 3 4 14h6l-1 7 9-11h-6z\" />\n\t\t</>,\n\t),\n\tcpu: I(\n\t\t<>\n\t\t\t<rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" />\n\t\t\t<rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" />\n\t\t\t<path d=\"M9 2v2M15 2v2M9 20v2M15 20v2M2 9h2M2 15h2M20 9h2M20 15h2\" />\n\t\t</>,\n\t),\n\t\"circle-dot\": I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n\t\t</>,\n\t),\n\t\"toggle-right\": I(\n\t\t<>\n\t\t\t<rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"6\" />\n\t\t\t<circle cx=\"16\" cy=\"12\" r=\"2.5\" fill=\"currentColor\" />\n\t\t</>,\n\t),\n\tsliders: I(\n\t\t<>\n\t\t\t<path d=\"M21 4h-7M10 4H3M21 12h-9M8 12H3M21 20h-5M12 20H3M14 2v4M8 10v4M16 18v4\" />\n\t\t</>,\n\t),\n\t\"sliders-horizontal\": I(\n\t\t<>\n\t\t\t<path d=\"M21 4h-7M10 4H3M21 12h-9M8 12H3M21 20h-5M12 20H3M14 2v4M8 10v4M16 18v4\" />\n\t\t</>,\n\t),\n\tbox: I(\n\t\t<>\n\t\t\t<path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\" />\n\t\t\t<path d=\"m3.3 7 8.7 5 8.7-5\" />\n\t\t\t<path d=\"M12 22V12\" />\n\t\t</>,\n\t),\n\t\"columns-3\": I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"1\" />\n\t\t\t<path d=\"M9 4v16M15 4v16\" />\n\t\t</>,\n\t),\n\t\"settings-2\": I(\n\t\t<>\n\t\t\t<path d=\"M20 7h-9M14 17H5\" />\n\t\t\t<circle cx=\"17\" cy=\"17\" r=\"3\" />\n\t\t\t<circle cx=\"7\" cy=\"7\" r=\"3\" />\n\t\t</>,\n\t),\n\t\"file-diff\": I(\n\t\t<>\n\t\t\t<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n\t\t\t<path d=\"M14 2v6h6\" />\n\t\t\t<path d=\"M12 12v6M9 15h6M9 18h6\" />\n\t\t</>,\n\t),\n\t\"git-branch\": I(\n\t\t<>\n\t\t\t<circle cx=\"6\" cy=\"6\" r=\"2\" />\n\t\t\t<circle cx=\"6\" cy=\"18\" r=\"2\" />\n\t\t\t<circle cx=\"18\" cy=\"8\" r=\"2\" />\n\t\t\t<path d=\"M6 8v8\" />\n\t\t\t<path d=\"M18 10a6 6 0 0 1-6 6h-2\" />\n\t\t</>,\n\t),\n\t\"log-in\": I(\n\t\t<>\n\t\t\t<path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\" />\n\t\t\t<path d=\"m10 17 5-5-5-5\" />\n\t\t\t<path d=\"M15 12H3\" />\n\t\t</>,\n\t),\n\t\"plus-circle\": I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M8 12h8M12 8v8\" />\n\t\t</>,\n\t),\n\trepeat: I(\n\t\t<>\n\t\t\t<path d=\"m17 2 4 4-4 4\" />\n\t\t\t<path d=\"M3 11v-1a4 4 0 0 1 4-4h14\" />\n\t\t\t<path d=\"m7 22-4-4 4-4\" />\n\t\t\t<path d=\"M21 13v1a4 4 0 0 1-4 4H3\" />\n\t\t</>,\n\t),\n\tban: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"m5.6 5.6 12.8 12.8\" />\n\t\t</>,\n\t),\n\t\"trash-2\": I(\n\t\t<>\n\t\t\t<path d=\"M4 7h16M9 7V4h6v3M6 7l1 13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-13\" />\n\t\t\t<path d=\"M10 11v6M14 11v6\" />\n\t\t</>,\n\t),\n\t\"shopping-cart\": I(\n\t\t<>\n\t\t\t<circle cx=\"9\" cy=\"20\" r=\"1.5\" />\n\t\t\t<circle cx=\"18\" cy=\"20\" r=\"1.5\" />\n\t\t\t<path d=\"M2 3h3l3 12h10l3-8H7\" />\n\t\t</>,\n\t),\n\t\"credit-card\": I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n\t\t\t<path d=\"M3 10h18\" />\n\t\t\t<path d=\"M7 15h4\" />\n\t\t</>,\n\t),\n\tpackage: I(\n\t\t<>\n\t\t\t<path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\" />\n\t\t\t<path d=\"m3.3 7 8.7 5 8.7-5\" />\n\t\t\t<path d=\"M12 22V12\" />\n\t\t</>,\n\t),\n\tboxes: I(\n\t\t<>\n\t\t\t<path d=\"M7.5 7.5 3 10v5l4.5 2.5L12 15v-5z\" />\n\t\t\t<path d=\"M16.5 7.5 12 10v5l4.5 2.5L21 15v-5z\" />\n\t\t\t<path d=\"M12 2.5 7.5 5v5L12 12.5 16.5 10V5z\" />\n\t\t</>,\n\t),\n\ttags: I(\n\t\t<>\n\t\t\t<path d=\"M4 4h7l9 9-7 7-9-9z\" />\n\t\t\t<path d=\"M8 8h.01\" />\n\t\t\t<path d=\"M13 4h2l6 6\" />\n\t\t</>,\n\t),\n\t\"wallet-cards\": I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"7\" width=\"18\" height=\"13\" rx=\"2\" />\n\t\t\t<path d=\"M16 11h5v5h-5a2.5 2.5 0 0 1 0-5z\" />\n\t\t\t<path d=\"M5 7V5a2 2 0 0 1 2-2h10v4\" />\n\t\t</>,\n\t),\n\t\"receipt-text\": I(\n\t\t<>\n\t\t\t<path d=\"M6 3h12v18l-3-2-3 2-3-2-3 2z\" />\n\t\t\t<path d=\"M9 8h6M9 12h6M9 16h4\" />\n\t\t</>,\n\t),\n\t\"badge-dollar-sign\": I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M12 6v12M15 9.5c-.7-.8-1.7-1.2-3-1.2-1.6 0-2.7.8-2.7 2s1 1.7 2.7 2.1c1.8.4 3 .9 3 2.3S13.8 17 12 17c-1.4 0-2.6-.5-3.4-1.4\" />\n\t\t</>,\n\t),\n\t\"undo-2\": I(\n\t\t<>\n\t\t\t<path d=\"M9 14 4 9l5-5\" />\n\t\t\t<path d=\"M4 9h10a6 6 0 1 1 0 12h-2\" />\n\t\t</>,\n\t),\n} as const;\n\nexport type IconName = keyof typeof Icon;\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport { forwardRef } from \"react\";\nimport type { ButtonHTMLAttributes, CSSProperties, MouseEvent, ReactNode } from \"react\";\n\nexport type BtnKind = \"primary\" | \"navy\" | \"ghost\" | \"subtle\" | \"default\";\nexport type BtnSize = \"xs\" | \"sm\" | \"md\" | \"lg\";\n\nexport type BtnProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"size\"> & {\n kind?: BtnKind;\n size?: BtnSize;\n icon?: ReactNode;\n iconRight?: ReactNode;\n active?: boolean;\n danger?: boolean;\n};\n\nexport const Btn = forwardRef<HTMLButtonElement, BtnProps>(function Btn(\n { kind = \"default\", size = \"sm\", icon, iconRight, children, onClick, active, danger, style, disabled, type = \"button\", title, ...rest },\n ref,\n) {\n const H = size === \"xs\" ? 24 : size === \"sm\" ? 28 : size === \"md\" ? 32 : 36;\n const P = size === \"xs\" ? 8 : size === \"sm\" ? 10 : size === \"md\" ? 12 : 14;\n const s: CSSProperties = {\n display: \"inline-flex\", alignItems: \"center\", gap: 6, height: H, padding: `0 ${P}px`,\n borderRadius: 6, fontSize: size === \"xs\" ? 11.5 : 12.5, fontWeight: 500, cursor: \"pointer\",\n transition: \"background .12s, border-color .12s, color .12s\",\n whiteSpace: \"nowrap\",\n };\n if (kind === \"primary\") Object.assign(s, {\n background: \"var(--accent)\", color: \"var(--primary-fg)\", border: \"1px solid var(--accent)\",\n });\n else if (kind === \"navy\") Object.assign(s, {\n background: \"var(--primary)\", color: \"var(--primary-fg)\", border: \"1px solid var(--primary)\",\n });\n else if (kind === \"ghost\") Object.assign(s, {\n background: \"transparent\", color: active ? \"var(--text)\" : \"var(--text-2)\",\n border: \"1px solid transparent\", ...(active && { background: \"var(--surface-3)\" }),\n });\n else if (kind === \"subtle\") Object.assign(s, {\n background: active ? \"var(--surface-3)\" : \"var(--surface-2)\", color: \"var(--text-2)\",\n border: \"1px solid var(--border)\",\n });\n else Object.assign(s, {\n background: \"var(--surface)\", color: \"var(--text)\",\n border: \"1px solid var(--border)\",\n });\n // Danger styling is kind-aware. A destructive CTA (\"Delete record\") on a\n // primary button uses the full red treatment (solid danger bg + white\n // text + red border) so it reads as the intended destructive affordance,\n // not a purple accent button with red text. Secondary kinds (ghost /\n // subtle / default — e.g. an inline row-delete icon button) keep only the\n // tinted-text pattern so they remain visually secondary.\n if (danger) {\n if (kind === \"primary\") {\n Object.assign(s, {\n background: \"var(--danger)\",\n color: \"var(--primary-fg)\",\n borderColor: \"var(--danger)\",\n });\n } else {\n Object.assign(s, { color: \"var(--danger)\", borderColor: \"var(--border)\" });\n }\n }\n if (disabled) Object.assign(s, { opacity: 0.5, pointerEvents: \"none\" });\n Object.assign(s, style || {});\n return (\n <button\n ref={ref}\n type={type}\n onClick={onClick}\n title={title}\n disabled={disabled}\n {...rest}\n style={s}\n onMouseEnter={(e: MouseEvent<HTMLButtonElement>) => {\n if (kind === \"primary\" && danger) e.currentTarget.style.background = \"var(--danger-hover, var(--danger))\";\n else if (kind === \"primary\") e.currentTarget.style.background = \"var(--accent-2)\";\n else if (kind === \"navy\") e.currentTarget.style.background = \"var(--primary-hover)\";\n else if (kind !== \"ghost\") e.currentTarget.style.background = \"var(--surface-3)\";\n else e.currentTarget.style.background = \"var(--surface-3)\";\n }}\n onMouseLeave={(e: MouseEvent<HTMLButtonElement>) => {\n e.currentTarget.style.background = (s.background as string) ?? \"\";\n }}\n >\n {icon}{children}{iconRight}\n </button>\n );\n});\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport { forwardRef } from \"react\";\nimport type { CSSProperties, MouseEvent, ReactNode } from \"react\";\n\nexport type IconBtnProps = {\n icon: ReactNode;\n onClick?: (e: MouseEvent<HTMLButtonElement>) => void;\n title?: string;\n size?: number;\n active?: boolean;\n disabled?: boolean;\n style?: CSSProperties;\n};\n\nexport const IconBtn = forwardRef<HTMLButtonElement, IconBtnProps>(function IconBtn(\n { icon, onClick, title, size = 28, active, disabled, style },\n ref,\n) {\n return (\n <button\n type=\"button\"\n ref={ref}\n onClick={onClick}\n title={title}\n aria-label={title}\n disabled={disabled}\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n width: size, height: size, borderRadius: 6, border: \"1px solid transparent\",\n background: active ? \"var(--surface-3)\" : \"transparent\",\n color: active ? \"var(--text)\" : \"var(--text-2)\",\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n padding: 0,\n opacity: disabled ? 0.4 : 1,\n ...style,\n }}\n onMouseEnter={(e) => {\n if (disabled) return;\n e.currentTarget.style.background = \"var(--surface-3)\";\n e.currentTarget.style.color = \"var(--text)\";\n }}\n onMouseLeave={(e) => {\n if (disabled) return;\n e.currentTarget.style.background = active ? \"var(--surface-3)\" : \"transparent\";\n e.currentTarget.style.color = active ? \"var(--text)\" : \"var(--text-2)\";\n }}\n >\n {icon}\n </button>\n );\n});\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport type { CSSProperties, ReactNode } from \"react\";\n\nexport type PillTone =\n | \"indigo\" | \"emerald\" | \"amber\" | \"rose\"\n | \"sky\" | \"violet\" | \"slate\" | \"teal\";\nexport type PillSize = \"xs\" | \"sm\" | \"md\";\n\nexport type PillProps = {\n tone?: PillTone;\n size?: PillSize;\n dot?: boolean;\n style?: CSSProperties;\n children?: ReactNode;\n};\n\nexport function Pill({ tone = \"slate\", children, size = \"sm\", dot = false, style }: PillProps) {\n const bg = `var(--pill-${tone}-bg)`;\n const fg = `var(--pill-${tone})`;\n const h = size === \"sm\" ? 20 : size === \"xs\" ? 16 : 24;\n return (\n <span className=\"num\" style={{\n display: \"inline-flex\", alignItems: \"center\", gap: 6, height: h,\n padding: `0 ${size === \"xs\" ? 6 : 8}px`, borderRadius: 999,\n background: bg, color: fg, fontSize: size === \"xs\" ? 10.5 : 11.5, fontWeight: 500,\n whiteSpace: \"nowrap\", maxWidth: \"100%\", ...style,\n }}>\n {dot && <span style={{ width: 6, height: 6, borderRadius: 999, background: fg }} />}\n <span style={{\n minWidth: 0,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}>{children}</span>\n </span>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport type { ReactNode } from \"react\";\n\nexport function Kbd({ children }: { children?: ReactNode }) {\n return (\n <span\n className=\"mono\"\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n minWidth: 18, height: 18, padding: \"0 5px\", borderRadius: 4,\n background: \"var(--surface-3)\", border: \"1px solid var(--border)\",\n color: \"var(--text-3)\", fontSize: 10.5,\n }}\n >\n {children}\n </span>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\n\nexport type AvatarProps = {\n name: string;\n size?: number;\n color?: string;\n};\n\nexport function Avatar({ name, size = 22, color }: AvatarProps) {\n const initials = name.split(/\\s+/).map(w => w[0]).slice(0, 2).join(\"\").toUpperCase();\n const hash = name.split(\"\").reduce((a, c) => a + c.charCodeAt(0), 0);\n const colors = [\"#DCE4F6\", \"#E4DCF6\", \"#F6DCE4\", \"#F6E4DC\", \"#DCF6E4\", \"#DCF6F1\", \"#F1F6DC\", \"#F6DCF1\"];\n const bg = color || colors[hash % colors.length];\n return (\n <span\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n width: size, height: size, borderRadius: 999, background: bg, color: \"#1E2A4A\",\n fontSize: size < 20 ? 9.5 : 10.5, fontWeight: 600, flexShrink: 0,\n }}\n >\n {initials}\n </span>\n );\n}\n","// BrandGlyph: Declarion's angular \"D=\" mark, themeable via currentColor.\n//\n// Geometry mirrors `public/declarion-glyph.svg` exactly so the static\n// asset (used as an `<img>` source) and the inline React component\n// render an identical mark. The mark encodes the product thesis: a\n// stylized letter D with an \"=\" sign in the negative space of the\n// counter (\"declaration equals behavior\"). Trademark distinctive,\n// reads as a letter rather than a UI hamburger icon, scales from\n// favicon (16px) through hero (96px+).\n//\n// Color: `currentColor` — inheritable from the host CSS context. The\n// static SVG file pins to accent purple (#5B5BD6) for `<img>` use where\n// currentColor doesn't propagate.\n\nexport interface BrandGlyphProps {\n /** Pixel edge of the rendered SVG. Defaults to 24. */\n size?: number;\n className?: string;\n /** ARIA label; omit for purely decorative usages. */\n title?: string;\n}\n\nexport function BrandGlyph({ size = 24, className, title }: BrandGlyphProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 64 64\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n role={title ? \"img\" : undefined}\n aria-label={title}\n aria-hidden={title ? undefined : true}\n >\n <path\n fillRule=\"evenodd\"\n fill=\"currentColor\"\n d=\"M 6 6 H 42 L 58 22 V 42 L 42 58 H 6 Z M 18 18 V 46 H 38 L 46 38 V 26 L 38 18 Z\"\n />\n <rect x=\"22\" y=\"28\" width=\"20\" height=\"3\" fill=\"currentColor\" />\n <rect x=\"22\" y=\"33\" width=\"20\" height=\"3\" fill=\"currentColor\" />\n </svg>\n );\n}\n","import { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { CSSProperties, ReactNode } from \"react\";\n\nexport type DropdownProps = {\n open: boolean;\n onClose?: () => void;\n anchor: HTMLElement | null;\n align?: \"start\" | \"end\";\n width?: number;\n style?: CSSProperties;\n children?: ReactNode;\n};\n\nexport function Dropdown({ open, onClose, anchor, children, align = \"start\", width, style }: DropdownProps) {\n const ref = useRef<HTMLDivElement | null>(null);\n const [pos, setPos] = useState<{ top: number; left: number; placement: \"below\" | \"above\" } | null>(null);\n // Layout effect runs only when the open/anchor/align/width change — NOT on\n // children reference changes. A new children reference on every render would\n // loop setPos → re-render → new children → effect → setPos (React error\n // #185: too many re-renders). Measure menu height twice: first render uses\n // an estimate (260px), subsequent runs read the mounted node's offsetHeight.\n useLayoutEffect(() => {\n if (!open || !anchor) return;\n const r = anchor.getBoundingClientRect();\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 0;\n const menuH = ref.current?.offsetHeight || 260;\n const spaceBelow = vh - r.bottom;\n const placement: \"below\" | \"above\" = spaceBelow < menuH + 12 && r.top > menuH + 12 ? \"above\" : \"below\";\n const top = placement === \"below\" ? r.bottom + 4 : r.top - 4 - menuH;\n const left = align === \"end\" ? r.right - (width || 200) : r.left;\n setPos((prev) => {\n if (\n prev &&\n prev.top === top &&\n prev.left === left &&\n prev.placement === placement\n ) {\n return prev;\n }\n return { top, left, placement };\n });\n }, [open, anchor, align, width]);\n useEffect(() => {\n if (!open) return;\n const h = (e: MouseEvent) => {\n const target = e.target as Node | null;\n if (ref.current && target && !ref.current.contains(target) && anchor && !anchor.contains(target)) {\n onClose && onClose();\n }\n };\n document.addEventListener(\"mousedown\", h);\n return () => document.removeEventListener(\"mousedown\", h);\n }, [open, anchor, onClose]);\n if (!open || !pos) return null;\n return createPortal(\n <div\n ref={ref}\n style={{\n position: \"fixed\", top: pos.top, left: pos.left, zIndex: 200, minWidth: width || 200,\n background: \"var(--surface)\", border: \"1px solid var(--border)\", borderRadius: 8,\n boxShadow: \"var(--shadow-lg)\", padding: 4, ...style,\n }}\n >\n {children}\n </div>,\n document.body,\n );\n}\n","// HoverCard — lightweight hover-to-reveal popover for richer-than-title\n// previews on truncated cell content (e.g. rendered markdown). Mirrors the\n// Dropdown anchor + position-math approach so we avoid a Radix/floating-ui\n// dependency for the same primitive shape.\n//\n// v1 contract:\n// - Hover only. Keyboard focus does NOT open the card (deferred to a\n// dedicated a11y plan; documented in\n// docs/plans/2026-05-09-list-cell-truncation-and-hover.md Open Questions).\n// - 400ms open delay so brief mouse traversal doesn't flash cards.\n// - 150ms close delay lets the cursor cross the gap into the card body.\n// - The card body itself catches mouseenter, so the user can scroll and\n// read without the card collapsing.\n// - Viewport-edge handling: if anchor + width overflows horizontally, the\n// card mirrors to the right edge; if bottom overflows AND there is room\n// above, it flips above the trigger.\n// - Position re-measures both on viewport changes (scroll, resize) AND on\n// card-body size changes (initial mount, content reflow). A ResizeObserver\n// attached to the card via a callback ref handles the first-paint case\n// where offsetHeight isn't readable until after the portal mounts.\n// - The card mounts hidden (visibility:hidden) so the browser can lay it\n// out and the ResizeObserver can read its real size. Only after that\n// first real measurement does the card flip to visibility:visible. This\n// avoids the \"card paints above, then snaps below\" flicker that the\n// conservative MAX_HEIGHT fallback would otherwise produce when the\n// real card height is much smaller.\n//\n// Caller responsibility: render the trigger via `children`. The component\n// wraps it in an inline span — text-truncating cells stay layout-stable\n// (no extra block).\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { CSSProperties, ReactNode } from \"react\";\n\nconst OPEN_DELAY_MS = 400;\nconst CLOSE_DELAY_MS = 150;\nconst DEFAULT_WIDTH = 320;\nconst MAX_HEIGHT = 240;\nconst VIEWPORT_PADDING = 4;\nconst ANCHOR_GAP = 4;\n\nexport type HoverCardAlign = \"start\" | \"center\" | \"end\";\n\nexport type HoverCardProps = {\n /** The card body shown on hover. Caller controls the rendered content. */\n content: ReactNode;\n /** The trigger node. Wrapped in an inline span. */\n children: ReactNode;\n /** Card width in pixels. Default 320. */\n width?: number;\n /** Horizontal alignment relative to the anchor. Default `center`. */\n align?: HoverCardAlign;\n /** Optional inline style overrides on the card body. */\n style?: CSSProperties;\n};\n\ntype Pos = { top: number; left: number; placement: \"below\" | \"above\" };\n\nexport function HoverCard({\n content,\n children,\n width = DEFAULT_WIDTH,\n align = \"center\",\n style,\n}: HoverCardProps) {\n const triggerRef = useRef<HTMLSpanElement | null>(null);\n const cardElRef = useRef<HTMLDivElement | null>(null);\n const openTimer = useRef<number | null>(null);\n const closeTimer = useRef<number | null>(null);\n const [open, setOpen] = useState(false);\n const [pos, setPos] = useState<Pos | null>(null);\n // measured: true once we have a real cardElRef.current.offsetHeight read,\n // either from the ResizeObserver's first delivery or from a synchronous\n // fallback in environments without ResizeObserver. Drives visibility so\n // the user never sees the card at a placeholder position.\n const [measured, setMeasured] = useState(false);\n\n // measure is identity-stable so it can be referenced by the ResizeObserver\n // callback ref AND scroll/resize listeners without churning observer wiring.\n const measure = useCallback(() => {\n const anchor = triggerRef.current;\n if (!anchor) return;\n const rect = anchor.getBoundingClientRect();\n const vw = typeof window !== \"undefined\" ? window.innerWidth : 0;\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 0;\n\n // Card height: real measurement when mounted, else fall back to MAX_HEIGHT\n // (the worst case for placement). Using MAX_HEIGHT as the fallback means\n // the first-paint placement decision is conservative — we'll choose\n // \"above\" if there's any chance of bottom overflow, then re-measure once\n // the card is in the DOM. Either we stay above (correct), or we flip\n // back to below once we see the real height fits below (correct).\n const cardH = cardElRef.current?.offsetHeight ?? MAX_HEIGHT;\n\n const spaceBelow = vh - rect.bottom;\n const placement: \"below\" | \"above\" =\n spaceBelow < cardH + ANCHOR_GAP * 2 && rect.top > cardH + ANCHOR_GAP * 2 ? \"above\" : \"below\";\n const top =\n placement === \"below\" ? rect.bottom + ANCHOR_GAP : rect.top - ANCHOR_GAP - cardH;\n\n let left: number;\n if (align === \"start\") left = rect.left;\n else if (align === \"end\") left = rect.right - width;\n else left = rect.left + rect.width / 2 - width / 2;\n if (left + width > vw - VIEWPORT_PADDING) left = Math.max(VIEWPORT_PADDING, rect.right - width);\n if (left < VIEWPORT_PADDING) left = VIEWPORT_PADDING;\n\n setPos((prev) => {\n if (prev && prev.top === top && prev.left === left && prev.placement === placement) {\n return prev;\n }\n return { top, left, placement };\n });\n }, [align, width]);\n\n // Card mounts/unmounts via this callback ref. Wiring the ResizeObserver\n // here (not in useLayoutEffect) ensures the observer attaches the moment\n // the portal commits — that first observed entry triggers a re-measure\n // with the real offsetHeight and flips the card to visible.\n const observerRef = useRef<ResizeObserver | null>(null);\n const setCardEl = useCallback(\n (node: HTMLDivElement | null) => {\n cardElRef.current = node;\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n if (!node) return;\n if (typeof ResizeObserver !== \"undefined\") {\n // First observation fires synchronously-from-microtask after observe;\n // re-measure picks up the real height and setMeasured reveals the card.\n const ro = new ResizeObserver(() => {\n measure();\n setMeasured(true);\n });\n ro.observe(node);\n observerRef.current = ro;\n } else {\n // Environments without ResizeObserver (jsdom): nothing to observe,\n // fall through to the conservative fallback placement and reveal.\n setMeasured(true);\n }\n },\n [measure],\n );\n\n const clearTimers = () => {\n if (openTimer.current !== null) {\n window.clearTimeout(openTimer.current);\n openTimer.current = null;\n }\n if (closeTimer.current !== null) {\n window.clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n };\n\n const scheduleOpen = () => {\n if (closeTimer.current !== null) {\n window.clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n if (open || openTimer.current !== null) return;\n openTimer.current = window.setTimeout(() => {\n openTimer.current = null;\n setOpen(true);\n }, OPEN_DELAY_MS);\n };\n\n const scheduleClose = () => {\n if (openTimer.current !== null) {\n window.clearTimeout(openTimer.current);\n openTimer.current = null;\n }\n if (closeTimer.current !== null) return;\n closeTimer.current = window.setTimeout(() => {\n closeTimer.current = null;\n setOpen(false);\n }, CLOSE_DELAY_MS);\n };\n\n // Cleanup timers AND any active observer on unmount.\n useEffect(\n () => () => {\n clearTimers();\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n },\n [],\n );\n\n // Initial position pass when the card opens; reposition on viewport changes.\n // The ResizeObserver covers the \"real card height differs from fallback\"\n // case once the DOM commits.\n useEffect(() => {\n if (!open) {\n // Reset measured so the next open cycle hides the card again until the\n // first real measurement lands. Without this, a stale measured=true\n // would let a re-opened card flash at the previous open's coordinates\n // before the new measure() runs.\n setMeasured(false);\n return;\n }\n measure();\n window.addEventListener(\"scroll\", measure, true);\n window.addEventListener(\"resize\", measure);\n return () => {\n window.removeEventListener(\"scroll\", measure, true);\n window.removeEventListener(\"resize\", measure);\n };\n }, [open, measure]);\n\n const card =\n open && pos\n ? createPortal(\n <div\n ref={setCardEl}\n role=\"tooltip\"\n onMouseEnter={() => {\n if (closeTimer.current !== null) {\n window.clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n }}\n onMouseLeave={scheduleClose}\n style={{\n position: \"fixed\",\n top: pos.top,\n left: pos.left,\n width,\n maxHeight: MAX_HEIGHT,\n overflowY: \"auto\",\n zIndex: 250,\n background: \"var(--surface)\",\n border: \"1px solid var(--border)\",\n borderRadius: 8,\n boxShadow: \"var(--shadow-lg)\",\n padding: 10,\n fontSize: 13,\n color: \"var(--text)\",\n // Hidden until the first real height read lands. Card still\n // occupies layout so the ResizeObserver can deliver a size;\n // pointer-events:none avoids accidental hover capture during\n // the brief invisible frame.\n visibility: measured ? \"visible\" : \"hidden\",\n pointerEvents: measured ? \"auto\" : \"none\",\n ...style,\n }}\n >\n {content}\n </div>,\n document.body,\n )\n : null;\n\n return (\n <>\n <span\n ref={triggerRef}\n onMouseEnter={scheduleOpen}\n onMouseLeave={scheduleClose}\n // Display: inline preserves cell layout (table cells truncate via\n // their td CSS; the trigger wrapper does not introduce a block).\n style={{ display: \"inline\", maxWidth: \"100%\" }}\n >\n {children}\n </span>\n {card}\n </>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport type { ReactNode, MouseEvent } from \"react\";\nimport { Icon } from \"./Icons\";\n\nexport type ChipProps = {\n tone?: string;\n icon?: ReactNode;\n children?: ReactNode;\n onRemove?: () => void;\n onClick?: () => void;\n};\n\nexport function Chip({ icon, children, onRemove, onClick }: ChipProps) {\n return (\n <span onClick={onClick} style={{\n display: \"inline-flex\", alignItems: \"center\", gap: 6, height: 24,\n padding: \"0 8px\", borderRadius: 6, background: \"var(--surface-3)\",\n border: \"1px solid var(--border)\", fontSize: 12, color: \"var(--text-2)\",\n cursor: onClick ? \"pointer\" : \"default\",\n }}>\n {icon}\n {children}\n {onRemove && (\n <button\n type=\"button\"\n onClick={(e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onRemove(); }}\n style={{\n background: \"transparent\", border: 0, padding: 0, marginLeft: 2,\n color: \"var(--text-3)\", cursor: \"pointer\", display: \"flex\",\n }}\n >\n <Icon.x size={12} />\n </button>\n )}\n </span>\n );\n}\n","import { useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { Icon } from \"./Icons\";\nimport { IconBtn } from \"./IconBtn\";\nimport { Pill, type PillTone } from \"./Pill\";\n\nexport type SectionBadge = {\n text: string;\n tone?: PillTone;\n dot?: boolean;\n};\n\n// Visual weight of a section card. \"primary\" is a raised card for the page's\n// main content; \"secondary\" is a quieter recessed card for supporting detail.\n// Resolves the design-brief P2 \"sections are a stack of identical white boxes\".\nexport type SectionEmphasis = \"primary\" | \"secondary\";\n\nexport type SectionCardProps = {\n title: ReactNode;\n subtitle?: ReactNode;\n right?: ReactNode;\n badge?: SectionBadge;\n // Count chip after the title (e.g. number of child rows).\n count?: number;\n children?: ReactNode;\n // Pinned content below the body, above the card's bottom edge.\n footer?: ReactNode;\n collapsible?: boolean;\n defaultOpen?: boolean;\n icon?: ReactNode;\n emphasis?: SectionEmphasis;\n // Heading level (role=\"heading\" aria-level) for the section title: 2 for a\n // top-level section, 3 for a section nested inside another section or tab.\n // Keeps screen-reader heading navigation hierarchical.\n headingLevel?: number;\n padding?: string;\n};\n\nconst PALETTE: Record<SectionEmphasis, { surface: string; shadow: string }> = {\n primary: { surface: \"var(--surface)\", shadow: \"var(--shadow-xs)\" },\n secondary: { surface: \"var(--surface-2)\", shadow: \"none\" },\n};\n\nexport function SectionCard({\n title,\n subtitle,\n right,\n badge,\n count,\n children,\n footer,\n collapsible = true,\n defaultOpen = true,\n icon,\n emphasis = \"primary\",\n headingLevel = 2,\n padding = \"16px\",\n}: SectionCardProps) {\n const [open, setOpen] = useState(defaultOpen);\n // Unknown emphasis values fall back to primary (forward-compatible with\n // schema additions).\n const palette = PALETTE[emphasis] ?? PALETTE.primary;\n\n return (\n <div\n data-emphasis={emphasis}\n style={{\n background: palette.surface,\n border: \"1px solid var(--border)\",\n borderRadius: 10,\n overflow: \"hidden\",\n boxShadow: palette.shadow,\n // In a flex-column scroll container, `overflow: hidden` makes flexbox\n // treat `min-height: auto` as 0, so flex-shrink:1 (default) crushes the\n // card to a sliver. `flex-shrink: 0` keeps the card at content height;\n // the scroll container handles overflow.\n flexShrink: 0,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n padding: \"10px 14px\",\n borderBottom: open ? \"1px solid var(--divider)\" : \"none\",\n minHeight: 40,\n }}\n >\n {/* The section title is a heading (screen-reader landmark) wrapping the\n collapse toggle. The toggle is a role=\"button\" that fills the\n heading, so clicking anywhere on the title area opens/closes the\n section - the standard accordion pattern. Badge / header actions /\n chevron stay outside the heading so they remain independently\n clickable and a role=\"button\" never wraps another button. */}\n <div\n role=\"heading\"\n aria-level={headingLevel}\n style={{ display: \"flex\", flex: 1, minWidth: 0 }}\n >\n <div\n role={collapsible ? \"button\" : undefined}\n tabIndex={collapsible ? 0 : undefined}\n aria-expanded={collapsible ? open : undefined}\n onClick={collapsible ? () => setOpen((prev) => !prev) : undefined}\n onKeyDown={\n collapsible\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setOpen((prev) => !prev);\n }\n }\n : undefined\n }\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n flex: 1,\n minWidth: 0,\n cursor: collapsible ? \"pointer\" : \"default\",\n userSelect: \"none\",\n }}\n >\n {icon && (\n <span style={{ color: \"var(--text-3)\", display: \"flex\", flexShrink: 0 }}>{icon}</span>\n )}\n <div\n style={{\n fontSize: 12.5,\n fontWeight: 600,\n color: \"var(--text)\",\n letterSpacing: \"-0.005em\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n minWidth: 0,\n }}\n >\n {title}\n </div>\n {count !== undefined && (\n <span\n className=\"num\"\n style={{\n fontSize: 11,\n fontWeight: 600,\n color: \"var(--text-3)\",\n background: \"var(--surface-3)\",\n borderRadius: 999,\n padding: \"1px 7px\",\n minWidth: 20,\n textAlign: \"center\",\n flexShrink: 0,\n }}\n >\n {count}\n </span>\n )}\n {subtitle && (\n <div\n style={{\n fontSize: 11.5,\n color: \"var(--text-3)\",\n flexShrink: 0,\n borderLeft: \"1px solid var(--divider)\",\n paddingLeft: 8,\n marginLeft: 2,\n }}\n >\n {subtitle}\n </div>\n )}\n </div>\n </div>\n {badge && (\n <Pill tone={badge.tone ?? \"violet\"} size=\"xs\" dot={badge.dot}>\n {badge.text}\n </Pill>\n )}\n {right}\n {collapsible && (\n <IconBtn\n size={24}\n icon={open ? <Icon.up size={14} /> : <Icon.down size={14} />}\n onClick={() => setOpen((prev) => !prev)}\n title={open ? \"Collapse\" : \"Expand\"}\n />\n )}\n </div>\n {open && <div style={{ padding }}>{children}</div>}\n {footer && open && (\n <div\n style={{\n padding: \"8px 14px\",\n borderTop: \"1px solid var(--divider)\",\n background: \"var(--surface-2)\",\n fontSize: 11.5,\n color: \"var(--text-3)\",\n }}\n >\n {footer}\n </div>\n )}\n </div>\n );\n}\n","import { useState, useCallback } from \"react\";\nimport { Icon } from \"./Icons\";\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nconst COPY_FEEDBACK_MS = 1200;\n\nexport type RecordIdBadgeProps = {\n value: string;\n};\n\n/**\n * Compact record-ID badge. Truncates UUIDs to their first segment for readability\n * and copies the full value on click. Non-UUID ids render in full.\n */\nexport function RecordIdBadge({ value }: RecordIdBadgeProps) {\n const [copied, setCopied] = useState(false);\n const isUuid = UUID_RE.test(value);\n const display = isUuid ? `${value.slice(0, 8)}…` : value;\n\n const onCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n window.setTimeout(() => setCopied(false), COPY_FEEDBACK_MS);\n } catch {\n // Clipboard API unavailable (insecure context, permissions). Caller sees no feedback; acceptable.\n }\n }, [value]);\n\n return (\n <button\n type=\"button\"\n onClick={onCopy}\n title={copied ? \"Copied\" : `Copy ${value}`}\n className=\"mono inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[11px] text-text-4 hover:bg-surface-2 hover:text-text-3 transition-colors shrink-0 border border-transparent hover:border-border\"\n >\n <span>{display}</span>\n {copied ? <Icon.check size={10} /> : <Icon.copy size={10} style={{ opacity: 0.6 }} />}\n </button>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/detail.jsx\nimport type { ReactNode } from \"react\";\n\nexport type RowFieldProps = {\n label: ReactNode;\n children?: ReactNode;\n wide?: boolean;\n editing?: boolean;\n required?: boolean;\n hint?: string;\n};\n\nexport function RowField({ label, children, wide, editing, required }: RowFieldProps) {\n return (\n <div style={{\n display: \"flex\", flexDirection: wide ? \"column\" : \"row\", gap: wide ? 4 : 16,\n padding: \"4px 0\", gridColumn: wide ? \"1 / -1\" : \"auto\",\n alignItems: wide ? \"stretch\" : \"center\",\n }}>\n <div style={{\n width: wide ? \"auto\" : 140, flexShrink: 0, fontSize: 11.5, color: \"var(--text-3)\", fontWeight: 500,\n letterSpacing: \"0.005em\", display: \"flex\", alignItems: \"center\", gap: 4, minHeight: editing ? 30 : 24,\n }}>\n <span>{label}</span>\n {required && <span style={{ color: \"var(--danger)\" }}>*</span>}\n </div>\n <div style={{\n flex: 1, fontSize: 12.5, color: \"var(--text)\", minWidth: 0,\n overflow: \"hidden\", overflowWrap: \"anywhere\",\n }}>\n {children}\n </div>\n </div>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/fields.jsx\n\nexport type BoolToggleProps = {\n value?: boolean;\n onChange?: (v: boolean) => void;\n // Accessibility (Finding 2): this primitive is a <button role=\"checkbox\">,\n // not an <input>, so a <label htmlFor> cannot target it. ariaLabelledby\n // points at the form label's id instead. id keeps the control addressable.\n id?: string;\n ariaLabelledby?: string;\n};\n\nexport function BoolToggle({ value, onChange, id, ariaLabelledby }: BoolToggleProps) {\n return (\n <button\n type=\"button\"\n id={id}\n aria-labelledby={ariaLabelledby}\n role=\"checkbox\"\n aria-checked={!!value}\n onClick={() => onChange && onChange(!value)}\n style={{\n width: 32, height: 18, borderRadius: 999, border: \"none\", padding: 2, position: \"relative\",\n background: value ? \"var(--accent)\" : \"var(--border-strong)\",\n cursor: \"pointer\", transition: \"background .15s\",\n }}\n >\n <span style={{\n display: \"block\", width: 14, height: 14, borderRadius: 999, background: \"var(--accent-foreground)\",\n transform: value ? \"translateX(14px)\" : \"translateX(0)\",\n transition: \"transform .15s\", boxShadow: \"0 1px 2px rgba(0,0,0,.15)\",\n }} />\n </button>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport type { ReactNode } from \"react\";\nimport { Kbd } from \"./Kbd\";\n\nexport type MenuItemProps = {\n icon?: ReactNode;\n children?: ReactNode;\n onClick?: () => void;\n danger?: boolean;\n kbd?: ReactNode;\n active?: boolean;\n divider?: boolean;\n disabled?: boolean;\n title?: string;\n // Pass-through for test selectors. Without this, callers like TopBar's\n // \"Exit impersonation\" item silently drop their data-testid, breaking\n // RTL tests and any future automation that targets specific menu rows.\n \"data-testid\"?: string;\n};\n\nexport function MenuItem({ icon, children, onClick, danger, kbd, active, divider, disabled, title, \"data-testid\": dataTestId }: MenuItemProps) {\n if (divider) return <div style={{ height: 1, background: \"var(--divider)\", margin: \"4px 0\" }} />;\n return (\n <div\n onClick={disabled ? undefined : onClick}\n data-testid={dataTestId}\n aria-disabled={disabled || undefined}\n title={title}\n style={{\n display: \"flex\", alignItems: \"center\", gap: 8, padding: \"6px 10px\", borderRadius: 5,\n fontSize: 12.5, color: danger ? \"var(--danger)\" : \"var(--text-2)\", cursor: disabled ? \"not-allowed\" : \"pointer\",\n background: active ? \"var(--surface-3)\" : \"transparent\",\n opacity: disabled ? 0.45 : 1,\n }}\n onMouseEnter={(e) => { if (!disabled) e.currentTarget.style.background = \"var(--surface-3)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = active ? \"var(--surface-3)\" : \"transparent\"; }}\n >\n {icon && <span style={{ color: danger ? \"var(--danger)\" : \"var(--text-3)\", display: \"flex\" }}>{icon}</span>}\n <span style={{ flex: 1 }}>{children}</span>\n {kbd && <Kbd>{kbd}</Kbd>}\n </div>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport type { MouseEvent } from \"react\";\n\nexport type CheckProps = {\n checked?: boolean;\n onChange?: (v: boolean) => void;\n indeterminate?: boolean;\n size?: number;\n};\n\nexport function Check({ checked, onChange, indeterminate, size = 14 }: CheckProps) {\n return (\n <span\n onClick={(e: MouseEvent<HTMLSpanElement>) => { e.stopPropagation(); onChange && onChange(!checked); }}\n style={{\n display: \"inline-flex\", width: size, height: size, borderRadius: 3,\n border: `1px solid ${checked || indeterminate ? \"var(--accent)\" : \"var(--border-strong)\"}`,\n background: checked || indeterminate ? \"var(--accent)\" : \"var(--surface)\",\n alignItems: \"center\", justifyContent: \"center\", cursor: \"pointer\", flexShrink: 0,\n }}\n >\n {checked && (\n <svg width={size - 4} height={size - 4} viewBox=\"0 0 10 10\" fill=\"none\" stroke=\"var(--accent-foreground)\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m2 5 2 2 4-5\" />\n </svg>\n )}\n {indeterminate && !checked && <span style={{ width: 6, height: 1.5, background: \"var(--accent-foreground)\" }} />}\n </span>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\n\nexport function Spinner({ size = 14 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" style={{ animation: \"spin 0.8s linear infinite\" }}>\n <style>{`@keyframes spin{to{transform:rotate(360deg);}}`}</style>\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"var(--border)\" strokeWidth=\"2.5\" fill=\"none\" />\n <path d=\"M12 3a9 9 0 0 1 9 9\" stroke=\"var(--accent)\" strokeWidth=\"2.5\" fill=\"none\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n","// Plan 2026-05-26 §B13 — stock visual treatment for a field/property\n// the current caller cannot read due to its classification tier.\n// Used by FieldsBlock + PropertiesBlock when entity.field_access[code]\n// reports read=\"denied\" (no plaintext sent over the wire).\n//\n// Renders a lock icon + the tier's localized display name (resolved\n// from schema.classifications), with a tooltip exposing the exact\n// permission grant string an administrator would need to add to the\n// caller's role. The grant string is the operator-facing hand-off\n// surface from B9: the user can copy/paste it into a support ticket.\n\nimport type { ClassificationTierDef } from \"@/types/schema\";\nimport { Icon } from \"./Icons\";\n\ninterface ClassifiedFieldLockedProps {\n // Tier code from FieldAccessInfo.classification. Used as fallback\n // label when the tier catalog isn't present in schema (e.g. test\n // harnesses) or carries no localized name.\n tier: string;\n // Tier catalog entry from schema.classifications[tier]. Optional;\n // when present, supplies localized name + audit_on_read hint that\n // sharpen the visual treatment.\n tierDef?: ClassificationTierDef;\n // Operator-facing permission string the admin needs to add to the\n // caller's role. From FieldAccessInfo.required_permission.\n requiredPermission?: string;\n // Locale for resolving tier.name; defaults to \"en\" when not passed.\n locale?: string;\n // Variant — \"value\" renders as a display-mode value placeholder\n // (used in FieldsBlock); \"input\" renders as a disabled-input\n // placeholder (used in FormField write-disabled). Both share the\n // lock icon + tier label; \"input\" gets a border to fit alongside\n // editable inputs.\n variant?: \"value\" | \"input\";\n}\n\nexport function ClassifiedFieldLocked({\n tier,\n tierDef,\n requiredPermission,\n locale = \"en\",\n variant = \"value\",\n}: ClassifiedFieldLockedProps) {\n const label = tierDef?.name?.[locale] ?? tierDef?.name?.en ?? tier;\n const title = requiredPermission\n ? `Locked: requires permission \"${requiredPermission}\". Ask your administrator to grant it to your role.`\n : `Locked: ${label} classification — requires explicit grant.`;\n const inputStyles =\n variant === \"input\"\n ? \"border border-divider rounded-md px-2 py-1 bg-surface\"\n : \"\";\n return (\n <span\n title={title}\n aria-label={title}\n className={`inline-flex items-center gap-1 text-muted-foreground italic select-none ${inputStyles}`}\n >\n <Icon.lock size={12} />\n <span>{label}</span>\n </span>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/fields.jsx\n// Mock data references (APPDATA.COMPANIES) are replaced by passed-in props so the\n// design's RefField markup stays intact while the data layer is wired separately.\nimport { useMemo, useRef, useState } from \"react\";\nimport type {\n\tButtonHTMLAttributes,\n\tCSSProperties,\n\tInputHTMLAttributes,\n\tReactNode,\n} from \"react\";\nimport { Icon } from \"./Icons\";\nimport { Dropdown } from \"./Dropdown\";\nimport { MenuItem } from \"./MenuItem\";\nimport { Chip } from \"./Chip\";\nimport { Btn } from \"./Btn\";\nimport { IconBtn } from \"./IconBtn\";\nimport { BoolToggle } from \"./BoolToggle\";\n\nexport type FieldLabelProps = {\n\tchildren?: ReactNode;\n\trequired?: boolean;\n\thint?: string;\n};\n\nexport const FieldLabel = ({ children, required, hint }: FieldLabelProps) => (\n\t<div\n\t\tstyle={{\n\t\t\tdisplay: \"flex\",\n\t\t\talignItems: \"center\",\n\t\t\tgap: 4,\n\t\t\tfontSize: 11.5,\n\t\t\tcolor: \"var(--text-3)\",\n\t\t\tfontWeight: 500,\n\t\t\tmarginBottom: 4,\n\t\t\tletterSpacing: \"0.01em\",\n\t\t}}\n\t>\n\t\t<span>{children}</span>\n\t\t{required && (\n\t\t\t<span aria-hidden=\"true\" style={{ color: \"var(--danger)\" }}>\n\t\t\t\t*\n\t\t\t</span>\n\t\t)}\n\t\t{hint && (\n\t\t\t<span\n\t\t\t\ttitle={hint}\n\t\t\t\tstyle={{ cursor: \"help\", color: \"var(--text-4)\", display: \"flex\" }}\n\t\t\t>\n\t\t\t\t<Icon.info size={11} />\n\t\t\t</span>\n\t\t)}\n\t</div>\n);\n\nconst baseInput: CSSProperties = {\n\twidth: \"100%\",\n\theight: 30,\n\tpadding: \"0 10px\",\n\tfontSize: 12.5,\n\tlineHeight: \"28px\",\n\tbackground: \"var(--surface)\",\n\tcolor: \"var(--text)\",\n\tborder: \"1px solid var(--border)\",\n\tborderRadius: 6,\n\toutline: \"none\",\n\ttransition: \"border-color .12s, box-shadow .12s\",\n};\n\nexport type TextInputProps = Omit<\n\tInputHTMLAttributes<HTMLInputElement>,\n\t\"value\" | \"onChange\" | \"prefix\"\n> & {\n\tvalue?: string | null;\n\tonChange?: (v: string) => void;\n\tprefix?: ReactNode;\n\tsuffix?: ReactNode;\n\tstyle?: CSSProperties;\n};\n\nexport function TextInput({\n\tvalue,\n\tonChange,\n\tplaceholder,\n\tprefix,\n\tsuffix,\n\tstyle,\n\t...rest\n}: TextInputProps) {\n\tconst [focused, setFocused] = useState(false);\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\talignItems: \"center\",\n\t\t\t\tgap: 6,\n\t\t\t\t...baseInput,\n\t\t\t\tpadding: prefix || suffix ? \"0 8px\" : \"0 10px\",\n\t\t\t\tborderColor: focused ? \"var(--accent)\" : \"var(--border)\",\n\t\t\t\tboxShadow: focused ? `0 0 0 3px var(--accent-ring)` : \"none\",\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t{prefix && (\n\t\t\t\t<span style={{ color: \"var(--text-3)\", display: \"flex\" }}>\n\t\t\t\t\t{prefix}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t<input\n\t\t\t\tvalue={value ?? \"\"}\n\t\t\t\tonChange={(e) => onChange && onChange(e.target.value)}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tonFocus={() => setFocused(true)}\n\t\t\t\tonBlur={() => setFocused(false)}\n\t\t\t\tstyle={{\n\t\t\t\t\tborder: 0,\n\t\t\t\t\toutline: 0,\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tflex: 1,\n\t\t\t\t\tfontSize: 12.5,\n\t\t\t\t\tcolor: \"var(--text)\",\n\t\t\t\t\tpadding: 0,\n\t\t\t\t\tminWidth: 0,\n\t\t\t\t}}\n\t\t\t\t{...rest}\n\t\t\t/>\n\t\t\t{suffix && (\n\t\t\t\t<span style={{ color: \"var(--text-3)\", display: \"flex\" }}>\n\t\t\t\t\t{suffix}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nexport type TextAreaProps = {\n\tvalue?: string | null;\n\tonChange?: (v: string) => void;\n\tplaceholder?: string;\n\trows?: number;\n\t// When true the textarea fills its flex parent (height:100%, minHeight:0)\n\t// and disables its own browser resize handle. Used inside the activity\n\t// composer so the outer drag handle is the single source of resize truth.\n\tfill?: boolean;\n\t// Accessibility: a stable id pairs the textarea with a <label htmlFor>,\n\t// name carries the field code into form payloads / a11y tooling, and\n\t// ariaRequired marks required fields for screen readers. Reason: the\n\t// create/edit form labels its fields via <label htmlFor> (Finding 2).\n\tid?: string;\n\tname?: string;\n\tariaRequired?: boolean;\n};\n\nexport function TextArea({\n\tvalue,\n\tonChange,\n\tplaceholder,\n\trows = 4,\n\tfill,\n\tid,\n\tname,\n\tariaRequired,\n}: TextAreaProps) {\n\tconst [focused, setFocused] = useState(false);\n\tconst fillStyle = fill\n\t\t? { flex: 1, height: \"100%\", minHeight: 0, resize: \"none\" as const }\n\t\t: { height: \"auto\", resize: \"vertical\" as const };\n\treturn (\n\t\t<textarea\n\t\t\tid={id}\n\t\t\tname={name}\n\t\t\taria-required={ariaRequired || undefined}\n\t\t\tvalue={value ?? \"\"}\n\t\t\tonChange={(e) => onChange && onChange(e.target.value)}\n\t\t\tplaceholder={placeholder}\n\t\t\trows={fill ? undefined : rows}\n\t\t\tonFocus={() => setFocused(true)}\n\t\t\tonBlur={() => setFocused(false)}\n\t\t\tstyle={{\n\t\t\t\t...baseInput,\n\t\t\t\tpadding: \"8px 10px\",\n\t\t\t\tlineHeight: 1.5,\n\t\t\t\t...fillStyle,\n\t\t\t\tborderColor: focused ? \"var(--accent)\" : \"var(--border)\",\n\t\t\t\tboxShadow: focused ? `0 0 0 3px var(--accent-ring)` : \"none\",\n\t\t\t\tfontFamily: \"inherit\",\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nexport type SelectOption = { value: string; label: ReactNode };\nexport type SelectProps = Omit<\n\tButtonHTMLAttributes<HTMLButtonElement>,\n\t\"value\" | \"onChange\"\n> & {\n\tvalue?: string;\n\toptions: SelectOption[];\n\tonChange: (v: string) => void;\n\tplaceholder?: string;\n};\n\nconst SELECT_SEARCH_THRESHOLD = 20;\nconst SELECT_MAX_VISIBLE_OPTIONS = 100;\n\nfunction optionSearchText(option: SelectOption): string {\n\tif (typeof option.label === \"string\" || typeof option.label === \"number\")\n\t\treturn String(option.label);\n\treturn option.value;\n}\n\nexport function Select({\n\tvalue,\n\toptions,\n\tonChange,\n\tplaceholder = \"Select...\",\n\t...rest\n}: SelectProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst [query, setQuery] = useState(\"\");\n\tconst ref = useRef<HTMLButtonElement | null>(null);\n\tconst opt = options.find((o) => o.value === value);\n\tconst searchable = options.length > SELECT_SEARCH_THRESHOLD;\n\tconst filteredOptions = useMemo(() => {\n\t\tconst needle = query.trim().toLowerCase();\n\t\tif (!needle) return options.slice(0, SELECT_MAX_VISIBLE_OPTIONS);\n\t\treturn options\n\t\t\t.filter((option) =>\n\t\t\t\toptionSearchText(option).toLowerCase().includes(needle),\n\t\t\t)\n\t\t\t.slice(0, SELECT_MAX_VISIBLE_OPTIONS);\n\t}, [options, query]);\n\treturn (\n\t\t<>\n\t\t\t{/* type=\"button\" is load-bearing: without it, a <button> inside a <form>\n defaults to type=\"submit\" and every dropdown click submits the form\n (which is how the TimelineComposer quick-add was firing on every\n combobox interaction). Keep this explicit on every primitive button.\n\n Spread `{...rest}` BEFORE onClick/aria-* so a caller cannot override\n our open/close handler. Functional `setOpen(prev => !prev)` instead of\n `setOpen(!open)` avoids stale-closure bugs when the parent re-renders\n between the click handler being created and being invoked (the\n symptom of the v0.1.85 Set Stage dropdown bug). */}\n\t\t\t<button\n\t\t\t\t{...rest}\n\t\t\t\ttype=\"button\"\n\t\t\t\tref={ref}\n\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\taria-expanded={open}\n\t\t\t\tonClick={() => {\n\t\t\t\t\tsetOpen((prev) => {\n\t\t\t\t\t\tconst next = !prev;\n\t\t\t\t\t\tif (next) setQuery(\"\");\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t}}\n\t\t\t\tstyle={{\n\t\t\t\t\t...baseInput,\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tjustifyContent: \"space-between\",\n\t\t\t\t\ttextAlign: \"left\",\n\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t\t...rest.style,\n\t\t\t\t\tcolor: opt ? \"var(--text)\" : \"var(--text-placeholder)\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\tgap: 6,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{opt ? opt.label : placeholder}\n\t\t\t\t</span>\n\t\t\t\t<Icon.down size={12} cls=\"\" style={{ color: \"var(--text-3)\" }} />\n\t\t\t</button>\n\t\t\t<Dropdown\n\t\t\t\topen={open}\n\t\t\t\tanchor={ref.current}\n\t\t\t\tonClose={() => setOpen(false)}\n\t\t\t\twidth={ref.current?.offsetWidth}\n\t\t\t\tstyle={{\n\t\t\t\t\tmaxHeight: \"min(360px, calc(100vh - 24px))\",\n\t\t\t\t\toverflowY: \"auto\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{searchable && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tpadding: 6,\n\t\t\t\t\t\t\tposition: \"sticky\",\n\t\t\t\t\t\t\ttop: -4,\n\t\t\t\t\t\t\tbackground: \"var(--surface)\",\n\t\t\t\t\t\t\tzIndex: 1,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TextInput\n\t\t\t\t\t\t\tvalue={query}\n\t\t\t\t\t\t\tonChange={setQuery}\n\t\t\t\t\t\t\tplaceholder=\"Search…\"\n\t\t\t\t\t\t\tprefix={<Icon.search size={12} />}\n\t\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{filteredOptions.map((o) => (\n\t\t\t\t\t<MenuItem\n\t\t\t\t\t\tkey={o.value}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\tonChange(o.value);\n\t\t\t\t\t\t\tsetOpen(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tactive={o.value === value}\n\t\t\t\t\t>\n\t\t\t\t\t\t{o.label}\n\t\t\t\t\t</MenuItem>\n\t\t\t\t))}\n\t\t\t\t{filteredOptions.length === 0 && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tpadding: \"8px 10px\",\n\t\t\t\t\t\t\tfontSize: 12.5,\n\t\t\t\t\t\t\tcolor: \"var(--text-3)\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tNo matches\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</Dropdown>\n\t\t</>\n\t);\n}\n\nexport type DateInputProps = {\n\tvalue?: string | null;\n\tonChange?: (v: string) => void;\n};\n\nexport function DateInput({ value, onChange }: DateInputProps) {\n\treturn (\n\t\t<TextInput\n\t\t\tvalue={value || \"\"}\n\t\t\tonChange={onChange}\n\t\t\tplaceholder=\"YYYY-MM-DD HH:mm\"\n\t\t\tprefix={<Icon.calendar size={13} />}\n\t\t/>\n\t);\n}\n\nexport type PasswordInputProps = {\n\tvalue?: string | null;\n\tonChange?: (v: string) => void;\n\tplaceholder?: string;\n\tshowStrength?: boolean;\n\t// Accessibility: forwarded to the inner password <input> so the create/edit\n\t// form can pair it with a <label htmlFor> and mark required fields.\n\tid?: string;\n\tname?: string;\n\tariaRequired?: boolean;\n};\n\nfunction scorePassword(pw: string): number {\n\tif (!pw) return 0;\n\tlet s = 0;\n\tif (pw.length >= 8) s++;\n\tif (pw.length >= 12) s++;\n\tif (/[A-Z]/.test(pw) && /[a-z]/.test(pw)) s++;\n\tif (/\\d/.test(pw)) s++;\n\tif (/[^A-Za-z0-9]/.test(pw)) s++;\n\treturn Math.min(4, s);\n}\n\nconst STRENGTH_LABELS = [\"Too short\", \"Weak\", \"Fair\", \"Good\", \"Strong\"];\nconst STRENGTH_COLORS = [\n\t\"var(--danger)\",\n\t\"var(--danger)\",\n\t\"var(--warning, #B45309)\",\n\t\"var(--accent)\",\n\t\"var(--success, #3FBF8F)\",\n];\n\nexport function PasswordInput({\n\tvalue,\n\tonChange,\n\tplaceholder = \"Enter password\",\n\tshowStrength,\n\tid,\n\tname,\n\tariaRequired,\n}: PasswordInputProps) {\n\tconst [show, setShow] = useState(false);\n\tconst pw = value || \"\";\n\tconst score = scorePassword(pw);\n\treturn (\n\t\t<div>\n\t\t\t<TextInput\n\t\t\t\tid={id}\n\t\t\t\tname={name}\n\t\t\t\taria-required={ariaRequired || undefined}\n\t\t\t\ttype={show ? \"text\" : \"password\"}\n\t\t\t\tvalue={pw}\n\t\t\t\tonChange={onChange}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tsuffix={\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\taria-label={show ? \"Hide password\" : \"Show password\"}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tbackground: \"none\",\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t\t\t\tcolor: \"var(--text-3)\",\n\t\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonClick={() => setShow((prev) => !prev)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{show ? <Icon.eyeOff size={14} /> : <Icon.eye size={14} />}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t{showStrength && (\n\t\t\t\t<div\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tmarginTop: 6,\n\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\tgap: 8,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<div style={{ display: \"flex\", gap: 3, flex: 1 }}>\n\t\t\t\t\t\t{[0, 1, 2, 3].map((i) => (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tkey={i}\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\t\t\t\theight: 3,\n\t\t\t\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\t\t\t\tbackground:\n\t\t\t\t\t\t\t\t\t\ti < score ? STRENGTH_COLORS[score] : \"var(--surface-3)\",\n\t\t\t\t\t\t\t\t\ttransition: \"background .15s\",\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tfontSize: 10.5,\n\t\t\t\t\t\t\tcolor: \"var(--text-3)\",\n\t\t\t\t\t\t\tminWidth: 54,\n\t\t\t\t\t\t\ttextAlign: \"right\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{pw ? STRENGTH_LABELS[score] : \"\"}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nexport type TagsInputProps = {\n\tvalue?: string[];\n\tonChange: (v: string[]) => void;\n};\n\nexport function TagsInput({ value = [], onChange }: TagsInputProps) {\n\tconst [txt, setTxt] = useState(\"\");\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\t...baseInput,\n\t\t\t\theight: \"auto\",\n\t\t\t\tminHeight: 30,\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tflexWrap: \"wrap\",\n\t\t\t\tgap: 4,\n\t\t\t\tpadding: \"4px 6px\",\n\t\t\t\talignItems: \"center\",\n\t\t\t}}\n\t\t>\n\t\t\t{value.map((v, i) => (\n\t\t\t\t<Chip\n\t\t\t\t\tkey={i}\n\t\t\t\t\ttone=\"slate\"\n\t\t\t\t\tonRemove={() => onChange(value.filter((_, j) => j !== i))}\n\t\t\t\t>\n\t\t\t\t\t{v}\n\t\t\t\t</Chip>\n\t\t\t))}\n\t\t\t<input\n\t\t\t\tvalue={txt}\n\t\t\t\tonChange={(e) => setTxt(e.target.value)}\n\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\tif (e.key === \"Enter\" && txt.trim()) {\n\t\t\t\t\t\tonChange([...value, txt.trim()]);\n\t\t\t\t\t\tsetTxt(\"\");\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tif (e.key === \"Backspace\" && !txt && value.length)\n\t\t\t\t\t\tonChange(value.slice(0, -1));\n\t\t\t\t}}\n\t\t\t\tplaceholder={value.length ? \"\" : \"Add tag… (Enter)\"}\n\t\t\t\tstyle={{\n\t\t\t\t\tborder: 0,\n\t\t\t\t\toutline: 0,\n\t\t\t\t\tflex: 1,\n\t\t\t\t\tminWidth: 80,\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tfontSize: 12.5,\n\t\t\t\t\tpadding: \"4px 2px\",\n\t\t\t\t}}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nexport type JsonFieldProps = {\n\tvalue?: string;\n\tonChange?: (v: string) => void;\n};\n\nexport function JsonField({ value, onChange }: JsonFieldProps) {\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tborder: \"1px solid var(--border)\",\n\t\t\t\tborderRadius: 6,\n\t\t\t\tbackground: \"var(--surface-2)\",\n\t\t\t\toverflow: \"hidden\",\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tpadding: \"6px 10px\",\n\t\t\t\t\tbackground: \"var(--surface-3)\",\n\t\t\t\t\tborderBottom: \"1px solid var(--border)\",\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tgap: 8,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tclassName=\"mono\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tfontSize: 10.5,\n\t\t\t\t\t\tcolor: \"var(--text-3)\",\n\t\t\t\t\t\ttextTransform: \"uppercase\",\n\t\t\t\t\t\tletterSpacing: \"0.04em\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tJSON\n\t\t\t\t</span>\n\t\t\t\t<span style={{ flex: 1 }} />\n\t\t\t\t<Btn size=\"xs\" kind=\"ghost\">\n\t\t\t\t\tFormat\n\t\t\t\t</Btn>\n\t\t\t\t<Btn size=\"xs\" kind=\"ghost\">\n\t\t\t\t\tValidate\n\t\t\t\t</Btn>\n\t\t\t</div>\n\t\t\t<textarea\n\t\t\t\tclassName=\"mono\"\n\t\t\t\tvalue={value || \"\"}\n\t\t\t\tonChange={(e) => onChange && onChange(e.target.value)}\n\t\t\t\tstyle={{\n\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\tminHeight: 140,\n\t\t\t\t\tpadding: \"10px 12px\",\n\t\t\t\t\tfontSize: 12,\n\t\t\t\t\tlineHeight: 1.6,\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tborder: 0,\n\t\t\t\t\toutline: 0,\n\t\t\t\t\tresize: \"vertical\",\n\t\t\t\t\tcolor: \"var(--text)\",\n\t\t\t\t}}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nexport type RefFieldItem = { id: string; name: string };\nexport type RefFieldProps = {\n\tvalue?: string;\n\tentity?: string;\n\tonChange?: (v: string) => void;\n\titems?: RefFieldItem[];\n\t// Accessibility: this primitive renders a <button>, not an <input>, so it\n\t// cannot be paired with a <label htmlFor>. ariaLabelledby points at the\n\t// label element's id instead; ariaRequired marks required fields. id keeps\n\t// the control individually addressable (Finding 2).\n\tid?: string;\n\tariaLabelledby?: string;\n\tariaRequired?: boolean;\n};\n\nexport function RefField({\n\tvalue,\n\tentity = \"company\",\n\tonChange,\n\titems = [],\n\tid,\n\tariaLabelledby,\n\tariaRequired,\n}: RefFieldProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst ref = useRef<HTMLButtonElement | null>(null);\n\treturn (\n\t\t<>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tid={id}\n\t\t\t\taria-labelledby={ariaLabelledby}\n\t\t\t\taria-required={ariaRequired || undefined}\n\t\t\t\tref={ref}\n\t\t\t\tonClick={() => setOpen(true)}\n\t\t\t\tstyle={{\n\t\t\t\t\t...baseInput,\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tjustifyContent: \"space-between\",\n\t\t\t\t\ttextAlign: \"left\",\n\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\tgap: 8,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: 18,\n\t\t\t\t\t\t\theight: 18,\n\t\t\t\t\t\t\tborderRadius: 4,\n\t\t\t\t\t\t\tbackground: \"var(--accent-soft)\",\n\t\t\t\t\t\t\tcolor: \"var(--accent)\",\n\t\t\t\t\t\t\tdisplay: \"inline-flex\",\n\t\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\t\tjustifyContent: \"center\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon.link size={11} />\n\t\t\t\t\t</span>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tcolor: value ? \"var(--accent)\" : \"var(--text-placeholder)\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{value || `Link to ${entity}…`}\n\t\t\t\t\t</span>\n\t\t\t\t</span>\n\t\t\t\t<Icon.search size={12} cls=\"\" style={{ color: \"var(--text-3)\" }} />\n\t\t\t</button>\n\t\t\t<Dropdown\n\t\t\t\topen={open}\n\t\t\t\tanchor={ref.current}\n\t\t\t\tonClose={() => setOpen(false)}\n\t\t\t\twidth={ref.current?.offsetWidth}\n\t\t\t>\n\t\t\t\t<div style={{ padding: 4 }}>\n\t\t\t\t\t<TextInput\n\t\t\t\t\t\tplaceholder={`Search ${entity}…`}\n\t\t\t\t\t\tprefix={<Icon.search size={12} />}\n\t\t\t\t\t\tstyle={{ marginBottom: 4 }}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t{items.slice(0, 6).map((c) => (\n\t\t\t\t\t<MenuItem\n\t\t\t\t\t\tkey={c.id}\n\t\t\t\t\t\ticon={<Icon.building size={13} />}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\tonChange && onChange(c.name);\n\t\t\t\t\t\t\tsetOpen(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{c.name}\n\t\t\t\t\t</MenuItem>\n\t\t\t\t))}\n\t\t\t</Dropdown>\n\t\t</>\n\t);\n}\n\n// Display-mode field row (label + value)\nexport type ViewFieldProps = {\n\tlabel: ReactNode;\n\tchildren?: ReactNode;\n\tmono?: boolean;\n\twide?: boolean;\n\tempty?: boolean;\n};\n\nexport function ViewField({\n\tlabel,\n\tchildren,\n\tmono,\n\twide,\n\tempty,\n}: ViewFieldProps) {\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tflexDirection: wide ? \"column\" : \"row\",\n\t\t\t\tgap: wide ? 4 : 16,\n\t\t\t\tminHeight: 24,\n\t\t\t\talignItems: \"baseline\",\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\twidth: wide ? \"auto\" : 140,\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tfontSize: 11.5,\n\t\t\t\t\tcolor: \"var(--text-3)\",\n\t\t\t\t\tfontWeight: 500,\n\t\t\t\t\tletterSpacing: \"0.01em\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{label}\n\t\t\t</div>\n\t\t\t<div\n\t\t\t\tclassName={mono ? \"mono num\" : \"num\"}\n\t\t\t\tstyle={{\n\t\t\t\t\tflex: 1,\n\t\t\t\t\tfontSize: 12.5,\n\t\t\t\t\tcolor: empty ? \"var(--text-4)\" : \"var(--text)\",\n\t\t\t\t\tlineHeight: \"22px\",\n\t\t\t\t\tminWidth: 0,\n\t\t\t\t\twordBreak: \"break-word\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{empty ? \"—\" : children}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n// Quick-edit cell — display by default, input on click.\nexport type QuickEditCellProps = {\n\tvalue?: string;\n\tonChange?: (v: string) => void;\n\ttype?: \"text\" | \"select\" | \"bool\";\n\toptions?: SelectOption[];\n\ttone?: string;\n};\n\nexport function QuickEditCell({\n\tvalue,\n\tonChange,\n\ttype = \"text\",\n\toptions,\n}: QuickEditCellProps) {\n\tconst [editing, setEditing] = useState(false);\n\tconst [tmp, setTmp] = useState<string | undefined>(value);\n\tconst save = () => {\n\t\tonChange && tmp !== undefined && onChange(tmp);\n\t\tsetEditing(false);\n\t};\n\tconst cancel = () => {\n\t\tsetTmp(value);\n\t\tsetEditing(false);\n\t};\n\tif (editing) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={{ display: \"flex\", alignItems: \"center\", gap: 4 }}\n\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\tif (e.key === \"Enter\") save();\n\t\t\t\t\tif (e.key === \"Escape\") cancel();\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{type === \"select\" ? (\n\t\t\t\t\t<Select\n\t\t\t\t\t\tvalue={tmp}\n\t\t\t\t\t\toptions={options || []}\n\t\t\t\t\t\tonChange={(v) => {\n\t\t\t\t\t\t\tsetTmp(v);\n\t\t\t\t\t\t\tonChange && onChange(v);\n\t\t\t\t\t\t\tsetEditing(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : type === \"bool\" ? (\n\t\t\t\t\t<BoolToggle\n\t\t\t\t\t\tvalue={tmp === \"true\"}\n\t\t\t\t\t\tonChange={(v) => {\n\t\t\t\t\t\t\tconst next = String(v);\n\t\t\t\t\t\t\tsetTmp(next);\n\t\t\t\t\t\t\tonChange && onChange(next);\n\t\t\t\t\t\t\tsetEditing(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<TextInput value={tmp ?? \"\"} onChange={setTmp} autoFocus />\n\t\t\t\t)}\n\t\t\t\t{type !== \"select\" && type !== \"bool\" && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<IconBtn\n\t\t\t\t\t\t\tsize={24}\n\t\t\t\t\t\t\ticon={<Icon.check size={13} />}\n\t\t\t\t\t\t\tonClick={save}\n\t\t\t\t\t\t\ttitle=\"Save\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<IconBtn\n\t\t\t\t\t\t\tsize={24}\n\t\t\t\t\t\t\ticon={<Icon.x size={13} />}\n\t\t\t\t\t\t\tonClick={cancel}\n\t\t\t\t\t\t\ttitle=\"Cancel\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t}\n\treturn (\n\t\t<div\n\t\t\tonClick={() => setEditing(true)}\n\t\t\tstyle={{\n\t\t\t\tpadding: \"4px 6px\",\n\t\t\t\tmargin: \"-4px -6px\",\n\t\t\t\tborderRadius: 4,\n\t\t\t\tcursor: \"text\",\n\t\t\t\tborder: \"1px dashed transparent\",\n\t\t\t\tminHeight: 24,\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\talignItems: \"center\",\n\t\t\t\tgap: 4,\n\t\t\t}}\n\t\t\tonMouseEnter={(e) => {\n\t\t\t\te.currentTarget.style.borderColor = \"var(--border)\";\n\t\t\t}}\n\t\t\tonMouseLeave={(e) => {\n\t\t\t\te.currentTarget.style.borderColor = \"transparent\";\n\t\t\t}}\n\t\t>\n\t\t\t{value || <span style={{ color: \"var(--text-4)\" }}>Click to edit</span>}\n\t\t</div>\n\t);\n}\n","/**\n * OrderedMap preserves the insertion order of a string-keyed map while\n * keeping O(1) lookup. It mirrors the Go `ordmap.OrderedMap[T]` container\n * on the server side. Use it for schema sub-maps (entity fields, handler\n * params, resolved_params) where YAML/JSON declaration order is part of\n * the UI contract.\n *\n * JS objects already preserve insertion order for string keys (ES2015+),\n * but the Go side emits JSON that is parsed into a plain object by\n * default — this class wraps the hydrated object so call sites get a\n * consistent API (`get`, `has`, iteration as `[name, value]` tuples) and\n * the type system enforces read-only access.\n */\nexport class OrderedMap<T extends { name?: string }> implements Iterable<[string, T]> {\n readonly #items: readonly T[];\n readonly #index: ReadonlyMap<string, number>;\n\n constructor(items: readonly T[]) {\n this.#items = items;\n const idx = new Map<string, number>();\n for (let i = 0; i < items.length; i++) {\n const n = items[i].name;\n if (n !== undefined) idx.set(n, i);\n }\n this.#index = idx;\n }\n\n /** Build from a `{ name: value }` object, populating each value's `name`\n * field from the object key. Insertion order is the JS property order. */\n static fromObject<T extends { name?: string }>(\n raw: Readonly<Record<string, unknown>> | null | undefined,\n ): OrderedMap<T> {\n if (!raw) return new OrderedMap<T>([]);\n const out: T[] = [];\n for (const [name, body] of Object.entries(raw)) {\n out.push({ ...(body as object), name } as T);\n }\n return new OrderedMap<T>(out);\n }\n\n get length(): number {\n return this.#items.length;\n }\n\n has(name: string): boolean {\n return this.#index.has(name);\n }\n\n get(name: string): T | undefined {\n const i = this.#index.get(name);\n return i === undefined ? undefined : this.#items[i];\n }\n\n /** Read-only items in declaration order. */\n items(): readonly T[] {\n return this.#items;\n }\n\n /** Names in declaration order. */\n names(): readonly string[] {\n return this.#items.map((it) => it.name ?? \"\");\n }\n\n *[Symbol.iterator](): IterableIterator<[string, T]> {\n for (const it of this.#items) {\n yield [it.name ?? \"\", it];\n }\n }\n}\n","import { OrderedMap } from \"./ordmap\";\nimport type { FileFieldDef } from \"./files\";\nexport { OrderedMap };\n\nexport type LocalizedString = Record<string, string>;\n\n/**\n * Per-entity empty-state copy declared in the manifest under\n * `display.empty_state`. Title and Body are localized; LearnMoreURL is a\n * plain string. The SDK falls back to a generic \"No <plural> yet\" derived\n * from `display.name_plural` when this is absent. Read-only entities never\n * render the legacy \"Create your first...\" copy regardless of EmptyStateDef.\n */\nexport interface EmptyStateDef {\n title?: LocalizedString;\n body?: LocalizedString;\n learn_more_url?: string;\n}\n\n/**\n * Reserved sentinel value for Screen.detail_screen (list screens). Disables\n * row-click navigation even when the entity declares a canonical detail. Paired\n * with Go's engine.DetailScreenNone - keep the literal \"none\" in sync.\n */\nexport const DETAIL_SCREEN_NONE = \"none\";\n\nexport function loc(ls: LocalizedString | undefined, lang = \"en\"): string {\n if (!ls) return \"\";\n return ls[lang] ?? Object.values(ls)[0] ?? \"\";\n}\n\n// DISPLAY_KEY is the synthetic row property where the server places a\n// rendered display.template. Read by getDisplayValue() below; the value is\n// always a string when present. Uses the `$`-prefix convention shared with\n// other engine-injected synthetic keys (`$row_version`, `$units`, `$refs`)\n// so it does not collide with consumer-defined field names. Mirrors\n// `engine.DisplayKey` in golang/internal/engine/display_templates.go — keep\n// the constants in sync.\nexport const DISPLAY_KEY = \"$display\";\n\n// getDisplayValue returns the string label for a row, preferring a rendered\n// template (`row.$display`, server-resolved when entity has display.template)\n// over the raw display_field column. Returns undefined when neither is\n// available so callers can decide on their own fallback (typically the row's\n// primary key).\n//\n// Ref-derived labels are NOT resolved here. By platform design, display is\n// declarative: an entity that needs to label itself by a referenced record\n// declares `display.template` (e.g. `${row.user_id}`), and the server's\n// display-template ref-recursion (docs/plans/completed/2026-04-27-display-\n// template-ref-recursion.md) renders the final string into `$display`. The\n// client just reads `$display`. `display.field` is for a scalar column on\n// the entity itself; pointing it at a ref is a schema misconfiguration, not\n// something the client papers over.\n//\n// Localized JSONB fields (e.g. `name: {en: \"...\", ru: \"...\"}`) are unwrapped\n// via loc() so callers do not need to handle the multilingual case\n// themselves. Without this unwrap, `String({...})` produces \"[object Object]\"\n// — a regression caught in review by codex.\nexport function getDisplayValue(\n row: Record<string, unknown> | null | undefined,\n entity: { display?: { display_field?: string } } | null | undefined,\n): string | undefined {\n if (!row) return undefined;\n const rendered = row[DISPLAY_KEY];\n if (typeof rendered === \"string\" && rendered !== \"\") return rendered;\n const field = entity?.display?.display_field;\n if (!field) return undefined;\n const v = row[field];\n if (v == null) return undefined;\n if (typeof v === \"object\" && !Array.isArray(v)) {\n const text = loc(v as LocalizedString);\n return text || undefined;\n }\n return String(v);\n}\n\n// resolveRefRecordLabel returns a human label for a server-embedded\n// referenced record (one entry of a `$refs` payload): its rendered\n// `$display` when present, else the value at `displayField` (localized-JSONB\n// unwrapped via loc()), else the `fallback` (typically the foreign-key value\n// itself).\n//\n// Single resolver for ref-record labels. The ref-field editor (RefField) and\n// the ref-link table cell (refLink) both route through it. Each previously\n// carried its own copy and they had drifted: RefField unwrapped a localized\n// object via Object.values()[0] (locale-blind, always the first key),\n// refLink preferred the \"en\" key. loc() is the correct locale-aware unwrap;\n// consolidating fixes both.\nexport function resolveRefRecordLabel(\n record: Record<string, unknown>,\n displayField: string | undefined,\n fallback: string,\n): string {\n const rendered = record[DISPLAY_KEY];\n if (typeof rendered === \"string\" && rendered !== \"\") return rendered;\n if (displayField) {\n const v = record[displayField];\n if (v != null) {\n if (typeof v === \"object\" && !Array.isArray(v)) {\n return loc(v as LocalizedString) || fallback;\n }\n return String(v);\n }\n }\n return fallback;\n}\n\n// routeToRegex turns a screen route pattern into an anchored matcher.\n// Literal segments are regex-escaped; `:param` segments match any single\n// non-slash path segment. A trailing slash on the route is ignored.\nfunction routeToRegex(route: string): RegExp {\n const segs = route\n .replace(/\\/+$/, \"\")\n .split(\"/\")\n .map((s) => (s.startsWith(\":\") ? \"[^/]+\" : s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")));\n return new RegExp(\"^\" + segs.join(\"/\") + \"$\");\n}\n\n// shortId trims a record id for use inside a tab title. UUIDs are unreadable\n// at full length in a 12-char tab; the first segment of a UUID (or the first\n// 8 chars of any other id) is enough to disambiguate two open detail tabs.\n// Reason: a detail tab labelled only \"User\" is ambiguous when several users\n// are open; the short id keeps each tab distinct without showing a full UUID.\nfunction shortId(segment: string): string {\n const decoded = (() => {\n try {\n return decodeURIComponent(segment);\n } catch {\n return segment;\n }\n })();\n const head = decoded.split(\"-\")[0];\n return head.length > 8 ? head.slice(0, 8) : head;\n}\n\n// screenTitleForPath resolves a human title (+ icon) for a router pathname by\n// matching it against the registered screen routes. An exact (wildcard-free)\n// route match wins over a `:param` match so `/admin/users` resolves to the\n// list screen even though the detail route `/admin/users/:id` also has the\n// same prefix. Returns undefined when no screen owns the path.\n//\n// Title resolution order for a matched screen:\n// 1. screen.display.name (the explicit screen title).\n// 2. For a detail (`:param`) route with no screen name: the bound entity's\n// display name plus a short record id (e.g. \"User a1b2c3d4\"). The engine\n// may register a detail screen without a display.name; without this\n// branch such a tab would fall back to the raw pathname (a bare UUID).\n// Reason: Finding 4 - a tab must never show a raw entity UUID.\n// Returns undefined only when no screen route matches the path at all.\n//\n// Reason: useTabNavigate opens a tab when navigating. Callers that don't\n// pass an explicit title (e.g. an href-mode action dispatched from the\n// toolbar) would otherwise get the raw URL as the tab label. Detail tabs get\n// this resolved title initially, then SmartDetailPage refines it to the\n// record label once the row loads.\nexport function screenTitleForPath(\n pathname: string,\n screens: Record<string, Screen> | undefined,\n entities?: Record<string, Entity>,\n): { title: string; icon?: string } | undefined {\n if (!screens) return undefined;\n const norm = pathname.replace(/\\/+$/, \"\") || \"/\";\n let wildcardMatch: { title: string; icon?: string } | undefined;\n for (const screen of Object.values(screens)) {\n if (!screen.route) continue;\n if (!routeToRegex(screen.route).test(norm)) continue;\n const isWildcard = screen.route.includes(\"/:\");\n const screenName = loc(screen.display?.name);\n // Resolve a title even when the screen itself is nameless: a detail\n // screen falls back to \"<EntityName> <shortId>\" so the tab is readable.\n let title = screenName;\n if (!title && isWildcard && entities && screen.entity) {\n const entityName = loc(entities[screen.entity]?.display?.name);\n if (entityName) {\n const lastSegment = norm.slice(norm.lastIndexOf(\"/\") + 1);\n title = lastSegment ? `${entityName} ${shortId(lastSegment)}` : entityName;\n }\n }\n if (!title) continue;\n const hit = { title, icon: screen.display?.icon };\n if (!isWildcard) return hit; // exact match wins\n wildcardMatch ??= hit;\n }\n return wildcardMatch;\n}\n\n// fieldDisplayName resolves a field's display label.\n// For ref fields without an explicit display.name, falls back to the\n// referenced entity's singular name (e.g. organization_id → \"Organization\").\nexport function fieldDisplayName(\n field: EntityField,\n fieldName: string,\n entities?: Record<string, Entity>,\n): string {\n const explicit = loc(field.display?.name);\n if (explicit) return explicit;\n if (field.type === \"ref\" && field.ref?.entity && entities) {\n const refEntity = entities[field.ref.entity];\n if (refEntity) {\n const entityName = loc(refEntity.display?.name);\n if (entityName) return entityName;\n }\n }\n return fieldName;\n}\n\nexport interface RefDisplay {\n field: string;\n}\n\nexport interface RefConfig {\n entity: string;\n field?: string; // lookup column on target entity (default: primary key)\n display?: RefDisplay;\n fields?: string[];\n}\n\nexport interface UnitConfig {\n storage: string;\n display?: string;\n}\n\nexport interface EntityField {\n /**\n * Populated by the schema hydrator from the enclosing map key. Tests and\n * fixtures may omit it; production code always receives it set.\n */\n name?: string;\n type: string;\n required?: boolean;\n primary?: boolean;\n auto?: boolean;\n // Server-owned value the user never types (e.g. last_login_at). Rendered\n // read-only in edit/create forms, same as `auto`.\n readonly?: boolean;\n timezone?: string;\n precision?: number;\n scale?: number;\n unit?: UnitConfig;\n default?: unknown;\n display?: {\n name: LocalizedString;\n description?: LocalizedString;\n width?: number;\n widget?: string;\n is_listable?: boolean;\n is_filterable?: boolean;\n list_preview?: { max_chars: number };\n ref_display_field?: string;\n span?: number | \"full\";\n // 1a.5 cell renderer hints. The engine fills `widget` with a smart default\n // at YAML-load time, so this object always carries a renderer hint by the\n // time it reaches the UI; these three are author-supplied overrides.\n bool_labels?: { true: LocalizedString; false: LocalizedString };\n value_map?: Record<string, { label?: LocalizedString; color?: string }>;\n currency?: string;\n currency_field?: string;\n currency_display?: \"symbol\" | \"narrow_symbol\" | \"code\" | \"name\";\n };\n values?: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n enum?: string;\n files?: FileFieldDef;\n ref?: RefConfig;\n structure?: string;\n array?: boolean;\n // copyable exposes a plain copy-to-clipboard icon next to the value in display mode.\n // Dumb by design: copies the field value as-is, no side effects.\n copyable?: boolean;\n /**\n * Plan 2026-05-26 §4 / B13. Names the data_classifications tier\n * gating reads + writes on this field. Read-side: stripped from the\n * row when the caller lacks `classification:<tier>:read`. Write-side:\n * 422 FIELDS_FORBIDDEN when the caller writes the key without\n * `classification:<tier>:write`. Frontend reads the tier's localized\n * display name from the top-level `classifications:` map and\n * cross-references `schema.entities.<code>.field_access.<field>` for\n * the per-caller decision.\n */\n classification?: string;\n}\n\n/**\n * Per-caller classification decision for one classified field on one\n * entity. Plan 2026-05-26 §8 / B9. Populated by the schema endpoint\n * from the caller's grants + authority tier; the frontend reads this\n * to render the locked-widget badge (\"🔒 Compensation\"), disable write\n * inputs, and surface the operator-facing `required_permission` hint\n * to the user (e.g. \"Ask your admin to grant you\n * classification:compensation:read\").\n */\nexport interface FieldAccessInfo {\n read: \"granted\" | \"denied\";\n write: \"granted\" | \"denied\";\n classification: string;\n /** Only set when read OR write is denied — the exact grant string an\n * administrator needs to add to a role to unlock this field. */\n required_permission?: string;\n}\n\nexport interface StructureDef {\n name: LocalizedString;\n description?: LocalizedString;\n fields: OrderedMap<EntityField>;\n}\n\nexport type ChildDisplayMode = \"table\" | \"timeline\" | \"list\" | \"cards\";\n\nexport interface TimelineConfig {\n type_field?: string;\n time_field?: string;\n summary_field?: string;\n content_field?: string;\n author_field?: string;\n direction_field?: string;\n intent_field?: string;\n scroll?: boolean;\n auto_scroll?: \"none\" | \"bottom\" | \"top\";\n}\n\nexport interface CardsConfig {\n columns_count?: number;\n header_field?: string;\n badge_field?: string;\n}\n\nexport interface ChildQuickAdd {\n fields: string[];\n defaults?: Record<string, unknown>;\n placeholder?: LocalizedString;\n}\n\nexport interface ChildDisplay {\n name: LocalizedString;\n icon?: string;\n mode?: ChildDisplayMode;\n columns?: string[];\n sort?: string;\n limit?: number;\n timeline?: TimelineConfig;\n cards?: CardsConfig;\n editable?: boolean;\n searchable?: boolean;\n filters?: string[];\n position_field?: string;\n /**\n * Row interaction for `mode: table`.\n * - `navigate`: identity cell (first column) is a link to the child's\n * detail; other cells read-only. Default for associated entities\n * (child has its own detail screen).\n * - `inline_edit`: click a cell to edit it; typing auto-saves after a\n * 500ms debounce. One active cell at a time.\n * - `row_edit`: a per-row Edit button puts the whole row into edit mode\n * (all editable cells become inputs); an explicit Confirm/Cancel pair\n * commits or discards. Nothing persists until Confirm - same flow as\n * the \"Add row\" draft.\n * - `readonly`: pure display.\n */\n interaction?: \"navigate\" | \"inline_edit\" | \"row_edit\" | \"readonly\";\n}\n\nexport interface ChildRelation {\n entity: string;\n foreign_key: string | string[];\n display?: ChildDisplay;\n quick_add?: ChildQuickAdd;\n}\n\nexport interface StatusDef {\n code: string;\n name: LocalizedString;\n description?: LocalizedString;\n color?: string;\n is_final?: boolean;\n}\n\nexport interface StatusGroupDef {\n name: LocalizedString;\n description?: LocalizedString;\n is_main?: boolean;\n initial: string;\n statuses: StatusDef[];\n transitions?: Record<string, string[]>;\n // How a detail page renders the group: \"pill\" (default - read-only pill /\n // editable dropdown) or \"stepper\" (an ordered-stage pipeline). Unknown\n // values fall back to \"pill\".\n display_mode?: \"pill\" | \"stepper\";\n}\n\nexport interface PropertyDef {\n name: LocalizedString;\n description?: LocalizedString;\n type: string;\n display?: EntityField[\"display\"];\n values?: EntityField[\"values\"];\n enum?: string;\n ref?: RefConfig;\n structure?: string;\n readonly?: boolean;\n}\n\n// propertyToField converts a PropertyDef to an EntityField for use with renderField().\n// Merges prop.name as fallback display name; prop.display.name wins if set.\nexport function propertyToField(prop: PropertyDef): EntityField {\n const baseName = prop.name;\n const display = prop.display\n ? { ...prop.display, name: prop.display.name ?? baseName }\n : { name: baseName };\n return {\n type: prop.type,\n display,\n values: prop.values,\n ref: prop.ref,\n structure: prop.structure,\n };\n}\n\nexport interface EnumDef {\n name: LocalizedString;\n description?: LocalizedString;\n values: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n}\n\nexport interface ParameterDef {\n name: LocalizedString;\n description?: LocalizedString;\n type: string;\n default?: unknown;\n is_public?: boolean;\n category?: string;\n /** Override scopes accepted on writes. Subset of: env, tenant, role, user, object. Empty = all. */\n scopes?: string[];\n}\n\nexport interface AssociationDisplay {\n name?: LocalizedString;\n icon?: string;\n}\n\nexport interface AssociationDef {\n target: string;\n display?: AssociationDisplay;\n source: string;\n code: string;\n}\n\nexport type EntityMutationOp = \"create\" | \"update\" | \"delete\" | \"restore\";\n\nexport interface EntityMutations {\n create?: boolean;\n update?: boolean;\n delete?: boolean;\n restore?: boolean;\n}\n\nexport interface Entity {\n table: string;\n primary_key?: string[];\n virtual?: boolean;\n readonly?: boolean;\n mutations?: EntityMutations;\n default_timezone?: string;\n display: {\n name: LocalizedString;\n name_plural: LocalizedString;\n description?: LocalizedString;\n icon: string;\n display_field?: string;\n // display_template, when set on the server, causes the data layer to\n // render a per-row label and ship it under the row's $display key.\n // The SDK doesn't need the template string itself — it only needs to\n // know whether to prefer $display over display_field. We expose the\n // raw template here so consumer apps can introspect / debug schemas.\n display_template?: string;\n empty_state?: EmptyStateDef;\n };\n fields: OrderedMap<EntityField>;\n soft_delete?: string;\n tenant_key?: string;\n children?: ChildRelation[];\n status_groups?: Record<string, StatusGroupDef>;\n properties?: Record<string, PropertyDef>;\n search_fields?: string[];\n actions?: Record<string, Action>;\n handlers?: Record<string, HandlerDef>;\n associations?: Record<string, AssociationDef>;\n files?: OrderedMap<FileFieldDef>;\n detail_screen?: string; // Canonical detail screen for records of this entity. Required when any detail screen targets the entity.\n /** Standard CSV export gate per docs/plans/2026-05-01-standard-table-export.md.\n * Absent block (or absent `enabled`) means export is enabled. Only an\n * explicit `enabled: false` opts out, mirroring the Go ExportEnabled()\n * helper. Same shape ships on Screen for per-screen overrides. */\n export?: ExportConfig;\n /** At most one row visible per caller. Loader requires either a\n * caller-bound `prefilter` or `access: self` to back this. Frontend\n * routes a singleton entity's detail screen at the screen's declared\n * `route:` without a `:id` segment, and skips list-route registration. */\n singleton?: boolean;\n /** Server-enforced WHERE applied unconditionally on every read/write\n * via server/handlers/data_prefilter.go. Values may be literal scalars\n * OR `$caller.*` expressions (`$caller.user_id`, `$caller.tenant_id`)\n * resolved at request time. Security boundary, not a UX hint. */\n prefilter?: Record<string, unknown>;\n /** Hard entity-wide access gate. `\"self\"` restricts every read/write\n * to rows where the field marked `owner: true` matches the caller's\n * user id (chokepoint + with_check). `\"platform_admin\"` restricts to\n * platform owner / superadmin roles. Empty = standard RBAC. */\n access?: \"self\" | \"platform_admin\";\n /** Whether the entity participates in RBAC permission gating\n * (`entity:<code>:<op>` grants). Mirrors engine.Entity.Permissions. */\n permissions?: boolean;\n /**\n * Optional structural tree for placing and grouping actions across all\n * placement slots. Absent = runtime composes a flat list from all actions\n * matching each slot's visibility[], sorted by position ascending.\n * Server delivers RBAC-pruned nodes in tagged-union wire format (plan §8).\n */\n action_layout?: ActionLayoutNode[];\n /**\n * Plan 2026-05-26 §B9 / §B13. Per-caller classification access\n * decision keyed by field name. Only present for entities that\n * declare at least one classified field; absent on non-classification\n * entities so the wire stays byte-equivalent for non-classification\n * deployments. Frontend reads this map to render the locked-widget\n * badge, disable write inputs, and surface the required_permission\n * hint to the user.\n */\n field_access?: Record<string, FieldAccessInfo>;\n /**\n * Per-entity realtime opt-in. When true the entity is in the CDC\n * publication, its list views auto-update from the SSE stream, and the\n * toolbar shows a green \"Live\" indicator. Absent or false (default OFF)\n * means the entity is not live: no indicator, and the always-present\n * manual refresh control is the only freshness mechanism. Server emits\n * this with `omitempty`, so `false` arrives as absent. See\n * docs/plans/completed/2026-05-18-realtime-cdc-redesign.md.\n */\n realtime?: boolean;\n /**\n * Per-entity row-count strategy for list views. \"exact\" (default, also\n * the meaning of absent) shows an exact total; \"estimated\" shows an\n * O(1) query-planner estimate, rendered coarse (~3.6M) for high-volume\n * tables. Independent of `realtime`. The SDK keys list-view count\n * precision on the response `meta.count_mode`, not this field, so a\n * forced exact count still renders precisely. See\n * docs/plans/2026-05-18-declarative-row-count.md.\n */\n count?: \"exact\" | \"estimated\";\n}\n\nexport interface ExportConfig {\n enabled?: boolean;\n}\n\nexport function entityAllowsMutation(\n entity: Pick<Entity, \"readonly\" | \"mutations\"> | undefined,\n op: EntityMutationOp,\n): boolean {\n if (!entity || entity.readonly) return false;\n return entity.mutations?.[op] ?? true;\n}\n\n// getPrimaryKeyFields returns the ordered list of primary key field names.\n// Checks entity.primary_key first (composite PK), falls back to scanning\n// fields for field.primary (single PK), defaults to [\"id\"].\nexport function getPrimaryKeyFields(entity: Entity): string[] {\n if (entity.primary_key && entity.primary_key.length > 0) {\n return entity.primary_key;\n }\n for (const [name, f] of entity.fields) {\n if (f.primary) return [name];\n }\n return [\"id\"];\n}\n\n// PkValues is a map of PK field names to their string values.\nexport type PkValues = Record<string, string>;\n\n// extractPkValues extracts PK field values from a record.\nexport function extractPkValues(entity: Entity, record: Record<string, unknown>): PkValues {\n const fields = getPrimaryKeyFields(entity);\n const values: PkValues = {};\n for (const f of fields) {\n values[f] = String(record[f] ?? \"\");\n }\n return values;\n}\n\nexport function pkValuePartsToId(values: string[]): string {\n if (values.length === 1) return values[0];\n return JSON.stringify(values);\n}\n\n// pkValuesToId converts PK values to a single string identifier for use as\n// cache keys, React keys, etc. For single PK returns the value directly.\n// For composite PK serializes an ordered JSON array so delimiter characters in\n// PK values cannot collide with the route/cache representation.\nexport function pkValuesToId(pkValues: PkValues): string {\n return pkValuePartsToId(Object.values(pkValues));\n}\n\n// pkValuesToDetailId serializes PK values in entity-declared PK order for\n// detail routes. This avoids relying on object insertion order for composite\n// keys supplied by consumer code.\nexport function pkValuesToDetailId(entity: Entity, pkValues: PkValues): string {\n const fields = getPrimaryKeyFields(entity);\n return pkValuePartsToId(fields.map((field) => pkValues[field] ?? \"\"));\n}\n\nexport function pkValuesFromId(id: string, expectedCount: number): string[] | null {\n if (expectedCount <= 1) return [id];\n try {\n const parsed = JSON.parse(id) as unknown;\n if (\n Array.isArray(parsed) &&\n parsed.length === expectedCount &&\n parsed.every((value) => typeof value === \"string\")\n ) {\n return parsed;\n }\n } catch {\n return null;\n }\n return null;\n}\n\n// resolveDetailRoute returns the route template of the detail screen that\n// records of `entity` should navigate to. Resolution order:\n// 1. `list.detail_screen` (per-list-screen override). `DETAIL_SCREEN_NONE`\n// explicitly disables navigation.\n// 2. `entity.detail_screen` (canonical pointer declared on the entity).\n// `list` is omitted by callers that have no list-screen context (e.g.\n// associated/children tables on a detail screen) — those callers use the\n// canonical pointer directly.\nexport function resolveDetailRoute(\n list: Pick<Screen, \"detail_screen\"> | undefined,\n entity: Pick<Entity, \"detail_screen\"> | undefined,\n allScreens: Record<string, { route?: string }> | undefined,\n): string | null {\n if (list?.detail_screen === DETAIL_SCREEN_NONE) return null;\n const code = list?.detail_screen ?? entity?.detail_screen;\n if (!code) return null;\n return allScreens?.[code]?.route ?? null;\n}\n\nexport function buildDetailHrefFromId(\n list: Pick<Screen, \"detail_screen\">,\n id: string,\n entity: Pick<Entity, \"detail_screen\"> | undefined,\n allScreens: Record<string, { route?: string }> | undefined,\n): string | null {\n if (!id) return null;\n const route = resolveDetailRoute(list, entity, allScreens);\n if (!route) return null;\n return route.replace(\":id\", encodeURIComponent(id));\n}\n\nexport function buildEntityDetailHref(\n list: Pick<Screen, \"detail_screen\">,\n entity: Entity | undefined,\n allScreens: Record<string, { route?: string }> | undefined,\n pkValues: PkValues,\n): string | null {\n if (!entity) return null;\n const fields = getPrimaryKeyFields(entity);\n if (fields.some((field) => !pkValues[field])) return null;\n return buildDetailHrefFromId(list, pkValuesToDetailId(entity, pkValues), entity, allScreens);\n}\n\nexport function buildRowDetailHref(\n list: Pick<Screen, \"detail_screen\">,\n entity: Entity | undefined,\n allScreens: Record<string, { route?: string }> | undefined,\n row: Record<string, unknown>,\n): string | null {\n if (!entity) return null;\n return buildEntityDetailHref(list, entity, allScreens, extractPkValues(entity, row));\n}\n\n// isCompositePk returns true if the entity has more than one PK field.\nexport function isCompositePk(entity: Entity): boolean {\n return getPrimaryKeyFields(entity).length > 1;\n}\n\nexport type SizeValue = string; // integer weight (as string), \"<n>px\", \"auto\", \"fill\"\n\nexport interface SectionBadgeConfig {\n text: LocalizedString;\n tone?: \"indigo\" | \"emerald\" | \"amber\" | \"rose\" | \"sky\" | \"violet\" | \"slate\" | \"teal\";\n dot?: boolean;\n}\n\nexport interface SectionNode {\n name: LocalizedString;\n items: LayoutNode[];\n collapsed?: boolean;\n columns?: number; // 1 or 2 (default: 2)\n icon?: string; // icon name from Icon registry\n badge?: SectionBadgeConfig;\n // Visual weight. \"primary\" (default) is a raised card; \"secondary\" is a\n // quieter recessed card for supporting detail. Unknown values fall back to\n // \"primary\".\n emphasis?: \"primary\" | \"secondary\";\n}\n\nexport interface RowConfig {\n items: LayoutNode[];\n gap?: number;\n resizable?: boolean;\n stack_below?: number | \"never\";\n width?: SizeValue;\n height?: SizeValue;\n}\n\nexport interface ColumnConfig {\n items: LayoutNode[];\n gap?: number;\n width?: SizeValue;\n height?: SizeValue;\n}\n\nexport interface TabsConfig {\n items: LayoutNode[];\n}\n\n// LayoutField is one entry in a screen's `fields:` layout block, carrying\n// the field name and any screen-scoped overrides (e.g. inline action buttons).\n// YAML also accepts a bare string, which the server normalizes to { name }.\nexport interface LayoutField {\n name: string;\n actions?: Action[];\n}\n\nexport interface LayoutNode {\n // Container kinds (exactly one, or none if leaf).\n row?: RowConfig;\n column?: ColumnConfig;\n tabs?: TabsConfig;\n\n section?: SectionNode;\n\n // Leaf kinds.\n children?: string;\n associated?: string; // associated entity code (independent entity with FK back)\n properties?: true | string[];\n statuses?: true | string[];\n fields?: LayoutField[];\n\n // Sizing (valid when nested inside row or column).\n width?: SizeValue;\n height?: SizeValue;\n min_width?: string;\n max_width?: string;\n\n // Child-override keys (only valid when children is set).\n label?: LocalizedString;\n icon?: string;\n mode?: ChildDisplayMode;\n columns?: string[];\n sort?: string;\n limit?: number;\n quick_add?: ChildQuickAdd;\n timeline?: TimelineConfig;\n cards?: CardsConfig;\n editable?: boolean;\n searchable?: boolean;\n filters?: string[];\n position_field?: string;\n interaction?: \"navigate\" | \"inline_edit\" | \"row_edit\" | \"readonly\";\n}\n\n// AuditLineDef is one declared provenance line for the detail-page audit\n// strip: a label plus a timestamp field code (`at`) and/or an actor field\n// code (`by`). Both codes render through the normal field-display pipeline.\nexport interface AuditLineDef {\n label: LocalizedString;\n at?: string;\n by?: string;\n}\n\n// AuditConfig configures the detail screen's record-provenance strip (the\n// created / updated footer). Omit the whole block = the automatic strip from\n// the platform convention fields. See docs/dsl.md.\nexport interface AuditConfig {\n // Default (omitted) is on; false hides the strip entirely.\n enabled?: boolean;\n // When non-empty, replaces the automatic created/updated lines.\n lines?: AuditLineDef[];\n}\n\nexport interface Screen {\n type: \"list\" | \"detail\" | \"custom\" | \"record_list\";\n entity?: string;\n route: string;\n component?: string;\n display?: {\n name: LocalizedString;\n icon: string;\n };\n columns?: string[];\n default_columns?: string[]; // Subset visible initially. Omit = all visible.\n filters?: string[];\n default_filters?: string[]; // Subset shown initially in filter panel. Omit = empty.\n search_fields?: string[];\n sort_default?: string;\n actions?: string[];\n row_actions?: string[];\n items?: LayoutNode[];\n sidebar?: LayoutNode[]; // right sidebar layout (always visible, independent of tabs)\n sidebar_width?: string; // sidebar CSS width (default: \"380px\")\n // Detail screens: field names and/or status group codes surfaced as a\n // compact summary strip in the record header. Omit = none.\n highlights?: string[];\n // Detail screens: configures the record-provenance strip at the foot of\n // the page. Omit = the automatic created/updated strip.\n audit?: AuditConfig;\n self?: boolean;\n list_width?: string; // record_list: CSS width of the left list panel (e.g. \"50%\", \"400px\")\n list_resizable?: boolean; // record_list: enable drag-to-resize the list panel\n // list only: tri-valued.\n // absent -> inherit entity.detail_screen\n // \"none\" -> explicit opt-out (row-click disabled)\n // any code -> override with that detail screen\n detail_screen?: string;\n fixed_filters?: Record<string, unknown>; // backend-injected WHERE clauses\n views?: ViewDefinition[]; // System views (presets) from DSL, read-only\n\n /** Action slot promotion for list screens (rule-of-2). UI honors first 2.\n * Note: primary_record_actions (detail header) was removed in Task 5 of plan\n * 2026-04-21-action-toolbar-priority-overflow. Use action_layout instead. */\n primary_actions?: string[];\n primary_bulk_actions?: string[];\n\n /** \"open\" (default) navigates to detail; \"peek\" opens QuickPeek drawer. */\n on_row_click?: \"open\" | \"peek\";\n\n quick_peek?: QuickPeekConfig;\n inline_edit?: InlineEditConfig;\n column_overrides?: Record<string, ColumnSpec>;\n activity_rail?: ActivityRailConfig;\n /** Per-screen override for the CSV export gate. Same shape as Entity.export.\n * Either gate being false hides the toolbar Export menu and makes the\n * POST endpoint return 403 EXPORT_DISABLED. */\n export?: ExportConfig;\n /**\n * Optional per-screen structural tree for placing and grouping actions.\n * When set, fully replaces entity.action_layout for this screen.\n * Absent = inherit entity.action_layout (then default-flat if also absent).\n * Server delivers RBAC-pruned nodes in tagged-union wire format (plan §8).\n */\n action_layout?: ActionLayoutNode[];\n}\n\nexport interface QuickPeekConfig {\n enabled?: boolean;\n width?: number;\n /**\n * Explicit list of field codes to show. Highest precedence. When absent,\n * `sections` is consulted; when that's also absent the platform falls back\n * to all simple scalar fields on the entity (capped at 8).\n */\n fields?: string[];\n /** Section names from the detail-layout. Their `fields:` get flattened. */\n sections?: string[];\n inline_editable?: boolean;\n primary_action?: string;\n}\n\nexport interface InlineEditConfig {\n enabled?: boolean;\n /** dblclick | enter | always */\n trigger?: string;\n}\n\nexport interface ColumnSpec {\n inline_edit?: boolean;\n width?: string;\n}\n\nexport interface ActivityRailConfig {\n children: string;\n /** left | right (default right) */\n position?: string;\n width?: number;\n}\n\n/** System view (preset) defined in screen YAML. Read-only. */\nexport interface ViewDefinition {\n code: string;\n name: LocalizedString;\n icon?: string;\n filters?: Array<{ field: string; op: string; value?: unknown }>;\n columns?: string[];\n sort?: string;\n}\n\nexport interface NavNode {\n screen?: string;\n name?: LocalizedString;\n icon?: string;\n items?: NavNode[];\n area?: string;\n badge?: string;\n children?: NavNode[];\n}\n\nexport interface AreaDef {\n code: string;\n name?: LocalizedString;\n icon?: string;\n position?: number;\n home_screen?: string;\n required_permission?: string;\n}\n\nexport interface AccentDef {\n color?: string;\n color_2?: string;\n soft?: string;\n ring?: string;\n on_dark?: string;\n on_light?: string;\n}\n\nexport interface HandlerParamDisplay {\n name?: LocalizedString;\n description?: LocalizedString;\n widget?: string;\n}\n\nexport interface HandlerParam {\n /** Populated by the schema hydrator from the enclosing map key. */\n name?: string;\n type?: string;\n required?: boolean;\n default?: unknown;\n hidden?: boolean;\n enum?: string;\n values?: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n ref?: string;\n display?: HandlerParamDisplay;\n /**\n * Narrows the param's option set. Values may be literals or templates\n * using the ui_steps interpolation vocabulary (e.g. \"${params.other}\").\n * Semantics are type-specific: for type=\"status\", a \"status_group\" key\n * selects the group whose statuses are offered.\n */\n filter?: Record<string, string>;\n}\n\nexport interface ActionCondition {\n status?: string[];\n field?: string;\n op?: string;\n value?: unknown;\n}\n\nexport interface UISetFieldStep {\n target: string;\n // Value is propagated typed (booleans, numbers, Dates survive). When a string\n // value contains a template token (e.g. \"${now}\", \"${row.touch}\"), the\n // interpolator returns the raw resolved value for single-token templates.\n // Mixed strings (\"Hi ${row.name}\") stringify as usual.\n value: unknown;\n}\n\nexport interface UIShowToastStep {\n kind?: \"success\" | \"error\" | \"info\";\n message: string;\n}\n\n// UIStep is a tagged union - exactly one variant field is set per step.\nexport interface UIStep {\n copy_to_clipboard?: string;\n set_field?: UISetFieldStep;\n focus_field?: string;\n show_toast?: UIShowToastStep;\n}\n\n/**\n * Leaf node in an action_layout tree. References a single action by code.\n * Wire format (plan §8): {\"kind\": \"action\", \"code\": \"<code>\"}\n */\nexport interface ActionLayoutLeaf {\n kind: \"action\";\n code: string;\n}\n\n/**\n * Branch node in an action_layout tree. Groups child nodes under a labelled dropdown.\n * Wire format (plan §8): {\"kind\": \"group\", \"name\": {...}, \"icon\": \"...\", \"items\": [...]}\n * Items is always non-empty (enforced by loader).\n */\nexport interface ActionLayoutGroup {\n kind: \"group\";\n name?: LocalizedString;\n icon?: string;\n items: ActionLayoutNode[];\n}\n\n/**\n * Discriminated union of all action_layout tree nodes.\n * Narrow via `node.kind === \"action\"` (leaf) or `node.kind === \"group\"` (branch).\n */\nexport type ActionLayoutNode = ActionLayoutLeaf | ActionLayoutGroup;\n\n/**\n * Single row-state condition for visible_if / enabled_if / conditions.\n * Operators: eq | ne | in | not_in | gt | lt | ge | le.\n */\nexport interface ActionConditionEntry {\n field?: string;\n op?: string;\n value?: unknown;\n status?: string[];\n}\n\n/**\n * Array of row-state conditions with AND semantics. YAML accepts both single\n * object and array form (see Go ActionConditionList unmarshal); wire format\n * from server is always array (server normalizes during schema response).\n */\nexport type ActionConditionList = ActionConditionEntry[];\n\nexport interface Action {\n /**\n * Server-side handler code. One of four dispatch fields - see plan §1-§2.\n * Reason: the new wire format encodes dispatch mode by which field is set\n * (handler | association | widget | href), so an explicit `type` enum is\n * redundant and was removed. Exactly one of the four should be set per action.\n */\n handler?: string;\n /**\n * Association code for nav-only actions that navigate to a related list.\n * Reason: same dispatch-by-field-presence rule; see plan §1-§2.\n */\n association?: string;\n /**\n * SDK widget registry name. Phase 2 wires the registry; today the field\n * is plumbed through the schema and consumed by Task 38's toolbar pipeline.\n * Reason: lets actions render bespoke UI (e.g. inline picker) instead of\n * server-handled forms, without inventing a new entity per widget.\n */\n widget?: string;\n /**\n * Client-side navigation URL template (supports `${id}` and other row tokens).\n * Reason: replaces the implicit \"edit\"/\"create\" type enum - any href-driven\n * action (open a custom screen, deep-link a report) uses this field; the\n * server never dispatches it.\n */\n href?: string;\n /**\n * Widget-specific opaque metadata. Schema/Action loader passes through\n * untouched; the widget consumes its own keys.\n * Reason: keeps the Action shape stable as new widgets ship without\n * growing the typed surface for each one.\n */\n config?: Record<string, unknown>;\n entity?: string;\n display: {\n name: LocalizedString;\n icon: string;\n /**\n * Promotes the action to a header button (vs. dropdown item).\n * Reason: explicit per-action UX control replaces the old position<=10\n * heuristic, lets schema authors mark their headline action even when\n * other actions sort earlier.\n */\n primary?: boolean;\n /**\n * Render as icon-only button (no label text).\n * Reason: lets a dense toolbar host high-frequency actions without\n * cluttering the bar with labels; tooltip still shows display.name.\n */\n icon_only?: boolean;\n /**\n * Button size hint. Default \"md\".\n * Reason: secondary toolbars (associated blocks, inline editors) need\n * smaller buttons than primary header bars - the schema author picks.\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Keyboard shortcut hint (e.g. \"Cmd+S\"). Rendered in tooltip/menu.\n * Reason: discoverability for power users; binding is wired in Task 38.\n */\n shortcut?: string;\n /**\n * Localized help text for tooltip/popover.\n * Reason: separate from display.name so the title stays terse while a\n * longer explanation surfaces on hover.\n */\n help?: LocalizedString;\n };\n visibility?: string[];\n confirmation?: LocalizedString;\n conditions?: ActionCondition[];\n /**\n * Ordering within a placement slot and overflow priority. Lower = earlier\n * in bar AND last to overflow. Default 0; ties broken by declaration order.\n * Step-10 convention. See plan §1 and §3.\n */\n position?: number;\n /**\n * Hide the action when condition does not hold against current row.\n * Distinct from RBAC hide and from `enabled_if` disable. AND semantics\n * across array elements. See plan §1, §5.\n */\n visible_if?: ActionConditionList;\n /**\n * Disable the action (greyed out + tooltip) when condition does not hold.\n * For bulk-mode multi-row selection, disabled if ANY selected row fails.\n * See plan §1, §5.\n */\n enabled_if?: ActionConditionList;\n /**\n * Localized tooltip shown when action is disabled by `enabled_if`.\n * Required when `enabled_if` is set (loader validates in Task 3).\n */\n enabled_if_reason?: LocalizedString;\n /** Forces confirm + danger styling. */\n destructive?: boolean;\n /** UI shows a toast instead of a blocking result modal; adds a navigation link if progress_screen is set. */\n long_running?: boolean;\n /** Screen code to navigate to after a long_running action starts (resolved via schema.screens). */\n progress_screen?: string;\n resolved_params?: OrderedMap<HandlerParam>;\n /**\n * Default values of params marked hidden+default by the action. The UI\n * seeds formData with these so filter templates resolve references to\n * prefilled siblings (e.g. \"${params.status_group}\") and so the\n * submission payload includes them. Not rendered in the modal.\n */\n resolved_hidden_defaults?: Record<string, unknown>;\n ui_steps?: UIStep[];\n}\n\nexport interface LanguageDef {\n code: string;\n name: LocalizedString;\n}\n\nexport interface HandlerDef {\n code: string;\n type: string;\n entity?: string;\n display?: {\n name?: LocalizedString;\n icon?: string;\n };\n params?: OrderedMap<HandlerParam>;\n success_event?: string;\n}\n\nexport interface Branding {\n app_name?: string;\n app_logo?: string;\n app_initial?: string;\n accent_color?: string;\n ai_name?: string;\n wordmark?: string;\n version_label?: string;\n status_url?: string;\n auth_tagline?: LocalizedString;\n auth_subtagline?: LocalizedString;\n auth_badges?: LocalizedString[];\n // Optional consumer-app CSS override file, served relative to the UI\n // bundle root (e.g. \"/crm-brand.css\"). The SDK injects a <link> at\n // runtime. The file should override the narrow set of tokens that\n // differ from the base palette — never a full redefinition.\n css_url?: string;\n}\n\nexport interface Schema {\n languages: LanguageDef[];\n structures: Record<string, StructureDef>;\n entities: Record<string, Entity>;\n screens: Record<string, Screen>;\n navigation: NavNode[];\n actions: Record<string, Action>;\n handlers?: Record<string, HandlerDef>;\n enums: Record<string, EnumDef>;\n parameters: Record<string, ParameterDef>;\n messages?: Record<string, LocalizedString>;\n branding?: Branding;\n areas?: AreaDef[];\n accents?: Record<string, AccentDef>;\n /**\n * Plan 2026-05-26 §B9 / §B13. data_classifications catalog keyed by\n * tier code — display name + description + audit_on_read flag + icon\n * + sod_protected flag. Absent when the consumer declares no tiers\n * (preserves byte-equivalent wire shape for non-classification\n * deployments). Frontend resolves the localized tier name from this\n * map when rendering locked-widget badges.\n */\n classifications?: Record<string, ClassificationTierDef>;\n}\n\n/**\n * Plan 2026-05-26 §B9. One entry in the top-level classifications map.\n * Mirrors engine.DataClassification.\n */\nexport interface ClassificationTierDef {\n name: LocalizedString;\n description?: LocalizedString;\n audit_on_read?: boolean;\n icon?: string;\n /**\n * When true, the tier triggers stricter SoD controls: superadmin\n * reveals emit a distinct audit code, tenant param\n * `auth.superadmin_classification_bypass=false` disables the\n * implicit bypass, role self-assignment is refused, transitive role\n * inheritance is hard-errored at load. Plan §11 Decisions Log #20-22.\n */\n sod_protected?: boolean;\n}\n","import { apiFetch } from \"./client\";\nimport type {\n Schema,\n Entity,\n StructureDef,\n HandlerDef,\n Action,\n EntityField,\n HandlerParam,\n} from \"@/types/schema\";\nimport type { FileFieldDef } from \"@/types/files\";\nimport { OrderedMap } from \"@/types/schema\";\n\n// Raw JSON shape: Fields/Params arrive as plain JSON objects (insertion-\n// ordered by the Go marshaller). Hydrated into OrderedMap instances at\n// fetch time so call sites get O(1) lookup and ordered iteration.\n\ntype RawObj = Record<string, any>;\n\nfunction hydrateHandler(raw: RawObj): HandlerDef {\n return {\n ...(raw as HandlerDef),\n params: raw.params ? OrderedMap.fromObject<HandlerParam>(raw.params) : undefined,\n };\n}\n\nfunction hydrateAction(raw: RawObj): Action {\n return {\n ...(raw as Action),\n resolved_params: raw.resolved_params\n ? OrderedMap.fromObject<HandlerParam>(raw.resolved_params)\n : undefined,\n };\n}\n\nfunction hydrateEntity(raw: RawObj): Entity {\n const handlers: Record<string, HandlerDef> = {};\n if (raw.handlers) {\n for (const [k, v] of Object.entries(raw.handlers as RawObj)) handlers[k] = hydrateHandler(v as RawObj);\n }\n const actions: Record<string, Action> = {};\n if (raw.actions) {\n for (const [k, v] of Object.entries(raw.actions as RawObj)) actions[k] = hydrateAction(v as RawObj);\n }\n return {\n ...(raw as Entity),\n fields: OrderedMap.fromObject<EntityField>(raw.fields),\n files: raw.files ? OrderedMap.fromObject<FileFieldDef>(raw.files) : undefined,\n handlers: raw.handlers ? handlers : undefined,\n actions: raw.actions ? actions : undefined,\n };\n}\n\nfunction hydrateSchema(raw: RawObj): Schema {\n const entities: Record<string, Entity> = {};\n if (raw.entities) {\n for (const [k, v] of Object.entries(raw.entities as RawObj)) entities[k] = hydrateEntity(v as RawObj);\n }\n const structures: Record<string, StructureDef> = {};\n if (raw.structures) {\n for (const [k, v] of Object.entries(raw.structures as RawObj)) {\n structures[k] = { ...(v as StructureDef), fields: OrderedMap.fromObject<EntityField>((v as RawObj).fields) };\n }\n }\n const handlers: Record<string, HandlerDef> = {};\n if (raw.handlers) {\n for (const [k, v] of Object.entries(raw.handlers as RawObj)) handlers[k] = hydrateHandler(v as RawObj);\n }\n const actions: Record<string, Action> = {};\n if (raw.actions) {\n for (const [k, v] of Object.entries(raw.actions as RawObj)) actions[k] = hydrateAction(v as RawObj);\n }\n return {\n ...(raw as Schema),\n entities,\n structures,\n handlers,\n actions,\n };\n}\n\nexport async function fetchSchema(): Promise<Schema> {\n const raw = await apiFetch<RawObj>(\"/api/schema\");\n return hydrateSchema(raw);\n}\n","import { callHandler, scheduleProactiveRefresh } from \"./client\";\nimport type {\n CheckSetupResponse,\n LoginResponse,\n AuthUser,\n Tenant,\n SSOProvider,\n} from \"@/types/api\";\n\n// Every auth endpoint now dispatches through POST /api/actions/{code}.\n// The shared callHandler helper in client.ts wraps the envelope and\n// returns the typed handler result directly. Cookies are set by the\n// backend via the HTTPCustomizer interface on *auth.LoginResult, so the\n// client-side wrappers never see tokens - they return user + tenant only.\n\nexport async function checkSetup(): Promise<CheckSetupResponse> {\n return callHandler<CheckSetupResponse>(\"auth.check_setup\");\n}\n\nexport async function login(\n email: string,\n password: string,\n remember: boolean = true,\n): Promise<LoginResponse> {\n const res = await callHandler<LoginResponse>(\"auth.login\", { email, password, remember });\n scheduleProactiveRefresh(res.expires_at);\n return res;\n}\n\nexport async function signup(\n email: string,\n password: string,\n displayName: string,\n): Promise<LoginResponse> {\n const res = await callHandler<LoginResponse>(\"auth.signup\", {\n email,\n password,\n display_name: displayName,\n });\n scheduleProactiveRefresh(res.expires_at);\n return res;\n}\n\n// auth.me returns { ...user, tenant? } per MeResult. The AuthUser type\n// on the frontend already reflects that shape.\nexport async function getMe(): Promise<AuthUser> {\n return callHandler<AuthUser>(\"auth.me\");\n}\n\n// auth.list_tenants returns { tenants: [...] } from ListTenantsResult.\nexport async function listTenants(): Promise<Tenant[]> {\n const result = await callHandler<{ tenants: Tenant[] }>(\"auth.list_tenants\");\n return result.tenants;\n}\n\nexport async function switchTenant(tenantId: string): Promise<LoginResponse> {\n const res = await callHandler<LoginResponse>(\"auth.switch_tenant\", {\n tenant_id: tenantId,\n });\n scheduleProactiveRefresh(res.expires_at);\n return res;\n}\n\nexport async function createTenant(code: string, name: string): Promise<Tenant> {\n return callHandler<Tenant>(\"auth.create_tenant\", { code, name });\n}\n\nexport async function logout(): Promise<void> {\n await callHandler(\"auth.logout\");\n}\n\n// sso_provider.list is a global handler with AllowUnauthenticated - used\n// on the login page before the user has a session.\nexport async function listSSOProviders(tenantCode?: string): Promise<SSOProvider[]> {\n const result = await callHandler<{ providers: SSOProvider[] }>(\n \"sso_provider.list\",\n tenantCode ? { tenant_code: tenantCode } : {},\n );\n return result.providers;\n}\n\nexport function ssoAuthorizeUrl(\n slug: string,\n tenantCode?: string,\n redirect?: string,\n): string {\n const params = new URLSearchParams();\n if (tenantCode) params.set(\"tenant\", tenantCode);\n if (redirect) params.set(\"redirect\", redirect);\n const qs = params.toString();\n return `/api/auth/sso/authorize/${encodeURIComponent(slug)}${qs ? `?${qs}` : \"\"}`;\n}\n\n/**\n * Impersonation client surface. Each call dispatches through\n * POST /api/actions/{code} like every other auth handler. The server\n * sets / clears the impersonation cookies via the LoginResult\n * HTTPCustomizer; the client receives the public response shape\n * (user / tenant / expires_at) and reloads the auth context.\n */\nexport interface ImpersonationStartResponse extends LoginResponse {\n impersonation_session_id: string;\n session_expires_at: string;\n}\n\nexport async function impersonationStart(\n targetUserId: string,\n reason: string,\n durationMinutes?: number,\n): Promise<ImpersonationStartResponse> {\n const params: Record<string, unknown> = {\n target_user_id: targetUserId,\n reason,\n };\n if (durationMinutes != null) params.duration_minutes = durationMinutes;\n return callHandler<ImpersonationStartResponse>(\"impersonation.start\", params);\n}\n\nexport async function impersonationStop(): Promise<LoginResponse> {\n return callHandler<LoginResponse>(\"impersonation.stop\");\n}\n\nexport async function impersonationRevoke(sessionId: string): Promise<void> {\n await callHandler(\"impersonation.revoke\", { session_id: sessionId });\n}\n\nexport async function changePassword(\n currentPassword: string,\n newPassword: string,\n): Promise<void> {\n await callHandler(\"auth.change_password\", {\n current_password: currentPassword,\n new_password: newPassword,\n });\n}\n","import { create } from \"zustand\";\nimport type { AuthUser, Tenant } from \"@/types/api\";\nimport { getMe, listTenants, logout as logoutApi } from \"@/api/auth\";\nimport { cancelProactiveRefresh } from \"@/api/client\";\n\ninterface AuthState {\n user: AuthUser | null;\n isAuthenticated: boolean;\n isLoading: boolean;\n activeTenant: Tenant | null;\n tenants: Tenant[];\n initialize: () => Promise<void>;\n refreshMe: () => Promise<void>;\n setUser: (user: AuthUser, tenant?: Tenant) => void;\n setTenants: (tenants: Tenant[]) => void;\n setActiveTenant: (tenant: Tenant) => void;\n logout: () => Promise<void>;\n}\n\nexport const useAuthStore = create<AuthState>((set) => ({\n user: null,\n isAuthenticated: false,\n isLoading: true,\n activeTenant: null,\n tenants: [],\n\n initialize: async () => {\n // Session lives in httpOnly cookies the JS cannot see. Probe auth.me\n // (dispatched via POST /api/actions/auth.me) with the cookie attached;\n // 401 means unauthenticated.\n try {\n const user = await getMe();\n const tenant = user.tenant ?? null;\n\n let tenants: Tenant[] = [];\n try {\n tenants = await listTenants();\n } catch {\n // Non-critical - user may only have one tenant.\n }\n\n set({\n user,\n isAuthenticated: true,\n isLoading: false,\n activeTenant: tenant,\n tenants,\n });\n } catch {\n set({ user: null, isAuthenticated: false, isLoading: false });\n }\n },\n\n refreshMe: async () => {\n try {\n const user = await getMe();\n set({ user, activeTenant: user.tenant ?? null });\n } catch {\n // Non-critical - caller handles display fallback.\n }\n },\n\n setUser: (user: AuthUser, tenant?: Tenant) => {\n set({\n user,\n isAuthenticated: true,\n isLoading: false,\n activeTenant: tenant ?? null,\n });\n },\n\n setTenants: (tenants: Tenant[]) => {\n set({ tenants });\n },\n\n setActiveTenant: (tenant: Tenant) => {\n set({ activeTenant: tenant });\n },\n\n logout: async () => {\n // Stop the proactive refresh timer before tearing down the session, so\n // no renewal fires against an about-to-be-revoked refresh token.\n cancelProactiveRefresh();\n try {\n await logoutApi();\n } catch {\n // Best-effort - clear local state regardless.\n }\n set({\n user: null,\n isAuthenticated: false,\n activeTenant: null,\n tenants: [],\n });\n },\n}));\n","import { useQuery } from \"@tanstack/react-query\";\nimport { fetchSchema } from \"@/api/schema\";\nimport { useAuthStore } from \"@/stores/auth\";\n\nexport function useSchema() {\n const isAuthenticated = useAuthStore((s) => s.isAuthenticated);\n return useQuery({\n // isAuthenticated in the key gives authenticated and unauthenticated\n // requests separate cache entries. Without this, the unauthenticated\n // schema (no screens/navigation) would be cached and reused after login,\n // producing a 404 flash on every first page load until a hard refresh.\n queryKey: [\"schema\", isAuthenticated],\n queryFn: fetchSchema,\n staleTime: Infinity,\n enabled: isAuthenticated,\n });\n}\n","import { create } from \"zustand\";\n\n// Allowed values are deliberately narrow — stored and server-provided values\n// that fall outside the allowlist are normalized to DEFAULTS. This defends\n// against stale localStorage (e.g. legacy \"forest\" theme from a tenant that\n// no longer ships custom themes) and against malformed server params.\nexport type ThemeId = \"light\" | \"dark\";\nexport type AccentId = \"violet\" | \"blue\" | \"teal\" | \"amber\" | \"rose\";\nexport type Density = \"compact\" | \"comfortable\" | \"cozy\";\nexport type SidebarMode = \"wide\" | \"collapsed\";\nexport type TabsPosition = \"top\" | \"bottom\";\nexport type AiSurface = \"command\" | \"panel\" | \"both\" | \"off\";\nexport type FaviconSource = \"google\" | \"direct\" | \"none\";\nexport type ToastPosition =\n | \"top-left\"\n | \"top-center\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\";\n\nexport interface Appearance {\n theme: ThemeId;\n accent: AccentId;\n density: Density;\n sidebar: SidebarMode;\n tabsPosition: TabsPosition;\n tabsMaxOpen: number;\n /** When false, tabs are not persisted across reloads (mirrors ui_tabs_persist). */\n tabsPersist: boolean;\n radius: number;\n zebra: boolean;\n aiSurface: AiSurface;\n /** Favicon source for unknown hosts in URL cells. See ui_favicon_source. */\n faviconSource: FaviconSource;\n /** Where toasts appear. Read by <Toaster> in app.tsx. See ui_toast_position. */\n toastPosition: ToastPosition;\n}\n\nconst DEFAULTS: Appearance = {\n theme: \"light\",\n accent: \"violet\",\n density: \"compact\",\n sidebar: \"wide\",\n tabsPosition: \"top\",\n tabsMaxOpen: 12,\n tabsPersist: true,\n radius: 7,\n zebra: true,\n aiSurface: \"both\",\n faviconSource: \"google\",\n toastPosition: \"bottom-right\",\n};\n\nconst THEMES: readonly ThemeId[] = [\"light\", \"dark\"];\nconst ACCENTS: readonly AccentId[] = [\"violet\", \"blue\", \"teal\", \"amber\", \"rose\"];\nconst DENSITIES: readonly Density[] = [\"compact\", \"comfortable\", \"cozy\"];\nconst SIDEBARS: readonly SidebarMode[] = [\"wide\", \"collapsed\"];\nconst TAB_POSITIONS: readonly TabsPosition[] = [\"top\", \"bottom\"];\nconst AI_SURFACES: readonly AiSurface[] = [\"command\", \"panel\", \"both\", \"off\"];\nconst FAVICON_SOURCES: readonly FaviconSource[] = [\"google\", \"direct\", \"none\"];\nconst TOAST_POSITIONS: readonly ToastPosition[] = [\n \"top-left\",\n \"top-center\",\n \"top-right\",\n \"bottom-left\",\n \"bottom-center\",\n \"bottom-right\",\n];\n\nfunction oneOf<T extends string>(allowed: readonly T[], v: unknown): T | undefined {\n return typeof v === \"string\" && (allowed as readonly string[]).includes(v) ? (v as T) : undefined;\n}\n\n// Normalize an arbitrary partial object to a valid Appearance by dropping\n// unknown keys and out-of-range enum values. Applied to BOTH localStorage\n// reads and server-supplied params so stale or malformed data never lands\n// on <html>.\nfunction normalize(raw: Partial<Record<keyof Appearance, unknown>>): Partial<Appearance> {\n const out: Partial<Appearance> = {};\n const t = oneOf(THEMES, raw.theme); if (t) out.theme = t;\n const a = oneOf(ACCENTS, raw.accent); if (a) out.accent = a;\n const d = oneOf(DENSITIES, raw.density); if (d) out.density = d;\n const s = oneOf(SIDEBARS, raw.sidebar); if (s) out.sidebar = s;\n const tp = oneOf(TAB_POSITIONS, raw.tabsPosition); if (tp) out.tabsPosition = tp;\n const ai = oneOf(AI_SURFACES, raw.aiSurface); if (ai) out.aiSurface = ai;\n const fs = oneOf(FAVICON_SOURCES, raw.faviconSource); if (fs) out.faviconSource = fs;\n const tpos = oneOf(TOAST_POSITIONS, raw.toastPosition); if (tpos) out.toastPosition = tpos;\n if (typeof raw.tabsMaxOpen === \"number\" && raw.tabsMaxOpen > 0) out.tabsMaxOpen = raw.tabsMaxOpen;\n if (typeof raw.radius === \"number\" && raw.radius >= 0 && raw.radius <= 32) out.radius = raw.radius;\n if (typeof raw.zebra === \"boolean\") out.zebra = raw.zebra;\n if (typeof raw.tabsPersist === \"boolean\") out.tabsPersist = raw.tabsPersist;\n return out;\n}\n\nconst STORAGE_KEY = \"declarion-appearance\";\n\nfunction readStorageRaw(): Partial<Record<keyof Appearance, unknown>> | null {\n if (typeof window === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n return raw ? JSON.parse(raw) : null;\n } catch {\n return null;\n }\n}\n\nfunction writeStorage(a: Appearance) {\n if (typeof window === \"undefined\") return;\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(a));\n } catch {\n // ignore\n }\n}\n\n// applyAppearance is the ONLY writer of theme-related state on <html>. It\n// sets attributes the CSS cascade picks up (see globals.css [data-theme],\n// [data-accent], [data-density], [data-sidebar], [data-tabbar], [data-zebra],\n// [data-ai]) and two inline values for the border-radius slider. All built-in\n// palettes flip via the cascade; there is no JS-driven token rewriting.\nexport function applyAppearance(a: Appearance) {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n root.dataset.theme = a.theme;\n root.dataset.accent = a.accent;\n root.dataset.density = a.density;\n root.dataset.sidebar = a.sidebar;\n root.dataset.tabbar = a.tabsPosition;\n root.dataset.zebra = a.zebra ? \"on\" : \"off\";\n root.dataset.ai = a.aiSurface;\n root.style.setProperty(\"--radius-md\", `${a.radius}px`);\n root.style.setProperty(\"--radius-lg\", `${a.radius + 3}px`);\n}\n\n// Param-code → Appearance-key map. Owned here so Tweaks, the hydrator, and\n// future backend integrations share one source of truth.\nconst PARAM_MAP: Record<string, keyof Appearance> = {\n ui_theme: \"theme\",\n ui_accent: \"accent\",\n ui_density: \"density\",\n ui_sidebar: \"sidebar\",\n ui_tabs_position: \"tabsPosition\",\n ui_tabs_max_open: \"tabsMaxOpen\",\n ui_tabs_persist: \"tabsPersist\",\n ui_radius: \"radius\",\n ui_zebra_rows: \"zebra\",\n ui_ai_surface: \"aiSurface\",\n ui_favicon_source: \"faviconSource\",\n ui_toast_position: \"toastPosition\",\n};\n\ninterface AppearanceState extends Appearance {\n set: <K extends keyof Appearance>(key: K, value: Appearance[K]) => void;\n setMany: (patch: Partial<Appearance>) => void;\n /** Apply tenant defaults from server params. ONLY fills keys the user has\n * not already set locally — any field present in localStorage wins.\n * That preserves the user's Tweaks choices across reloads while still\n * picking up tenant defaults on first visit. */\n hydrateFromParams: (params: Record<string, unknown>) => void;\n}\n\nconst storedRaw = readStorageRaw();\nconst storedKeys = storedRaw ? new Set(Object.keys(storedRaw) as (keyof Appearance)[]) : new Set<keyof Appearance>();\nconst initial: Appearance = { ...DEFAULTS, ...(storedRaw ? normalize(storedRaw) : {}) };\nif (typeof window !== \"undefined\") applyAppearance(initial);\n\nexport const useAppearanceStore = create<AppearanceState>((set, get) => ({\n ...initial,\n set: (key, value) => {\n const patch = normalize({ [key]: value } as Partial<Record<keyof Appearance, unknown>>);\n if (patch[key] === undefined) return; // invalid value dropped silently\n const next = { ...get(), ...patch } as AppearanceState;\n applyAppearance(next);\n writeStorage(next);\n storedKeys.add(key);\n set(patch as Partial<AppearanceState>);\n },\n setMany: (rawPatch) => {\n const patch = normalize(rawPatch as Partial<Record<keyof Appearance, unknown>>);\n if (!Object.keys(patch).length) return;\n const next = { ...get(), ...patch } as AppearanceState;\n applyAppearance(next);\n writeStorage(next);\n for (const k of Object.keys(patch) as (keyof Appearance)[]) storedKeys.add(k);\n set(patch as Partial<AppearanceState>);\n },\n hydrateFromParams: (params) => {\n // Translate server param codes to appearance keys and drop anything the\n // user has already explicitly set locally. Without this guard, a reload\n // would overwrite user Tweaks with tenant defaults from /api/params/public.\n const candidate: Partial<Record<keyof Appearance, unknown>> = {};\n for (const [paramCode, appearanceKey] of Object.entries(PARAM_MAP)) {\n if (storedKeys.has(appearanceKey)) continue;\n if (params[paramCode] !== undefined) candidate[appearanceKey] = params[paramCode];\n }\n const patch = normalize(candidate);\n if (!Object.keys(patch).length) return;\n const next = { ...useAppearanceStore.getState(), ...patch } as AppearanceState;\n applyAppearance(next);\n // Intentionally DO NOT writeStorage here — tenant defaults are not user\n // choices, so they shouldn't populate localStorage. Next reload applies\n // the same path fresh from /api/params/public.\n set(patch as Partial<AppearanceState>);\n },\n}));\n","import type { CSSProperties } from \"react\";\nimport { Icon as DesignIcon, type IconName as DesignIconName } from \"@/components/primitives/Icons\";\n\ninterface DynamicIconProps {\n name: string;\n size?: number | string;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function DynamicIcon({ name, size, className, style }: DynamicIconProps) {\n const Comp = DesignIcon[name as DesignIconName] ?? DesignIcon.folder;\n const n = typeof size === \"number\" ? size : typeof size === \"string\" ? parseFloat(size) : undefined;\n return <Comp size={n} cls={className} style={style} />;\n}\n","import { apiFetch, apiFetchBlob } from \"./client\";\nimport { ApiError } from \"@/types/api\";\nimport type { ListParams, ListResponse, DataResponse } from \"@/types/api\";\nimport type { PkValues } from \"@/types/schema\";\nimport type { ExportRequest } from \"@/components/pages/exportRequest\";\n\nfunction buildListUrl(entity: string, params: ListParams): string {\n const url = new URL(`/api/data/${entity}`, window.location.origin);\n\n if (params.page) url.searchParams.set(\"page\", String(params.page));\n if (params.per_page) url.searchParams.set(\"per_page\", String(params.per_page));\n if (params.sort) url.searchParams.set(\"sort\", params.sort);\n if (params.search) url.searchParams.set(\"search\", params.search);\n\n if (params.filters && params.filters.length > 0) {\n url.searchParams.set(\"filters\", JSON.stringify(params.filters));\n }\n\n if (params.include_deleted) {\n url.searchParams.set(\"include_deleted\", \"true\");\n }\n\n if (params.expand) {\n for (const e of params.expand) {\n url.searchParams.append(\"expand\", e);\n }\n }\n\n if (params.select && params.select.length > 0) {\n url.searchParams.set(\"select\", params.select.join(\",\"));\n }\n\n if (params.screen) url.searchParams.set(\"screen\", params.screen);\n if (params.preview) url.searchParams.set(\"preview\", \"true\");\n\n // Row-count strategy. Omitted (the default) is window-only: rows without\n // a total, so the page never blocks on a slow COUNT(*). \"window\" is\n // emitted explicitly only when a caller passes it; it is equivalent to\n // omission server-side.\n if (params.count) url.searchParams.set(\"count\", params.count);\n\n return url.pathname + url.search;\n}\n\nexport async function listEntities(\n entity: string,\n params: ListParams = {},\n options: { signal?: AbortSignal } = {},\n): Promise<ListResponse> {\n return apiFetch<ListResponse>(buildListUrl(entity, params), { signal: options.signal });\n}\n\n// getEntity fetches a single record by primary key values.\n// Accepts either a PkValues object (composite PK support) or a plain string\n// (single-PK convenience - sent as query param `id=<value>`).\nexport async function getEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<DataResponse> {\n const params = new URLSearchParams();\n if (typeof pkValues === \"string\") {\n params.set(\"id\", pkValues);\n } else {\n for (const [key, value] of Object.entries(pkValues)) {\n params.set(key, value);\n }\n }\n return apiFetch<DataResponse>(`/api/data/${entity}?${params.toString()}`);\n}\n\n// createEntity routes through the platform-default __create action.\n// Plan 2026-06-01-write-api-final §1.2: writes leave the legacy CRUD\n// POST /api/data/{entity} route and dispatch via /api/actions/<entity>.__create\n// with a FLAT envelope ({entity, fields}). The server-side handler\n// (data_write_handlers.go::DataCreateParams) decodes those top-level keys\n// directly into its typed struct via JSON tags; there is NO `params:`\n// wrapper on the wire. The handler result is DataCreateResult{rows};\n// we unwrap rows[0] to preserve the DataResponse shape this function\n// has historically returned to its callers.\nexport async function createEntity(\n entity: string,\n data: Record<string, unknown>,\n): Promise<DataResponse> {\n const response = await executeAction(`${entity}.__create`, {\n entity,\n fields: data,\n });\n const result = response.result as { rows?: Record<string, unknown>[] } | undefined;\n const rows = result?.rows ?? [];\n return { data: rows[0] };\n}\n\n// updateEntity routes through the platform-default __update action.\n// Plan 2026-06-01-write-api-final §1.2: dispatches\n// /api/actions/<entity>.__update with a FLAT envelope\n// ({object_ids, entity, fields}). The server's data.update handler\n// (data_write_handlers.go::DataUpdateParams) decodes those top-level\n// keys directly; there is NO `params:` wrapper and NO `items[]` on the\n// wire — per-row variation composes through system.batch instead\n// (mirrors createMany / upsertMany / EntityClient.updateMany). The\n// handler result is DataUpdateResult{rows, rows_matched}; we unwrap\n// rows[0] to preserve the DataResponse shape this function has\n// historically returned.\n//\n// Accepts either a PkValues object (composite PK) or a plain string id\n// (single-PK convenience - encoded via encodeObjectId, mirroring delete\n// / restore).\nexport async function updateEntity(\n entity: string,\n pkValues: PkValues | string,\n data: Record<string, unknown>,\n): Promise<DataResponse> {\n const id = typeof pkValues === \"string\" ? pkValues : encodeObjectId(pkValues);\n const response = await executeAction(`${entity}.__update`, {\n object_ids: [id],\n entity,\n fields: data,\n });\n const result = response.result as\n | { rows?: Record<string, unknown>[]; rows_matched?: number }\n | undefined;\n const rows = result?.rows ?? [];\n return { data: rows[0] };\n}\n\n// deleteEntity routes through the platform-default __delete action.\n// Plan 2026-06-01-write-api-final §1.2: dispatches\n// /api/actions/<entity>.__delete with a FLAT envelope\n// ({object_ids, entity}). The reserved `object_ids` key populates\n// ctx.ObjectIDs; the dispatcher derives items from those IDs + the\n// entity's PK fields. NO `params:` wrapper, NO legacy `_ids` (rejected\n// 400 by parseActionBody as of Task 5).\n//\n// Accepts either a string id (single-column PK - the common case) or a\n// PkValues object (composite PK joined by U+001F to match the platform\n// object-id encoding the server expects, see store.SplitObjectID).\nexport async function deleteEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<void> {\n const id = typeof pkValues === \"string\" ? pkValues : encodeObjectId(pkValues);\n await executeAction(`${entity}.__delete`, {\n object_ids: [id],\n entity,\n });\n}\n\n// encodeObjectId joins composite-PK values into a single opaque string\n// using the platform Unit-Separator convention. Server-side inverse\n// lives at store.SplitObjectID; the per-field zip uses entity.\n// PrimaryKeyFields() declaration order. Iteration order on the input\n// must match that declaration order - PkValues is a Record so callers\n// must construct it field-by-field; for single-column PKs the\n// \"encoding\" is just the value verbatim.\nexport function encodeObjectId(pkValues: PkValues): string {\n const parts = Object.values(pkValues);\n if (parts.length === 1) return parts[0];\n // U+001F = ASCII Unit Separator; matches the Go-side ObjectID join.\n return parts.join(\"\u001f\");\n}\n\n// restoreEntity routes through the platform-default __restore action.\n// Plan 2026-06-01-write-api-final §1.2: the legacy CRUD route\n// POST /api/data/{entity}/restore is retired (returns 410); restores\n// now dispatch /api/actions/<entity>.__restore with a FLAT envelope\n// ({object_ids, entity}). Composite PKs encode to a single opaque\n// string via encodeObjectId (U+001F join); the server splits via\n// store.SplitObjectID.\nexport async function restoreEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<void> {\n const id = typeof pkValues === \"string\" ? pkValues : encodeObjectId(pkValues);\n await executeAction(`${entity}.__restore`, {\n object_ids: [id],\n entity,\n });\n}\n\n/** Result of POST /api/data/{entity}/export. The server streams a CSV\n * blob; the client gets the bytes plus the server-resolved filename\n * (parsed from Content-Disposition by apiFetchBlob, with RFC 5987\n * filename* preferred). Triggering the actual download (anchor click)\n * is the caller's job — separation lets ExportMenu show the bytes in a\n * toast when the browser blocks the download. */\nexport interface ExportResponse {\n blob: Blob;\n filename: string;\n}\n\n// exportEntities POSTs the export request body and returns the streamed\n// CSV blob plus the filename to use on the resulting download. Server-side\n// errors propagate as ApiError so ExportMenu can show the {code, message}\n// envelope inline (the dropdown stays open per UX contract).\nexport async function exportEntities(\n entity: string,\n body: ExportRequest,\n): Promise<ExportResponse> {\n const result = await apiFetchBlob(`/api/data/${entity}/export`, {\n method: \"POST\",\n body: JSON.stringify(body),\n });\n return { blob: result.blob, filename: result.filename };\n}\n\n/**\n * Action request body is flat: top-level keys are handler params. The only\n * reserved control key is `object_ids` (array of object IDs for\n * single/batch scope). The server resolves entity from the action's\n * registration; the URL code is fully qualified (\"entity.action\" for\n * entity-scoped, \"action\" for global). Legacy `_ids` is rejected 400 by\n * the server (parseActionBody) — there is no compat shim.\n */\nexport type ActionExecuteRequest = Record<string, unknown>;\n\nexport interface ActionExecuteResponse {\n status: string;\n result?: unknown;\n audit_operation_id?: string;\n object_count?: number;\n /** IDs that succeeded (batch_mode: each responses). */\n success?: string[];\n /** Per-item errors (batch_mode: each responses with failures or partial). */\n errors?: ActionItemError[];\n /** Per-item skips (batch_mode: each responses where conditions filtered rows). */\n skipped?: ActionItemSkip[];\n}\n\nexport interface ActionItemError {\n id: string;\n error: string;\n /** Sidecar DeclarionCode when available (e.g. VALIDATION_ERROR), else \"\". */\n code?: string;\n}\n\nexport interface ActionItemSkip {\n id: string;\n reason: string;\n}\n\n/**\n * Thrown by executeAction when the platform returns 4xx with the invoke:each\n * batch shape (all items failed). Carries the per-item details so the UI can\n * render a meaningful toast instead of a generic \"request failed\".\n *\n * Pre-dispatch failures (auth, unknown action, invoke-shape mismatch) keep\n * throwing the standard ApiError; use `instanceof ActionBatchError` to\n * distinguish.\n */\nexport class ActionBatchError extends Error {\n readonly status: number;\n readonly response: ActionExecuteResponse;\n\n constructor(status: number, response: ActionExecuteResponse) {\n const first = response.errors && response.errors[0]?.error;\n super(first || \"Action failed\");\n this.name = \"ActionBatchError\";\n this.status = status;\n this.response = response;\n }\n}\n\nfunction isActionBatchBody(v: unknown): v is ActionExecuteResponse {\n if (!v || typeof v !== \"object\") return false;\n const r = v as Record<string, unknown>;\n return typeof r.status === \"string\" && Array.isArray(r.errors);\n}\n\n/**\n * Build a flat action body from handler params + optional object IDs.\n * Promotes `ids` to the reserved `object_ids` key. Throws if a caller\n * passes a param literally named `object_ids` (collision with the\n * reserved control key) or the now-rejected legacy `_ids` key.\n *\n * Plan 2026-06-01-write-api-final: the wire-level reserved key is\n * `object_ids` (server-side parseActionBody decodes it into\n * ctx.ObjectIDs). The legacy `_ids` envelope was removed in Task 5;\n * passing it triggers a 400 from the server.\n */\nexport function buildActionBody(\n params: Record<string, unknown> | undefined,\n ids?: string[] | undefined,\n): ActionExecuteRequest {\n const body: Record<string, unknown> = { ...(params ?? {}) };\n if (\"object_ids\" in body) {\n throw new Error('handler param \"object_ids\" collides with reserved key');\n }\n if (\"_ids\" in body) {\n throw new Error('handler param \"_ids\" is a removed legacy key; use object_ids');\n }\n if (ids !== undefined) {\n body.object_ids = ids;\n }\n return body;\n}\n\n/**\n * Invoke an action. The URL `code` must be fully qualified for\n * entity-scoped actions (e.g. `lead.archive`). For global actions it's the\n * action code on its own (e.g. `auth.login`).\n */\nexport async function executeAction(\n code: string,\n body: ActionExecuteRequest,\n): Promise<ActionExecuteResponse> {\n try {\n return await apiFetch<ActionExecuteResponse>(`/api/actions/${code}`, {\n method: \"POST\",\n body: JSON.stringify(body),\n });\n } catch (err) {\n // 4xx with invoke:each batch body (all items failed) → surface per-item\n // detail via ActionBatchError so toasts can show the real reason. Other\n // errors (pre-dispatch 4xx with standard envelope, 5xx, network) keep\n // propagating as ApiError unchanged.\n if (err instanceof ApiError && isActionBatchBody(err.raw)) {\n throw new ActionBatchError(err.status, err.raw);\n }\n throw err;\n }\n}\n\nexport interface AssociationResponse {\n target_entity: string;\n ids: string[];\n count: number;\n}\n\nexport async function resolveAssociation(\n code: string,\n ids: string[],\n): Promise<AssociationResponse> {\n const params = new URLSearchParams();\n params.set(\"ids\", ids.join(\",\"));\n return apiFetch<AssociationResponse>(`/api/associations/${code}?${params.toString()}`);\n}\n","// Markdown: the eager, lightweight entry point for markdown rendering. Every\n// feature module imports THIS, never react-markdown directly. The heavy\n// renderer + parser live in MarkdownRenderer.tsx, pulled in on demand via a\n// dynamic import so they form their own chunk outside the eager SDK bundle.\n// capabilityPrefetch warms that chunk during idle time after first paint, so\n// in practice the fallback below is rarely seen.\nimport { lazy, Suspense } from \"react\";\nimport type { MarkdownRendererProps } from \"./MarkdownRenderer\";\n\nconst LazyMarkdownRenderer = lazy(() =>\n import(\"./MarkdownRenderer\").then((m) => ({ default: m.MarkdownRenderer })),\n);\n\nfunction MarkdownFallback() {\n return <div className=\"h-4 w-2/3 rounded bg-muted animate-pulse\" />;\n}\n\nexport function Markdown(props: MarkdownRendererProps) {\n return (\n <Suspense fallback={<MarkdownFallback />}>\n <LazyMarkdownRenderer {...props} />\n </Suspense>\n );\n}\n\nexport type { MarkdownRendererProps } from \"./MarkdownRenderer\";\n","// FieldType is the SDK-side mirror of Go's engine.FieldType enum\n// (see golang/internal/engine/types.go:72-96).\n//\n// This union MUST stay character-identical to the Go enum. The CI sync gate\n// `TestExportFieldTypes` (golang/internal/engine) writes\n// `golang/.testdata/field_types.json`; the vitest suite reads that fixture and\n// asserts that this union's members exactly match.\n//\n// Adding a field type:\n// 1. Add the constant to golang/internal/engine/types.go.\n// 2. Add the literal here.\n// 3. Add the new key to `editRegistry` in components/fields/index.tsx.\n// 4. Add the new entry to `defaultWidgetForField` in\n// golang/internal/engine/registry.go (exhaustiveness lint will fail\n// otherwise).\nexport type FieldType =\n | \"uuid\"\n | \"string\"\n | \"text\"\n | \"rich_text\"\n | \"int\"\n | \"float\"\n | \"bool\"\n | \"date\"\n | \"time\"\n | \"timestamp\"\n | \"email\"\n | \"url\"\n | \"phone\"\n | \"enum\"\n | \"json\"\n | \"ref\"\n | \"tags\"\n | \"multilang\"\n | \"multilang_text\"\n | \"structure\"\n | \"secret\"\n | \"password\"\n | \"decimal\"\n | \"string_array\"\n | \"int_array\"\n | \"uuid_array\"\n | \"bytes\";\n\n// FIELD_TYPES is the runtime list of every FieldType, used by the CI sync\n// gate that compares against golang/.testdata/field_types.json. Order is\n// alphabetical to match the Go-side fixture writer (sort.Strings).\nexport const FIELD_TYPES: readonly FieldType[] = [\n \"bool\",\n \"bytes\",\n \"date\",\n \"decimal\",\n \"email\",\n \"enum\",\n \"float\",\n \"int\",\n \"int_array\",\n \"json\",\n \"multilang\",\n \"multilang_text\",\n \"password\",\n \"phone\",\n \"ref\",\n \"rich_text\",\n \"secret\",\n \"string\",\n \"string_array\",\n \"structure\",\n \"tags\",\n \"text\",\n \"time\",\n \"timestamp\",\n \"url\",\n \"uuid\",\n \"uuid_array\",\n] as const;\n","import { useState, useCallback } from \"react\";\nimport { Icon, IconBtn } from \"@/components/primitives\";\n\ninterface CopyButtonProps {\n value: string;\n title?: string;\n className?: string;\n size?: \"sm\" | \"icon\";\n}\n\nexport function CopyButton({ value, title, size = \"icon\" }: CopyButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(\n async (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n // ignore\n }\n },\n [value],\n );\n\n const iconSize = size === \"sm\" ? 12 : 14;\n const btnSize = size === \"sm\" ? 22 : 28;\n\n return (\n <IconBtn\n size={btnSize}\n icon={\n copied ? (\n <Icon.check size={iconSize} style={{ color: \"var(--success)\" }} />\n ) : (\n <Icon.copy size={iconSize} />\n )\n }\n onClick={handleCopy}\n title={title ?? \"Copy to clipboard\"}\n />\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport { CopyButton } from \"@/components/shared/CopyButton\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function StringField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n if (mode === \"display\") {\n const text = String(value ?? \"\");\n if (field.copyable && text) {\n return (\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: 4 }}>\n <span style={{ fontSize: 12.5 }}>{text}</span>\n <CopyButton value={text} size=\"sm\" />\n </span>\n );\n }\n return <span style={{ fontSize: 12.5 }}>{text || <span style={{ color: \"var(--text-4)\" }}>—</span>}</span>;\n }\n\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n />\n );\n}\n","import { TextArea, TextInput } from \"@/components/primitives\";\nimport { CopyButton } from \"@/components/shared/CopyButton\";\nimport { Markdown } from \"@/components/shared/Markdown\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function TextField({ field, fieldName, value, mode, onChange, fill, compact, fieldId }: FieldRendererProps) {\n const widget = field.display?.widget;\n\n if (mode === \"display\") {\n const text = String(value ?? \"\");\n if (!text) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n\n const rendered = widget === \"markdown\" ? (\n <Markdown content={text} />\n ) : widget === \"code\" ? (\n <pre\n className=\"mono\"\n style={{\n fontSize: 12,\n background: \"var(--surface-2)\",\n color: \"var(--text)\",\n borderRadius: 6,\n border: \"1px solid var(--border)\",\n padding: 14,\n overflowX: \"auto\",\n maxHeight: 600,\n overflowY: \"auto\",\n whiteSpace: \"pre\",\n }}\n >\n {text}\n </pre>\n ) : (\n <p style={{ fontSize: 12.5, whiteSpace: \"pre-wrap\", wordBreak: \"break-word\", margin: 0 }}>{text}</p>\n );\n\n if (field.copyable) {\n return (\n <div style={{ position: \"relative\" }}>\n {rendered}\n <div style={{ position: \"absolute\", top: 0, right: 0 }}>\n <CopyButton value={text} size=\"sm\" />\n </div>\n </div>\n );\n }\n\n return rendered;\n }\n\n // Compact mode (inline table cell / draft row): render a single-line input\n // regardless of widget. A 4-row textarea inside a fixed-height row breaks\n // the layout; long text stays scrollable horizontally inside the input.\n if (compact) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n />\n );\n }\n const rows = widget === \"markdown\" || widget === \"code\" ? 10 : 4;\n return (\n <TextArea\n id={fieldId}\n name={fieldName}\n ariaRequired={field.required}\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n rows={rows}\n fill={fill}\n />\n );\n}\n","import { Pill, Select, type PillTone } from \"@/components/primitives\";\nimport { loc } from \"@/types/schema\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst NULL_SENTINEL = \"__declarion_enum_null__\";\n\nexport function EnumField({ field, value, mode, onChange, fieldId, labelId }: FieldRendererProps) {\n const values = field.values ?? [];\n const current = values.find((v) => v.code === value);\n\n if (mode === \"display\") {\n if (!current) {\n return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n }\n return (\n <Pill tone={(current.color as PillTone) ?? \"slate\"} size=\"xs\">\n {loc(current.name)}\n </Pill>\n );\n }\n\n const showClearOption = !field.required;\n const currentValue = value != null && value !== \"\" ? String(value) : NULL_SENTINEL;\n\n const options = [\n ...(showClearOption ? [{ value: NULL_SENTINEL, label: \"— None —\" }] : []),\n ...values.map((v) => ({ value: v.code, label: loc(v.name) || v.code })),\n ];\n\n return (\n <Select\n // Select renders a <button>, not an <input>: <label htmlFor> cannot\n // target it, so the form's label is wired via aria-labelledby instead\n // (Finding 2).\n id={fieldId}\n aria-labelledby={labelId}\n aria-required={field.required || undefined}\n value={currentValue}\n options={options}\n onChange={(v) => onChange?.(v === NULL_SENTINEL ? null : v)}\n placeholder=\"Select…\"\n />\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\n// EmailField is the EDIT-mode renderer for FieldType \"email\". Display-mode\n// rendering lives in the `email` cell factory (see cells/factories/email.tsx)\n// per the 2026-04-29-field-rendering-two-registry-cut plan §3 dispatcher\n// contract. `renderField` only routes edit-mode calls here, so this\n// component does not handle `mode === \"display\"`.\nexport function EmailField({ field, fieldName, value, onChange, fieldId }: FieldRendererProps) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"email\"\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n />\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\n// UrlField is the EDIT-mode renderer for FieldType \"url\". Display-mode\n// rendering lives in the `url` cell factory (see cells/factories/url.tsx)\n// per the 2026-04-29-field-rendering-two-registry-cut plan §3 dispatcher\n// contract: the display branch is a single source of truth and lives in\n// the cell registry, not in this component. `renderField` only routes\n// edit-mode calls here, so this component does not handle `mode === \"display\"`.\n//\n// The legacy display branch (anchor + favicon + LinkedIn slug) is preserved\n// in the cell factory; the URL parsing helpers it depends on are in\n// cells/factories/url-helpers.ts so both share the exact same parser.\nexport function UrlField({ field, fieldName, value, onChange, fieldId }: FieldRendererProps) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"url\"\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n placeholder=\"https://\"\n />\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\n// PhoneField is the EDIT-mode renderer for FieldType \"phone\". Display-mode\n// rendering lives in the `phone` cell factory (see cells/factories/phone.tsx).\n// `renderField` only routes edit-mode calls here, so this component does not\n// handle `mode === \"display\"`.\n//\n// Per plan §5: tel-keyboard <input>, no national-format mask. Region-aware\n// formatting waits on a region-metadata plan (see Open Questions Q5 in the\n// 2026-04-29-field-rendering-two-registry-cut plan).\nexport function PhoneField({ field, fieldName, value, onChange, fieldId }: FieldRendererProps) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"tel\"\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n placeholder=\"+1 555 555 5555\"\n />\n );\n}\n","import { formatISO, formatDistanceToNowStrict } from \"date-fns\";\n\n/**\n * Wire format for outgoing datetime payloads: local wall-clock with offset,\n * e.g. \"2026-04-22T15:18:00-05:00\" (or \"...Z\" when local == UTC).\n *\n * Every API call that sends a timestamp value must go through this helper:\n * ui-actions `${now}`, TimestampField submit, quick-add defaults, status\n * history `set_at`. The offset makes the instant unambiguous for passthrough\n * fields and is stripped by the backend for fields with configured timezone.\n *\n * See docs/gotchas.md#timezone--unit-conversions.\n */\nexport function formatWireDateTime(date: Date = new Date()): string {\n return formatISO(date);\n}\n\n/**\n * Format an offset-aware timestamp string (e.g. \"2026-03-27T14:30:00+03:00\")\n * for display WITHOUT browser-local timezone conversion. The server returns\n * timestamps already converted to the target timezone - we display as-is.\n *\n * Falls back to browser-local formatting for bare datetime strings.\n */\nexport function formatOffsetTimestamp(raw: string): string {\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n\n if (offsetMatch || isUTC) {\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n\n let tz: string | undefined;\n if (isUTC) {\n tz = \"UTC\";\n } else if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0);\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n if (minutes === 0) {\n tz = hours === 0 ? \"UTC\" : `Etc/GMT${sign === \"+\" ? \"-\" : \"+\"}${hours}`;\n }\n }\n\n if (tz) {\n try {\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: tz,\n }).format(date);\n } catch {\n // Fall through.\n }\n }\n\n // Non-standard offset (e.g. +05:30): compute local time manually.\n if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localMs = date.getTime() + offsetMs;\n const localDate = new Date(localMs);\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\",\n }).format(localDate);\n }\n }\n\n // Bare datetime or unparseable: fall back to browser-local.\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n }).format(date);\n}\n\n/**\n * Relative-or-absolute timestamp formatting for the time_ago cell renderer.\n *\n * Returns a short relative phrase (\"5 minutes ago\", \"2 days ago\") when the\n * timestamp is within the last 30 days, and an ISO date (\"2026-01-15\") when\n * older. Linear / Stripe / Datadog convention — avoids the \"1y 4mo 12d ago\"\n * eyesore for stable historical data.\n *\n * `absolute` is the offset-aware long form intended for the cell's hover\n * tooltip; the user always has access to the precise timestamp.\n *\n * Bare or unparseable input falls back to the raw string for both fields.\n */\nexport function formatRelativeOrAbsolute(\n raw: string | Date | null | undefined,\n now: Date = new Date(),\n): { text: string; absolute: string } {\n if (raw == null || raw === \"\") return { text: \"—\", absolute: \"\" };\n const date = raw instanceof Date ? raw : new Date(String(raw));\n if (isNaN(date.getTime())) {\n const fallback = String(raw);\n return { text: fallback, absolute: fallback };\n }\n const absolute = typeof raw === \"string\" ? formatOffsetTimestamp(raw) : formatOffsetTimestamp(date.toISOString());\n const ageMs = now.getTime() - date.getTime();\n const thirtyDaysMs = 30 * 24 * 60 * 60 * 1000;\n if (Math.abs(ageMs) > thirtyDaysMs) {\n const text = formatISO(date, { representation: \"date\" });\n return { text, absolute };\n }\n const text = formatDistanceToNowStrict(date, { addSuffix: true });\n return { text, absolute };\n}\n","import { TextInput } from \"@/components/primitives\";\nimport { formatWireDateTime } from \"@/lib/timestamp\";\nimport type { FieldRendererProps } from \"./index\";\n\n// Declarion timestamp fields fall into two display modes:\n//\n// hasTz=true — field.timezone is configured (e.g. $user, $ref, \"Europe/Moscow\").\n// Server already converted the value into that zone and sends\n// an offset-suffixed string like \"2026-04-10T16:27:00+03:00\".\n// Display and the <datetime-local> input both render the wall-\n// clock component of that string verbatim. A tz abbreviation\n// hint is shown next to the value so users know which zone.\n//\n// hasTz=false — field has NO timezone source. Server passes the value\n// through; DB stores the UTC instant carried by the wire\n// payload's offset. Client reads the UTC string and renders\n// in the browser's local zone; onChange submits local wall-\n// clock with offset via formatWireDateTime.\n//\n// The two modes never mix: tz infrastructure lives on the server for hasTz\n// fields, on the client for hasTz=false fields.\n\nfunction formatTimestampWithTz(raw: string, isDateOnly: boolean): string {\n if (isDateOnly) {\n const d = new Date(raw + \"T00:00:00\");\n if (isNaN(d.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n }).format(d);\n }\n\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n\n let tz: string | undefined;\n if (isUTC) {\n tz = \"UTC\";\n } else if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0);\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n if (minutes === 0) {\n tz = hours === 0 ? \"UTC\" : `Etc/GMT${sign === \"+\" ? \"-\" : \"+\"}${hours}`;\n }\n }\n\n if (tz) {\n try {\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n hour: \"2-digit\", minute: \"2-digit\", timeZone: tz,\n }).format(date);\n } catch {\n // fall through\n }\n }\n\n if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localDate = new Date(date.getTime() + offsetMs);\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n hour: \"2-digit\", minute: \"2-digit\", timeZone: \"UTC\",\n }).format(localDate);\n }\n\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n hour: \"2-digit\", minute: \"2-digit\",\n }).format(date);\n}\n\nfunction formatTimestampLocal(raw: string, isDateOnly: boolean): string {\n if (isDateOnly) {\n const d = new Date(raw + \"T00:00:00\");\n if (isNaN(d.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n }).format(d);\n }\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n hour: \"2-digit\", minute: \"2-digit\",\n }).format(date);\n}\n\nfunction extractTzAbbrev(raw: string): string | null {\n if (raw.endsWith(\"Z\")) return \"UTC\";\n const m = raw.match(/([+-]\\d{2}:\\d{2})$/);\n if (!m) return null;\n const sign = m[1].charAt(0);\n const hours = parseInt(m[1].substring(1, 3), 10);\n const minutes = parseInt(m[1].substring(4, 6), 10);\n if (hours === 0 && minutes === 0) return \"UTC\";\n const minPart = minutes > 0 ? `:${String(minutes).padStart(2, \"0\")}` : \"\";\n return `UTC${sign}${hours}${minPart}`;\n}\n\nfunction toInputValueWithTz(raw: string, isDateOnly: boolean): string {\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n const date = new Date(raw);\n if (isNaN(date.getTime())) return \"\";\n\n if (isUTC) {\n const y = date.getUTCFullYear();\n const mo = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n const d = String(date.getUTCDate()).padStart(2, \"0\");\n if (isDateOnly) return `${y}-${mo}-${d}`;\n const h = String(date.getUTCHours()).padStart(2, \"0\");\n const mi = String(date.getUTCMinutes()).padStart(2, \"0\");\n return `${y}-${mo}-${d}T${h}:${mi}`;\n }\n\n if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localDate = new Date(date.getTime() + offsetMs);\n const y = localDate.getUTCFullYear();\n const mo = String(localDate.getUTCMonth() + 1).padStart(2, \"0\");\n const d = String(localDate.getUTCDate()).padStart(2, \"0\");\n if (isDateOnly) return `${y}-${mo}-${d}`;\n const h = String(localDate.getUTCHours()).padStart(2, \"0\");\n const mi = String(localDate.getUTCMinutes()).padStart(2, \"0\");\n return `${y}-${mo}-${d}T${h}:${mi}`;\n }\n\n if (isDateOnly) return raw.slice(0, 10);\n return raw.slice(0, 16);\n}\n\nfunction toInputValueLocal(raw: string, isDateOnly: boolean): string {\n const date = new Date(raw);\n if (isNaN(date.getTime())) return \"\";\n const y = date.getFullYear();\n const mo = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n if (isDateOnly) return `${y}-${mo}-${d}`;\n const h = String(date.getHours()).padStart(2, \"0\");\n const mi = String(date.getMinutes()).padStart(2, \"0\");\n return `${y}-${mo}-${d}T${h}:${mi}`;\n}\n\nexport function TimestampField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n const isDateOnly = field.type === \"date\";\n const hasTz = !!field.timezone;\n\n if (mode === \"display\") {\n if (!value) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n const raw = String(value);\n const formatted = hasTz\n ? formatTimestampWithTz(raw, isDateOnly)\n : formatTimestampLocal(raw, isDateOnly);\n const tzAbbrev = hasTz && !isDateOnly ? extractTzAbbrev(raw) : null;\n return (\n <span style={{ fontSize: 12.5 }}>\n {formatted}\n {tzAbbrev && <span style={{ marginLeft: 4, color: \"var(--text-3)\" }}>{tzAbbrev}</span>}\n </span>\n );\n }\n\n const inputValue = value\n ? (hasTz ? toInputValueWithTz(String(value), isDateOnly) : toInputValueLocal(String(value), isDateOnly))\n : \"\";\n\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type={isDateOnly ? \"date\" : \"datetime-local\"}\n value={inputValue}\n onChange={(v) => {\n if (!v) {\n onChange?.(null);\n return;\n }\n if (hasTz || isDateOnly) {\n // hasTz: server owns the zone; send the bare local wall-clock and\n // let the CUT+ATTACH pipeline re-zone it.\n // isDateOnly: server stores date (no tz), client sends YYYY-MM-DD.\n onChange?.(v);\n return;\n }\n // hasTz=false: send local wall-clock with offset. `new Date(v)` parses\n // the tz-less `datetime-local` value in the browser's local zone;\n // formatWireDateTime serializes it as \"YYYY-MM-DDTHH:mm:ss±HH:mm\".\n // The offset carries the unambiguous instant for passthrough storage.\n const d = new Date(v);\n if (isNaN(d.getTime())) {\n onChange?.(v);\n return;\n }\n onChange?.(formatWireDateTime(d));\n }}\n />\n );\n}\n","import { BoolToggle } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function BoolField({ value, mode, onChange, fieldId, labelId }: FieldRendererProps) {\n const checked = Boolean(value);\n\n if (mode === \"display\") {\n return (\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6, fontSize: 12.5 }}>\n <span\n style={{\n display: \"inline-block\",\n width: 6,\n height: 6,\n borderRadius: 999,\n background: checked ? \"var(--success)\" : \"var(--text-4)\",\n }}\n />\n {checked ? \"Yes\" : \"No\"}\n </span>\n );\n }\n\n return (\n <BoolToggle\n id={fieldId}\n ariaLabelledby={labelId}\n value={checked}\n onChange={(v) => onChange?.(v)}\n />\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nfunction formatDecimalString(value: string): string {\n const trimmed = value.trim();\n if (trimmed === \"\" || trimmed === \"-\") return trimmed;\n\n const negative = trimmed.startsWith(\"-\");\n const abs = negative ? trimmed.slice(1) : trimmed;\n const [intPart, fracPart] = abs.split(\".\");\n\n let formattedInt: string;\n try {\n formattedInt = new Intl.NumberFormat().format(BigInt(intPart || \"0\"));\n } catch {\n return value;\n }\n\n let result = negative ? `-${formattedInt}` : formattedInt;\n if (fracPart !== undefined) result += `.${fracPart}`;\n return result;\n}\n\nconst numFormatter = new Intl.NumberFormat();\n\nexport function NumberField({ field, fieldName, value, mode, onChange, record, fieldId }: FieldRendererProps) {\n const isMoney = field.display?.widget === \"money\";\n const isDecimal = field.type === \"decimal\" || isMoney;\n\n const units = record?.[\"$units\"] as Record<string, string> | undefined;\n const unitSuffix = units?.[fieldName];\n const staticUnit = !unitSuffix && field.unit ? (field.unit.display || field.unit.storage) : undefined;\n const displayUnit =\n unitSuffix || (staticUnit && !staticUnit.startsWith(\"$\") ? staticUnit : undefined);\n\n if (mode === \"display\") {\n if (value == null) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n\n let formatted: string | null;\n if (isDecimal && typeof value === \"string\") {\n formatted = formatDecimalString(value);\n } else {\n const num = Number(value);\n formatted = isNaN(num) ? null : numFormatter.format(num);\n }\n\n if (formatted == null) return <span style={{ fontSize: 12.5 }}>—</span>;\n\n return (\n <span className=\"num\" style={{ fontSize: 12.5, fontVariantNumeric: \"tabular-nums\" }}>\n {formatted}\n {displayUnit && (\n <span style={{ color: \"var(--text-3)\", marginLeft: 4 }}>{displayUnit}</span>\n )}\n </span>\n );\n }\n\n if (isDecimal) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"text\"\n inputMode=\"decimal\"\n pattern=\"-?\\d*\\.?\\d*\"\n value={value != null ? String(value) : \"\"}\n onChange={(v) => {\n if (v === \"\") onChange?.(null);\n else onChange?.(v);\n }}\n />\n );\n }\n\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"number\"\n step={field.type === \"float\" ? \"0.01\" : \"1\"}\n value={value != null ? String(value) : \"\"}\n onChange={(v) => {\n if (v === \"\") onChange?.(null);\n else onChange?.(field.type === \"int\" ? parseInt(v, 10) : parseFloat(v));\n }}\n />\n );\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { listEntities } from \"@/api/data\";\nimport type { ListParams, ListResponse } from \"@/types/api\";\n\n/**\n * useEntityData fetches one page-window of entity rows.\n *\n * Decoupled-count contract (docs/plans/2026-05-18-declarative-row-count.md):\n * this hook issues the WINDOW request only - `count: \"window\"`, so the\n * server returns the page of rows and never blocks on a COUNT(*). The total\n * is fetched separately by `useEntityCount`; the table renders rows the\n * moment this query resolves, independent of count latency.\n */\nexport function useEntityData(entity: string | undefined, params: ListParams) {\n const windowParams: ListParams = { ...params, count: \"window\" };\n return useQuery({\n queryKey: [\"entity-data\", entity, windowParams],\n queryFn: ({ signal }) => listEntities(entity!, windowParams, { signal }),\n enabled: !!entity,\n placeholderData: (prev, prevQuery) => {\n // Only reuse previous data within the same entity (pagination/sorting).\n // Cross-entity placeholder causes wrong rows/columns flash.\n const prevEntity = (prevQuery?.queryKey as unknown[])?.[1];\n return prevEntity === entity ? prev : undefined;\n },\n });\n}\n\n/**\n * useEntityCount fetches the total row count for a list view in a SEPARATE\n * request from the window (`count: \"only\"` - the server skips the data\n * query entirely and returns just `meta.total` + `meta.count_mode`).\n *\n * The count is page-independent: `page` and `sort` are stripped from the\n * params so a page change or a re-sort does not refetch the count - only a\n * filter / search / screen / include_deleted change invalidates it.\n *\n * The server picks exact vs estimated per the entity's declared `count`\n * strategy; the resolved `meta.count_mode` tells the caller which precision\n * to render. A count failure does NOT break the table: callers treat a\n * failed/absent count as \"unknown\" and fall back to the loaded row count.\n */\nexport function useEntityCount(entity: string | undefined, params: ListParams) {\n // Strip page-window knobs - the count describes the whole filtered set,\n // not one page, so it must not refetch when only the page or sort moves.\n const countParams: ListParams = {\n ...params,\n count: \"only\",\n page: undefined,\n per_page: undefined,\n sort: undefined,\n select: undefined,\n expand: undefined,\n };\n return useQuery<ListResponse>({\n queryKey: [\"entity-count\", entity, countParams],\n queryFn: ({ signal }) => listEntities(entity!, countParams, { signal }),\n enabled: !!entity,\n // The count is a slow, best-effort number; do not retry-storm a\n // multi-second estimate, and keep a resolved count warm across page\n // changes within the same filter set.\n retry: 1,\n staleTime: 30_000,\n placeholderData: (prev, prevQuery) => {\n const prevEntity = (prevQuery?.queryKey as unknown[])?.[1];\n return prevEntity === entity ? prev : undefined;\n },\n });\n}\n","import { useSchema } from \"./useSchema\";\nimport type { Entity } from \"@/types/schema\";\n\nexport function useEntity(entityCode: string | undefined): Entity | undefined {\n const { data: schema } = useSchema();\n if (!schema || !entityCode) return undefined;\n return schema.entities[entityCode];\n}\n","import { useMemo } from \"react\";\nimport { Select } from \"@/components/primitives\";\nimport { useEntityData } from \"@/hooks/useEntityData\";\nimport { useEntity } from \"@/hooks/useEntity\";\nimport { resolveRefRecordLabel } from \"@/types/schema\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function RefField({ field, value, mode, onChange, refs, fieldId, labelId }: FieldRendererProps) {\n const refEntityCode = field.ref?.entity;\n const entity = useEntity(refEntityCode);\n\n const displayField =\n field.display?.ref_display_field ?? field.ref?.display?.field ?? entity?.display?.display_field;\n const pk = useMemo(\n () => (entity ? ([...entity.fields].find(([, f]) => f.primary)?.[0] ?? \"id\") : \"id\"),\n [entity],\n );\n\n const { data: response, isLoading: optionsLoading } = useEntityData(\n mode === \"edit\" ? refEntityCode : undefined,\n { per_page: 200, sort: displayField ? `${displayField}:asc` : undefined },\n );\n const options = useMemo(() => response?.data ?? [], [response?.data]);\n\n const displayValue = useMemo(() => {\n if (value == null) return \"—\";\n const strVal = String(value);\n\n if (refs && refEntityCode) {\n const entityRefs = refs[refEntityCode];\n if (entityRefs) {\n const refRecord = entityRefs[strVal];\n if (refRecord) {\n return resolveRefRecordLabel(refRecord, displayField, strVal);\n }\n }\n }\n\n if (options.length > 0) {\n const match = options.find((r) => String(r[pk]) === strVal);\n if (match) return resolveRefRecordLabel(match, displayField, String(value));\n }\n\n return strVal;\n }, [value, refs, refEntityCode, displayField, options, pk]);\n\n if (mode === \"display\") {\n return <span style={{ fontSize: 12.5 }}>{displayValue}</span>;\n }\n\n const currentId = String(value ?? \"\");\n const hasCurrentInOptions = options.some((r) => String(r[pk]) === currentId);\n\n const selectOptions = [\n { value: \"\", label: \"Select…\" },\n ...(optionsLoading && currentId\n ? [{ value: currentId, label: displayValue }]\n : []),\n ...(!optionsLoading && currentId && !hasCurrentInOptions\n ? [{ value: currentId, label: displayValue }]\n : []),\n ...options.map((r) => {\n const id = String(r[pk]);\n const label = resolveRefRecordLabel(r, displayField, id);\n return { value: id, label };\n }),\n ];\n\n return (\n <Select\n // Select renders a <button>, not an <input>: <label htmlFor> cannot\n // target it, so the form's label is wired via aria-labelledby instead\n // (Finding 2).\n id={fieldId}\n aria-labelledby={labelId}\n aria-required={field.required || undefined}\n value={currentId}\n options={selectOptions}\n onChange={(v) => onChange?.(v || null)}\n placeholder=\"Select…\"\n />\n );\n}\n","import { lazy, Suspense } from \"react\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst JsonEditor = lazy(() =>\n import(\"./JsonEditor\").then((m) => ({ default: m.JsonEditor })),\n);\n\nfunction JsonEditorFallback() {\n return (\n <div className=\"h-20 rounded-md border border-border bg-muted animate-pulse\" />\n );\n}\n\n// isEmptyJsonValue reports whether a JSON field holds nothing worth showing:\n// null/undefined, a blank string, an empty object, or an empty array. The\n// readonly JSON editor renders a tall empty box for these, so display-mode\n// callers collapse to the empty token instead. Exported for the `json` cell\n// factory so list and detail surfaces agree on what \"empty\" means. A bare\n// `0` / `false` / non-empty string is a real value and is NOT empty.\nexport function isEmptyJsonValue(value: unknown): boolean {\n if (value == null) return true;\n if (typeof value === \"string\") return value.trim() === \"\";\n if (Array.isArray(value)) return value.length === 0;\n if (typeof value === \"object\") return Object.keys(value as object).length === 0;\n return false;\n}\n\nexport function JsonField({ value, mode, onChange, fieldId }: FieldRendererProps) {\n if (mode === \"display\") {\n if (isEmptyJsonValue(value)) {\n return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n }\n return (\n <Suspense fallback={<JsonEditorFallback />}>\n <JsonEditor value={value} readOnly />\n </Suspense>\n );\n }\n\n // The JSON editor is a CodeMirror surface, not a native <input>. id is set\n // on its container so the form's <label> association resolves to a real\n // element (Finding 2); the label is also wired via aria-labelledby on the\n // editor group, see JsonEditor.\n return (\n <Suspense fallback={<JsonEditorFallback />}>\n <JsonEditor value={value} onChange={onChange} id={fieldId} />\n </Suspense>\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport type { FieldRendererProps } from \"./index\";\n\ntype LangMap = Record<string, string>;\n\nfunction parseLangMap(value: unknown): LangMap {\n if (value == null) return {};\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as LangMap;\n }\n if (typeof value === \"string\") {\n return { en: value };\n }\n return {};\n}\n\nexport function MultilangField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n const { data: schema } = useSchema();\n const languages = schema?.languages?.length\n ? schema.languages\n : [{ code: \"en\", name: { en: \"English\" } }];\n const langMap = parseLangMap(value);\n\n if (mode === \"display\") {\n const displayVal = Object.values(langMap)[0] ?? \"—\";\n return <span style={{ fontSize: 12.5 }}>{displayVal}</span>;\n }\n\n const handleLangChange = (lang: string, text: string) => {\n const updated = { ...langMap, [lang]: text };\n for (const k of Object.keys(updated)) {\n if (!updated[k]) delete updated[k];\n }\n onChange?.(Object.keys(updated).length > 0 ? updated : null);\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n {languages.map((lang, i) => {\n // Per-language id: the first language carries the block's fieldId so\n // the form's <label htmlFor> resolves; the per-language code <label>\n // pairs each input with its own language tag (Finding 2).\n const langInputId = fieldId ? (i === 0 ? fieldId : `${fieldId}-${lang.code}`) : undefined;\n return (\n <div key={lang.code} style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <label\n htmlFor={langInputId}\n style={{\n width: 24,\n fontSize: 10.5,\n color: \"var(--text-3)\",\n textTransform: \"uppercase\",\n flexShrink: 0,\n letterSpacing: \"0.04em\",\n fontWeight: 500,\n }}\n >\n {lang.code}\n </label>\n <div style={{ flex: 1 }}>\n <TextInput\n id={langInputId}\n name={fieldName ? `${fieldName}.${lang.code}` : undefined}\n aria-required={field.required && i === 0 ? true : undefined}\n value={langMap[lang.code] ?? \"\"}\n onChange={(v) => handleLangChange(lang.code, v)}\n placeholder={`Value (${lang.code})`}\n />\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n","import { TextArea } from \"@/components/primitives\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport type { FieldRendererProps } from \"./index\";\n\ntype LangMap = Record<string, string>;\n\nfunction parseLangMap(value: unknown): LangMap {\n if (value == null) return {};\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as LangMap;\n }\n if (typeof value === \"string\") {\n return { en: value };\n }\n return {};\n}\n\nexport function MultilangTextField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n const { data: schema } = useSchema();\n const languages = schema?.languages?.length\n ? schema.languages\n : [{ code: \"en\", name: { en: \"English\" } }];\n const langMap = parseLangMap(value);\n\n if (mode === \"display\") {\n const displayVal = Object.values(langMap)[0] ?? \"—\";\n return <p style={{ fontSize: 12.5, whiteSpace: \"pre-wrap\", margin: 0 }}>{displayVal}</p>;\n }\n\n const handleLangChange = (lang: string, text: string) => {\n const updated = { ...langMap, [lang]: text };\n for (const k of Object.keys(updated)) {\n if (!updated[k]) delete updated[k];\n }\n onChange?.(Object.keys(updated).length > 0 ? updated : null);\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 10 }}>\n {languages.map((lang, i) => {\n // Per-language id: the first language carries the block's fieldId so\n // the form's <label htmlFor> resolves; the per-language code <label>\n // pairs each textarea with its own language tag (Finding 2).\n const langInputId = fieldId ? (i === 0 ? fieldId : `${fieldId}-${lang.code}`) : undefined;\n return (\n <div key={lang.code} style={{ display: \"flex\", flexDirection: \"column\", gap: 4 }}>\n <label\n htmlFor={langInputId}\n style={{\n fontSize: 10.5,\n color: \"var(--text-3)\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n fontWeight: 500,\n }}\n >\n {lang.code}\n </label>\n <TextArea\n id={langInputId}\n name={fieldName ? `${fieldName}.${lang.code}` : undefined}\n ariaRequired={field.required && i === 0}\n value={langMap[lang.code] ?? \"\"}\n onChange={(v) => handleLangChange(lang.code, v)}\n placeholder={`Value (${lang.code})`}\n rows={4}\n />\n </div>\n );\n })}\n </div>\n );\n}\n","import { Btn, FieldLabel, Icon, IconBtn } from \"@/components/primitives\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { loc } from \"@/types/schema\";\nimport type { StructureDef } from \"@/types/schema\";\nimport type { FieldRendererProps } from \"./index\";\nimport { renderField } from \"./index\";\nimport { JsonField } from \"./JsonField\";\n\nexport function StructureField(props: FieldRendererProps) {\n const { field, value, mode, onChange, locale, fieldId } = props;\n const { data: schema } = useSchema();\n\n const structDef = field.structure ? schema?.structures?.[field.structure] : undefined;\n\n if (!structDef) return <JsonField {...props} />;\n\n // fieldId (Finding 2): a structure renders a labelled group of nested\n // fields, not a single input. It is placed on the group container so the\n // form's <label htmlFor> resolves to a real element. Array structures place\n // it on their outer wrapper; nested-field <label>s scope inside the group.\n if (field.array) {\n return <StructureArrayRenderer structDef={structDef} value={value} mode={mode} onChange={onChange} locale={locale} fieldId={fieldId} />;\n }\n\n return <StructureObjectRenderer structDef={structDef} value={value} mode={mode} onChange={onChange} locale={locale} fieldId={fieldId} />;\n}\n\nfunction StructureObjectRenderer({\n structDef,\n value,\n mode,\n onChange,\n locale,\n fieldId,\n}: {\n structDef: StructureDef;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n locale: string;\n fieldId?: string;\n}) {\n const obj = (typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? value\n : {}) as Record<string, unknown>;\n\n const fieldOrder = structDef.fields.names();\n\n const containerStyle = {\n display: \"flex\",\n flexDirection: \"column\" as const,\n gap: mode === \"display\" ? 8 : 12,\n border: \"1px solid var(--border)\",\n borderRadius: 8,\n padding: 12,\n background: \"var(--surface-2)\",\n };\n\n if (mode === \"display\") {\n const hasAnyValue = fieldOrder.some((key) => obj[key] != null && obj[key] !== \"\");\n if (!hasAnyValue) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n\n return (\n <div style={containerStyle}>\n {fieldOrder.map((key) => {\n const field = structDef.fields.get(key);\n if (!field) return null;\n const fieldValue = obj[key];\n if (fieldValue == null) return null;\n\n return (\n <div key={key} style={{ display: \"flex\", alignItems: \"baseline\", gap: 8 }}>\n <span\n style={{\n fontSize: 11.5,\n fontWeight: 500,\n color: \"var(--text-3)\",\n minWidth: 100,\n flexShrink: 0,\n }}\n >\n {field.display ? loc(field.display.name) : key}\n </span>\n <div style={{ minWidth: 0, flex: 1 }}>\n {field.type === \"structure\" && field.structure ? (\n <StructureField field={field} fieldName={key} value={fieldValue} mode=\"display\" locale={locale} />\n ) : (\n renderField({ field, fieldName: key, value: fieldValue, mode: \"display\", locale })\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n }\n\n const handleFieldChange = (key: string) => (fieldValue: unknown) => {\n onChange?.({ ...obj, [key]: fieldValue });\n };\n\n return (\n <div style={containerStyle} id={fieldId} role=\"group\">\n {fieldOrder.map((key) => {\n const field = structDef.fields.get(key);\n if (!field) return null;\n return (\n <div key={key} style={{ display: \"flex\", flexDirection: \"column\", gap: 2 }}>\n <FieldLabel required={field.required}>\n {field.display ? loc(field.display.name) : key}\n </FieldLabel>\n {field.type === \"structure\" && field.structure ? (\n <StructureField\n field={field}\n fieldName={key}\n value={obj[key]}\n mode=\"edit\"\n onChange={handleFieldChange(key)}\n locale={locale}\n />\n ) : (\n renderField({\n field,\n fieldName: key,\n value: obj[key],\n mode: \"edit\",\n onChange: handleFieldChange(key),\n locale,\n })\n )}\n </div>\n );\n })}\n </div>\n );\n}\n\nfunction StructureArrayRenderer({\n structDef,\n value,\n mode,\n onChange,\n locale,\n fieldId,\n}: {\n structDef: StructureDef;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n locale: string;\n fieldId?: string;\n}) {\n const items = Array.isArray(value) ? value : [];\n\n if (mode === \"display\") {\n if (items.length === 0) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n {items.map((item, idx) => (\n <StructureObjectRenderer key={idx} structDef={structDef} value={item} mode=\"display\" locale={locale} />\n ))}\n </div>\n );\n }\n\n const handleItemChange = (idx: number) => (itemValue: unknown) => {\n const next = [...items];\n next[idx] = itemValue;\n onChange?.(next);\n };\n\n const handleAdd = () => {\n onChange?.([...items, {}]);\n };\n\n const handleRemove = (idx: number) => () => {\n const next = items.filter((_, i) => i !== idx);\n onChange?.(next);\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }} id={fieldId} role=\"group\">\n {items.map((item, idx) => (\n <div key={idx} style={{ position: \"relative\" }}>\n <StructureObjectRenderer\n structDef={structDef}\n value={item}\n mode=\"edit\"\n onChange={handleItemChange(idx)}\n locale={locale}\n />\n <div style={{ position: \"absolute\", top: 6, right: 6 }}>\n <IconBtn\n size={24}\n icon={<Icon.trash size={12} />}\n onClick={handleRemove(idx)}\n title=\"Remove\"\n />\n </div>\n </div>\n ))}\n <div>\n <Btn icon={<Icon.plus size={13} />} onClick={handleAdd}>\n Add\n </Btn>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { PasswordInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst SECRET_SENTINEL = \"[SET]\";\n\nexport function SecretField({ field, fieldName, value, mode, onChange, record, fieldId }: FieldRendererProps) {\n const [inputValue, setInputValue] = useState(\"\");\n\n const isUpdate = record !== undefined;\n const hasExistingValue =\n value === SECRET_SENTINEL || (typeof value === \"string\" && value !== \"\");\n\n if (mode === \"display\") {\n if (hasExistingValue) {\n return (\n <span className=\"mono\" style={{ fontSize: 12.5, color: \"var(--text-3)\" }}>\n {SECRET_SENTINEL}\n </span>\n );\n }\n return (\n <span style={{ fontSize: 12.5, color: \"var(--text-4)\", fontStyle: \"italic\" }}>Not set</span>\n );\n }\n\n const handleChange = (v: string) => {\n setInputValue(v);\n if (isUpdate) {\n if (v === \"\") onChange?.(hasExistingValue ? SECRET_SENTINEL : \"\");\n else onChange?.(v);\n } else {\n onChange?.(v);\n }\n };\n\n return (\n <PasswordInput\n id={fieldId}\n name={fieldName}\n ariaRequired={field.required}\n value={inputValue}\n onChange={handleChange}\n placeholder={isUpdate ? \"Leave blank to keep existing value\" : \"Enter value\"}\n />\n );\n}\n","import { useState } from \"react\";\nimport { PasswordInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst SECRET_SENTINEL = \"[SET]\";\n\nexport function PasswordField({ field, fieldName, value, mode, onChange, record, fieldId }: FieldRendererProps) {\n const [inputValue, setInputValue] = useState(\"\");\n\n const isUpdate = record !== undefined;\n const hasExistingValue =\n value === SECRET_SENTINEL || (typeof value === \"string\" && value !== \"\");\n\n if (mode === \"display\") {\n if (hasExistingValue) {\n return (\n <span className=\"mono\" style={{ fontSize: 12.5, color: \"var(--text-3)\" }}>\n {SECRET_SENTINEL}\n </span>\n );\n }\n return (\n <span style={{ fontSize: 12.5, color: \"var(--text-4)\", fontStyle: \"italic\" }}>Not set</span>\n );\n }\n\n const handleChange = (v: string) => {\n setInputValue(v);\n if (isUpdate) {\n if (v === \"\") onChange?.(hasExistingValue ? SECRET_SENTINEL : \"\");\n else onChange?.(v);\n } else {\n onChange?.(v);\n }\n };\n\n return (\n <PasswordInput\n id={fieldId}\n name={fieldName}\n ariaRequired={field.required}\n value={inputValue}\n onChange={handleChange}\n placeholder={isUpdate ? \"Leave blank to keep existing value\" : \"Enter password\"}\n />\n );\n}\n","import { useState, type KeyboardEvent } from \"react\";\nimport { Btn, Chip, Icon, TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nfunction toStringArray(value: unknown): string[] {\n if (Array.isArray(value)) return value.filter((v) => v != null).map(String);\n return [];\n}\n\nexport function StringArrayField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n const items = toStringArray(value);\n const [draft, setDraft] = useState(\"\");\n\n if (mode === \"display\") {\n if (items.length === 0) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n return (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4 }}>\n {items.map((item, i) => (\n <Chip key={i} tone=\"slate\">{item}</Chip>\n ))}\n </div>\n );\n }\n\n const addItem = () => {\n const trimmed = draft.trim();\n if (!trimmed) return;\n onChange?.([...items, trimmed]);\n setDraft(\"\");\n };\n\n const removeItem = (index: number) => {\n onChange?.(items.filter((_, i) => i !== index));\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n addItem();\n }\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n {items.length > 0 && (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4 }}>\n {items.map((item, i) => (\n <Chip key={i} tone=\"slate\" onRemove={() => removeItem(i)}>{item}</Chip>\n ))}\n </div>\n )}\n <div style={{ display: \"flex\", gap: 4 }}>\n <div style={{ flex: 1 }}>\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n value={draft}\n onChange={setDraft}\n onKeyDown={handleKeyDown}\n placeholder=\"Add item…\"\n />\n </div>\n <Btn icon={<Icon.plus size={13} />} onClick={addItem}>Add</Btn>\n </div>\n </div>\n );\n}\n","import { useState, type KeyboardEvent } from \"react\";\nimport { Btn, Chip, Icon, TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nfunction toIntArray(value: unknown): number[] {\n if (Array.isArray(value)) {\n return value.filter((v) => v != null).map(Number).filter((n) => !isNaN(n));\n }\n return [];\n}\n\nexport function IntArrayField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n const items = toIntArray(value);\n const [draft, setDraft] = useState(\"\");\n\n if (mode === \"display\") {\n if (items.length === 0) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n return (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4 }}>\n {items.map((item, i) => (\n <Chip key={i} tone=\"slate\">{item}</Chip>\n ))}\n </div>\n );\n }\n\n const addItem = () => {\n const trimmed = draft.trim();\n if (!trimmed) return;\n const num = Number(trimmed);\n if (isNaN(num) || !Number.isInteger(num)) return;\n onChange?.([...items, num]);\n setDraft(\"\");\n };\n\n const removeItem = (index: number) => {\n onChange?.(items.filter((_, i) => i !== index));\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n addItem();\n }\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n {items.length > 0 && (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4 }}>\n {items.map((item, i) => (\n <Chip key={i} tone=\"slate\" onRemove={() => removeItem(i)}>{item}</Chip>\n ))}\n </div>\n )}\n <div style={{ display: \"flex\", gap: 4 }}>\n <div style={{ flex: 1 }}>\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"number\"\n value={draft}\n onChange={setDraft}\n onKeyDown={handleKeyDown}\n placeholder=\"Add number…\"\n />\n </div>\n <Btn icon={<Icon.plus size={13} />} onClick={addItem}>Add</Btn>\n </div>\n </div>\n );\n}\n","import type { FileWidget } from \"./types\";\n\n// Module-scope file widget registry. Consumer apps register custom widgets\n// via `registerFileWidget(\"math_figure\", MathFigureWidget)` before mount.\n// Built-in widgets (square_image, circle_image, wide_banner, grid,\n// document_card, file_list) are registered eagerly when their module loads.\nconst widgets = new Map<string, FileWidget>();\n\nexport function registerFileWidget(code: string, widget: FileWidget): void {\n widgets.set(code, widget);\n}\n\nexport function getFileWidget(code: string): FileWidget | undefined {\n return widgets.get(code);\n}\n\nexport function hasFileWidget(code: string): boolean {\n return widgets.has(code);\n}\n\n// Test-only: clear the registry between tests so re-registrations don't\n// accumulate. Production code never calls this.\nexport function __resetFileWidgetRegistryForTests(): void {\n widgets.clear();\n}\n","// Cropper indirection. The plan calls for `react-image-crop` when\n// `crop_on_upload: true`, but we keep that dependency out of the SDK core\n// so apps that don't need cropping pay no bundle cost. Consumer apps wire\n// their cropper of choice via `setImageCropper(fn)`; the default is a\n// pass-through that returns the original blob untouched.\n//\n// Tests can substitute a deterministic stub via setImageCropper to assert\n// the round-trip without a real cropper UI.\n\nimport type { ReactNode } from \"react\";\n\nexport interface CropperOptions {\n aspectRatio?: number;\n // file is the picked source. Returns a Blob (likely image/jpeg|png) plus\n // a final filename. The caller wraps it back into a File for upload.\n file: File;\n}\n\nexport interface CropperResult {\n blob: Blob;\n filename: string;\n}\n\nexport type ImageCropper = (opts: CropperOptions) => Promise<CropperResult>;\n\nconst passthroughCropper: ImageCropper = async ({ file }) => ({\n blob: file,\n filename: file.name,\n});\n\nlet activeCropper: ImageCropper = passthroughCropper;\n\nexport function setImageCropper(c: ImageCropper | null): void {\n activeCropper = c ?? passthroughCropper;\n}\n\nexport function getImageCropper(): ImageCropper {\n return activeCropper;\n}\n\n// Some host apps prefer a modal-based cropper. The renderer is optional and\n// unused by the built-in widgets in Wave 1 — exposed for forward-compat so\n// react-image-crop integrations can share infrastructure.\nlet cropperRenderer: ((node: ReactNode) => void) | null = null;\nexport function setCropperRenderer(fn: ((node: ReactNode) => void) | null): void {\n cropperRenderer = fn;\n}\nexport function getCropperRenderer(): ((node: ReactNode) => void) | null {\n return cropperRenderer;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { CSSProperties, DragEvent, KeyboardEvent } from \"react\";\nimport {\n uploadFile,\n discardFile,\n validateClientSide,\n formatBytes,\n UploadError,\n} from \"./upload\";\nimport { getImageCropper } from \"./cropper\";\nimport {\n focalPointObjectPosition,\n preferredListThumbnailURL,\n preferredThumbnailVariant,\n readFocalPoint,\n resolveFileAltText,\n withFocalPoint,\n} from \"./helpers\";\nimport { useDraftRegistration } from \"./draft-scope\";\nimport { useEmbedFileSrc } from \"./useEmbedFileSrc\";\nimport { singleFileFromValue } from \"./value\";\nimport type { FileWidgetProps, HydratedFile, UploadProgress } from \"./types\";\n\n// Internal state machine for an image-style file widget. Three stable\n// states: empty, populated, in-flight (upload running). Errors live on\n// the side and clear on retry.\ntype WidgetStatus = \"idle\" | \"uploading\" | \"error\";\n\nexport interface ImageWidgetVisualConfig {\n // shape: square or circle. Drives placeholder + clip-path.\n shape: \"square\" | \"circle\" | \"wide\";\n // CSS aspect-ratio (e.g. \"1 / 1\", \"16 / 9\"). Falls back per shape.\n aspectRatio?: string;\n // CSS width or undefined to let the parent decide.\n width?: string;\n}\n\nexport interface ImageWidgetInternalProps extends FileWidgetProps {\n visual: ImageWidgetVisualConfig;\n}\n\nfunction previewUrl(f: HydratedFile | null, preferredDerivationKey?: string): string | undefined {\n return preferredListThumbnailURL(f, preferredDerivationKey);\n}\n\n// initialsFromAlt extracts up to two initials from a label, falling back\n// to \"?\" if empty. Used by the placeholder when widget renders empty.\nfunction initialsFromAlt(label: string): string {\n const parts = label.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\n return (parts[0][0] + parts[1][0]).toUpperCase();\n}\n\nexport function ImageWidget(props: ImageWidgetInternalProps) {\n const { field, fieldName, value, onChange, mode, alt, disabled, visual, uploadFieldCode, uploadSlotCode } = props;\n const file = singleFileFromValue(value);\n const [status, setStatus] = useState<WidgetStatus>(\"idle\");\n const [progress, setProgress] = useState<UploadProgress | null>(null);\n const [error, setError] = useState<{ code: string; message: string } | null>(null);\n const [pendingDraftId, setPendingDraftId] = useState<string | null>(null);\n const [isEditingFocalPoint, setIsEditingFocalPoint] = useState(false);\n const abortRef = useRef<AbortController | null>(null);\n const cancelledUploadRef = useRef(false);\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n const { register, unregister, isDraft } = useDraftRegistration();\n\n // Cleanup on unmount: abort in-flight upload + discard registered draft.\n useEffect(() => {\n return () => {\n if (abortRef.current) abortRef.current.abort();\n };\n }, []);\n\n const ariaLabel = useMemo(() => {\n return resolveFileAltText(file, alt, field.display?.placeholder || fieldName);\n }, [alt, field.display?.placeholder, fieldName, file]);\n\n const accept = (field.accepts ?? [\"image/*\"]).join(\",\");\n\n const startUpload = useCallback(async (raw: File) => {\n // Client-side validation mirrors the server's accepts + max_size_bytes\n // checks so the user gets immediate feedback.\n const v = validateClientSide(raw, field.accepts, field.max_size_bytes);\n if (v) {\n setError(v);\n setStatus(\"error\");\n return;\n }\n\n let toUpload: File = raw;\n if (field.display?.crop_on_upload) {\n try {\n const cropper = getImageCropper();\n const aspect = parseAspect(field.display.aspect_ratio);\n const { blob, filename } = await cropper({ file: raw, aspectRatio: aspect });\n toUpload = new File([blob], filename, { type: blob.type || raw.type });\n } catch (err) {\n setError({ code: \"CROP_FAILED\", message: err instanceof Error ? err.message : \"Crop failed\" });\n setStatus(\"error\");\n return;\n }\n }\n\n setError(null);\n cancelledUploadRef.current = false;\n setStatus(\"uploading\");\n setProgress({ loaded: 0, total: toUpload.size, pct: 0 });\n const ctrl = new AbortController();\n abortRef.current = ctrl;\n\n try {\n const result = await uploadFile({\n file: toUpload,\n entityCode: props.entityCode,\n fieldCode: uploadFieldCode ?? fieldName,\n slotCode: uploadSlotCode,\n signal: ctrl.signal,\n onProgress: setProgress,\n });\n if (cancelledUploadRef.current) {\n void discardFile(result.id).catch(() => {});\n unregister(result.id);\n return;\n }\n if (file && isDraft(file.id)) {\n void discardFile(file.id).catch(() => {});\n unregister(file.id);\n }\n // Register the freshly-uploaded draft with the form scope so a\n // form Cancel can discard it. Stays registered until form save\n // (parent calls scope.markCommitted) or the user replaces/removes.\n register(result.id, () => discardFile(result.id));\n setPendingDraftId(result.id);\n setStatus(\"idle\");\n setProgress(null);\n // Materialize a HydratedFile from the upload result. Server returns\n // enough metadata to render the preview without a re-fetch.\n const next: HydratedFile = {\n id: result.id,\n filename: result.filename,\n content_type: result.content_type,\n size_bytes: result.size_bytes,\n sha256: result.sha256,\n width: result.width,\n height: result.height,\n url: result.url,\n metadata: result.metadata,\n };\n // Respect mode: array vs single. For these single-image widgets we\n // always emit a single object; array-mode widgets (Grid) use their\n // own append logic.\n onChange?.(field.mode === \"array\" ? [next] : next);\n } catch (err) {\n if (err instanceof UploadError && err.code === \"ABORTED\") {\n // User-initiated cancel — already handled in handleCancel.\n return;\n }\n const e = err instanceof UploadError\n ? { code: err.code, message: err.message }\n : { code: \"UNKNOWN\", message: err instanceof Error ? err.message : \"Upload failed\" };\n setError(e);\n setStatus(\"error\");\n setProgress(null);\n }\n }, [\n field.accepts,\n field.max_size_bytes,\n field.display?.crop_on_upload,\n field.display?.aspect_ratio,\n field.mode,\n fieldName,\n onChange,\n props.entityCode,\n register,\n isDraft,\n file,\n unregister,\n uploadFieldCode,\n uploadSlotCode,\n ]);\n\n const handleCancel = useCallback(() => {\n if (status === \"uploading\" && abortRef.current) {\n cancelledUploadRef.current = true;\n abortRef.current.abort();\n abortRef.current = null;\n setStatus(\"idle\");\n setProgress(null);\n }\n // Cancel mid-upload: if the server already created the row (e.g. body\n // streamed fully then we aborted reading the response), the GC sweep\n // catches the draft. We additionally fire discard if we have an id.\n if (pendingDraftId) {\n void discardFile(pendingDraftId).catch(() => {});\n unregister(pendingDraftId);\n setPendingDraftId(null);\n }\n }, [status, pendingDraftId, unregister]);\n\n const handleRemove = useCallback(() => {\n if (file && isDraft(file.id)) {\n void discardFile(file.id).catch(() => {});\n unregister(file.id);\n setPendingDraftId(null);\n }\n onChange?.(field.mode === \"array\" ? [] : null);\n }, [file, field.mode, isDraft, onChange, unregister]);\n\n const handleRetry = useCallback(() => {\n setError(null);\n setStatus(\"idle\");\n fileInputRef.current?.click();\n }, []);\n\n const onPick = useCallback(() => {\n if (disabled) return;\n fileInputRef.current?.click();\n }, [disabled]);\n\n const onKeyDown = useCallback((e: KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPick();\n }\n }, [disabled, onPick]);\n\n const onDragOver = useCallback((e: DragEvent<HTMLDivElement>) => {\n if (disabled) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"copy\";\n }, [disabled]);\n\n const onDrop = useCallback((e: DragEvent<HTMLDivElement>) => {\n if (disabled) return;\n e.preventDefault();\n const f = e.dataTransfer.files?.[0];\n if (f) void startUpload(f);\n }, [disabled, startUpload]);\n\n const onChangeFile = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const f = e.target.files?.[0];\n // Reset value so picking the same file twice still triggers change.\n e.target.value = \"\";\n if (f) void startUpload(f);\n }, [startUpload]);\n\n const aspect = visual.aspectRatio ?? defaultAspect(visual.shape, field.display?.aspect_ratio);\n const focalPoint = readFocalPoint(file);\n const containerStyle: CSSProperties = {\n aspectRatio: aspect,\n width: visual.width ?? (visual.shape === \"wide\" ? \"100%\" : \"120px\"),\n };\n\n const isPreview = !!file;\n // In normal cookie mode `previewUrl` is the static thumbnail URL and\n // `useEmbedFileSrc` returns it unchanged. In Bearer-only embed mode the hook\n // resolves the same thumbnail through the embed file URL endpoint and yields\n // a presigned or `blob:` URL a native `<img>` can load without a header.\n const staticPreview = previewUrl(file, field.display?.listable_thumbnail);\n const previewVariant = preferredThumbnailVariant(file, field.display?.listable_thumbnail);\n const preview = useEmbedFileSrc(file?.id, previewVariant, staticPreview);\n const displayMode = mode === \"display\";\n const handleSetFocalPoint = useCallback((e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n setIsEditingFocalPoint((value) => !value);\n }, []);\n\n const handlePickFocalPoint = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n if (!file || !isEditingFocalPoint) return;\n const rect = e.currentTarget.getBoundingClientRect();\n const x = rect.width > 0 ? (e.clientX - rect.left) / rect.width : 0.5;\n const y = rect.height > 0 ? (e.clientY - rect.top) / rect.height : 0.5;\n const next = withFocalPoint(file, {\n x: Math.max(0, Math.min(1, x)),\n y: Math.max(0, Math.min(1, y)),\n });\n onChange?.(field.mode === \"array\" ? [next] : next);\n setIsEditingFocalPoint(false);\n }, [field.mode, file, isEditingFocalPoint, onChange]);\n\n // Display mode is read-only: just the image (or placeholder). No drop zone,\n // no controls. Used when a record is rendered in a list cell.\n if (displayMode) {\n return (\n <div\n className={containerClass(visual.shape, false)}\n style={containerStyle}\n aria-label={ariaLabel}\n >\n {isPreview && preview ? (\n <img\n src={preview}\n alt={ariaLabel}\n className={imgClass(visual.shape)}\n style={{ objectPosition: focalPointObjectPosition(focalPoint) }}\n loading=\"lazy\"\n />\n ) : (\n <Placeholder shape={visual.shape} label={ariaLabel} placeholder={field.display?.placeholder} />\n )}\n </div>\n );\n }\n\n return (\n <div\n className={containerClass(visual.shape, !disabled)}\n style={containerStyle}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-label={ariaLabel}\n aria-disabled={disabled || undefined}\n aria-busy={status === \"uploading\" || undefined}\n aria-invalid={status === \"error\" || undefined}\n onClick={status === \"idle\" && !isPreview ? onPick : undefined}\n onMouseDown={isEditingFocalPoint ? handlePickFocalPoint : undefined}\n onKeyDown={onKeyDown}\n onDragOver={onDragOver}\n onDrop={onDrop}\n data-testid={isEditingFocalPoint ? \"focal-point-target\" : `file-widget-${fieldName}`}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n onChange={onChangeFile}\n style={{ display: \"none\" }}\n data-testid={`file-input-${fieldName}`}\n />\n\n {isPreview && preview ? (\n <img\n src={preview}\n alt={ariaLabel}\n className={imgClass(visual.shape)}\n style={{ objectPosition: focalPointObjectPosition(focalPoint) }}\n loading=\"lazy\"\n />\n ) : status !== \"uploading\" ? (\n <Placeholder shape={visual.shape} label={ariaLabel} placeholder={field.display?.placeholder} />\n ) : null}\n\n {status === \"uploading\" && (\n <ProgressRing pct={progress?.pct ?? 0} />\n )}\n\n {/* Pending-draft amber dot indicator. Visible until parent form\n markCommitted() the draft; hosts that don't use FileDraftScope\n still see the indicator while the widget owns a fresh draft. */}\n {pendingDraftId && (\n <span\n className=\"absolute right-1 top-1 h-2 w-2 rounded-full bg-warning\"\n aria-hidden=\"true\"\n data-testid=\"draft-indicator\"\n />\n )}\n\n {/* Hover overlay (Change / Remove) when populated. Click events\n stopPropagate so they don't trigger the picker open on the root. */}\n {isPreview && status === \"idle\" && !disabled && (\n <div className=\"absolute inset-0 flex items-center justify-center gap-2 bg-black/40 opacity-0 transition-opacity hover:opacity-100 focus-within:opacity-100\">\n {field.display?.focal_point && (\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={handleSetFocalPoint}\n data-testid=\"focal-point-toggle\"\n >\n {isEditingFocalPoint ? \"Cancel focus\" : \"Set focus\"}\n </button>\n )}\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={(e) => { e.stopPropagation(); onPick(); }}\n >\n Change\n </button>\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-destructive hover:bg-surface-2\"\n onClick={(e) => { e.stopPropagation(); handleRemove(); }}\n >\n Remove\n </button>\n </div>\n )}\n\n {focalPoint && isPreview && (\n <span\n className=\"absolute h-3 w-3 -translate-x-1/2 -translate-y-1/2 rounded-full border border-white bg-black/70\"\n style={{ left: `${focalPoint.x * 100}%`, top: `${focalPoint.y * 100}%` }}\n data-testid=\"focal-point-marker\"\n />\n )}\n\n {/* Cancel button while uploading. Sits as an overlay button. */}\n {status === \"uploading\" && (\n <button\n type=\"button\"\n className=\"absolute bottom-1 right-1 rounded-sm border border-border bg-card px-2 py-0.5 text-xs\"\n onClick={(e) => { e.stopPropagation(); handleCancel(); }}\n data-testid=\"cancel-upload\"\n >\n Cancel\n </button>\n )}\n\n {/* Error state. Shows message + Retry; the container also gets a\n destructive border via the error class above. */}\n {status === \"error\" && error && (\n <div\n className=\"absolute inset-x-0 bottom-0 flex items-center justify-between gap-2 bg-destructive-soft px-2 py-1 text-xs text-destructive\"\n role=\"alert\"\n >\n <span className=\"truncate\" title={error.message}>{error.message}</span>\n <button\n type=\"button\"\n className=\"underline\"\n onClick={(e) => { e.stopPropagation(); handleRetry(); }}\n data-testid=\"retry-upload\"\n >\n Retry\n </button>\n </div>\n )}\n </div>\n );\n}\n\nfunction containerClass(shape: ImageWidgetVisualConfig[\"shape\"], interactive: boolean): string {\n // Tailwind classes use semantic tokens (no hardcoded colors) per project\n // theming rules in CLAUDE.md. The container is positioned for overlay\n // children (progress ring, hover toolbar, error banner).\n const base = \"relative overflow-hidden border border-border bg-surface-2\";\n const shapeClass =\n shape === \"circle\" ? \"rounded-full\" :\n shape === \"wide\" ? \"rounded-md\" :\n \"rounded-md\";\n const interactiveClass = interactive\n ? \"cursor-pointer focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent\"\n : \"\";\n return [base, shapeClass, interactiveClass].filter(Boolean).join(\" \");\n}\n\nfunction imgClass(shape: ImageWidgetVisualConfig[\"shape\"]): string {\n // Cover the entire container so square/circle crops are visually clean.\n // Wide banners also use cover so the focal point stays centered.\n return shape === \"circle\"\n ? \"h-full w-full object-cover\"\n : \"h-full w-full object-cover\";\n}\n\nfunction defaultAspect(shape: ImageWidgetVisualConfig[\"shape\"], explicit?: string): string {\n if (explicit) return explicit.replace(\":\", \" / \");\n if (shape === \"wide\") return \"16 / 9\";\n return \"1 / 1\";\n}\n\nfunction parseAspect(value: string | undefined): number | undefined {\n if (!value) return undefined;\n const cleaned = value.replace(/\\s/g, \"\");\n const m = cleaned.match(/^(\\d+(?:\\.\\d+)?)[:/](\\d+(?:\\.\\d+)?)$/);\n if (!m) return undefined;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (!a || !b) return undefined;\n return a / b;\n}\n\nfunction Placeholder({\n shape,\n label,\n placeholder,\n}: {\n shape: ImageWidgetVisualConfig[\"shape\"];\n label: string;\n placeholder?: string;\n}) {\n if (placeholder === \"initials\") {\n return (\n <div className=\"flex h-full w-full items-center justify-center bg-surface-3 text-text-3\">\n <span className={shape === \"circle\" ? \"text-lg font-medium\" : \"text-base font-medium\"}>\n {initialsFromAlt(label)}\n </span>\n </div>\n );\n }\n return (\n <div className=\"flex h-full w-full items-center justify-center bg-surface-3 text-text-4\">\n <span className=\"text-xs\">{shape === \"wide\" ? \"Drop image here\" : \"+\"}</span>\n </div>\n );\n}\n\nfunction ProgressRing({ pct }: { pct: number }) {\n const radius = 18;\n const circumference = 2 * Math.PI * radius;\n const offset = circumference - (Math.max(0, Math.min(100, pct)) / 100) * circumference;\n return (\n <div\n className=\"absolute inset-0 flex items-center justify-center bg-black/30\"\n data-testid=\"upload-progress\"\n aria-label={`Uploading ${Math.round(pct)}%`}\n role=\"progressbar\"\n aria-valuenow={Math.round(pct)}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <svg width=\"48\" height=\"48\" viewBox=\"0 0 48 48\">\n <circle\n cx=\"24\"\n cy=\"24\"\n r={radius}\n stroke=\"currentColor\"\n strokeOpacity=\"0.25\"\n strokeWidth=\"4\"\n fill=\"none\"\n className=\"text-foreground\"\n />\n <circle\n cx=\"24\"\n cy=\"24\"\n r={radius}\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n fill=\"none\"\n strokeDasharray={circumference}\n strokeDashoffset={offset}\n strokeLinecap=\"round\"\n className=\"text-accent\"\n transform=\"rotate(-90 24 24)\"\n />\n </svg>\n <span className=\"absolute text-xs text-foreground\">{Math.round(pct)}%</span>\n </div>\n );\n}\n\n// Format helpers re-exported for tests + storybook-style consumers.\nexport { formatBytes };\n","import { ImageWidget } from \"./ImageWidget\";\nimport type { FileWidgetProps } from \"./types\";\n\n// SquareImage: 1:1 image upload widget. Use cases: contact avatars (admin\n// view), product square thumbnails, badge artwork. Per einstein §6.1.\n//\n// Behaviors (inherited from ImageWidget):\n// - empty placeholder (text or initials)\n// - hover overlay with Change/Remove\n// - drag-drop upload\n// - progress ring while in flight\n// - error border + Retry on failure\n// - amber dot when a draft is pending\nexport function SquareImage(props: FileWidgetProps) {\n return <ImageWidget {...props} visual={{ shape: \"square\" }} />;\n}\n","import { ImageWidget } from \"./ImageWidget\";\nimport type { FileWidgetProps } from \"./types\";\n\n// CircleImage: avatar variant of SquareImage with a circular CSS clip.\n// Used for user avatars, contact profile photos. Per einstein §6.2.\nexport function CircleImage(props: FileWidgetProps) {\n return <ImageWidget {...props} visual={{ shape: \"circle\" }} />;\n}\n","import { ImageWidget } from \"./ImageWidget\";\nimport type { FileWidgetProps } from \"./types\";\n\n// WideBanner: aspect-ratio rectangle for hero/banner imagery. Defaults to\n// 16:9 but the field's `display.aspect_ratio` overrides. Per einstein §6.3.\n//\n// `focal_point` is parsed and stored upstream; Wave-1 widget honors it as a\n// CSS object-position only when explicitly populated in metadata. The\n// in-widget focal-point picker UI is deferred to Wave 2 (skipping the\n// crosshair overlay keeps the Wave-1 surface narrow).\nexport function WideBanner(props: FileWidgetProps) {\n return <ImageWidget {...props} visual={{ shape: \"wide\" }} />;\n}\n","// GridLazy: the eager entry point for the `grid` file widget. The real Grid\n// pulls @dnd-kit (drag-to-reorder). Loading it lazily keeps @dnd-kit in its\n// own chunk, out of the eager SDK bundle. builtins.ts registers THIS wrapper,\n// and the file-widgets barrel re-exports it as `Grid`, so there is no static\n// import path to the heavy module.\nimport { lazy, Suspense } from \"react\";\nimport type { FileWidgetProps } from \"./types\";\n\nconst LazyGrid = lazy(() => import(\"./Grid\").then((m) => ({ default: m.Grid })));\n\nfunction GridFallback() {\n return <div className=\"h-24 w-full rounded-md bg-muted animate-pulse\" />;\n}\n\nexport function GridLazy(props: FileWidgetProps) {\n return (\n <Suspense fallback={<GridFallback />}>\n <LazyGrid {...props} />\n </Suspense>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n uploadFile,\n discardFile,\n validateClientSide,\n formatBytes,\n UploadError,\n} from \"./upload\";\nimport { useDraftRegistration } from \"./draft-scope\";\nimport { canPreviewFile, downloadFileURL, previewFileURL } from \"./helpers\";\nimport { useEmbedFileOpener } from \"./useEmbedFileSrc\";\nimport { singleFileFromValue } from \"./value\";\nimport type {\n FileWidgetProps,\n HydratedFile,\n UploadProgress,\n} from \"./types\";\n\n// DocumentCard widget: a single-file card for documents (PDF, DOCX, XLSX).\n// Per einstein §6.5.\n//\n// Layout: thumbnail (or generic file icon), filename (inline-editable),\n// size + upload metadata, action buttons (Download / Preview / Replace /\n// Remove). Wave-1 preview opens the file in a new tab; Wave-2 swaps in\n// pdf.js inline viewer.\n\ntype Status = \"idle\" | \"uploading\" | \"error\";\n\nfunction FileIcon({ contentType }: { contentType?: string }) {\n // Compact text-based file glyph keyed off the content type. Avoids pulling\n // in an SVG icon library; consumer apps that want richer icons swap the\n // widget out via registerFileWidget.\n const label = (() => {\n if (!contentType) return \"FILE\";\n if (contentType.includes(\"pdf\")) return \"PDF\";\n if (contentType.includes(\"word\")) return \"DOC\";\n if (contentType.includes(\"sheet\") || contentType.includes(\"excel\")) return \"XLS\";\n if (contentType.startsWith(\"image/\")) return \"IMG\";\n return contentType.split(\"/\")[1]?.slice(0, 4).toUpperCase() ?? \"FILE\";\n })();\n return (\n <div className=\"flex h-16 w-16 flex-none items-center justify-center rounded-md border border-border bg-surface-3 text-xs font-medium text-muted-foreground\">\n {label}\n </div>\n );\n}\n\nexport function DocumentCard(props: FileWidgetProps) {\n const { field, fieldName, value, onChange, mode, disabled, uploadFieldCode, uploadSlotCode } = props;\n const file = singleFileFromValue(value);\n const [status, setStatus] = useState<Status>(\"idle\");\n const [progress, setProgress] = useState<UploadProgress | null>(null);\n const [error, setError] = useState<{ code: string; message: string } | null>(\n null,\n );\n const [editingName, setEditingName] = useState(false);\n const [draftName, setDraftName] = useState(file?.filename ?? \"\");\n const abortRef = useRef<AbortController | null>(null);\n const cancelledUploadRef = useRef(false);\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n const { register, unregister, isDraft } = useDraftRegistration();\n // Cookie mode: opens the static URL directly. Embed mode: resolves the file\n // through the Bearer-authenticated endpoint first, then opens the presigned\n // or `blob:` URL - `window.open` cannot attach an `Authorization` header.\n const { open: openEmbedFile } = useEmbedFileOpener();\n\n useEffect(() => {\n return () => {\n if (abortRef.current) abortRef.current.abort();\n };\n }, []);\n\n useEffect(() => {\n setDraftName(file?.filename ?? \"\");\n }, [file?.filename]);\n\n const accept = (field.accepts ?? []).join(\",\");\n\n const startUpload = useCallback(\n async (raw: File) => {\n const v = validateClientSide(raw, field.accepts, field.max_size_bytes);\n if (v) {\n setError(v);\n setStatus(\"error\");\n return;\n }\n setError(null);\n cancelledUploadRef.current = false;\n setStatus(\"uploading\");\n setProgress({ loaded: 0, total: raw.size, pct: 0 });\n const ctrl = new AbortController();\n abortRef.current = ctrl;\n try {\n const result = await uploadFile({\n file: raw,\n entityCode: props.entityCode,\n fieldCode: uploadFieldCode ?? fieldName,\n slotCode: uploadSlotCode,\n signal: ctrl.signal,\n onProgress: setProgress,\n });\n if (cancelledUploadRef.current) {\n void discardFile(result.id).catch(() => {});\n unregister(result.id);\n return;\n }\n if (file && isDraft(file.id)) {\n void discardFile(file.id).catch(() => {});\n unregister(file.id);\n }\n register(result.id, () => discardFile(result.id));\n setStatus(\"idle\");\n setProgress(null);\n const next: HydratedFile = {\n id: result.id,\n filename: result.filename,\n content_type: result.content_type,\n size_bytes: result.size_bytes,\n sha256: result.sha256,\n width: result.width,\n height: result.height,\n url: result.url,\n metadata: result.metadata,\n };\n onChange?.(field.mode === \"array\" ? [next] : next);\n } catch (err) {\n if (err instanceof UploadError && err.code === \"ABORTED\") return;\n const e =\n err instanceof UploadError\n ? { code: err.code, message: err.message }\n : {\n code: \"UNKNOWN\",\n message: err instanceof Error ? err.message : \"Upload failed\",\n };\n setError(e);\n setStatus(\"error\");\n setProgress(null);\n }\n },\n [field.accepts, field.max_size_bytes, field.mode, fieldName, file, isDraft, onChange, props.entityCode, register, unregister, uploadFieldCode, uploadSlotCode],\n );\n\n const onPick = useCallback(() => {\n if (disabled) return;\n fileInputRef.current?.click();\n }, [disabled]);\n\n const onChangeFile = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const f = e.target.files?.[0];\n e.target.value = \"\";\n if (f) void startUpload(f);\n },\n [startUpload],\n );\n\n const handleRemove = useCallback(() => {\n if (file && isDraft(file.id)) {\n void discardFile(file.id).catch(() => {});\n unregister(file.id);\n }\n onChange?.(field.mode === \"array\" ? [] : null);\n }, [file, field.mode, isDraft, onChange, unregister]);\n\n const handleCancel = useCallback(() => {\n if (status === \"uploading\" && abortRef.current) {\n cancelledUploadRef.current = true;\n abortRef.current.abort();\n abortRef.current = null;\n setStatus(\"idle\");\n setProgress(null);\n }\n }, [status]);\n\n const handleDownload = useCallback(() => {\n if (!file) return;\n openEmbedFile(file.id, \"download\", downloadFileURL(file));\n }, [file, openEmbedFile]);\n\n const previewAllowed = file ? canPreviewFile(file) : false;\n const handlePreview = useCallback(() => {\n if (!file || !canPreviewFile(file)) return;\n openEmbedFile(file.id, \"preview\", previewFileURL(file));\n }, [file, openEmbedFile]);\n\n const commitFilename = useCallback(() => {\n if (!file) {\n setEditingName(false);\n return;\n }\n const trimmed = draftName.trim();\n setEditingName(false);\n if (!trimmed || trimmed === file.filename) {\n setDraftName(file.filename);\n return;\n }\n const next = { ...file, filename: trimmed };\n onChange?.(field.mode === \"array\" ? [next] : next);\n }, [draftName, file, onChange, field.mode]);\n\n const isDisplay = mode === \"display\";\n\n // Empty state: show a click/drop-to-upload card.\n if (!file && status !== \"uploading\") {\n return (\n <div\n data-testid={`file-widget-${fieldName}`}\n className=\"flex items-center gap-3 rounded-md border border-dashed border-border bg-surface p-3\"\n >\n <FileIcon />\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-sm text-foreground\">\n {field.display?.placeholder || \"No document attached\"}\n </span>\n {!isDisplay && (\n <button\n type=\"button\"\n className=\"self-start rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={onPick}\n disabled={disabled}\n data-testid=\"upload\"\n >\n Upload\n </button>\n )}\n </div>\n {!isDisplay && (\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept || undefined}\n onChange={onChangeFile}\n style={{ display: \"none\" }}\n data-testid={`file-input-${fieldName}`}\n />\n )}\n {status === \"error\" && error && (\n <div className=\"ml-auto text-xs text-destructive\" role=\"alert\">\n {error.message}\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div\n data-testid={`file-widget-${fieldName}`}\n className=\"flex items-center gap-3 rounded-md border border-border bg-surface p-3\"\n aria-busy={status === \"uploading\" || undefined}\n aria-invalid={status === \"error\" || undefined}\n >\n <FileIcon contentType={file?.content_type} />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n {editingName && file ? (\n <input\n type=\"text\"\n className=\"rounded-sm border border-border bg-card px-1 py-0.5 text-sm text-foreground\"\n value={draftName}\n autoFocus\n onChange={(e) => setDraftName(e.target.value)}\n onBlur={commitFilename}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commitFilename();\n else if (e.key === \"Escape\") {\n setEditingName(false);\n setDraftName(file.filename);\n }\n }}\n data-testid=\"filename-input\"\n />\n ) : (\n <button\n type=\"button\"\n className=\"truncate text-left text-sm font-medium text-foreground hover:underline\"\n onClick={() => !isDisplay && file && setEditingName(true)}\n disabled={isDisplay || disabled || !file}\n title={file?.filename}\n data-testid=\"filename\"\n >\n {file?.filename ?? \"Uploading…\"}\n </button>\n )}\n <div className=\"flex flex-wrap gap-2 text-xs text-muted-foreground\">\n {file && <span>{formatBytes(file.size_bytes)}</span>}\n {file?.page_count != null && <span>{file.page_count} pages</span>}\n {file?.uploaded_at && <span>{formatDate(file.uploaded_at)}</span>}\n {file?.uploaded_by && <span>by {file.uploaded_by}</span>}\n {file?.version?.number != null && (\n <span data-testid=\"version-badge\">v{file.version.number}</span>\n )}\n </div>\n {status === \"uploading\" && (\n <div\n className=\"text-xs text-muted-foreground\"\n role=\"progressbar\"\n aria-valuenow={progress?.pct ?? 0}\n aria-valuemin={0}\n aria-valuemax={100}\n data-testid=\"upload-progress\"\n >\n Uploading {progress?.pct ?? 0}%\n </div>\n )}\n {status === \"error\" && error && (\n <div className=\"text-xs text-destructive\" role=\"alert\">\n {error.message}\n </div>\n )}\n </div>\n <div className=\"flex flex-none items-center gap-1\">\n {file && status !== \"uploading\" && (\n <>\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={handleDownload}\n data-testid=\"download\"\n >\n Download\n </button>\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2 disabled:cursor-not-allowed disabled:opacity-50\"\n onClick={handlePreview}\n disabled={!previewAllowed}\n title={previewAllowed ? undefined : \"Preview is available only for images and PDFs\"}\n data-testid=\"preview\"\n >\n Preview\n </button>\n {!isDisplay && (\n <>\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={onPick}\n disabled={disabled}\n data-testid=\"replace\"\n >\n Replace\n </button>\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-destructive hover:bg-surface-2\"\n onClick={handleRemove}\n disabled={disabled}\n data-testid=\"remove\"\n >\n Remove\n </button>\n </>\n )}\n </>\n )}\n {status === \"uploading\" && (\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs\"\n onClick={handleCancel}\n data-testid=\"cancel-upload\"\n >\n Cancel\n </button>\n )}\n </div>\n {!isDisplay && (\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept || undefined}\n onChange={onChangeFile}\n style={{ display: \"none\" }}\n data-testid={`file-input-${fieldName}`}\n />\n )}\n </div>\n );\n}\n\nfunction formatDate(iso: string): string {\n const d = new Date(iso);\n if (isNaN(d.getTime())) return iso;\n return d.toISOString().slice(0, 10);\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n uploadFile,\n discardFile,\n validateClientSide,\n formatBytes,\n UploadError,\n} from \"./upload\";\nimport { useDraftRegistration } from \"./draft-scope\";\nimport { downloadFileURL } from \"./helpers\";\nimport { useEmbedFileOpener } from \"./useEmbedFileSrc\";\nimport { fileArrayFromValue } from \"./value\";\nimport type {\n FileWidgetProps,\n HydratedFile,\n UploadProgress,\n} from \"./types\";\n\n// FileList widget: vertical list of files with per-row actions. Per einstein\n// §6.6. No thumbnails (use the Grid widget for image galleries). Each row\n// shows a small file-type label, the filename, size + content type, and the\n// Download / Remove actions.\n\ninterface InFlight {\n localId: string;\n filename: string;\n progress: UploadProgress | null;\n error: { code: string; message: string } | null;\n abort: () => void;\n}\n\nfunction shortType(ct: string): string {\n if (!ct) return \"\";\n const after = ct.split(\"/\")[1] ?? ct;\n return after.toUpperCase().slice(0, 6);\n}\n\nexport function FileList(props: FileWidgetProps) {\n const { field, fieldName, value, onChange, mode, disabled } = props;\n const items = fileArrayFromValue(value);\n const [tiles, setTiles] = useState<InFlight[]>([]);\n const { register, unregister, isDraft } = useDraftRegistration();\n const valueRef = useRef<HydratedFile[]>(items);\n valueRef.current = items;\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n const cancelledUploadsRef = useRef<Set<string>>(new Set());\n const tilesRef = useRef<InFlight[]>([]);\n tilesRef.current = tiles;\n // Cookie mode: opens the static download URL directly. Embed mode: resolves\n // the file through the Bearer-authenticated endpoint first, then opens the\n // presigned or `blob:` URL (`window.open` cannot send an auth header).\n const { open: openEmbedFile } = useEmbedFileOpener();\n\n useEffect(() => {\n return () => {\n tilesRef.current.forEach((t) => t.abort());\n };\n }, []);\n\n const accept = (field.accepts ?? []).join(\",\");\n const isDisplay = mode === \"display\";\n\n const startUpload = useCallback(\n async (raw: File) => {\n const v = validateClientSide(raw, field.accepts, field.max_size_bytes);\n const localId = `row-${Math.random().toString(36).slice(2)}-${Date.now()}`;\n const ctrl = new AbortController();\n if (v) {\n setTiles((prev) => [\n ...prev,\n {\n localId,\n filename: raw.name,\n progress: null,\n error: v,\n abort: () => {},\n },\n ]);\n return;\n }\n setTiles((prev) => [\n ...prev,\n {\n localId,\n filename: raw.name,\n progress: { loaded: 0, total: raw.size, pct: 0 },\n error: null,\n abort: () => ctrl.abort(),\n },\n ]);\n try {\n const result = await uploadFile({\n file: raw,\n entityCode: props.entityCode,\n fieldCode: fieldName,\n signal: ctrl.signal,\n onProgress: (p) =>\n setTiles((prev) =>\n prev.map((t) =>\n t.localId === localId ? { ...t, progress: p } : t,\n ),\n ),\n });\n if (cancelledUploadsRef.current.delete(localId)) {\n void discardFile(result.id).catch(() => {});\n unregister(result.id);\n return;\n }\n register(result.id, () => discardFile(result.id));\n const next: HydratedFile = {\n id: result.id,\n filename: result.filename,\n content_type: result.content_type,\n size_bytes: result.size_bytes,\n sha256: result.sha256,\n width: result.width,\n height: result.height,\n url: result.url,\n metadata: result.metadata,\n };\n const merged = [...valueRef.current, next];\n valueRef.current = merged;\n onChange?.(merged);\n setTiles((prev) => prev.filter((t) => t.localId !== localId));\n } catch (err) {\n if (err instanceof UploadError && err.code === \"ABORTED\") {\n setTiles((prev) => prev.filter((t) => t.localId !== localId));\n return;\n }\n const e =\n err instanceof UploadError\n ? { code: err.code, message: err.message }\n : {\n code: \"UNKNOWN\",\n message: err instanceof Error ? err.message : \"Upload failed\",\n };\n setTiles((prev) =>\n prev.map((t) =>\n t.localId === localId\n ? { ...t, error: e, progress: null, abort: () => {} }\n : t,\n ),\n );\n }\n },\n [field.accepts, field.max_size_bytes, fieldName, onChange, props.entityCode, register, unregister],\n );\n\n const handleFiles = useCallback(\n (files: FileList | File[]) => {\n Array.from(files).forEach((f) => void startUpload(f));\n },\n [startUpload],\n );\n\n const onPick = useCallback(() => {\n if (disabled) return;\n fileInputRef.current?.click();\n }, [disabled]);\n\n const onChangeFile = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files;\n e.target.value = \"\";\n if (files && files.length > 0) handleFiles(files);\n },\n [handleFiles],\n );\n\n const handleRemove = useCallback(\n (id: string) => {\n if (isDraft(id)) {\n void discardFile(id).catch(() => {});\n unregister(id);\n }\n onChange?.(items.filter((f) => f.id !== id));\n },\n [isDraft, items, onChange, unregister],\n );\n\n const handleDownload = useCallback(\n (f: HydratedFile) => {\n openEmbedFile(f.id, \"download\", downloadFileURL(f));\n },\n [openEmbedFile],\n );\n\n return (\n <div\n data-testid={`file-widget-${fieldName}`}\n className=\"flex flex-col gap-2\"\n >\n <ul className=\"flex flex-col divide-y divide-divider rounded-md border border-border bg-surface\">\n {items.length === 0 && tiles.length === 0 && (\n <li className=\"px-3 py-4 text-center text-sm text-muted-foreground\">\n {field.display?.placeholder || \"No files\"}\n </li>\n )}\n {items.map((f) => (\n <li\n key={f.id}\n className=\"flex items-center gap-3 px-3 py-2\"\n data-testid={`row-${f.id}`}\n >\n <span className=\"flex-none rounded-sm border border-border bg-surface-3 px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n {shortType(f.content_type)}\n </span>\n <button\n type=\"button\"\n onClick={() => handleDownload(f)}\n className=\"min-w-0 flex-1 truncate text-left text-sm text-foreground hover:underline\"\n title={f.filename}\n >\n {f.filename}\n </button>\n <span className=\"flex-none text-xs text-muted-foreground\">\n {formatBytes(f.size_bytes)}\n </span>\n <button\n type=\"button\"\n className=\"flex-none rounded-sm border border-border bg-card px-2 py-0.5 text-xs text-foreground hover:bg-surface-2\"\n onClick={() => handleDownload(f)}\n data-testid={`download-${f.id}`}\n >\n Download\n </button>\n {!isDisplay && (\n <button\n type=\"button\"\n className=\"flex-none rounded-sm border border-border bg-card px-2 py-0.5 text-xs text-destructive hover:bg-surface-2\"\n onClick={() => handleRemove(f.id)}\n disabled={disabled}\n data-testid={`remove-${f.id}`}\n >\n Remove\n </button>\n )}\n </li>\n ))}\n {tiles.map((t) => (\n <li\n key={t.localId}\n className=\"flex items-center gap-3 px-3 py-2\"\n data-testid={`pending-row-${t.localId}`}\n aria-busy={!t.error}\n aria-invalid={!!t.error || undefined}\n >\n <span className=\"flex-none truncate text-sm text-foreground\" title={t.filename}>\n {t.filename}\n </span>\n <span className=\"flex-1\" />\n {t.error ? (\n <span role=\"alert\" className=\"text-xs text-destructive\">\n {t.error.message}\n </span>\n ) : (\n <span\n className=\"text-xs text-muted-foreground\"\n role=\"progressbar\"\n aria-valuenow={t.progress?.pct ?? 0}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n {t.progress?.pct ?? 0}%\n </span>\n )}\n <button\n type=\"button\"\n className=\"flex-none rounded-sm border border-border bg-card px-2 py-0.5 text-xs\"\n onClick={() => {\n t.abort();\n cancelledUploadsRef.current.add(t.localId);\n setTiles((prev) =>\n prev.filter((x) => x.localId !== t.localId),\n );\n }}\n >\n {t.error ? \"Dismiss\" : \"Cancel\"}\n </button>\n </li>\n ))}\n </ul>\n {!isDisplay && (\n <>\n <button\n type=\"button\"\n className=\"self-start rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={onPick}\n disabled={disabled}\n data-testid=\"add-files\"\n >\n Add files\n </button>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept || undefined}\n multiple\n onChange={onChangeFile}\n style={{ display: \"none\" }}\n data-testid={`file-input-${fieldName}`}\n />\n </>\n )}\n </div>\n );\n}\n","import type { FileNamedSlotDef, FileFieldDef, HydratedFile, NamedFileFieldValue } from \"@/types/files\";\nimport type { FileWidgetProps } from \"./types\";\nimport { getFileWidget } from \"./registry\";\n\nfunction asNamedMap(value: FileWidgetProps[\"value\"]): NamedFileFieldValue {\n if (!value || Array.isArray(value) || typeof value !== \"object\") return {};\n return value as NamedFileFieldValue;\n}\n\nfunction humanizeSlot(code: string): string {\n return code\n .split(\"_\")\n .filter(Boolean)\n .map((part) => part.slice(0, 1).toUpperCase() + part.slice(1))\n .join(\" \");\n}\n\nfunction slotLooksLikeImage(slot: FileNamedSlotDef | undefined, file: HydratedFile | null | undefined): boolean {\n if (file?.content_type?.startsWith(\"image/\")) return true;\n return (slot?.accepts ?? []).some((mime) => mime === \"image/*\" || mime.startsWith(\"image/\"));\n}\n\nfunction buildSlotField(field: FileFieldDef, slotCode: string, slot: FileNamedSlotDef | undefined, file: HydratedFile | null | undefined): FileFieldDef {\n return {\n ...field,\n name: `${field.name}.${slotCode}`,\n mode: \"single\",\n accepts: slot?.accepts ?? field.accepts,\n max_size_bytes: slot?.max_size_bytes ?? field.max_size_bytes,\n slots: undefined,\n display: {\n ...(field.display ?? { widget: \"document_card\" }),\n widget: slotLooksLikeImage(slot, file) ? \"square_image\" : \"document_card\",\n aspect_ratio: slot?.aspect_ratio ?? field.display?.aspect_ratio,\n placeholder: field.display?.placeholder ?? humanizeSlot(slotCode),\n },\n };\n}\n\nexport function LabeledSlots(props: FileWidgetProps) {\n const { field, fieldName, entityCode, value, onChange, mode, disabled } = props;\n const slots = Object.entries(field.slots ?? {});\n const values = asNamedMap(value);\n\n if (slots.length === 0) {\n return <span className=\"text-sm text-muted-foreground\">No slots configured</span>;\n }\n\n return (\n <div style={{ display: \"grid\", gap: 12 }}>\n {slots.map(([slotCode, slot]) => {\n const file = values[slotCode] ?? null;\n const slotField = buildSlotField(field, slotCode, slot, file);\n const widgetCode = slotField.display?.widget ?? \"document_card\";\n const Widget = getFileWidget(widgetCode);\n if (!Widget) {\n return (\n <div key={slotCode} style={{ display: \"grid\", gap: 6 }}>\n <div style={{ fontSize: 12, fontWeight: 600, color: \"var(--text-2)\" }}>{humanizeSlot(slotCode)}</div>\n <span className=\"text-sm text-muted-foreground\">{`Unknown file widget: ${widgetCode}`}</span>\n </div>\n );\n }\n return (\n <div key={slotCode} style={{ display: \"grid\", gap: 6 }}>\n <div style={{ fontSize: 12, fontWeight: 600, color: \"var(--text-2)\" }}>{humanizeSlot(slotCode)}</div>\n <Widget\n field={slotField}\n fieldName={slotCode}\n entityCode={entityCode}\n value={file}\n mode={mode}\n disabled={disabled}\n uploadFieldCode={fieldName}\n uploadSlotCode={slotCode}\n onChange={(next) => {\n if (!onChange) return;\n onChange({\n ...values,\n [slotCode]: (next as HydratedFile | null) ?? null,\n });\n }}\n />\n </div>\n );\n })}\n </div>\n );\n}\n","import { registerFileWidget } from \"./registry\";\nimport { SquareImage } from \"./SquareImage\";\nimport { CircleImage } from \"./CircleImage\";\nimport { WideBanner } from \"./WideBanner\";\nimport { GridLazy } from \"./GridLazy\";\nimport { DocumentCard } from \"./DocumentCard\";\nimport { FileList } from \"./FileList\";\nimport { LabeledSlots } from \"./LabeledSlots\";\n\nlet builtinsRegistered = false;\n\nexport function registerBuiltinFileWidgets(): void {\n if (builtinsRegistered) return;\n registerFileWidget(\"square_image\", SquareImage);\n registerFileWidget(\"circle_image\", CircleImage);\n registerFileWidget(\"wide_banner\", WideBanner);\n registerFileWidget(\"grid\", GridLazy);\n registerFileWidget(\"document_card\", DocumentCard);\n registerFileWidget(\"file_list\", FileList);\n registerFileWidget(\"labeled_slots\", LabeledSlots);\n builtinsRegistered = true;\n}\n","import type { ReactNode } from \"react\";\nimport { fieldDisplayName } from \"@/types/schema\";\nimport type { Entity, Screen } from \"@/types/schema\";\nimport type { FileFieldDef, FileFieldValue } from \"@/types/files\";\nimport { renderField } from \"@/components/fields\";\nimport type { RefsMap } from \"@/components/fields\";\nimport { createRichTextValue, richTextMarkdown } from \"@/lib/rich-text\";\nimport { getFileWidget } from \"./registry\";\nimport { registerBuiltinFileWidgets } from \"./builtins\";\n\nregisterBuiltinFileWidgets();\n\nexport function getEntityFileField(\n entity: Pick<Entity, \"files\">,\n fieldName: string,\n): FileFieldDef | undefined {\n return entity.files?.get(fieldName);\n}\n\nexport function getFileFieldValue(\n record: Record<string, unknown>,\n fieldName: string,\n): FileFieldValue {\n if (Object.prototype.hasOwnProperty.call(record, fieldName)) {\n return (record[fieldName] as FileFieldValue) ?? null;\n }\n const files = record.$files as Record<string, FileFieldValue> | undefined;\n return files?.[fieldName] ?? null;\n}\n\nexport function getSchemaFieldValue(\n entity: Pick<Entity, \"fields\" | \"files\">,\n record: Record<string, unknown>,\n fieldName: string,\n): unknown {\n const fileField = getEntityFileField(entity, fieldName);\n if (fileField) return getFileFieldValue(record, fieldName);\n const field = entity.fields.get(fieldName);\n if (field?.type === \"rich_text\" && field.files?.mode === \"rich_text_inline\") {\n return createRichTextValue(record[fieldName], getFileFieldValue(record, fieldName));\n }\n return record[fieldName];\n}\n\nexport function serializeSchemaFieldValue(\n entity: Pick<Entity, \"fields\" | \"files\">,\n fieldName: string,\n value: unknown,\n): unknown {\n const field = entity.fields.get(fieldName);\n if (field?.type === \"rich_text\" && field.files?.mode === \"rich_text_inline\") {\n return richTextMarkdown(value);\n }\n return value;\n}\n\nexport function resolveSchemaFieldLabel(\n entity: Pick<Entity, \"fields\" | \"files\">,\n fieldName: string,\n entities?: Record<string, Entity>,\n): string {\n const fileField = getEntityFileField(entity, fieldName);\n if (fileField) return fileField.name || fieldName;\n const field = entity.fields.get(fieldName);\n return field ? fieldDisplayName(field, fieldName, entities) : fieldName;\n}\n\nexport function renderSchemaField(props: {\n entity: Pick<Entity, \"fields\" | \"files\">;\n entityCode?: string;\n fieldName: string;\n record: Record<string, unknown>;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n refs?: RefsMap;\n disabled?: boolean;\n surface?: \"list\" | \"detail\";\n // 1a.5: schema lookups for the cell registry. Optional - when omitted, the\n // cell registry path falls back gracefully (status_pill loses status group\n // colors, ref_link loses its display label). Detail/QuickPeek pass these via\n // the FieldsBlock LayoutContext.schema. ref_link navigation is owned by the\n // global link interceptor, not threaded here.\n entities?: Record<string, Entity>;\n screens?: Record<string, Screen>;\n // locale: required per plan §3 contract; callers thread it via useUserLocale().\n locale: string;\n // Accessibility (Finding 2): a stable per-field id and the id of its label\n // element. Threaded to field renderers / file widgets so edit-mode inputs\n // pair with their <label>. Optional - omit for standalone display rendering.\n fieldId?: string;\n labelId?: string;\n}): ReactNode {\n const {\n entity,\n entityCode,\n fieldName,\n record,\n mode,\n onChange,\n refs,\n disabled,\n surface,\n entities,\n screens,\n locale,\n fieldId,\n labelId,\n } = props;\n const fileField = getEntityFileField(entity, fieldName);\n if (fileField) {\n const widgetCode = fileField.display?.widget ?? \"\";\n const Widget = getFileWidget(widgetCode);\n if (!Widget) {\n return (\n <span className=\"text-sm text-muted-foreground\">\n {widgetCode ? `Unknown file widget: ${widgetCode}` : \"Missing file widget\"}\n </span>\n );\n }\n return (\n <Widget\n field={fileField}\n fieldName={fieldName}\n entityCode={entityCode}\n value={getFileFieldValue(record, fieldName)}\n mode={mode}\n onChange={onChange}\n disabled={disabled}\n fieldId={fieldId}\n />\n );\n }\n const field = entity.fields.get(fieldName);\n if (!field) return null;\n return renderField({\n field,\n entityCode,\n fieldName,\n value: getSchemaFieldValue(entity, record, fieldName),\n mode,\n onChange,\n record,\n refs,\n surface,\n entity: entityCode && entities ? entities[entityCode] : undefined,\n entities,\n screens,\n locale,\n fieldId,\n labelId,\n });\n}\n","import type { Entity } from \"@/types/schema\";\nimport type { FileFieldDef, FileFieldValue, HydratedFile, NamedFileFieldValue } from \"@/types/files\";\nimport { extractDeclarionFileIds, richTextMarkdown } from \"@/lib/rich-text\";\nimport { getEntityFileField, getFileFieldValue, getSchemaFieldValue } from \"./host\";\n\nexport interface FileSetItem {\n file_id: string;\n filename?: string;\n slot?: string;\n position?: number;\n metadata?: Record<string, unknown>;\n}\n\nexport interface FileFieldPatch {\n clear?: true;\n set?: FileSetItem[];\n}\n\nfunction normalizedSingleValue(value: unknown): HydratedFile | null {\n if (!value || Array.isArray(value)) return null;\n return value as HydratedFile;\n}\n\nfunction normalizedArrayValue(value: unknown): HydratedFile[] {\n if (!Array.isArray(value)) return [];\n return value as HydratedFile[];\n}\n\nfunction normalizedNamedMapValue(value: unknown): NamedFileFieldValue {\n if (!value || Array.isArray(value) || typeof value !== \"object\") return {};\n return value as NamedFileFieldValue;\n}\n\nfunction normalizeFileValue(field: FileFieldDef, value: unknown): FileFieldValue {\n if (field.mode === \"array\") return normalizedArrayValue(value);\n if (field.mode === \"named_map\") return normalizedNamedMapValue(value);\n return normalizedSingleValue(value);\n}\n\nfunction toSetItem(file: HydratedFile, index: number, includePosition: boolean, slot?: string): FileSetItem {\n const item: FileSetItem = { file_id: file.id, filename: file.filename };\n if (slot) item.slot = slot;\n if (includePosition) item.position = index;\n if (file.metadata !== undefined) {\n item.metadata = file.metadata;\n }\n return item;\n}\n\nexport function buildFileFieldPatch(field: FileFieldDef, value: FileFieldValue): FileFieldPatch {\n if (field.mode === \"array\") {\n const files = normalizedArrayValue(value);\n if (files.length === 0) return { clear: true };\n return { set: files.map((file, index) => toSetItem(file, index, true)) };\n }\n if (field.mode === \"named_map\") {\n const slots = normalizedNamedMapValue(value);\n const set = Object.entries(slots)\n .filter(([, file]) => file != null)\n .map(([slot, file]) => toSetItem(file as HydratedFile, 0, false, slot));\n if (set.length === 0) return { clear: true };\n return { set };\n }\n const file = normalizedSingleValue(value);\n if (!file) return { clear: true };\n return { set: [toSetItem(file, 0, true)] };\n}\n\nfunction stablePatchKey(patch: FileFieldPatch): string {\n return JSON.stringify(patch);\n}\n\nexport function buildFilesPayload(opts: {\n entity: Pick<Entity, \"files\"> & Partial<Pick<Entity, \"fields\">>;\n formData: Record<string, unknown>;\n record: Record<string, unknown> | undefined;\n isNew: boolean;\n}): Record<string, FileFieldPatch> {\n const { entity, formData, record, isNew } = opts;\n const payload: Record<string, FileFieldPatch> = {};\n for (const fieldName of entity.files?.names() ?? []) {\n if (!Object.prototype.hasOwnProperty.call(formData, fieldName)) continue;\n const field = getEntityFileField(entity, fieldName);\n if (!field) continue;\n const nextValue = normalizeFileValue(field, formData[fieldName]);\n if (isNew) {\n const isEmpty = field.mode === \"array\"\n ? normalizedArrayValue(nextValue).length === 0\n : field.mode === \"named_map\"\n ? Object.values(normalizedNamedMapValue(nextValue)).every((file) => file == null)\n : normalizedSingleValue(nextValue) == null;\n if (isEmpty) continue;\n payload[fieldName] = buildFileFieldPatch(field, nextValue);\n continue;\n }\n const previousValue = normalizeFileValue(field, record ? getFileFieldValue(record, fieldName) : null);\n const nextPatch = buildFileFieldPatch(field, nextValue);\n const previousPatch = buildFileFieldPatch(field, previousValue);\n if (stablePatchKey(nextPatch) !== stablePatchKey(previousPatch)) {\n payload[fieldName] = nextPatch;\n }\n }\n const fields = entity.fields;\n if (!fields) return payload;\n for (const fieldName of fields.names()) {\n const field = fields.get(fieldName);\n const fileDef = field?.files;\n if (!fileDef || fileDef.mode !== \"rich_text_inline\") continue;\n if (!Object.prototype.hasOwnProperty.call(formData, fieldName)) continue;\n const nextPatch = buildRichTextInlinePatch(fileDef, formData[fieldName]);\n if (isNew) {\n if (nextPatch.clear) continue;\n payload[fieldName] = nextPatch;\n continue;\n }\n const previousPatch = buildRichTextInlinePatch(fileDef, record ? getSchemaFieldValue({ ...entity, fields }, record, fieldName) : null);\n if (stablePatchKey(nextPatch) !== stablePatchKey(previousPatch)) {\n payload[fieldName] = nextPatch;\n }\n }\n return payload;\n}\n\nexport function collectCommittedFileIds(payload: Record<string, FileFieldPatch>): string[] {\n const ids: string[] = [];\n for (const patch of Object.values(payload)) {\n for (const item of patch.set ?? []) ids.push(item.file_id);\n }\n return ids;\n}\n\nfunction buildRichTextInlinePatch(field: FileFieldDef, value: unknown): FileFieldPatch {\n if (field.mode !== \"rich_text_inline\") return { clear: true };\n const ids = extractDeclarionFileIds(richTextMarkdown(value));\n if (ids.length === 0) return { clear: true };\n return {\n set: ids.map((file_id, index) => ({ file_id, position: index })),\n };\n}\n","// Public barrel for the file-widget subsystem. Built-in widgets register\n// themselves into the registry on import (side-effect below); consumer\n// apps can override or add custom widgets via `registerFileWidget`.\n\nimport { registerBuiltinFileWidgets } from \"./builtins\";\n\nregisterBuiltinFileWidgets();\n\nexport { SquareImage } from \"./SquareImage\";\nexport { CircleImage } from \"./CircleImage\";\nexport { WideBanner } from \"./WideBanner\";\nexport { GridLazy as Grid } from \"./GridLazy\";\nexport { DocumentCard } from \"./DocumentCard\";\nexport { FileList } from \"./FileList\";\nexport { LabeledSlots } from \"./LabeledSlots\";\nexport {\n registerFileWidget,\n getFileWidget,\n hasFileWidget,\n __resetFileWidgetRegistryForTests,\n} from \"./registry\";\nexport {\n getEntityFileField,\n getFileFieldValue,\n getSchemaFieldValue,\n serializeSchemaFieldValue,\n resolveSchemaFieldLabel,\n renderSchemaField,\n} from \"./host\";\nexport {\n buildFileFieldPatch,\n buildFilesPayload,\n collectCommittedFileIds,\n} from \"./payload\";\nexport {\n uploadFile,\n discardFile,\n validateClientSide,\n formatBytes,\n UploadError,\n} from \"./upload\";\nexport {\n setImageCropper,\n getImageCropper,\n setCropperRenderer,\n getCropperRenderer,\n} from \"./cropper\";\nexport type {\n ImageCropper,\n CropperOptions,\n CropperResult,\n} from \"./cropper\";\nexport {\n FileDraftScope,\n useFileDraftScope,\n useDraftRegistration,\n} from \"./draft-scope\";\nexport type {\n FileDraftScopeApi,\n DraftEntry,\n} from \"./draft-scope\";\nexport type {\n FileFieldDef,\n FileFieldDisplay,\n FileFieldMode,\n FileWidget,\n FileWidgetProps,\n HydratedFile,\n UploadProgress,\n UploadedFile,\n} from \"./types\";\n","import { useMemo, useRef, useState } from \"react\";\nimport { Btn, Icon, Spinner, TextInput } from \"@/components/primitives\";\nimport { Markdown } from \"@/components/shared/Markdown\";\nimport type { HydratedFile, UploadedFile } from \"@/types/files\";\nimport {\n createRichTextValue,\n extractDeclarionFileIds,\n richTextTokenForFile,\n withoutRichTextFiles,\n withRichTextFile,\n} from \"@/lib/rich-text\";\nimport { discardFile, uploadFile, UploadError, validateClientSide } from \"@/components/file-widgets\";\nimport { useDraftRegistration } from \"@/components/file-widgets\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function RichTextField(props: FieldRendererProps) {\n const { field, entityCode, fieldName, value, mode, onChange, record, compact, fieldId } = props;\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const previewUrlsRef = useRef<Map<string, string>>(new Map());\n const draftIdsRef = useRef<Set<string>>(new Set());\n const [uploading, setUploading] = useState(0);\n const [error, setError] = useState<string | null>(null);\n const { register, unregister } = useDraftRegistration();\n\n const inlineFilesValue = (record?.$files as Record<string, unknown> | undefined)?.[fieldName];\n const rich = useMemo(\n () => createRichTextValue(value, inlineFilesValue),\n [inlineFilesValue, value],\n );\n const markdown = rich.markdown;\n const accepts = field.files?.accepts;\n const maxBytes = field.files?.max_size_bytes;\n\n const changeValue = (nextMarkdown: string, nextFiles = rich.files) => {\n const referenced = new Set(extractDeclarionFileIds(nextMarkdown));\n const removedDraftIds: string[] = [];\n for (const fileId of draftIdsRef.current) {\n if (!referenced.has(fileId)) removedDraftIds.push(fileId);\n }\n if (removedDraftIds.length > 0) {\n for (const fileId of removedDraftIds) {\n draftIdsRef.current.delete(fileId);\n unregister(fileId);\n void discardFile(fileId).catch(() => {});\n const preview = previewUrlsRef.current.get(fileId);\n if (preview) {\n URL.revokeObjectURL(preview);\n previewUrlsRef.current.delete(fileId);\n }\n }\n onChange?.(withoutRichTextFiles({ markdown: nextMarkdown, files: nextFiles }, removedDraftIds));\n return;\n }\n onChange?.({ markdown: nextMarkdown, files: nextFiles });\n };\n\n const insertToken = (base: { markdown: string; files: Record<string, HydratedFile> }, token: string, file?: HydratedFile) => {\n const el = textareaRef.current;\n const start = el?.selectionStart ?? base.markdown.length;\n const end = el?.selectionEnd ?? base.markdown.length;\n const nextMarkdown = `${base.markdown.slice(0, start)}${token}${base.markdown.slice(end)}`;\n const nextFiles = file ? withRichTextFile(base, file).files : base.files;\n changeValue(nextMarkdown, nextFiles);\n requestAnimationFrame(() => {\n if (!el) return;\n const nextPos = start + token.length;\n el.focus();\n el.setSelectionRange(nextPos, nextPos);\n });\n };\n\n const handleFiles = async (files: FileList | File[]) => {\n if (!entityCode || !field.files) return;\n const queue = Array.from(files);\n if (queue.length === 0) return;\n setError(null);\n setUploading((count) => count + queue.length);\n let current = { markdown, files: rich.files };\n for (const file of queue) {\n const validation = validateClientSide(file, accepts, maxBytes);\n if (validation) {\n setError(validation.message);\n setUploading((count) => count - 1);\n continue;\n }\n try {\n const uploaded = await uploadFile({ file, entityCode, fieldCode: fieldName });\n const previewUrl = file.type.startsWith(\"image/\") ? URL.createObjectURL(file) : undefined;\n if (previewUrl) previewUrlsRef.current.set(uploaded.id, previewUrl);\n const hydrated = uploadedFileToHydrated(uploaded, previewUrl);\n register(uploaded.id, () => discardFile(uploaded.id));\n draftIdsRef.current.add(uploaded.id);\n if (queue.length === 1) {\n const token = withLeadingSpacing(current.markdown, richTextTokenForFile(hydrated));\n insertToken(current, token, hydrated);\n current = withRichTextFile({\n markdown: `${current.markdown}${token}`,\n files: current.files,\n }, hydrated);\n } else {\n const token = withLeadingSpacing(current.markdown, richTextTokenForFile(hydrated));\n current = withRichTextFile({\n markdown: `${current.markdown}${token}`,\n files: current.files,\n }, hydrated);\n changeValue(current.markdown, current.files);\n }\n } catch (err) {\n setError(err instanceof UploadError ? err.message : \"Upload failed\");\n } finally {\n setUploading((count) => count - 1);\n }\n }\n };\n\n if (mode === \"display\") {\n if (!markdown) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n return <Markdown content={markdown} files={rich.files} />;\n }\n\n if (compact) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n value={markdown}\n onChange={(next) => changeValue(next)}\n />\n );\n }\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 10 }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, flexWrap: \"wrap\" }}>\n <Btn\n kind=\"ghost\"\n size=\"xs\"\n icon={uploading > 0 ? <Spinner size={12} /> : <Icon.plus size={12} />}\n onClick={() => inputRef.current?.click()}\n disabled={!entityCode || !field.files || uploading > 0}\n >\n {uploading > 0 ? \"Uploading…\" : \"Insert file\"}\n </Btn>\n <span style={{ fontSize: 11.5, color: \"var(--text-3)\" }}>\n Stores markdown with inline declarion://file/<id> refs.\n </span>\n {!entityCode && (\n <span style={{ fontSize: 11.5, color: \"var(--warn)\" }}>Inline uploads need entity context.</span>\n )}\n </div>\n <input\n ref={inputRef}\n type=\"file\"\n hidden\n accept={accepts?.join(\",\")}\n multiple\n onChange={(event) => {\n if (event.target.files) void handleFiles(event.target.files);\n event.target.value = \"\";\n }}\n />\n <textarea\n ref={textareaRef}\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n value={markdown}\n onChange={(event) => changeValue(event.target.value)}\n onPaste={(event) => {\n const files = Array.from(event.clipboardData.files ?? []).filter((file) => file.size > 0);\n if (files.length === 0) return;\n event.preventDefault();\n void handleFiles(files);\n }}\n onDrop={(event) => {\n const files = Array.from(event.dataTransfer.files ?? []).filter((file) => file.size > 0);\n if (files.length === 0) return;\n event.preventDefault();\n void handleFiles(files);\n }}\n onDragOver={(event) => event.preventDefault()}\n rows={12}\n style={{\n width: \"100%\",\n minHeight: 220,\n border: \"1px solid var(--border)\",\n borderRadius: 8,\n padding: \"10px 12px\",\n lineHeight: 1.5,\n fontFamily: \"inherit\",\n resize: \"vertical\",\n background: \"var(--surface)\",\n color: \"var(--text)\",\n }}\n />\n {error && <div style={{ fontSize: 12, color: \"var(--danger)\" }}>{error}</div>}\n <div style={{ border: \"1px solid var(--border)\", borderRadius: 8, padding: 12, background: \"var(--surface-2)\" }}>\n <div style={{ fontSize: 11.5, color: \"var(--text-3)\", marginBottom: 8 }}>Preview</div>\n {markdown ? (\n <Markdown content={markdown} files={rich.files} />\n ) : (\n <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>Empty</span>\n )}\n </div>\n </div>\n );\n}\n\nfunction withLeadingSpacing(markdown: string, token: string): string {\n if (!markdown) return `${token}\\n`;\n if (markdown.endsWith(\"\\n\\n\")) return token;\n if (markdown.endsWith(\"\\n\")) return `\\n${token}`;\n return `\\n\\n${token}`;\n}\n\nfunction uploadedFileToHydrated(uploaded: UploadedFile, previewUrl?: string): HydratedFile {\n return {\n id: uploaded.id,\n filename: uploaded.filename,\n content_type: uploaded.content_type,\n size_bytes: uploaded.size_bytes,\n sha256: uploaded.sha256,\n width: uploaded.width,\n height: uploaded.height,\n metadata: uploaded.metadata,\n url: previewUrl,\n };\n}\n","// text: trivial fallback renderer. Coerces value to string; null/undefined\n// renders an em-dash placeholder consistent with the rest of the SDK.\n//\n// Returns a plain string. The truncation tooltip on overflow:hidden cells is\n// owned by the `<td>` wrapper at the table-component layer (SmartListPage,\n// ChildrenTable), not by this factory. Wrapping every cell in a span here\n// produces 6,000 extra React elements on a 500x12 viewport - see\n// docs/plans/2026-05-09-virtual-list-100k.md §2.\nimport type { CellFactory, CellRenderer } from \"../registry\";\n\nexport const textFactory: CellFactory = (): CellRenderer => {\n return (value) => {\n if (value == null || value === \"\") return \"—\";\n if (typeof value === \"object\") {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n };\n};\n","// bool_pill: renders a colored Pill labeled by display.bool_labels (when set)\n// or a heuristic on the field's display.name / field code.\n//\n// Heuristic (factory time, run once per column):\n// - \"Is X\" / \"Has X\" → true: \"X\", false: \"Not X\" (e.g. \"Is Archived\" → \"Archived\" / \"Active\")\n// - field code \"is_x\" / \"has_x\" → strip prefix and titlecase\n// - otherwise → \"Yes\" / \"No\"\n//\n// True is emerald, false is slate. Authors who need different tones use\n// display.value_map, not bool_pill. We do not produce a third state for null —\n// nullable booleans render as em-dash via the text fallback path that any\n// good list filter avoids by hiding the column.\nimport { Pill } from \"@/components/primitives/Pill\";\nimport { loc } from \"@/types/schema\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nexport const boolPillFactory: CellFactory = (ctx): CellRenderer => {\n const { field, fieldName, locale = \"en\" } = ctx;\n const labels = resolveLabels(field, fieldName, locale);\n\n return (value: unknown): CellOutput => {\n if (value == null) return \"—\";\n const truthy = !!value;\n return (\n <Pill tone={truthy ? \"emerald\" : \"slate\"} size=\"xs\">\n {truthy ? labels.trueLabel : labels.falseLabel}\n </Pill>\n );\n };\n};\n\nfunction resolveLabels(\n field: { display?: { bool_labels?: { true: Record<string,string>; false: Record<string,string> }; name?: Record<string,string> } },\n fieldName: string,\n locale: string,\n): { trueLabel: string; falseLabel: string } {\n if (field.display?.bool_labels) {\n return {\n trueLabel: loc(field.display.bool_labels.true, locale) || \"Yes\",\n falseLabel: loc(field.display.bool_labels.false, locale) || \"No\",\n };\n }\n const dispName = field.display?.name ? loc(field.display.name, locale) : \"\";\n if (dispName.startsWith(\"Is \")) {\n const stem = dispName.slice(3).trim();\n return { trueLabel: stem || \"Yes\", falseLabel: stem ? `Not ${stem}` : \"No\" };\n }\n if (dispName.startsWith(\"Has \")) {\n const stem = dispName.slice(4).trim();\n return { trueLabel: stem || \"Yes\", falseLabel: stem ? `No ${stem}` : \"No\" };\n }\n if (fieldName.startsWith(\"is_\")) {\n const stem = titleCase(fieldName.slice(3));\n return { trueLabel: stem, falseLabel: `Not ${stem}` };\n }\n if (fieldName.startsWith(\"has_\")) {\n const stem = titleCase(fieldName.slice(4));\n return { trueLabel: stem, falseLabel: `No ${stem}` };\n }\n return { trueLabel: \"Yes\", falseLabel: \"No\" };\n}\n\nfunction titleCase(s: string): string {\n return s\n .split(\"_\")\n .map((p) => (p ? p[0].toUpperCase() + p.slice(1) : p))\n .join(\" \");\n}\n","// badge: renders a colored Pill for enum-shaped strings. Color and label are\n// resolved at factory time from (in priority order):\n// 1. display.value_map[code] — explicit author override\n// 2. field.values[].color — inline enum / referenced enum\n// 3. fallback slate, raw value\n//\n// The factory builds a Map<code, {tone, label}> once per column. The cell hot\n// path is one map lookup.\nimport { Pill, type PillTone } from \"@/components/primitives/Pill\";\nimport { loc } from \"@/types/schema\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\ntype LookupEntry = { tone: PillTone; label: string };\n\nconst VALID_TONES: ReadonlySet<PillTone> = new Set([\n \"indigo\", \"emerald\", \"amber\", \"rose\", \"sky\", \"violet\", \"slate\", \"teal\",\n]);\n\nfunction asTone(c?: string): PillTone {\n if (!c) return \"slate\";\n return VALID_TONES.has(c as PillTone) ? (c as PillTone) : \"slate\";\n}\n\nexport const badgeFactory: CellFactory = (ctx): CellRenderer => {\n const { field, locale = \"en\" } = ctx;\n const lookup = new Map<string, LookupEntry>();\n\n // Inline enum / resolved enum values.\n if (field.values) {\n for (const v of field.values) {\n lookup.set(v.code, { tone: asTone(v.color), label: loc(v.name, locale) || v.code });\n }\n }\n // value_map overrides. Color and label override INDEPENDENTLY: omitting\n // `color` keeps the inline-enum color (or slate fallback); omitting `label`\n // keeps the inline-enum label.\n if (field.display?.value_map) {\n for (const [code, entry] of Object.entries(field.display.value_map)) {\n const existing = lookup.get(code);\n const tone = entry.color ? asTone(entry.color) : (existing?.tone ?? \"slate\");\n const overrideLabel = entry.label ? loc(entry.label, locale) : \"\";\n const label = overrideLabel || existing?.label || code;\n lookup.set(code, { tone, label });\n }\n }\n\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const code = String(value);\n const hit = lookup.get(code);\n return (\n <Pill tone={hit?.tone ?? \"slate\"} size=\"xs\">\n {hit?.label ?? code}\n </Pill>\n );\n };\n};\n","// status_pill: renders a colored Pill for fields whose value is a status code\n// from one of the entity's status_groups. Color and label come from the group\n// definition (StatusDef.color, StatusDef.name).\n//\n// Author opts in via display.widget: status_pill on the field. The factory\n// flattens every status_group's statuses into a single Map<code, {tone,\n// label}> at factory time so the hot path is one map lookup.\n//\n// If multiple status groups expose the same code, the LAST one wins (rare;\n// authors should declare disjoint domains).\nimport { Pill, type PillTone } from \"@/components/primitives/Pill\";\nimport { loc } from \"@/types/schema\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\ntype LookupEntry = { tone: PillTone; label: string };\n\nconst VALID_TONES: ReadonlySet<PillTone> = new Set([\n \"indigo\", \"emerald\", \"amber\", \"rose\", \"sky\", \"violet\", \"slate\", \"teal\",\n]);\n\nfunction asTone(c?: string): PillTone {\n if (!c) return \"slate\";\n return VALID_TONES.has(c as PillTone) ? (c as PillTone) : \"slate\";\n}\n\nexport const statusPillFactory: CellFactory = (ctx): CellRenderer => {\n const { entity, locale = \"en\" } = ctx;\n const lookup = new Map<string, LookupEntry>();\n\n if (entity?.status_groups) {\n for (const group of Object.values(entity.status_groups)) {\n for (const status of group.statuses) {\n lookup.set(status.code, {\n tone: asTone(status.color),\n label: loc(status.name, locale) || status.code,\n });\n }\n }\n }\n\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const code = String(value);\n const hit = lookup.get(code);\n return (\n <Pill tone={hit?.tone ?? \"slate\"} size=\"xs\">\n {hit?.label ?? code}\n </Pill>\n );\n };\n};\n","// tag_list: renders array values as a row of Chips. Per-tag color/label via\n// optional display.value_map. The hot path is a single .map(); no per-tag\n// schema lookups beyond the prebuilt value-map.\nimport { Chip } from \"@/components/primitives/Chip\";\nimport { Pill, type PillTone } from \"@/components/primitives/Pill\";\nimport { loc } from \"@/types/schema\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nconst VALID_TONES: ReadonlySet<PillTone> = new Set([\n \"indigo\", \"emerald\", \"amber\", \"rose\", \"sky\", \"violet\", \"slate\", \"teal\",\n]);\n\nfunction asTone(c?: string): PillTone | null {\n if (!c) return null;\n return VALID_TONES.has(c as PillTone) ? (c as PillTone) : null;\n}\n\nexport const tagListFactory: CellFactory = (ctx): CellRenderer => {\n const { field, locale = \"en\" } = ctx;\n type Entry = { label: string; tone: PillTone | null };\n const lookup = new Map<string, Entry>();\n if (field.display?.value_map) {\n for (const [code, entry] of Object.entries(field.display.value_map)) {\n lookup.set(code, {\n label: (entry.label && loc(entry.label, locale)) || code,\n tone: asTone(entry.color),\n });\n }\n }\n\n return (value: unknown): CellOutput => {\n if (!Array.isArray(value) || value.length === 0) return \"—\";\n return (\n <span style={{ display: \"inline-flex\", gap: 4, flexWrap: \"wrap\" }}>\n {value.map((item, idx) => {\n const code = String(item);\n const hit = lookup.get(code);\n if (hit?.tone) {\n return (\n <Pill key={`${code}-${idx}`} tone={hit.tone} size=\"xs\">\n {hit.label}\n </Pill>\n );\n }\n return <Chip key={`${code}-${idx}`}>{hit?.label ?? code}</Chip>;\n })}\n </span>\n );\n };\n};\n","// time_ago: relative phrase for ≤30d, ISO date for older. Hover tooltip shows\n// the absolute offset-aware timestamp.\n//\n// timestamp_full: always shows the absolute offset-aware timestamp. Used when\n// authors set display.widget: timestamp_full to override the smart default.\nimport { formatOffsetTimestamp, formatRelativeOrAbsolute } from \"@/lib/timestamp\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nexport const timeAgoFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const raw = typeof value === \"string\" ? value : String(value);\n const { text, absolute } = formatRelativeOrAbsolute(raw);\n return <span title={absolute}>{text}</span>;\n };\n};\n\nexport const timestampFullFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const raw = typeof value === \"string\" ? value : String(value);\n return formatOffsetTimestamp(raw);\n };\n};\n","// next_run: domain-specific cell for the schedule entity's next_run_at field.\n//\n// Why a custom widget? `time_ago` renders any past timestamp as \"X ago\",\n// which for a SCHEDULER's next-run field reads as failure (\"we missed it\"),\n// when in reality cron schedules whose tick interval is non-zero will\n// briefly show next_run_at in the past — between the cron boundary firing\n// and the scheduler's next claim tick. That's the expected operating state,\n// not a problem. Surfacing it as \"X ago\" produces a constant stream of\n// false-alarm reads in production dashboards.\n//\n// State mapping (same approach as Oracle EM Scheduler / SAP CCMS / Quartz):\n// - future → \"in Xs\" (no badge)\n// - past, ≤ 60s ago → \"due\" (slate badge — about to fire)\n// - past, ≤ 5m ago → \"overdue Xs\" (amber badge — scheduler may be slow)\n// - past, > 5m ago → \"overdue Xm\" (rose badge — likely real problem)\n// - empty / unparsed → \"—\"\n//\n// Threshold rationale: 60s = 2× default scheduler tick interval (30s) so\n// the \"due\" window covers any tick alignment. 5m = scheduler's stale-lock\n// recovery threshold; past that, recoverStaleLocks should have re-armed\n// the row, so persistent overdue is a real signal worth flagging.\n//\n// `is_running`, `enabled`, `last_error` have their own columns; this cell\n// only interprets next_run_at. The hover tooltip carries the absolute\n// offset-aware timestamp so operators can read the literal value when\n// debugging timezone or cron-expression issues.\n\nimport { Pill } from \"@/components/primitives/Pill\";\nimport { formatOffsetTimestamp } from \"@/lib/timestamp\";\nimport { formatDistanceStrict } from \"date-fns\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nconst DUE_WINDOW_MS = 60 * 1000; // one-tick alignment buffer (default tick = 30s)\nconst OVERDUE_WARN_MS = 5 * 60 * 1000; // matches scheduler stale-lock threshold\n\nexport const nextRunFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const raw = typeof value === \"string\" ? value : String(value);\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n\n const absolute = formatOffsetTimestamp(raw);\n const ageMs = Date.now() - date.getTime();\n\n if (ageMs <= 0) {\n // Future — render as \"in X\" with the absolute timestamp on hover.\n const distance = formatDistanceStrict(date, new Date(), { addSuffix: false });\n return <span title={absolute}>in {distance}</span>;\n }\n\n if (ageMs <= DUE_WINDOW_MS) {\n return (\n <span title={absolute}>\n <Pill tone=\"slate\" size=\"xs\">due</Pill>\n </span>\n );\n }\n\n const distance = formatDistanceStrict(date, new Date(), { addSuffix: false });\n const tone = ageMs <= OVERDUE_WARN_MS ? \"amber\" : \"rose\";\n return (\n <span title={absolute}>\n <Pill tone={tone} size=\"xs\">overdue {distance}</Pill>\n </span>\n );\n };\n};\n","// money: currency-aware Intl.NumberFormat. Currency comes from\n// field.display.currency_field on the row when present, otherwise from\n// field.display.currency, then USD. Fraction digits derive from field.scale\n// (set on the typedef, e.g. money has scale: 4) and clamp to [0, 6].\nimport type { CellFactory, CellRenderer } from \"../registry\";\n\nexport const moneyFactory: CellFactory = (ctx): CellRenderer => {\n\tconst { field, locale = \"en\" } = ctx;\n\tconst staticCurrency = field.display?.currency || \"USD\";\n\tconst currencyField = field.display?.currency_field;\n\tconst currencyDisplay = normalizeCurrencyDisplay(\n\t\tfield.display?.currency_display,\n\t);\n\tconst scale = clamp(typeof field.scale === \"number\" ? field.scale : 2, 0, 6);\n\tconst formatterCache = new Map<string, Intl.NumberFormat>();\n\n\treturn (value: unknown, record = {}) => {\n\t\tif (value == null || value === \"\") return \"—\";\n\t\tconst n = typeof value === \"number\" ? value : Number(value);\n\t\tif (!Number.isFinite(n)) return String(value);\n\t\tconst rowCurrency = currencyField ? record[currencyField] : undefined;\n\t\tconst currency =\n\t\t\ttypeof rowCurrency === \"string\" && rowCurrency !== \"\"\n\t\t\t\t? rowCurrency\n\t\t\t\t: staticCurrency;\n\t\tconst cacheKey = `${locale}:${currency}:${currencyDisplay}:${scale}`;\n\t\tlet formatter = formatterCache.get(cacheKey);\n\t\tif (!formatter) {\n\t\t\tformatter = new Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency,\n\t\t\t\tcurrencyDisplay,\n\t\t\t\tminimumFractionDigits: scale,\n\t\t\t\tmaximumFractionDigits: scale,\n\t\t\t});\n\t\t\tformatterCache.set(cacheKey, formatter);\n\t\t}\n\t\treturn formatter.format(n);\n\t};\n};\n\nfunction normalizeCurrencyDisplay(\n\tvalue: unknown,\n): \"symbol\" | \"narrowSymbol\" | \"code\" | \"name\" {\n\tswitch (value) {\n\t\tcase \"narrow_symbol\":\n\t\t\treturn \"narrowSymbol\";\n\t\tcase \"code\":\n\t\tcase \"name\":\n\t\tcase \"symbol\":\n\t\t\treturn value;\n\t\tdefault:\n\t\t\treturn \"symbol\";\n\t}\n}\n\nfunction clamp(n: number, lo: number, hi: number): number {\n\tif (n < lo) return lo;\n\tif (n > hi) return hi;\n\treturn n;\n}\n","// ref_link: renders a foreign-key value as a link to the target entity's\n// canonical detail page. Display value comes from the row's `$refs` map\n// (server-rendered, includes the display.template result), or falls back to\n// the resolved display field, or the raw FK if neither is available.\n//\n// Two surfaces:\n// - list → an underlined inline link, compact for a dense table cell.\n// - detail → a bordered, navigable entity chip (icon + label) per the\n// design brief §9 (\"refs as entity chips, navigable\").\n//\n// Navigation: the link is a PLAIN real `<a href>` carrying the canonical\n// standalone detail route. It owns no click handler - the global link\n// interceptor (mounted in Layout) catches the plain left-click and routes it\n// through the embed navigation chokepoint, so the link stays embedded in an\n// iframe and SPA-navigates standalone, while copy-link / new-tab / middle-click\n// keep working natively off the real href. This is uniform with every other\n// anchor in the app (including markdown), which is what makes the embed\n// boundary total - a cell can no longer forget to wire navigation.\n//\n// All schema lookups (target entity, detail screen, route, display field,\n// entity icon) happen at factory time. The render path is pure.\nimport { resolveRefRecordLabel } from \"@/types/schema\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nexport const refLinkFactory: CellFactory = (ctx): CellRenderer => {\n const { field, entities, screens, refs, surface } = ctx;\n const refEntityCode = field.ref?.entity;\n const targetEntity = refEntityCode ? entities?.[refEntityCode] : undefined;\n const getRefs = typeof refs === \"function\" ? refs : () => refs;\n const isDetail = surface === \"detail\";\n const iconName = targetEntity?.display?.icon;\n\n // Resolve display field for the target entity (priority: field-level\n // override → ref.display.field → entity.display.display_field).\n const displayField =\n field.display?.ref_display_field ??\n field.ref?.display?.field ??\n targetEntity?.display?.display_field;\n\n // Resolve href template once per column.\n const detailScreenCode = targetEntity?.detail_screen;\n const detailScreen = detailScreenCode ? screens?.[detailScreenCode] : undefined;\n const route = detailScreen?.route;\n\n return (value: unknown, _record: RowRecord): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const raw = String(value);\n const display = resolveDisplayString(raw, refEntityCode, getRefs(), displayField);\n const href = route ? route.replace(\":id\", encodeURIComponent(raw)) : undefined;\n\n // Detail surface: a bordered entity chip - icon + label, navigable.\n if (isDetail) {\n const inner = (\n <>\n {iconName && (\n <span style={{ color: \"var(--text-3)\", display: \"flex\", flexShrink: 0 }}>\n <DynamicIcon name={iconName} size={13} />\n </span>\n )}\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>\n {display}\n </span>\n </>\n );\n // Plan §9: every link factory MUST emit `rel=\"noopener noreferrer\"`.\n if (href) {\n return (\n <a href={href} rel=\"noopener noreferrer\" className=\"detail-ref-chip\">\n {inner}\n </a>\n );\n }\n return <span className=\"detail-ref-chip\">{inner}</span>;\n }\n\n // List surface: compact underlined link.\n if (!href) return display;\n return (\n <a\n href={href}\n rel=\"noopener noreferrer\"\n style={{ color: \"inherit\", textDecoration: \"underline\", textUnderlineOffset: 2 }}\n >\n {display}\n </a>\n );\n };\n};\n\ntype RowRecord = Record<string, unknown>;\ntype RefsMap = Record<string, Record<string, Record<string, unknown>>>;\n\n// resolveDisplayString looks the FK value up in the request's $refs payload\n// and resolves the embedded record to a label via the shared\n// resolveRefRecordLabel (types/schema.ts). Returns the raw FK when the ref\n// is not embedded.\nfunction resolveDisplayString(\n raw: string,\n refEntityCode: string | undefined,\n refsRoot: RefsMap | undefined,\n displayField: string | undefined,\n): string {\n const refRecord =\n refEntityCode && refsRoot ? refsRoot[refEntityCode]?.[raw] : undefined;\n return refRecord ? resolveRefRecordLabel(refRecord, displayField, raw) : raw;\n}\n","// URL parsing/normalization helpers extracted from the legacy UrlField.\n// Used by the `url` cell factory and (via re-export) by `UrlInput`.\n//\n// Contract: pure functions, no DOM, no side effects. Safe to call from\n// factory build time or per-cell render.\n\nconst SAFE_PROTOCOLS = /^(https?|ftps?|ssh|mailto|tel):/i;\nexport const LONG_TLD = /^(info|name|tech|site|cloud|online|store|shop|blog|space|world|link|live|page|zone|life|team|work|host|land|news|wiki|mobi|coop|aero|asia)$/i;\n\nfunction looksLikeTLD(label: string): boolean {\n return /^[a-z]{2,3}$/i.test(label) || LONG_TLD.test(label);\n}\n\nexport function looksLikeHostname(candidate: string): boolean {\n if (!candidate.includes(\".\")) return false;\n const labels = candidate.split(\".\");\n if (labels.length < 3) return true;\n const first = labels[0].toLowerCase();\n if (/^(com|org|net|edu|gov)$/.test(first)) return false;\n if (/^(io|app|dev)$/.test(first)) {\n return looksLikeTLD(labels[labels.length - 1]);\n }\n return true;\n}\n\nexport function normalizeUrl(raw: string): string | null {\n if (SAFE_PROTOCOLS.test(raw)) return raw;\n const schemeMatch = raw.match(/^([a-z][a-z0-9+.-]*):/i);\n if (schemeMatch) {\n const scheme = schemeMatch[1];\n const afterColon = raw.slice(schemeMatch[0].length);\n if (/^\\d+([/?#]|$)/.test(afterColon) && looksLikeHostname(scheme)) {\n const port = parseInt(afterColon, 10);\n if (port >= 1 && port <= 65535) return `https://${raw}`;\n }\n if (scheme.toLowerCase() === \"localhost\") return `https://${raw}`;\n return null;\n }\n return `https://${raw}`;\n}\n\nexport function parseDomain(href: string): string | null {\n try {\n const hostname = new URL(href).hostname.replace(/^www\\./i, \"\");\n return hostname || null;\n } catch {\n return null;\n }\n}\n\n/**\n * LinkedIn is the only host we special-case. Recognized path prefixes\n * `/in/<slug>`, `/company/<slug>`, `/school/<slug>` render as `<prefix>/<slug>`.\n * Any other linkedin.com URL (feed, jobs, posts, bare host) falls through to\n * the default hostname rendering.\n */\nexport function linkedinLabel(href: string, domain: string): string | null {\n if (domain !== \"linkedin.com\") return null;\n try {\n const m = new URL(href).pathname.match(/^\\/(in|company|school)\\/([^/]+)/i);\n if (m) return `${m[1].toLowerCase()}/${decodeURIComponent(m[2])}`;\n } catch {\n // fall through\n }\n return null;\n}\n\nexport function isValidUrl(href: string): boolean {\n try {\n new URL(href);\n return true;\n } catch {\n return false;\n }\n}\n","// Inline-SVG host icons + configurable favicon fallback for unknown hosts.\n//\n// Curated brand SVGs always render for the well-known host set\n// (linkedin/github/x/youtube/gmail/slack/notion). Anything else routes\n// through `HostIcon`, which honors the `ui_favicon_source` user/tenant\n// parameter and falls back to a generic globe SVG on load failure.\n//\n// Source modes (see core_parameters.yaml `ui_favicon_source`):\n// google = www.google.com/s2/favicons (sharp; leaks host to Google)\n// direct = https://<host>/favicon.ico (no third party; leaks user IP\n// to each host and misses sites that only declare the icon\n// in <link>)\n// none = generic globe SVG (no external fetch)\n//\n// Adding a new well-known brand: extend the inline-SVG set below and\n// add the canonical (after-www) hostname to HOST_ICONS.\nimport { useEffect, useState, type FC, type SVGProps } from \"react\";\nimport { useAppearanceStore, type FaviconSource } from \"@/stores/appearance\";\n\ntype IconFC = FC<SVGProps<SVGSVGElement>>;\n\n// All icons share the same 16x16 box and inherit currentColor for stroke/fill\n// where applicable. Brand-colored fills are baked in for legibility.\nfunction svg(child: React.ReactNode, viewBox = \"0 0 24 24\"): IconFC {\n const Component: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox={viewBox}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n {child}\n </svg>\n );\n return Component;\n}\n\n// Generic globe (fallback for unknown hosts when source = \"none\" or when\n// an external favicon fetch fails).\nconst Globe = svg(\n <>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M3 12h18M12 3c3 3 3 15 0 18-3-3-3-15 0-18\" />\n </>,\n);\n\n// linkedin.com\nconst LinkedIn: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"#0A66C2\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M20.45 20.45h-3.55v-5.57c0-1.33-.02-3.04-1.85-3.04-1.85 0-2.13 1.45-2.13 2.94v5.67H9.36V9h3.41v1.56h.05c.48-.9 1.64-1.85 3.37-1.85 3.6 0 4.27 2.37 4.27 5.46v6.28zM5.34 7.43a2.06 2.06 0 1 1 0-4.12 2.06 2.06 0 0 1 0 4.12zM7.12 20.45H3.56V9h3.56v11.45zM22.22 0H1.77C.79 0 0 .77 0 1.72v20.56C0 23.23.79 24 1.77 24h20.45c.98 0 1.78-.77 1.78-1.72V1.72C24 .77 23.2 0 22.22 0z\" />\n </svg>\n);\n\n// github.com\nconst GitHub: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M12 .5a11.5 11.5 0 0 0-3.64 22.41c.58.1.79-.25.79-.56 0-.27-.01-1-.02-1.96-3.21.7-3.89-1.55-3.89-1.55-.52-1.34-1.28-1.7-1.28-1.7-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.2 1.77 1.2 1.03 1.77 2.71 1.26 3.37.96.1-.75.4-1.26.73-1.55-2.56-.29-5.26-1.28-5.26-5.71 0-1.26.45-2.3 1.19-3.11-.12-.29-.52-1.46.11-3.05 0 0 .97-.31 3.18 1.19a11.05 11.05 0 0 1 5.79 0c2.21-1.5 3.18-1.19 3.18-1.19.63 1.59.23 2.76.11 3.05.74.81 1.19 1.85 1.19 3.11 0 4.44-2.71 5.42-5.29 5.7.41.36.78 1.07.78 2.16 0 1.56-.01 2.81-.01 3.19 0 .31.21.68.8.56A11.5 11.5 0 0 0 12 .5z\" />\n </svg>\n);\n\n// x.com / twitter.com\nconst X: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M18.244 2H21.5l-7.62 8.71L23 22h-7.05l-5.52-7.21L4.07 22H.81l8.18-9.34L1 2h7.22l5 6.59L18.244 2zm-2.47 18h1.95L7.32 4h-2.1l10.55 16z\" />\n </svg>\n);\n\n// youtube.com\nconst YouTube: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"#FF0000\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M23.5 6.2a3 3 0 0 0-2.1-2.1C19.5 3.6 12 3.6 12 3.6s-7.5 0-9.4.5A3 3 0 0 0 .5 6.2C0 8.1 0 12 0 12s0 3.9.5 5.8a3 3 0 0 0 2.1 2.1c1.9.5 9.4.5 9.4.5s7.5 0 9.4-.5a3 3 0 0 0 2.1-2.1c.5-1.9.5-5.8.5-5.8s0-3.9-.5-5.8zM9.6 15.6V8.4l6.2 3.6-6.2 3.6z\" />\n </svg>\n);\n\n// gmail / mail.google.com\nconst Gmail: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"#EA4335\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M24 5.45v13.1A1.45 1.45 0 0 1 22.55 20H19.5V9.27L12 14.7 4.5 9.27V20H1.45A1.45 1.45 0 0 1 0 18.55V5.45A1.45 1.45 0 0 1 1.45 4h.5l10.05 7.27L22.05 4h.5A1.45 1.45 0 0 1 24 5.45z\" />\n </svg>\n);\n\n// slack.com\nconst Slack: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path fill=\"#E01E5A\" d=\"M5.04 15.12a2.52 2.52 0 1 1-2.52-2.52h2.52v2.52zm1.27 0a2.52 2.52 0 1 1 5.04 0v6.32a2.52 2.52 0 1 1-5.04 0v-6.32z\" />\n <path fill=\"#36C5F0\" d=\"M8.83 5.04a2.52 2.52 0 1 1 2.52-2.52v2.52H8.83zm0 1.27a2.52 2.52 0 1 1 0 5.04H2.52a2.52 2.52 0 1 1 0-5.04h6.31z\" />\n <path fill=\"#2EB67D\" d=\"M18.96 8.83a2.52 2.52 0 1 1 2.52 2.52h-2.52V8.83zm-1.27 0a2.52 2.52 0 1 1-5.04 0V2.52a2.52 2.52 0 1 1 5.04 0v6.31z\" />\n <path fill=\"#ECB22E\" d=\"M15.17 18.96a2.52 2.52 0 1 1-2.52 2.52v-2.52h2.52zm0-1.27a2.52 2.52 0 1 1 0-5.04h6.31a2.52 2.52 0 1 1 0 5.04h-6.31z\" />\n </svg>\n);\n\n// notion.so / notion.com\nconst Notion: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M4.46 3.83 14.94 3a3.7 3.7 0 0 1 2.5.62l3 2.16a1.4 1.4 0 0 1 .56 1.31v13.06a1.7 1.7 0 0 1-1.66 1.7l-12.5.78a2.4 2.4 0 0 1-1.85-.62L2.5 19.7a1.7 1.7 0 0 1-.5-1.2V5.16c0-.74.6-1.27 1.46-1.33l1-.01zm.46 1.86c-.31 0-.46.16-.46.47v12.25c0 .31.16.47.46.47l11.62-.7c.31 0 .46-.16.46-.47V6c0-.32-.16-.47-.46-.47L4.92 5.7zm5.57 2.32c.16 0 .31.16.31.31v.46l3.7.23c.31 0 .46.16.46.47v8.32c0 .31-.16.47-.46.47l-3.7.23c-.31 0-.46-.16-.46-.47V8.78c0-.16.15-.32.15-.46l-.04-.31z\" />\n </svg>\n);\n\n// Map of canonical domain -> icon component. Lookup keys are after-www\n// hostnames (parseDomain strips the leading www.).\nconst HOST_ICONS: Record<string, IconFC> = {\n \"linkedin.com\": LinkedIn,\n \"github.com\": GitHub,\n \"x.com\": X,\n \"twitter.com\": X,\n \"youtube.com\": YouTube,\n \"youtu.be\": YouTube,\n \"gmail.com\": Gmail,\n \"mail.google.com\": Gmail,\n \"slack.com\": Slack,\n \"notion.so\": Notion,\n \"notion.com\": Notion,\n};\n\n// Build the external favicon URL for a host given the active source mode.\n// Returns null when the source is \"none\" or the host is empty (callers\n// fall back to the generic globe).\nfunction externalFaviconUrl(domain: string, source: FaviconSource): string | null {\n if (!domain || source === \"none\") return null;\n if (source === \"google\") {\n return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=32`;\n }\n // direct: load /favicon.ico from the origin. Misses sites that only\n // declare the icon via <link rel=\"icon\">; the onError fallback covers it.\n return `https://${domain}/favicon.ico`;\n}\n\nconst ICON_BOX_STYLE: React.CSSProperties = {\n width: 16,\n height: 16,\n flexShrink: 0,\n objectFit: \"contain\",\n};\n\nexport interface HostIconProps {\n /** Canonical (after-www) hostname; pass null/empty to render the globe. */\n domain: string | null | undefined;\n}\n\n// HostIcon is the public renderer used by URL cells. For known brands it\n// returns the inline SVG. For unknown hosts it renders an <img> per the\n// `ui_favicon_source` setting and gracefully falls back to the globe on\n// load failure (no image at the URL, network error, blocked, etc).\nexport function HostIcon({ domain }: HostIconProps): React.ReactElement {\n const source = useAppearanceStore((s) => s.faviconSource);\n const key = domain ? domain.toLowerCase() : \"\";\n const Curated = key ? HOST_ICONS[key] : undefined;\n if (Curated) return <Curated />;\n\n const url = externalFaviconUrl(key, source);\n if (!url) return <Globe />;\n return <FaviconImg src={url} />;\n}\n\n// FaviconImg renders an <img> and reverts to the globe on error. Resets\n// state when src changes (column re-renders with a different host).\nfunction FaviconImg({ src }: { src: string }): React.ReactElement {\n const [failed, setFailed] = useState(false);\n useEffect(() => { setFailed(false); }, [src]);\n if (failed) return <Globe />;\n return (\n <img\n src={src}\n alt=\"\"\n width={16}\n height={16}\n loading=\"lazy\"\n decoding=\"async\"\n referrerPolicy=\"no-referrer\"\n style={ICON_BOX_STYLE}\n onError={() => setFailed(true)}\n />\n );\n}\n\nexport const GENERIC_GLOBE = Globe;\n","// The one empty-value token for cell renderers.\n//\n// The design brief mandates a single shared empty marker so every blank cell\n// reads identically - a muted em-dash in the `var(--text-4)` tone. Before this\n// the same `{ fontSize: 12.5, color: var(--text-4) }` style object was\n// copy-pasted into eight factory files, and one (richTextPreview) had drifted\n// to a plain hyphen. Import EMPTY_CELL instead of re-declaring it.\n//\n// passwordMask keeps its own \"Not set\" italic marker on purpose - an unset\n// secret is a distinct state, not a blank value.\n\nimport type { ReactElement } from \"react\";\n\nconst EMPTY_STYLE = { fontSize: 12.5, color: \"var(--text-4)\" } as const;\n\n// EMPTY_CELL is a static element; React reconciles it per cell location, so\n// one shared instance is safe and avoids a per-cell allocation.\nexport const EMPTY_CELL: ReactElement = <span style={EMPTY_STYLE}>—</span>;\n","// url: anchor with safe-protocol normalization, hostname label (with LinkedIn\n// slug special-case), and host icon. Curated brands (linkedin/github/x/...)\n// always render an inline SVG. Other hosts honor the `ui_favicon_source`\n// param (see HostIcon).\n//\n// `link` widget shares this factory's normalization but renders the full URL\n// as the label and skips the host icon. See linkFactory.\nimport { Icon } from \"@/components/primitives\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport {\n isValidUrl,\n linkedinLabel,\n normalizeUrl,\n parseDomain,\n} from \"./url-helpers\";\nimport { HostIcon } from \"./host-icons\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst ANCHOR_STYLE = {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n fontSize: 12.5,\n color: \"var(--accent)\",\n textDecoration: \"none\",\n} as const;\n\nconst PLAIN_STYLE = { fontSize: 12.5 } as const;\n\nexport const urlFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n const str = value == null ? \"\" : String(value);\n if (!str) return EMPTY_CELL;\n\n const href = normalizeUrl(str);\n if (href == null || !isValidUrl(href)) {\n return <span style={PLAIN_STYLE}>{str}</span>;\n }\n\n const domain = parseDomain(href);\n const linkText = linkedinLabel(href, domain ?? \"\") ?? domain ?? str;\n\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title={str}\n className=\"mono\"\n style={ANCHOR_STYLE}\n >\n <HostIcon domain={domain} />\n {linkText}\n <Icon.external size={11} />\n </a>\n );\n };\n};\n","// email: mailto anchor on the raw value. Display-mode only; edit affordance\n// is owned by `editRegistry[email]`.\n//\n// Parity contract with legacy EmailField.tsx:7-18: byte-equivalent output for\n// the same inputs (asserted by the snapshot test). Notably the raw value is\n// preserved verbatim — a \"mailto:foo@bar.com\" input therefore produces\n// href=\"mailto:mailto:foo@bar.com\". Any change is a separate product plan.\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst ANCHOR_STYLE = {\n fontSize: 12.5,\n color: \"var(--accent)\",\n textDecoration: \"none\",\n} as const;\n\nexport const emailFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n const str = value == null ? \"\" : String(value);\n if (!str) return EMPTY_CELL;\n return (\n <a href={`mailto:${str}`} className=\"mono\" style={ANCHOR_STYLE}>\n {str}\n </a>\n );\n };\n};\n","// phone: safe `tel:` link wrapping the raw value. No national formatting in\n// v1 — the platform has no per-field country/region metadata, and current UI\n// treats phone as plain text. Region-metadata-driven formatting is a separate\n// plan (see plan §4).\n//\n// On values that contain characters not safe for a tel: scheme (anything\n// outside [+0-9 ()-.]), the factory falls back to plain text — this is the\n// \"parse failure\" path called out in plan §4.\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst ANCHOR_STYLE = {\n fontSize: 12.5,\n color: \"var(--accent)\",\n textDecoration: \"none\",\n} as const;\n\nconst PLAIN_STYLE = { fontSize: 12.5 } as const;\n\n// Tel-safe characters per RFC 3966's visual-separator/global-number subset.\n// Also tolerate trailing/leading whitespace; we trim before checking.\nconst TEL_SAFE = /^[+()\\-.\\s\\d]+$/;\n\nexport const phoneFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n const str = value == null ? \"\" : String(value);\n if (!str) return EMPTY_CELL;\n\n const trimmed = str.trim();\n if (!TEL_SAFE.test(trimmed)) {\n return <span style={PLAIN_STYLE}>{str}</span>;\n }\n\n // Strip whitespace for the tel: target, keep raw label for display.\n const tel = trimmed.replace(/\\s+/g, \"\");\n return (\n <a href={`tel:${tel}`} className=\"mono\" style={ANCHOR_STYLE}>\n {str}\n </a>\n );\n };\n};\n","// number: locale-aware numeric formatter. Mirrors the legacy NumberField\n// display branch.\n//\n// String-backed decimals are formatted exactly: trailing zeros preserved,\n// fractional part copied verbatim, never coerced through JS Number (which\n// would lose precision for values past 2^53). Native numeric (int/float) and\n// non-string decimals format through Intl.NumberFormat using the resolved\n// locale.\n//\n// Unit suffix follows the legacy precedence: per-row $units override → static\n// field.unit (display preferred over storage; suppressed when it starts with\n// \"$\" because that range belongs to money widgets). Locale defaults to \"en\"\n// when not provided.\nimport type { CellFactory, CellRenderer, CellOutput, RowRecord } from \"../registry\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst VALUE_STYLE = {\n fontSize: 12.5,\n fontVariantNumeric: \"tabular-nums\" as const,\n};\nconst UNIT_STYLE = { color: \"var(--text-3)\", marginLeft: 4 } as const;\nconst PLAIN_STYLE = { fontSize: 12.5 } as const;\n\nfunction formatDecimalString(value: string, formatter: Intl.NumberFormat): string {\n const trimmed = value.trim();\n if (trimmed === \"\" || trimmed === \"-\") return trimmed;\n\n const negative = trimmed.startsWith(\"-\");\n const abs = negative ? trimmed.slice(1) : trimmed;\n const [intPart, fracPart] = abs.split(\".\");\n\n let formattedInt: string;\n try {\n formattedInt = formatter.format(BigInt(intPart || \"0\"));\n } catch {\n return value;\n }\n\n let result = negative ? `-${formattedInt}` : formattedInt;\n if (fracPart !== undefined) result += `.${fracPart}`;\n return result;\n}\n\nexport const numberFactory: CellFactory = (ctx): CellRenderer => {\n const { field, fieldName, locale = \"en\" } = ctx;\n // Build the formatter once per column. Decimal-string formatting only uses\n // it for the integer portion, so default options are fine.\n const formatter = new Intl.NumberFormat(locale);\n const isDecimal = field.type === \"decimal\";\n const staticUnit = field.unit ? field.unit.display || field.unit.storage : undefined;\n\n return (value: unknown, record: RowRecord): CellOutput => {\n if (value == null) return EMPTY_CELL;\n\n const units = record[\"$units\"] as Record<string, string> | undefined;\n const unitSuffix = units?.[fieldName];\n const displayUnit =\n unitSuffix || (staticUnit && !staticUnit.startsWith(\"$\") ? staticUnit : undefined);\n\n let formatted: string | null;\n if (isDecimal && typeof value === \"string\") {\n formatted = formatDecimalString(value, formatter);\n } else {\n const num = typeof value === \"number\" ? value : Number(value);\n formatted = Number.isFinite(num) ? formatter.format(num) : null;\n }\n\n if (formatted == null) return <span style={PLAIN_STYLE}>—</span>;\n\n return (\n <span className=\"num\" style={VALUE_STYLE}>\n {formatted}\n {displayUnit && <span style={UNIT_STYLE}>{displayUnit}</span>}\n </span>\n );\n };\n};\n","// code: wraps the value in a <code> element and applies the SDK's \"mono\"\n// utility so the typeface lines up with other code-shaped affordances\n// (UrlField hostnames, ref_link IDs, tag chips). Styling delegated to the\n// existing class so theme tokens stay the source of truth.\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst CODE_STYLE = { fontSize: 12.5 } as const;\n\nexport const codeFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return EMPTY_CELL;\n return (\n <code className=\"mono\" style={CODE_STYLE}>\n {String(value)}\n </code>\n );\n };\n};\n","// link: bare anchor for URLs that the author wants rendered verbatim (full\n// URL as label, no host icon, no LinkedIn slug rewrite). Safe-protocol check\n// shared with the `url` factory via normalizeUrl. Used by widget: link.\nimport { Icon } from \"@/components/primitives\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { isValidUrl, normalizeUrl } from \"./url-helpers\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst ANCHOR_STYLE = {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n fontSize: 12.5,\n color: \"var(--accent)\",\n textDecoration: \"none\",\n} as const;\n\nconst PLAIN_STYLE = { fontSize: 12.5 } as const;\n\nexport const linkFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n const str = value == null ? \"\" : String(value);\n if (!str) return EMPTY_CELL;\n\n const href = normalizeUrl(str);\n if (href == null || !isValidUrl(href)) {\n return <span style={PLAIN_STYLE}>{str}</span>;\n }\n\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title={str}\n className=\"mono\"\n style={ANCHOR_STYLE}\n >\n {str}\n <Icon.external size={11} />\n </a>\n );\n };\n};\n","import { JsonField, isEmptyJsonValue } from \"../../JsonField\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst DEFAULT_LIST_JSON_MAX_CHARS = 400;\nconst HARD_LIST_JSON_MAX_CHARS = 2000;\n\nfunction clampMaxChars(value: unknown): number {\n const configured = typeof value === \"number\" && Number.isFinite(value)\n ? Math.floor(value)\n : DEFAULT_LIST_JSON_MAX_CHARS;\n return Math.max(1, Math.min(configured, HARD_LIST_JSON_MAX_CHARS));\n}\n\nfunction truncateText(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text;\n return `${text.slice(0, maxChars)}...`;\n}\n\nfunction boundedJsonText(value: unknown, maxChars: number, seen: WeakSet<object>, depth = 0): string {\n if (value == null || value === \"\") return \"\";\n if (typeof value === \"string\") return truncateText(value, maxChars);\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n if (typeof value !== \"object\") return truncateText(String(value), maxChars);\n if (seen.has(value)) return \"[Circular]\";\n if (depth >= 3) return Array.isArray(value) ? \"[...]\" : \"{...}\";\n\n seen.add(value);\n const close = Array.isArray(value) ? \"]\" : \"}\";\n const open = Array.isArray(value) ? \"[\" : \"{\";\n const parts: string[] = [open];\n const entries = Array.isArray(value)\n ? value.map((item, index) => [String(index), item] as const)\n : Object.entries(value as Record<string, unknown>);\n\n for (const [key, child] of entries) {\n const current = parts.join(\"\");\n const separator = parts.length > 1 ? \",\" : \"\";\n const prefix = Array.isArray(value) ? separator : `${separator}${JSON.stringify(key)}:`;\n const remaining = maxChars - current.length - prefix.length - close.length;\n if (remaining <= 0) {\n parts.push(parts.length > 1 ? \",...\" : \"...\");\n break;\n }\n const rendered = boundedJsonText(child, remaining, seen, depth + 1);\n parts.push(prefix, rendered);\n if (parts.join(\"\").length >= maxChars) {\n parts.push(\",...\");\n break;\n }\n }\n parts.push(close);\n seen.delete(value);\n return truncateText(parts.join(\"\"), maxChars);\n}\n\nfunction jsonText(value: unknown, maxChars: number): string {\n return boundedJsonText(value, maxChars, new WeakSet<object>());\n}\n\nexport const jsonFactory: CellFactory = (ctx): CellRenderer => {\n const surface = ctx.surface ?? \"detail\";\n const maxChars = clampMaxChars(ctx.field.display?.list_preview?.max_chars);\n return (value: unknown): CellOutput => {\n // null, \"\", {}, [] all collapse to the shared empty token - on the list\n // surface a literal \"{}\" is noise, on detail the readonly editor would\n // render a tall empty box.\n if (isEmptyJsonValue(value)) return EMPTY_CELL;\n if (surface === \"list\") {\n const text = jsonText(value, maxChars);\n return (\n <span className=\"font-mono text-xs text-muted-foreground\" title={text}>\n {text}\n </span>\n );\n }\n return (\n <JsonField\n field={ctx.field}\n fieldName={ctx.fieldName}\n value={value}\n mode=\"display\"\n locale={ctx.locale}\n />\n );\n };\n};\n","// markdownPreview: strip markdown source to a single-line plain-text\n// preview using cheap regex passes - no parser. Used by the `markdown` and\n// `rich_text_preview` cell factories for the in-cell preview line; the full\n// formatted render is carried by a HoverCard on hover and by the detail\n// screen, so a regex strip is sufficient here.\n//\n// Why regex and not the unified/remark parser: the parser is the bulk of the\n// markdown bundle weight (~100 kB). The cell-factory registry is eager, so\n// importing the parser here would pin it into the eager SDK bundle and defeat\n// the lazy split of the markdown renderer. A preview is a one-line teaser;\n// minor imperfection on exotic constructs (tables, fenced code) is acceptable.\n//\n// Length is NOT capped here: the server caps the preview at SQL select time\n// (display.list_preview.max_chars + DECLARION_LIST_PREVIEW_DEFAULT_CHARS) and\n// the cell's CSS ellipsis bounds the visual width.\n\nexport interface MarkdownPreview {\n // Single-line plain text: markup removed, whitespace collapsed.\n text: string;\n // True when the source carried no markdown structure. In that case a\n // HoverCard popover would show nothing the in-cell span does not, so the\n // caller skips the popover. Detection is intentionally biased toward\n // false (treat ambiguous input as marked-up): an unnecessary popover is\n // harmless, a missing one hides the rich view.\n isPlain: boolean;\n}\n\ninterface StripRule {\n pattern: RegExp;\n replacement: string;\n // When false, the rule cleans cosmetic noise (e.g. a stray pipe) and does\n // NOT mark the source as non-plain. Defaults to true: a match means real\n // markdown structure, so a HoverCard popover is worth showing.\n structural?: boolean;\n}\n\n// Each rule strips one markdown construct, applied in order. A structural rule\n// that changes the text marks the source as non-plain.\nconst RULES: StripRule[] = [\n // fenced code blocks: drop the fences, keep the inner text\n { pattern: /```[^\\n]*\\n?([\\s\\S]*?)```/g, replacement: \"$1\" },\n // inline code: keep inner text\n { pattern: /`([^`]+)`/g, replacement: \"$1\" },\n // images: keep alt text\n { pattern: /!\\[([^\\]]*)\\]\\([^)]*\\)/g, replacement: \"$1\" },\n // inline links: keep link text\n { pattern: /\\[([^\\]]+)\\]\\([^)]*\\)/g, replacement: \"$1\" },\n // reference links: keep link text\n { pattern: /\\[([^\\]]+)\\]\\[[^\\]]*\\]/g, replacement: \"$1\" },\n // reference link definitions: drop the whole line\n { pattern: /^[ \\t]*\\[[^\\]]+\\]:[ \\t]*\\S.*$/gm, replacement: \"\" },\n // bold / italic / strikethrough with * or ~ (may sit intraword)\n { pattern: /(\\*\\*\\*|\\*\\*|\\*|~~)(?=\\S)([\\s\\S]*?\\S)\\1/g, replacement: \"$2\" },\n // emphasis with _ - only at word boundaries. CommonMark does not treat\n // intraword underscores as emphasis, so identifiers like first_name stay\n // intact (and stay \"plain\"). $1 keeps the boundary char, $3 the inner text.\n {\n pattern: /(^|[^A-Za-z0-9])(___|__|_)(?=\\S)([\\s\\S]*?\\S)\\2(?![A-Za-z0-9])/g,\n replacement: \"$1$3\",\n },\n // headings: drop the leading marker\n { pattern: /^[ \\t]*#{1,6}[ \\t]+/gm, replacement: \"\" },\n // blockquote markers\n { pattern: /^[ \\t]*>[ \\t]?/gm, replacement: \"\" },\n // list markers (bullet and ordered)\n { pattern: /^[ \\t]*(?:[-*+]|\\d+[.)])[ \\t]+/gm, replacement: \"\" },\n // table separator rows: |---|:--:| etc\n { pattern: /^[ \\t]*\\|?[ \\t]*:?-{2,}[-| :]*$/gm, replacement: \"\" },\n // remaining table pipes - cosmetic only: a lone pipe in prose is not a\n // table, so this rule does not flag the source as non-plain.\n { pattern: /\\|/g, replacement: \" \", structural: false },\n // raw HTML tags\n { pattern: /<\\/?[a-zA-Z][^>]*>/g, replacement: \"\" },\n // horizontal rules\n { pattern: /^[ \\t]*(?:[-*_][ \\t]*){3,}$/gm, replacement: \"\" },\n];\n\n/**\n * Convert markdown source to a single-line plain-text preview plus an\n * `isPlain` signal. One synchronous pass, no parser.\n */\nexport function markdownPreview(src: string): MarkdownPreview {\n if (!src) return { text: \"\", isPlain: true };\n let working = src;\n let hadMarkup = false;\n for (const rule of RULES) {\n const next = working.replace(rule.pattern, rule.replacement);\n if (next !== working && rule.structural !== false) hadMarkup = true;\n working = next;\n }\n const text = working.replace(/\\s+/g, \" \").trim();\n return { text, isPlain: !hadMarkup };\n}\n","// markdown: render a plain-string field as sanitized markdown. Distinct from\n// `rich_text_preview` (which renders the file-aware RichTextField shape with\n// {markdown, files}). This factory is the one consumer YAMLs reach for when\n// they want a simple markdown column on a `type: string`/`type: text` field.\n//\n// List vs detail surface:\n// - In list cells (ctx.surface === \"list\") rendering full markup inside a\n// narrow column produces cropped headings and half-rendered links; a\n// one-line plain-text preview goes in the cell (regex strip, no parser),\n// with the full rendered markup carried by a HoverCard popover on hover.\n// - In detail surfaces (ctx.surface \"detail\" or undefined), the inline\n// prose render is preserved.\n//\n// The `Markdown` wrapper is lazy: the heavy renderer + parser load on demand,\n// never in the eager bundle. Sanitization (skipHtml, javascript:-URI strip)\n// lives inside MarkdownRenderer.\nimport type { ReactElement } from \"react\";\nimport { HoverCard } from \"@/components/primitives\";\nimport { Markdown } from \"@/components/shared/Markdown\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { markdownPreview } from \"./markdownPreview\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nfunction renderMarkdown(src: string): ReactElement {\n return <Markdown content={src} />;\n}\n\nexport const markdownFactory: CellFactory = (ctx): CellRenderer => {\n const isList = ctx.surface === \"list\";\n return (value: unknown): CellOutput => {\n const str = value == null ? \"\" : String(value);\n if (!str) return EMPTY_CELL;\n if (!isList) return renderMarkdown(str);\n\n // List surface: plain-text preview in the cell. Plain content (no\n // markup) gets a native `title=` tooltip so we don't spawn a HoverCard\n // for cells that don't need a rich preview.\n const { text, isPlain } = markdownPreview(str);\n if (isPlain) {\n return <span title={text}>{text}</span>;\n }\n return (\n <HoverCard content={renderMarkdown(str)}>\n <span title={text}>{text}</span>\n </HoverCard>\n );\n };\n};\n","// password_mask: stateless display-mode renderer for secret-shaped fields.\n// Parity contract with legacy PasswordField.tsx:14: byte-equivalent output for\n// the same inputs (asserted by snapshot test). Render rules:\n// - empty / null value → \"Not set\" (italic, var(--text-4))\n// - \"[SET]\" sentinel OR any\n// non-empty string value → \"[SET]\" (mono, var(--text-3))\n//\n// MUST never emit the underlying value to the DOM, even in data-* attributes.\n// Any product change to this rendering (e.g. compact mask) is a separate plan.\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nconst SECRET_SENTINEL = \"[SET]\";\n\nconst SET_STYLE = { fontSize: 12.5, color: \"var(--text-3)\" } as const;\nconst EMPTY_STYLE = {\n fontSize: 12.5,\n color: \"var(--text-4)\",\n fontStyle: \"italic\",\n} as const;\n\nexport const passwordMaskFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n const hasExistingValue =\n value === SECRET_SENTINEL || (typeof value === \"string\" && value !== \"\");\n if (hasExistingValue) {\n return (\n <span className=\"mono\" style={SET_STYLE}>\n {SECRET_SENTINEL}\n </span>\n );\n }\n return <span style={EMPTY_STYLE}>Not set</span>;\n };\n};\n","// rich_text_preview: full sanitized markdown render for the RichText shape.\n// Parity contract with RichTextField's display branch: same `Markdown` wrapper,\n// same props, so output stays equivalent (asserted by parity.test.tsx).\n// - empty value renders a hyphen \"-\" (NOT em-dash) inside a span with\n// var(--text-4) color.\n// - non-empty value renders through the shared `Markdown` wrapper.\n// - sanitization (skipHtml, javascript:-URI strip) and declarion://file/<id>\n// resolution live inside MarkdownRenderer; passing `files` enables it.\n//\n// List vs detail surface:\n// - In list cells (ctx.surface === \"list\") rendering full markup with\n// possibly large image/link refs in a narrow column is unreadable; we\n// emit a plain-text preview span (regex strip, no parser) and carry the\n// rendered file-aware markup inside a HoverCard popover.\n// - In detail surfaces (ctx.surface \"detail\" or undefined), the inline\n// prose render is preserved.\n//\n// The `Markdown` wrapper is lazy: the heavy renderer + parser load on demand.\nimport type { ReactElement } from \"react\";\nimport { createRichTextValue } from \"@/lib/rich-text\";\nimport { HoverCard } from \"@/components/primitives\";\nimport type { HydratedFile } from \"@/types/files\";\nimport { Markdown } from \"@/components/shared/Markdown\";\nimport type { CellFactory, CellRenderer, CellOutput, RowRecord } from \"../registry\";\nimport { markdownPreview } from \"./markdownPreview\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nfunction renderRichMarkdown(\n markdown: string,\n files: Record<string, HydratedFile>,\n): ReactElement {\n return <Markdown content={markdown} files={files} />;\n}\n\nexport const richTextPreviewFactory: CellFactory = (ctx): CellRenderer => {\n const { fieldName } = ctx;\n const isList = ctx.surface === \"list\";\n return (value: unknown, record: RowRecord): CellOutput => {\n const inlineFilesValue = (record?.$files as Record<string, unknown> | undefined)?.[fieldName];\n const rich = createRichTextValue(value, inlineFilesValue);\n if (!rich.markdown) {\n return EMPTY_CELL;\n }\n if (!isList) return renderRichMarkdown(rich.markdown, rich.files);\n\n // List surface: plain-text preview in the cell. Plain content (no\n // markup) gets a native title-only tooltip; marked-up content gets a\n // HoverCard with the file-aware markdown render.\n const { text, isPlain } = markdownPreview(rich.markdown);\n if (isPlain) {\n return <span title={text}>{text}</span>;\n }\n return (\n <HoverCard content={renderRichMarkdown(rich.markdown, rich.files)}>\n <span title={text}>{text}</span>\n </HoverCard>\n );\n };\n};\n","// multilang_inline: render the first available locale value of a LangMap-shaped\n// value (multilang / multilang_text). Parity contract with legacy\n// MultilangField.tsx:25 / MultilangTextField.tsx:25:\n// - object value: render the caller-locale entry if non-empty, else the\n// first non-empty entry, else em-dash.\n// - bare-string value: coerce to { en: <value> } before lookup, mirroring\n// legacy parseLangMap (locked in for byte-equivalence).\n// - null / undefined: em-dash.\n//\n// Wrapper element follows field.type:\n// - multilang → <span> with `font-size: 12.5px`\n// - multilang_text → <p> with `white-space: pre-wrap; margin: 0px`\n//\n// Per plan §9, `lang` and `dir=\"auto\"` MUST be set on the wrapper so RTL/LTR\n// mixed content resolves correctly. `lang` follows the locale that supplied\n// the displayed text (which may be the fallback, not ctx.locale).\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\ntype LangMap = Record<string, string>;\n\nconst SPAN_STYLE = { fontSize: 12.5 } as const;\nconst PARA_STYLE = { fontSize: 12.5, whiteSpace: \"pre-wrap\", margin: 0 } as const;\n\nfunction parseLangMap(value: unknown): LangMap {\n if (value == null) return {};\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as LangMap;\n }\n if (typeof value === \"string\") {\n return { en: value };\n }\n return {};\n}\n\n// pickEntry returns [locale, text] for the entry the cell should display, or\n// null if no non-empty entry exists. Preference order:\n// 1. ctx.locale (if non-empty for that key)\n// 2. first non-empty entry (insertion order, mirrors Object.values()[0]).\nfunction pickEntry(map: LangMap, preferred?: string): [string, string] | null {\n if (preferred && typeof map[preferred] === \"string\" && map[preferred] !== \"\") {\n return [preferred, map[preferred]];\n }\n for (const [key, val] of Object.entries(map)) {\n if (typeof val === \"string\" && val !== \"\") return [key, val];\n }\n return null;\n}\n\nexport const multilangInlineFactory: CellFactory = (ctx): CellRenderer => {\n const { field, locale } = ctx;\n const isLong = field.type === \"multilang_text\";\n return (value: unknown): CellOutput => {\n const map = parseLangMap(value);\n const entry = pickEntry(map, locale);\n if (!entry) {\n // Empty case: keep wrapper element + style consistent with legacy\n // snapshots (span vs p). lang/dir are intentionally omitted on the\n // dash placeholder — there is no language to declare.\n if (isLong) {\n return <p style={PARA_STYLE}>—</p>;\n }\n return <span style={SPAN_STYLE}>—</span>;\n }\n const [lang, text] = entry;\n if (isLong) {\n return (\n <p style={PARA_STYLE} lang={lang} dir=\"auto\">\n {text}\n </p>\n );\n }\n return (\n <span style={SPAN_STYLE} lang={lang} dir=\"auto\">\n {text}\n </span>\n );\n };\n};\n","// Cell-renderer registry (1a.5).\n//\n// Display-mode rendering for entity table cells, detail-page fields, and\n// QuickPeek bodies. Keyed on `field.display.widget` (engine fills smart\n// defaults at YAML-load time, so this lookup never falls back to type-based\n// dispatch in the hot path).\n//\n// Architecture:\n// - Each renderer is a *factory* that closes over schema lookups\n// (status-group palette, currency formatter, bool labels, value_map)\n// and returns a `(value, record) => ReactNode` closure.\n// - `resolveCellRenderer(ctx)` looks up the factory by widget, calls it\n// once per column / per detail field, and is cached by EntityField\n// identity via a WeakMap so repeated calls during a render reuse the\n// same closure.\n// - The cell hot path is a single bound-function call. No per-row\n// `field.type` dispatch, no per-row schema traversal.\n\nimport type { ReactElement } from \"react\";\nimport type { EntityField, Entity, Screen } from \"@/types/schema\";\n\nexport type RowRecord = Record<string, unknown>;\n\n// CellOutput narrows the renderer return to the perf-correct shape.\n//\n// - `string` and `number` commit as text nodes with no fiber overhead. ~90%\n// of cells (text, number-formatted, date-formatted, code, badge labels)\n// should return one of these.\n// - `ReactElement` is the deliberate path for cells that need DOM (markdown\n// HoverCard, image, link with onClick, badge with color). One element per\n// cell, not a wrapping `<span>` around plain text - the latter is a 2x\n// mount-time regression at viewport scale (caught by sync.test.tsx perf\n// gate; see docs/plans/2026-05-09-virtual-list-100k.md §1).\n//\n// `ReactNode` (the React-default) also includes arrays, fragments, booleans,\n// null, undefined. Those legal but expensive shapes are deliberately excluded\n// here. Factories that need a multi-element output MUST wrap in `<>...</>`\n// (a Fragment is a ReactElement). Factories that previously returned `null`\n// MUST return the `\"—\"` em-dash placeholder string instead.\nexport type CellOutput = string | number | ReactElement;\n\nexport type CellRenderer = (value: unknown, record: RowRecord) => CellOutput;\n\nexport type RefsMap = Record<string, Record<string, Record<string, unknown>>>;\n\nexport interface CellResolveCtx {\n field: EntityField;\n fieldName: string;\n // surface: \"list\" indicates the cell is rendered inside a row in a table.\n // Branch-aware factories (markdown, rich_text_preview) emit a plain-text\n // preview + HoverCard for marked-up content in this surface; plain content\n // uses a native title-only tooltip. Undefined or \"detail\" preserves the\n // legacy inline render. Callers that render lists MUST pass \"list\"; detail\n // surfaces may omit. See docs/list-rendering.md.\n surface?: \"list\" | \"detail\";\n entity?: Entity;\n entities?: Record<string, Entity>;\n screens?: Record<string, Screen>;\n // refs: $refs payload from the current list/detail response. Pass either a\n // snapshot or a getter - list pages typically pass a getter (() =>\n // refsRef.current) so the cached factory reads the latest refs after a\n // refetch without rebuilding columns.\n refs?: RefsMap | (() => RefsMap | undefined);\n // locale: user's resolved language code (non-empty per plan §3 contract).\n // Every direct caller MUST supply this via useUserLocale() so factories\n // (time_ago, multilang_inline, money, ...) format consistently. The hook\n // guarantees a non-empty string; CI gate enforces propagation.\n locale: string;\n // No `navigate`: cells render plain real `<a href>` and the global link\n // interceptor (Layout) owns the click. This removed the per-cell drift\n // vector that let ref_link cells forget navigation and full-load the app.\n}\n\nexport type CellFactory = (ctx: CellResolveCtx) => CellRenderer;\n\nimport { textFactory } from \"./factories/text\";\nimport { boolPillFactory } from \"./factories/boolPill\";\nimport { badgeFactory } from \"./factories/badge\";\nimport { statusPillFactory } from \"./factories/statusPill\";\nimport { tagListFactory } from \"./factories/tagList\";\nimport { timeAgoFactory, timestampFullFactory } from \"./factories/timestamp\";\nimport { nextRunFactory } from \"./factories/nextRun\";\nimport { moneyFactory } from \"./factories/money\";\nimport { refLinkFactory } from \"./factories/refLink\";\nimport { urlFactory } from \"./factories/url\";\nimport { emailFactory } from \"./factories/email\";\nimport { phoneFactory } from \"./factories/phone\";\nimport { numberFactory } from \"./factories/number\";\nimport { codeFactory } from \"./factories/code\";\nimport { linkFactory } from \"./factories/link\";\nimport { jsonFactory } from \"./factories/json\";\nimport { markdownFactory } from \"./factories/markdown\";\nimport { passwordMaskFactory } from \"./factories/passwordMask\";\nimport { richTextPreviewFactory } from \"./factories/richTextPreview\";\nimport { multilangInlineFactory } from \"./factories/multilangInline\";\n\nconst REGISTRY: Record<string, CellFactory> = {\n text: textFactory,\n bool_pill: boolPillFactory,\n badge: badgeFactory,\n status_pill: statusPillFactory,\n tag_list: tagListFactory,\n time_ago: timeAgoFactory,\n timestamp_full: timestampFullFactory,\n next_run: nextRunFactory,\n money: moneyFactory,\n ref_link: refLinkFactory,\n url: urlFactory,\n email: emailFactory,\n phone: phoneFactory,\n number: numberFactory,\n code: codeFactory,\n link: linkFactory,\n json: jsonFactory,\n markdown: markdownFactory,\n password_mask: passwordMaskFactory,\n rich_text_preview: richTextPreviewFactory,\n multilang_inline: multilangInlineFactory,\n};\n\n// REGISTRY_WIDGETS is the sorted list of registered widget names. Exported so\n// the cross-language sync test can compare TS widget keys against\n// golang/.testdata/display_widgets.json without duplicating the list.\nexport const REGISTRY_WIDGETS: readonly string[] = Object.keys(REGISTRY).sort();\n\n// resolveCellRenderer instantiates a fresh renderer closure per call. We\n// intentionally do NOT cache by EntityField identity: the closure captures\n// ctx-derived values (entities, screens, locale, refs accessor) at\n// build time, and a key that ignored those would return a closure built with\n// stale or missing context — e.g. a ref_link resolved before $refs arrived\n// would keep using the empty refs forever. Hot paths (SmartListPage column\n// useMemo, ChildrenTable column useMemo, FieldsBlock per-field meta) already\n// memoize at the right granularity; layering an identity-only cache here\n// would only re-introduce the staleness bug.\nexport function resolveCellRenderer(ctx: CellResolveCtx): CellRenderer {\n const widget = ctx.field.display?.widget ?? \"text\";\n const factory = REGISTRY[widget];\n if (!factory) {\n throw new Error(\n `resolveCellRenderer: no factory registered for widget \"${widget}\" (field \"${ctx.fieldName}\"). The engine must stamp a smart default at YAML-load time; an unknown widget here indicates an out-of-sync allow-list.`,\n );\n }\n return factory(ctx);\n}\n","import type { EntityField, Entity, Screen } from \"@/types/schema\";\nimport { FIELD_TYPES, type FieldType } from \"@/types/fieldType\";\nimport { StringField } from \"./StringField\";\nimport { TextField } from \"./TextField\";\nimport { EnumField } from \"./EnumField\";\nimport { EmailField } from \"./EmailField\";\nimport { UrlField } from \"./UrlField\";\nimport { PhoneField } from \"./PhoneField\";\nimport { TimestampField } from \"./TimestampField\";\nimport { BoolField } from \"./BoolField\";\nimport { NumberField } from \"./NumberField\";\nimport { RefField } from \"./RefField\";\nimport { JsonField } from \"./JsonField\";\nimport { MultilangField } from \"./MultilangField\";\nimport { MultilangTextField } from \"./MultilangTextField\";\nimport { StructureField } from \"./StructureField\";\nimport { SecretField } from \"./SecretField\";\nimport { PasswordField } from \"./PasswordField\";\nimport { StringArrayField } from \"./StringArrayField\";\nimport { IntArrayField } from \"./IntArrayField\";\nimport { RichTextField } from \"./RichTextField\";\nimport { resolveCellRenderer } from \"./cells/registry\";\n\n// RefsMap is the $refs structure from list/detail API responses.\n// Shape: { entityCode: { recordId: { field: value, ... } } }\nexport type RefsMap = Record<string, Record<string, Record<string, unknown>>>;\n\nexport interface FieldRendererProps {\n field: EntityField;\n entityCode?: string;\n fieldName: string;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n // Accessibility (Finding 2): a stable per-field id used to pair a form input\n // with its <label htmlFor>. Edit-mode renderers MUST forward it as `id` on\n // the <input>/<textarea> they own (and `name={fieldName}`). Button-based\n // renderers (EnumField/RefField render a <button>, which cannot be the\n // target of htmlFor) instead point `aria-labelledby` at `labelId`.\n // Both are optional: standalone callers (StructureField nested fields,\n // tests) may omit them, in which case renderers fall back to no id/name.\n fieldId?: string;\n labelId?: string;\n record?: Record<string, unknown>;\n refs?: RefsMap;\n // fill: renderer should stretch to fill its flex parent (relevant for\n // resizable containers like the activity composer). Currently honored by\n // TextField edit mode.\n fill?: boolean;\n // compact: renderer is inside a fixed-height row (table cell, inline edit).\n // Multi-line-capable renderers (TextField for type:text) MUST render a\n // single-line input in this mode so the row height stays predictable.\n // Honored by TextField; other renderers may ignore it.\n compact?: boolean;\n surface?: \"list\" | \"detail\";\n // 1a.5 cell-renderer ctx. Display-mode rendering for fields whose\n // display.widget names a registered cell renderer (badge, bool_pill,\n // tag_list, time_ago, money, ref_link, …) goes through the cell registry.\n // entity/entities/screens are the schema lookups the registry closes over\n // once per column. Edit mode ignores all of these.\n entity?: Entity;\n entities?: Record<string, Entity>;\n screens?: Record<string, Screen>;\n // locale: user-resolved language code, required per plan §3 (\"CellResolveCtx.locale\n // is mandatory, not optional\"). Callers supply it via useUserLocale(). The\n // dispatcher passes it through to the cell registry; edit-mode renderers\n // generally ignore it (single-locale form inputs).\n locale: string;\n}\n\ntype FieldRenderer = React.ComponentType<FieldRendererProps>;\n\n// editRegistry: edit-mode dispatcher keyed by FieldType (not display.widget).\n// Populated per plan §5 of 2026-04-29-field-rendering-two-registry-cut.\n//\n// MUST be total over `FieldType`. The CI sync gate\n// (`golang/.testdata/field_types.json`) asserts that\n// `Object.keys(editRegistry).sort()` matches Go's enum exactly. Adding a new\n// FieldType requires a corresponding entry here; the dispatcher below throws\n// (no fallback) when this lookup misses.\nexport const editRegistry: Record<FieldType, FieldRenderer> = {\n string: StringField,\n text: TextField,\n rich_text: RichTextField,\n int: NumberField,\n float: NumberField,\n decimal: NumberField,\n bool: BoolField,\n timestamp: TimestampField,\n date: TimestampField,\n time: TimestampField,\n enum: EnumField,\n email: EmailField,\n url: UrlField,\n phone: PhoneField,\n uuid: StringField,\n // bytes is a bytea column surfaced as a lowercase-hex string; it edits as a\n // plain text input, same as uuid and tags.\n bytes: StringField,\n ref: RefField,\n json: JsonField,\n tags: StringField,\n string_array: StringArrayField,\n int_array: IntArrayField,\n // uuid_array is a UUID[] column; uuids are strings at the UI level, so it\n // edits with the same component as string_array.\n uuid_array: StringArrayField,\n multilang: MultilangField,\n multilang_text: MultilangTextField,\n structure: StructureField,\n secret: SecretField,\n password: PasswordField,\n};\n\n// Startup-time totality check (plan §3: \"Lookup misses MUST throw at startup,\n// not at render\"). The TS compiler narrowing on `Record<FieldType, …>` already\n// covers compile-time totality, but the runtime list mirrors the Go enum and\n// re-asserting equality here catches drift introduced by deliberate `any`\n// casts or merge conflicts in the registry literal.\nfor (const t of FIELD_TYPES) {\n if (!editRegistry[t]) {\n throw new Error(\n `editRegistry: missing entry for FieldType \"${t}\". The TS union (types/fieldType.ts) and editRegistry must stay in sync with golang/internal/engine/types.go.`,\n );\n }\n}\n\n// renderField is the dispatcher. Per plan §3 the rule chain is exactly:\n// 1. field.type === \"json\" && field.structure -> StructureField\n// 2. mode === \"edit\" -> editRegistry[field.type]\n// 3. otherwise (display mode) -> displayRegistry (cells)\n// No fallback. Lookup misses MUST throw, surfacing engine/SDK drift loudly\n// instead of demoting fields to plain text (which is the original-sin\n// regression this plan closes).\nexport function renderField(props: FieldRendererProps): React.ReactNode {\n // Rule 1: structured JSON renders via StructureField in BOTH edit and\n // display modes (it owns its own layout for both). Must run before rule 2\n // so structure-typed fields don't fall into editRegistry[\"json\"].\n if (props.field.type === \"json\" && props.field.structure) {\n return <StructureField {...props} />;\n }\n\n // Rule 2: edit dispatch by FieldType. Widget never re-routes edit mode.\n if (props.mode === \"edit\") {\n const t = props.field.type as FieldType;\n const Editor = editRegistry[t];\n if (!Editor) {\n throw new Error(\n `renderField: no edit-mode renderer for FieldType \"${props.field.type}\" (field \"${props.fieldName}\"). editRegistry must be total over FieldType; check types/fieldType.ts and components/fields/index.tsx.`,\n );\n }\n return <Editor {...props} />;\n }\n\n // Rule 3: display dispatch by widget through the cell registry. The engine\n // stamps a smart default at YAML-load time, so `widget` is non-empty for\n // every entity field; resolveCellRenderer throws on unknown widgets.\n const widget = props.field.display?.widget;\n if (!widget) {\n throw new Error(\n `renderField: display mode requires a non-empty field.display.widget (field \"${props.fieldName}\", type \"${props.field.type}\"). The engine must stamp a smart default; an empty widget here means the field bypassed ResolveDefaultWidgets.`,\n );\n }\n const renderer = resolveCellRenderer({\n field: props.field,\n fieldName: props.fieldName,\n surface: props.surface ?? \"detail\",\n entity: props.entity,\n entities: props.entities,\n screens: props.screens,\n // Pass through the refs payload (snapshot or getter) verbatim; the\n // factory closes over it and per-cell rendering is a single bound call.\n refs: props.refs as Record<string, Record<string, Record<string, unknown>>> | undefined,\n locale: props.locale,\n });\n return renderer(props.value, props.record ?? {});\n}\n","// useUserLocale resolves the active language code threaded through cell\n// factories' CellResolveCtx.locale. Per the\n// 2026-04-29-field-rendering-two-registry-cut plan (\"Locale source\n// contract\"), CellResolveCtx.locale is mandatory; every direct caller of\n// resolveCellRenderer (SmartListPage, ChildrenTable, the renderField\n// dispatcher) MUST consume this hook and pass the result.\n//\n// Resolution order (first non-empty wins):\n// 1. The authenticated user's preferred language, if surfaced on AuthUser.\n// The platform does not yet ship a profile field for this; the hook\n// reads `(user as { language?: string }).language` defensively so the\n// moment a profile field lands the resolution path lights up without\n// another change here.\n// 2. The first entry of `schema.languages` (always populated for a loaded\n// schema; this is the consumer-app default language).\n// 3. `navigator.language` reduced to its primary subtag (en-US -> en) as a\n// last-resort browser fallback.\n// 4. Hard-coded \"en\" if everything above is unavailable (e.g. SSR before\n// schema loads, no navigator). Returning a non-empty string is part of\n// the public contract; factories MAY assume it.\n\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useSchema } from \"./useSchema\";\n\nconst DEFAULT_LOCALE = \"en\";\n\nfunction navigatorPrimarySubtag(): string | undefined {\n if (typeof navigator === \"undefined\") return undefined;\n const raw = navigator.language;\n if (!raw) return undefined;\n const primary = raw.split(\"-\")[0];\n return primary || undefined;\n}\n\nexport function useUserLocale(): string {\n const user = useAuthStore((s) => s.user);\n const { data: schema } = useSchema();\n\n // Step 1: authenticated user profile language (forward-compat: not yet on\n // the AuthUser interface but tolerated here so the moment we add it the\n // resolution lights up).\n const profile = (user as { language?: string } | null)?.language;\n if (profile && profile.trim()) return profile;\n\n // Step 2: first language declared by the consumer schema.\n const first = schema?.languages?.[0]?.code;\n if (first && first.trim()) return first;\n\n // Step 3: browser default.\n const nav = navigatorPrimarySubtag();\n if (nav) return nav;\n\n // Step 4: hard fallback.\n return DEFAULT_LOCALE;\n}\n","// Shared chrome for the platform's detail-page data tables - the child-entity\n// tables (ChildrenTable / EditableChildrenTable / DraggableChildrenTable), the\n// associated-entity tables (AssociatedBlock) and the association-tab tables\n// (AssociationTabs).\n//\n// Single source of truth: a styling decision (column-header case, spacing,\n// borders, colors) is one edit here, not one edit per table. Before this,\n// the same <table>/<th>/<td> styles were copy-pasted across five components.\n\nimport type { CSSProperties } from \"react\";\n\n// The <table> element.\nexport const dataTableStyle: CSSProperties = {\n width: \"100%\",\n fontSize: 12.5,\n borderCollapse: \"separate\",\n borderSpacing: 0,\n};\n\n// Column-header cell (<th>). Sentence case - never all-caps.\nexport const dataTableHeadCellStyle: CSSProperties = {\n height: 30,\n padding: \"0 12px\",\n textAlign: \"left\",\n fontWeight: 600,\n fontSize: 11,\n color: \"var(--text-3)\",\n borderBottom: \"1px solid var(--divider)\",\n};\n\n// Body cell (<td>). Compact-action cells (row kebabs, drag handles) spread\n// this and override `padding` / `width`.\nexport const dataTableCellStyle: CSSProperties = {\n padding: \"6px 12px\",\n borderBottom: \"1px solid var(--divider)\",\n color: \"var(--text-2)\",\n verticalAlign: \"middle\",\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dataTableStyles-BwnbXviH.js","names":["#items","#index"],"sources":["../src/components/primitives/cx.ts","../src/components/primitives/Icons.tsx","../src/components/primitives/Btn.tsx","../src/components/primitives/IconBtn.tsx","../src/components/primitives/Pill.tsx","../src/components/primitives/Kbd.tsx","../src/components/primitives/Avatar.tsx","../src/components/primitives/BrandGlyph.tsx","../src/components/primitives/Dropdown.tsx","../src/components/primitives/HoverCard.tsx","../src/components/primitives/Chip.tsx","../src/components/primitives/SectionCard.tsx","../src/components/primitives/RecordIdBadge.tsx","../src/components/primitives/RowField.tsx","../src/components/primitives/BoolToggle.tsx","../src/components/primitives/MenuItem.tsx","../src/components/primitives/Check.tsx","../src/components/primitives/Spinner.tsx","../src/components/primitives/ClassifiedFieldLocked.tsx","../src/components/primitives/Fields.tsx","../src/types/ordmap.ts","../src/types/schema.ts","../src/api/schema.ts","../src/api/auth.ts","../src/stores/auth.ts","../src/hooks/useSchema.ts","../src/stores/appearance.ts","../src/components/shared/DynamicIcon.tsx","../src/api/data.ts","../src/components/shared/Markdown.tsx","../src/types/fieldType.ts","../src/components/shared/CopyButton.tsx","../src/components/fields/StringField.tsx","../src/components/fields/TextField.tsx","../src/components/fields/EnumField.tsx","../src/components/fields/EmailField.tsx","../src/components/fields/UrlField.tsx","../src/components/fields/PhoneField.tsx","../src/lib/timestamp.ts","../src/components/fields/TimestampField.tsx","../src/components/fields/BoolField.tsx","../src/components/fields/NumberField.tsx","../src/hooks/useEntityData.ts","../src/hooks/useEntity.ts","../src/components/fields/RefField.tsx","../src/components/fields/JsonField.tsx","../src/components/fields/MultilangField.tsx","../src/components/fields/MultilangTextField.tsx","../src/components/fields/StructureField.tsx","../src/components/fields/SecretField.tsx","../src/components/fields/PasswordField.tsx","../src/components/fields/StringArrayField.tsx","../src/components/fields/IntArrayField.tsx","../src/components/file-widgets/registry.ts","../src/components/file-widgets/cropper.ts","../src/components/file-widgets/ImageWidget.tsx","../src/components/file-widgets/SquareImage.tsx","../src/components/file-widgets/CircleImage.tsx","../src/components/file-widgets/WideBanner.tsx","../src/components/file-widgets/GridLazy.tsx","../src/components/file-widgets/DocumentCard.tsx","../src/components/file-widgets/FileList.tsx","../src/components/file-widgets/LabeledSlots.tsx","../src/components/file-widgets/builtins.ts","../src/components/file-widgets/host.tsx","../src/components/file-widgets/payload.ts","../src/components/file-widgets/index.ts","../src/components/fields/RichTextField.tsx","../src/components/fields/cells/factories/text.ts","../src/components/fields/cells/factories/boolPill.tsx","../src/components/fields/cells/factories/badge.tsx","../src/components/fields/cells/factories/statusPill.tsx","../src/components/fields/cells/factories/tagList.tsx","../src/components/fields/cells/factories/timestamp.tsx","../src/components/fields/cells/factories/nextRun.tsx","../src/components/fields/cells/factories/money.ts","../src/components/fields/cells/factories/refLink.tsx","../src/components/fields/cells/factories/url-helpers.ts","../src/components/fields/cells/factories/host-icons.tsx","../src/components/fields/cells/factories/emptyCell.tsx","../src/components/fields/cells/factories/url.tsx","../src/components/fields/cells/factories/email.tsx","../src/components/fields/cells/factories/phone.tsx","../src/components/fields/cells/factories/number.tsx","../src/components/fields/cells/factories/code.tsx","../src/components/fields/cells/factories/link.tsx","../src/components/fields/cells/factories/json.tsx","../src/components/fields/cells/factories/markdownPreview.ts","../src/components/fields/cells/factories/markdown.tsx","../src/components/fields/cells/factories/passwordMask.tsx","../src/components/fields/cells/factories/richTextPreview.tsx","../src/components/fields/cells/factories/multilangInline.tsx","../src/components/fields/cells/registry.ts","../src/components/fields/index.tsx","../src/hooks/useUserLocale.ts","../src/components/primitives/dataTableStyles.ts"],"sourcesContent":["export function cx(...a: Array<string | false | null | undefined>): string {\n return a.filter(Boolean).join(\" \");\n}\n","// Minimal, crisp icon set matching Lucide-style stroke (1.5) — all 14px/16px friendly.\n// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/icons.jsx.\nimport type { CSSProperties, ReactNode, FC } from \"react\";\n\nexport type IconProps = {\n\tsize?: number;\n\tcls?: string;\n\tstyle?: CSSProperties;\n};\n\nconst I = (path: ReactNode, opts: { sw?: number } = {}): FC<IconProps> => {\n\tconst Component: FC<IconProps> = ({ size = 14, cls = \"\", style = {} }) => (\n\t\t<svg\n\t\t\twidth={size}\n\t\t\theight={size}\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth={opts.sw ?? 1.5}\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tclassName={cls}\n\t\t\tstyle={style}\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t{path}\n\t\t</svg>\n\t);\n\treturn Component;\n};\n\nexport const Icon = {\n\t// App rail\n\thome: I(\n\t\t<>\n\t\t\t<path d=\"M3 10.5 12 3l9 7.5\" />\n\t\t\t<path d=\"M5 9.5V20a1 1 0 0 0 1 1h4v-6h4v6h4a1 1 0 0 0 1-1V9.5\" />\n\t\t</>,\n\t),\n\tinbox: I(\n\t\t<>\n\t\t\t<path d=\"M4 13v5a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5\" />\n\t\t\t<path d=\"M4 13h5l1 2h4l1-2h5\" />\n\t\t\t<path d=\"M4 13 7 5a2 2 0 0 1 2-1h6a2 2 0 0 1 2 1l3 8\" />\n\t\t</>,\n\t),\n\tflow: I(\n\t\t<>\n\t\t\t<circle cx=\"6\" cy=\"6\" r=\"2\" />\n\t\t\t<circle cx=\"18\" cy=\"6\" r=\"2\" />\n\t\t\t<circle cx=\"6\" cy=\"18\" r=\"2\" />\n\t\t\t<circle cx=\"18\" cy=\"18\" r=\"2\" />\n\t\t\t<path d=\"M8 6h8M6 8v8M18 8v8M8 18h8\" />\n\t\t</>,\n\t),\n\tpipeline: I(\n\t\t<>\n\t\t\t<path d=\"M3 6h13l5 3-5 3H3z\" />\n\t\t\t<path d=\"M3 13h9\" />\n\t\t\t<path d=\"M3 18h13\" />\n\t\t</>,\n\t),\n\tleads: I(\n\t\t<>\n\t\t\t<circle cx=\"9\" cy=\"8\" r=\"3\" />\n\t\t\t<path d=\"M3 20c0-3 3-5 6-5s6 2 6 5\" />\n\t\t\t<path d=\"M17 10l2 2 4-4\" />\n\t\t</>,\n\t),\n\tcompany: I(\n\t\t<>\n\t\t\t<path d=\"M4 21V6a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v15\" />\n\t\t\t<path d=\"M15 21V11h4a1 1 0 0 1 1 1v9\" />\n\t\t\t<path d=\"M7 9h2M7 13h2M7 17h2M11 9h1M11 13h1M11 17h1\" />\n\t\t</>,\n\t),\n\tactivity: I(\n\t\t<>\n\t\t\t<path d=\"M3 12h4l3-8 4 16 3-8h4\" />\n\t\t</>,\n\t),\n\tusers: I(\n\t\t<>\n\t\t\t<circle cx=\"9\" cy=\"8\" r=\"3\" />\n\t\t\t<path d=\"M2 21c0-3.5 3-6 7-6s7 2.5 7 6\" />\n\t\t\t<path d=\"M16 3.5a3 3 0 0 1 0 6\" />\n\t\t\t<path d=\"M22 20c0-2.5-1.5-5-4-6\" />\n\t\t</>,\n\t),\n\ttenant: I(\n\t\t<>\n\t\t\t<path d=\"M3 21V9l6-4 6 4M3 21h18\" />\n\t\t\t<path d=\"M15 21V9\" />\n\t\t\t<path d=\"M19 21V13l2-2\" />\n\t\t\t<path d=\"M7 13h2M7 17h2M11 13h1M11 17h1\" />\n\t\t</>,\n\t),\n\tshield: I(\n\t\t<>\n\t\t\t<path d=\"M12 3 4 6v6c0 4.5 3.5 8 8 9 4.5-1 8-4.5 8-9V6z\" />\n\t\t</>,\n\t),\n\tkey: I(\n\t\t<>\n\t\t\t<circle cx=\"8\" cy=\"14\" r=\"4\" />\n\t\t\t<path d=\"m11 11 9-9M17 5l3 3M15 7l3 3\" />\n\t\t</>,\n\t),\n\tgroup: I(\n\t\t<>\n\t\t\t<circle cx=\"8\" cy=\"10\" r=\"3\" />\n\t\t\t<circle cx=\"17\" cy=\"8\" r=\"2\" />\n\t\t\t<path d=\"M2 20c0-3 2.5-5 6-5s6 2 6 5\" />\n\t\t\t<path d=\"M15 16c2-1 4-1 6 0\" />\n\t\t</>,\n\t),\n\tidp: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n\t\t\t<path d=\"M3 10h18\" />\n\t\t\t<path d=\"M7 15h4\" />\n\t\t</>,\n\t),\n\taudit: I(\n\t\t<>\n\t\t\t<path d=\"M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z\" />\n\t\t\t<path d=\"M14 3v6h6\" />\n\t\t\t<path d=\"M8 13h8M8 17h5\" />\n\t\t</>,\n\t),\n\tlog: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n\t\t\t<path d=\"M7 9h10M7 13h10M7 17h6\" />\n\t\t</>,\n\t),\n\thandlers: I(\n\t\t<>\n\t\t\t<path d=\"M10 4 4 8v8l6 4 6-4\" />\n\t\t\t<path d=\"M16 4l4 2.5v8L16 17\" />\n\t\t\t<path d=\"m10 12 6-3.5\" />\n\t\t</>,\n\t),\n\tjobs: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"6\" width=\"18\" height=\"13\" rx=\"2\" />\n\t\t\t<path d=\"M8 6V4h8v2\" />\n\t\t\t<path d=\"M12 10v5\" />\n\t\t\t<path d=\"M10 12h4\" />\n\t\t</>,\n\t),\n\tsched: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"13\" r=\"8\" />\n\t\t\t<path d=\"M12 9v4l3 2\" />\n\t\t\t<path d=\"M9 3h6\" />\n\t\t</>,\n\t),\n\tentity: I(\n\t\t<>\n\t\t\t<ellipse cx=\"12\" cy=\"6\" rx=\"8\" ry=\"3\" />\n\t\t\t<path d=\"M4 6v6c0 1.7 3.6 3 8 3s8-1.3 8-3V6\" />\n\t\t\t<path d=\"M4 12v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6\" />\n\t\t</>,\n\t),\n\tfield: I(\n\t\t<>\n\t\t\t<path d=\"M4 6h16M4 12h10M4 18h16\" />\n\t\t</>,\n\t),\n\taction: I(\n\t\t<>\n\t\t\t<path d=\"M13 3 4 14h6l-1 7 9-11h-6z\" />\n\t\t</>,\n\t),\n\tcode: I(\n\t\t<>\n\t\t\t<path d=\"m8 8-4 4 4 4M16 8l4 4-4 4M14 4l-4 16\" />\n\t\t</>,\n\t),\n\n\t// Toolbar\n\tsearch: I(\n\t\t<>\n\t\t\t<circle cx=\"11\" cy=\"11\" r=\"7\" />\n\t\t\t<path d=\"m20 20-3.5-3.5\" />\n\t\t</>,\n\t),\n\tfilter: I(\n\t\t<>\n\t\t\t<path d=\"M3 5h18l-7 9v6l-4-2v-4z\" />\n\t\t</>,\n\t),\n\tcolumns: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"1\" />\n\t\t\t<path d=\"M9 4v16M15 4v16\" />\n\t\t</>,\n\t),\n\tplus: I(\n\t\t<>\n\t\t\t<path d=\"M12 5v14M5 12h14\" />\n\t\t</>,\n\t),\n\tminus: I(\n\t\t<>\n\t\t\t<path d=\"M5 12h14\" />\n\t\t</>,\n\t),\n\tsort: I(\n\t\t<>\n\t\t\t<path d=\"M8 4v16l-3-3M8 4l3 3\" />\n\t\t\t<path d=\"M16 20V4l-3 3M16 20l3-3\" />\n\t\t</>,\n\t),\n\tmore: I(\n\t\t<>\n\t\t\t<circle cx=\"5\" cy=\"12\" r=\"1.2\" />\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"1.2\" />\n\t\t\t<circle cx=\"19\" cy=\"12\" r=\"1.2\" />\n\t\t</>,\n\t\t{ sw: 2 },\n\t),\n\tx: I(\n\t\t<>\n\t\t\t<path d=\"M18 6 6 18M6 6l12 12\" />\n\t\t</>,\n\t),\n\tcheck: I(\n\t\t<>\n\t\t\t<path d=\"m5 12 5 5L20 7\" />\n\t\t</>,\n\t\t{ sw: 2 },\n\t),\n\tdown: I(\n\t\t<>\n\t\t\t<path d=\"m6 9 6 6 6-6\" />\n\t\t</>,\n\t),\n\tup: I(\n\t\t<>\n\t\t\t<path d=\"m6 15 6-6 6 6\" />\n\t\t</>,\n\t),\n\tright: I(\n\t\t<>\n\t\t\t<path d=\"m9 6 6 6-6 6\" />\n\t\t</>,\n\t),\n\tleft: I(\n\t\t<>\n\t\t\t<path d=\"m15 6-6 6 6 6\" />\n\t\t</>,\n\t),\n\tcheveron: I(\n\t\t<>\n\t\t\t<path d=\"m8 10 4 4 4-4\" />\n\t\t</>,\n\t),\n\tback: I(\n\t\t<>\n\t\t\t<path d=\"M19 12H5M12 19l-7-7 7-7\" />\n\t\t</>,\n\t),\n\n\t// Fields / actions\n\tcalendar: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" />\n\t\t\t<path d=\"M3 10h18\" />\n\t\t\t<path d=\"M8 3v4M16 3v4\" />\n\t\t</>,\n\t),\n\tclock: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M12 7v5l3 2\" />\n\t\t</>,\n\t),\n\tlock: I(\n\t\t<>\n\t\t\t<rect x=\"5\" y=\"11\" width=\"14\" height=\"9\" rx=\"2\" />\n\t\t\t<path d=\"M8 11V8a4 4 0 0 1 8 0v3\" />\n\t\t</>,\n\t),\n\temail: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n\t\t\t<path d=\"m3 7 9 6 9-6\" />\n\t\t</>,\n\t),\n\tlink: I(\n\t\t<>\n\t\t\t<path d=\"M10 14a5 5 0 0 0 7 0l3-3a5 5 0 1 0-7-7l-1 1\" />\n\t\t\t<path d=\"M14 10a5 5 0 0 0-7 0l-3 3a5 5 0 1 0 7 7l1-1\" />\n\t\t</>,\n\t),\n\thash: I(\n\t\t<>\n\t\t\t<path d=\"M5 9h14M5 15h14M10 3 8 21M16 3l-2 18\" />\n\t\t</>,\n\t),\n\teye: I(\n\t\t<>\n\t\t\t<path d=\"M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z\" />\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"3\" />\n\t\t</>,\n\t),\n\teyeOff: I(\n\t\t<>\n\t\t\t<path d=\"M3 3l18 18\" />\n\t\t\t<path d=\"M10.6 6.2A10 10 0 0 1 12 6c6.5 0 10 6 10 6a17 17 0 0 1-3.6 4.3M6.4 6.4A17 17 0 0 0 2 12s3.5 6 10 6c1.3 0 2.5-.2 3.6-.6\" />\n\t\t\t<path d=\"M9.9 9.9a3 3 0 0 0 4.2 4.2\" />\n\t\t</>,\n\t),\n\tcopy: I(\n\t\t<>\n\t\t\t<rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" />\n\t\t\t<path d=\"M5 15V5a2 2 0 0 1 2-2h10\" />\n\t\t</>,\n\t),\n\ttrash: I(\n\t\t<>\n\t\t\t<path d=\"M4 7h16M9 7V4h6v3M6 7l1 13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-13\" />\n\t\t</>,\n\t),\n\tedit: I(\n\t\t<>\n\t\t\t<path d=\"M4 20h4l11-11-4-4L4 16z\" />\n\t\t\t<path d=\"m13 6 4 4\" />\n\t\t</>,\n\t),\n\tsave: I(\n\t\t<>\n\t\t\t<path d=\"M4 5a2 2 0 0 1 2-2h10l4 4v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2z\" />\n\t\t\t<path d=\"M7 3v5h8V3M8 15h8v6H8z\" />\n\t\t</>,\n\t),\n\trefresh: I(\n\t\t<>\n\t\t\t<path d=\"M3 12a9 9 0 0 1 15-6.7L21 8\" />\n\t\t\t<path d=\"M21 3v5h-5\" />\n\t\t\t<path d=\"M21 12a9 9 0 0 1-15 6.7L3 16\" />\n\t\t\t<path d=\"M3 21v-5h5\" />\n\t\t</>,\n\t),\n\tdownload: I(\n\t\t<>\n\t\t\t<path d=\"M12 3v12\" />\n\t\t\t<path d=\"m7 10 5 5 5-5\" />\n\t\t\t<path d=\"M5 20h14\" />\n\t\t</>,\n\t),\n\tupload: I(\n\t\t<>\n\t\t\t<path d=\"M12 15V3\" />\n\t\t\t<path d=\"m7 8 5-5 5 5\" />\n\t\t\t<path d=\"M5 20h14\" />\n\t\t</>,\n\t),\n\tpaperclip: I(\n\t\t<>\n\t\t\t<path d=\"m21 10-9.2 9.2a5 5 0 1 1-7-7L14 3a3.5 3.5 0 0 1 5 5L9.8 17.2a2 2 0 1 1-3-3L15 6\" />\n\t\t</>,\n\t),\n\ttag: I(\n\t\t<>\n\t\t\t<path d=\"M4 4h7l9 9-7 7-9-9z\" />\n\t\t\t<circle cx=\"8\" cy=\"8\" r=\"1.5\" />\n\t\t</>,\n\t),\n\tbolt: I(\n\t\t<>\n\t\t\t<path d=\"M13 3 4 14h6l-1 7 9-11h-6z\" />\n\t\t</>,\n\t),\n\tbell: I(\n\t\t<>\n\t\t\t<path d=\"M18 16v-5a6 6 0 0 0-12 0v5l-2 3h16z\" />\n\t\t\t<path d=\"M10 20a2 2 0 0 0 4 0\" />\n\t\t</>,\n\t),\n\tai: I(\n\t\t<>\n\t\t\t<path d=\"M12 3v3M12 18v3M3 12h3M18 12h3M5.5 5.5l2 2M16.5 16.5l2 2M18.5 5.5l-2 2M7.5 16.5l-2 2\" />\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"3.5\" />\n\t\t</>,\n\t),\n\tsparkle: I(\n\t\t<>\n\t\t\t<path d=\"M12 3v4M12 17v4M3 12h4M17 12h4\" />\n\t\t\t<path d=\"m7 7 2 2M15 15l2 2M17 7l-2 2M9 15l-2 2\" />\n\t\t</>,\n\t),\n\tcommand: I(\n\t\t<>\n\t\t\t<path d=\"M9 3a3 3 0 1 1-3 3v12a3 3 0 1 1 3-3h6a3 3 0 1 1 3 3V6a3 3 0 1 1-3 3H9\" />\n\t\t</>,\n\t),\n\tmenu: I(\n\t\t<>\n\t\t\t<path d=\"M4 6h16M4 12h16M4 18h16\" />\n\t\t</>,\n\t),\n\tdot: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"4\" fill=\"currentColor\" />\n\t\t</>,\n\t),\n\tglobe: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M3 12h18M12 3c3 3 3 15 0 18-3-3-3-15 0-18\" />\n\t\t</>,\n\t),\n\tfolder: I(\n\t\t<>\n\t\t\t<path d=\"M3 6a1 1 0 0 1 1-1h5l2 2h8a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z\" />\n\t\t</>,\n\t),\n\tfile: I(\n\t\t<>\n\t\t\t<path d=\"M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z\" />\n\t\t\t<path d=\"M14 3v6h6\" />\n\t\t</>,\n\t),\n\tbranch: I(\n\t\t<>\n\t\t\t<circle cx=\"6\" cy=\"6\" r=\"2\" />\n\t\t\t<circle cx=\"6\" cy=\"18\" r=\"2\" />\n\t\t\t<circle cx=\"18\" cy=\"8\" r=\"2\" />\n\t\t\t<path d=\"M6 8v8\" />\n\t\t\t<path d=\"M18 10c0 4-4 4-6 6\" />\n\t\t</>,\n\t),\n\tsun: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"4\" />\n\t\t\t<path d=\"M12 3v2M12 19v2M3 12h2M19 12h2M5.6 5.6l1.4 1.4M17 17l1.4 1.4M18.4 5.6 17 7M7 17l-1.4 1.4\" />\n\t\t</>,\n\t),\n\tmoon: I(\n\t\t<>\n\t\t\t<path d=\"M20 14A8 8 0 0 1 10 4a8 8 0 1 0 10 10z\" />\n\t\t</>,\n\t),\n\tsettings: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"3\" />\n\t\t\t<path d=\"M19 12a7 7 0 0 0-.2-1.7l2-1.5-2-3.4-2.3.9a7 7 0 0 0-3-1.7L13 2h-4l-.5 2.6a7 7 0 0 0-3 1.7L3.2 5.4l-2 3.4 2 1.5A7 7 0 0 0 3 12c0 .6.1 1.2.2 1.7l-2 1.5 2 3.4 2.3-.9a7 7 0 0 0 3 1.7L9 22h4l.5-2.6a7 7 0 0 0 3-1.7l2.3.9 2-3.4-2-1.5c.1-.5.2-1.1.2-1.7z\" />\n\t\t</>,\n\t),\n\tlogout: I(\n\t\t<>\n\t\t\t<path d=\"M14 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\" />\n\t\t\t<path d=\"M10 17 5 12l5-5\" />\n\t\t\t<path d=\"M5 12h12\" />\n\t\t</>,\n\t),\n\tloader: I(\n\t\t<>\n\t\t\t<path d=\"M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M18.4 5.6l-2.8 2.8M8.4 15.6l-2.8 2.8\" />\n\t\t</>,\n\t),\n\tgrid: I(\n\t\t<>\n\t\t\t<rect x=\"4\" y=\"4\" width=\"7\" height=\"7\" rx=\"1\" />\n\t\t\t<rect x=\"13\" y=\"4\" width=\"7\" height=\"7\" rx=\"1\" />\n\t\t\t<rect x=\"4\" y=\"13\" width=\"7\" height=\"7\" rx=\"1\" />\n\t\t\t<rect x=\"13\" y=\"13\" width=\"7\" height=\"7\" rx=\"1\" />\n\t\t</>,\n\t),\n\tstar: I(\n\t\t<>\n\t\t\t<path d=\"m12 3 3 6 6 1-4.5 4.5 1 6.5L12 18l-5.5 3 1-6.5L3 10l6-1z\" />\n\t\t</>,\n\t),\n\twarning: I(\n\t\t<>\n\t\t\t<path d=\"m12 3 10 18H2z\" />\n\t\t\t<path d=\"M12 10v5M12 18v.5\" />\n\t\t</>,\n\t),\n\tinfo: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M12 11v6M12 8v.5\" />\n\t\t</>,\n\t),\n\tbuilding: I(\n\t\t<>\n\t\t\t<path d=\"M4 21V3h12v18M4 21h16\" />\n\t\t\t<path d=\"M16 9h4v12\" />\n\t\t\t<path d=\"M7 6h2M7 10h2M7 14h2M11 6h2M11 10h2M11 14h2\" />\n\t\t</>,\n\t),\n\tdevice: I(\n\t\t<>\n\t\t\t<rect x=\"5\" y=\"3\" width=\"14\" height=\"18\" rx=\"2\" />\n\t\t\t<path d=\"M10 18h4\" />\n\t\t</>,\n\t),\n\tarrowUp: I(\n\t\t<>\n\t\t\t<path d=\"M12 19V5M5 12l7-7 7 7\" />\n\t\t</>,\n\t),\n\tarrowDown: I(\n\t\t<>\n\t\t\t<path d=\"M12 5v14M5 12l7 7 7-7\" />\n\t\t</>,\n\t),\n\texternal: I(\n\t\t<>\n\t\t\t<path d=\"M14 4h6v6\" />\n\t\t\t<path d=\"M20 4 10 14\" />\n\t\t\t<path d=\"M20 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5\" />\n\t\t</>,\n\t),\n\tdbtable: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"1\" />\n\t\t\t<path d=\"M3 9h18M3 13h18M9 9v10M15 9v10\" />\n\t\t</>,\n\t),\n\n\t// Kebab-case aliases used by YAML schemas (entity.display.icon, screen.display.icon, nav icons).\n\t// Kept as string keys so lookups via Icon[name] match the YAML value directly.\n\t\"users-round\": I(\n\t\t<>\n\t\t\t<circle cx=\"10\" cy=\"8\" r=\"5\" />\n\t\t\t<path d=\"M2 21a8 8 0 0 1 16 0\" />\n\t\t\t<path d=\"M17 4a5 5 0 0 1 0 8\" />\n\t\t\t<path d=\"M22 21a6 6 0 0 0-4-5.6\" />\n\t\t</>,\n\t),\n\tuser: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"7\" r=\"4\" />\n\t\t\t<path d=\"M6 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2\" />\n\t\t</>,\n\t),\n\t\"user-plus\": I(\n\t\t<>\n\t\t\t<circle cx=\"9\" cy=\"7\" r=\"4\" />\n\t\t\t<path d=\"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\" />\n\t\t\t<path d=\"M19 8v6M22 11h-6\" />\n\t\t</>,\n\t),\n\t\"shield-check\": I(\n\t\t<>\n\t\t\t<path d=\"M12 3 4 6v6c0 4.5 3.5 8 8 9 4.5-1 8-4.5 8-9V6z\" />\n\t\t\t<path d=\"m9 12 2 2 4-4\" />\n\t\t</>,\n\t),\n\t\"shield-plus\": I(\n\t\t<>\n\t\t\t<path d=\"M12 3 4 6v6c0 4.5 3.5 8 8 9 4.5-1 8-4.5 8-9V6z\" />\n\t\t\t<path d=\"M9 12h6M12 9v6\" />\n\t\t</>,\n\t),\n\t\"key-round\": I(\n\t\t<>\n\t\t\t<path d=\"M2 18v3c0 .6.4 1 1 1h4v-3h3v-3h2l1.4-1.4a6.5 6.5 0 1 0-4-4z\" />\n\t\t\t<circle cx=\"16.5\" cy=\"7.5\" r=\"0.5\" fill=\"currentColor\" />\n\t\t</>,\n\t),\n\t\"list-checks\": I(\n\t\t<>\n\t\t\t<path d=\"m3 17 2 2 4-4\" />\n\t\t\t<path d=\"m3 7 2 2 4-4\" />\n\t\t\t<path d=\"M13 6h8M13 12h8M13 18h8\" />\n\t\t</>,\n\t),\n\tlist: I(\n\t\t<>\n\t\t\t<path d=\"M8 6h13M8 12h13M8 18h13\" />\n\t\t\t<circle cx=\"3.5\" cy=\"6\" r=\"0.5\" fill=\"currentColor\" />\n\t\t\t<circle cx=\"3.5\" cy=\"12\" r=\"0.5\" fill=\"currentColor\" />\n\t\t\t<circle cx=\"3.5\" cy=\"18\" r=\"0.5\" fill=\"currentColor\" />\n\t\t</>,\n\t),\n\t\"play-circle\": I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M10 8.5v7L16 12z\" />\n\t\t</>,\n\t),\n\tplay: I(\n\t\t<>\n\t\t\t<path d=\"M6 3 20 12 6 21z\" />\n\t\t</>,\n\t),\n\tlayers: I(\n\t\t<>\n\t\t\t<path d=\"M12 2 2 7l10 5 10-5z\" />\n\t\t\t<path d=\"m2 12 10 5 10-5\" />\n\t\t\t<path d=\"m2 17 10 5 10-5\" />\n\t\t</>,\n\t),\n\tlayout: I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n\t\t\t<path d=\"M3 9h18\" />\n\t\t\t<path d=\"M9 21V9\" />\n\t\t</>,\n\t),\n\t\"layout-dashboard\": I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"3\" width=\"7\" height=\"9\" rx=\"1\" />\n\t\t\t<rect x=\"14\" y=\"3\" width=\"7\" height=\"5\" rx=\"1\" />\n\t\t\t<rect x=\"14\" y=\"12\" width=\"7\" height=\"9\" rx=\"1\" />\n\t\t\t<rect x=\"3\" y=\"16\" width=\"7\" height=\"5\" rx=\"1\" />\n\t\t</>,\n\t),\n\tdatabase: I(\n\t\t<>\n\t\t\t<ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" />\n\t\t\t<path d=\"M3 5v14c0 1.7 4 3 9 3s9-1.3 9-3V5\" />\n\t\t\t<path d=\"M3 12c0 1.7 4 3 9 3s9-1.3 9-3\" />\n\t\t</>,\n\t),\n\tzap: I(\n\t\t<>\n\t\t\t<path d=\"M13 3 4 14h6l-1 7 9-11h-6z\" />\n\t\t</>,\n\t),\n\tcpu: I(\n\t\t<>\n\t\t\t<rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" />\n\t\t\t<rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" />\n\t\t\t<path d=\"M9 2v2M15 2v2M9 20v2M15 20v2M2 9h2M2 15h2M20 9h2M20 15h2\" />\n\t\t</>,\n\t),\n\t\"circle-dot\": I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" />\n\t\t</>,\n\t),\n\t\"toggle-right\": I(\n\t\t<>\n\t\t\t<rect x=\"2\" y=\"6\" width=\"20\" height=\"12\" rx=\"6\" />\n\t\t\t<circle cx=\"16\" cy=\"12\" r=\"2.5\" fill=\"currentColor\" />\n\t\t</>,\n\t),\n\tsliders: I(\n\t\t<>\n\t\t\t<path d=\"M21 4h-7M10 4H3M21 12h-9M8 12H3M21 20h-5M12 20H3M14 2v4M8 10v4M16 18v4\" />\n\t\t</>,\n\t),\n\t\"sliders-horizontal\": I(\n\t\t<>\n\t\t\t<path d=\"M21 4h-7M10 4H3M21 12h-9M8 12H3M21 20h-5M12 20H3M14 2v4M8 10v4M16 18v4\" />\n\t\t</>,\n\t),\n\tbox: I(\n\t\t<>\n\t\t\t<path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\" />\n\t\t\t<path d=\"m3.3 7 8.7 5 8.7-5\" />\n\t\t\t<path d=\"M12 22V12\" />\n\t\t</>,\n\t),\n\t\"columns-3\": I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"1\" />\n\t\t\t<path d=\"M9 4v16M15 4v16\" />\n\t\t</>,\n\t),\n\t\"settings-2\": I(\n\t\t<>\n\t\t\t<path d=\"M20 7h-9M14 17H5\" />\n\t\t\t<circle cx=\"17\" cy=\"17\" r=\"3\" />\n\t\t\t<circle cx=\"7\" cy=\"7\" r=\"3\" />\n\t\t</>,\n\t),\n\t\"file-diff\": I(\n\t\t<>\n\t\t\t<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n\t\t\t<path d=\"M14 2v6h6\" />\n\t\t\t<path d=\"M12 12v6M9 15h6M9 18h6\" />\n\t\t</>,\n\t),\n\t\"git-branch\": I(\n\t\t<>\n\t\t\t<circle cx=\"6\" cy=\"6\" r=\"2\" />\n\t\t\t<circle cx=\"6\" cy=\"18\" r=\"2\" />\n\t\t\t<circle cx=\"18\" cy=\"8\" r=\"2\" />\n\t\t\t<path d=\"M6 8v8\" />\n\t\t\t<path d=\"M18 10a6 6 0 0 1-6 6h-2\" />\n\t\t</>,\n\t),\n\t\"log-in\": I(\n\t\t<>\n\t\t\t<path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\" />\n\t\t\t<path d=\"m10 17 5-5-5-5\" />\n\t\t\t<path d=\"M15 12H3\" />\n\t\t</>,\n\t),\n\t\"plus-circle\": I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M8 12h8M12 8v8\" />\n\t\t</>,\n\t),\n\trepeat: I(\n\t\t<>\n\t\t\t<path d=\"m17 2 4 4-4 4\" />\n\t\t\t<path d=\"M3 11v-1a4 4 0 0 1 4-4h14\" />\n\t\t\t<path d=\"m7 22-4-4 4-4\" />\n\t\t\t<path d=\"M21 13v1a4 4 0 0 1-4 4H3\" />\n\t\t</>,\n\t),\n\tban: I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"m5.6 5.6 12.8 12.8\" />\n\t\t</>,\n\t),\n\t\"trash-2\": I(\n\t\t<>\n\t\t\t<path d=\"M4 7h16M9 7V4h6v3M6 7l1 13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-13\" />\n\t\t\t<path d=\"M10 11v6M14 11v6\" />\n\t\t</>,\n\t),\n\t\"shopping-cart\": I(\n\t\t<>\n\t\t\t<circle cx=\"9\" cy=\"20\" r=\"1.5\" />\n\t\t\t<circle cx=\"18\" cy=\"20\" r=\"1.5\" />\n\t\t\t<path d=\"M2 3h3l3 12h10l3-8H7\" />\n\t\t</>,\n\t),\n\t\"credit-card\": I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n\t\t\t<path d=\"M3 10h18\" />\n\t\t\t<path d=\"M7 15h4\" />\n\t\t</>,\n\t),\n\tpackage: I(\n\t\t<>\n\t\t\t<path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\" />\n\t\t\t<path d=\"m3.3 7 8.7 5 8.7-5\" />\n\t\t\t<path d=\"M12 22V12\" />\n\t\t</>,\n\t),\n\tboxes: I(\n\t\t<>\n\t\t\t<path d=\"M7.5 7.5 3 10v5l4.5 2.5L12 15v-5z\" />\n\t\t\t<path d=\"M16.5 7.5 12 10v5l4.5 2.5L21 15v-5z\" />\n\t\t\t<path d=\"M12 2.5 7.5 5v5L12 12.5 16.5 10V5z\" />\n\t\t</>,\n\t),\n\ttags: I(\n\t\t<>\n\t\t\t<path d=\"M4 4h7l9 9-7 7-9-9z\" />\n\t\t\t<path d=\"M8 8h.01\" />\n\t\t\t<path d=\"M13 4h2l6 6\" />\n\t\t</>,\n\t),\n\t\"wallet-cards\": I(\n\t\t<>\n\t\t\t<rect x=\"3\" y=\"7\" width=\"18\" height=\"13\" rx=\"2\" />\n\t\t\t<path d=\"M16 11h5v5h-5a2.5 2.5 0 0 1 0-5z\" />\n\t\t\t<path d=\"M5 7V5a2 2 0 0 1 2-2h10v4\" />\n\t\t</>,\n\t),\n\t\"receipt-text\": I(\n\t\t<>\n\t\t\t<path d=\"M6 3h12v18l-3-2-3 2-3-2-3 2z\" />\n\t\t\t<path d=\"M9 8h6M9 12h6M9 16h4\" />\n\t\t</>,\n\t),\n\t\"badge-dollar-sign\": I(\n\t\t<>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"9\" />\n\t\t\t<path d=\"M12 6v12M15 9.5c-.7-.8-1.7-1.2-3-1.2-1.6 0-2.7.8-2.7 2s1 1.7 2.7 2.1c1.8.4 3 .9 3 2.3S13.8 17 12 17c-1.4 0-2.6-.5-3.4-1.4\" />\n\t\t</>,\n\t),\n\t\"undo-2\": I(\n\t\t<>\n\t\t\t<path d=\"M9 14 4 9l5-5\" />\n\t\t\t<path d=\"M4 9h10a6 6 0 1 1 0 12h-2\" />\n\t\t</>,\n\t),\n} as const;\n\nexport type IconName = keyof typeof Icon;\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport { forwardRef } from \"react\";\nimport type { ButtonHTMLAttributes, CSSProperties, MouseEvent, ReactNode } from \"react\";\n\nexport type BtnKind = \"primary\" | \"navy\" | \"ghost\" | \"subtle\" | \"default\";\nexport type BtnSize = \"xs\" | \"sm\" | \"md\" | \"lg\";\n\nexport type BtnProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"size\"> & {\n kind?: BtnKind;\n size?: BtnSize;\n icon?: ReactNode;\n iconRight?: ReactNode;\n active?: boolean;\n danger?: boolean;\n};\n\nexport const Btn = forwardRef<HTMLButtonElement, BtnProps>(function Btn(\n { kind = \"default\", size = \"sm\", icon, iconRight, children, onClick, active, danger, style, disabled, type = \"button\", title, ...rest },\n ref,\n) {\n const H = size === \"xs\" ? 24 : size === \"sm\" ? 28 : size === \"md\" ? 32 : 36;\n const P = size === \"xs\" ? 8 : size === \"sm\" ? 10 : size === \"md\" ? 12 : 14;\n const s: CSSProperties = {\n display: \"inline-flex\", alignItems: \"center\", gap: 6, height: H, padding: `0 ${P}px`,\n borderRadius: 6, fontSize: size === \"xs\" ? 11.5 : 12.5, fontWeight: 500, cursor: \"pointer\",\n transition: \"background .12s, border-color .12s, color .12s\",\n whiteSpace: \"nowrap\",\n };\n if (kind === \"primary\") Object.assign(s, {\n background: \"var(--accent)\", color: \"var(--primary-fg)\", border: \"1px solid var(--accent)\",\n });\n else if (kind === \"navy\") Object.assign(s, {\n background: \"var(--primary)\", color: \"var(--primary-fg)\", border: \"1px solid var(--primary)\",\n });\n else if (kind === \"ghost\") Object.assign(s, {\n background: \"transparent\", color: active ? \"var(--text)\" : \"var(--text-2)\",\n border: \"1px solid transparent\", ...(active && { background: \"var(--surface-3)\" }),\n });\n else if (kind === \"subtle\") Object.assign(s, {\n background: active ? \"var(--surface-3)\" : \"var(--surface-2)\", color: \"var(--text-2)\",\n border: \"1px solid var(--border)\",\n });\n else Object.assign(s, {\n background: \"var(--surface)\", color: \"var(--text)\",\n border: \"1px solid var(--border)\",\n });\n // Danger styling is kind-aware. A destructive CTA (\"Delete record\") on a\n // primary button uses the full red treatment (solid danger bg + white\n // text + red border) so it reads as the intended destructive affordance,\n // not a purple accent button with red text. Secondary kinds (ghost /\n // subtle / default — e.g. an inline row-delete icon button) keep only the\n // tinted-text pattern so they remain visually secondary.\n if (danger) {\n if (kind === \"primary\") {\n Object.assign(s, {\n background: \"var(--danger)\",\n color: \"var(--primary-fg)\",\n borderColor: \"var(--danger)\",\n });\n } else {\n Object.assign(s, { color: \"var(--danger)\", borderColor: \"var(--border)\" });\n }\n }\n if (disabled) Object.assign(s, { opacity: 0.5, pointerEvents: \"none\" });\n Object.assign(s, style || {});\n return (\n <button\n ref={ref}\n type={type}\n onClick={onClick}\n title={title}\n disabled={disabled}\n {...rest}\n style={s}\n onMouseEnter={(e: MouseEvent<HTMLButtonElement>) => {\n if (kind === \"primary\" && danger) e.currentTarget.style.background = \"var(--danger-hover, var(--danger))\";\n else if (kind === \"primary\") e.currentTarget.style.background = \"var(--accent-2)\";\n else if (kind === \"navy\") e.currentTarget.style.background = \"var(--primary-hover)\";\n else if (kind !== \"ghost\") e.currentTarget.style.background = \"var(--surface-3)\";\n else e.currentTarget.style.background = \"var(--surface-3)\";\n }}\n onMouseLeave={(e: MouseEvent<HTMLButtonElement>) => {\n e.currentTarget.style.background = (s.background as string) ?? \"\";\n }}\n >\n {icon}{children}{iconRight}\n </button>\n );\n});\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport { forwardRef } from \"react\";\nimport type { CSSProperties, MouseEvent, ReactNode } from \"react\";\n\nexport type IconBtnProps = {\n icon: ReactNode;\n onClick?: (e: MouseEvent<HTMLButtonElement>) => void;\n title?: string;\n size?: number;\n active?: boolean;\n disabled?: boolean;\n style?: CSSProperties;\n};\n\nexport const IconBtn = forwardRef<HTMLButtonElement, IconBtnProps>(function IconBtn(\n { icon, onClick, title, size = 28, active, disabled, style },\n ref,\n) {\n return (\n <button\n type=\"button\"\n ref={ref}\n onClick={onClick}\n title={title}\n aria-label={title}\n disabled={disabled}\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n width: size, height: size, borderRadius: 6, border: \"1px solid transparent\",\n background: active ? \"var(--surface-3)\" : \"transparent\",\n color: active ? \"var(--text)\" : \"var(--text-2)\",\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n padding: 0,\n opacity: disabled ? 0.4 : 1,\n ...style,\n }}\n onMouseEnter={(e) => {\n if (disabled) return;\n e.currentTarget.style.background = \"var(--surface-3)\";\n e.currentTarget.style.color = \"var(--text)\";\n }}\n onMouseLeave={(e) => {\n if (disabled) return;\n e.currentTarget.style.background = active ? \"var(--surface-3)\" : \"transparent\";\n e.currentTarget.style.color = active ? \"var(--text)\" : \"var(--text-2)\";\n }}\n >\n {icon}\n </button>\n );\n});\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport type { CSSProperties, ReactNode } from \"react\";\n\nexport type PillTone =\n | \"indigo\" | \"emerald\" | \"amber\" | \"rose\"\n | \"sky\" | \"violet\" | \"slate\" | \"teal\";\nexport type PillSize = \"xs\" | \"sm\" | \"md\";\n\nexport type PillProps = {\n tone?: PillTone;\n size?: PillSize;\n dot?: boolean;\n style?: CSSProperties;\n children?: ReactNode;\n};\n\nexport function Pill({ tone = \"slate\", children, size = \"sm\", dot = false, style }: PillProps) {\n const bg = `var(--pill-${tone}-bg)`;\n const fg = `var(--pill-${tone})`;\n const h = size === \"sm\" ? 20 : size === \"xs\" ? 16 : 24;\n return (\n <span className=\"num\" style={{\n display: \"inline-flex\", alignItems: \"center\", gap: 6, height: h,\n padding: `0 ${size === \"xs\" ? 6 : 8}px`, borderRadius: 999,\n background: bg, color: fg, fontSize: size === \"xs\" ? 10.5 : 11.5, fontWeight: 500,\n whiteSpace: \"nowrap\", maxWidth: \"100%\", ...style,\n }}>\n {dot && <span style={{ width: 6, height: 6, borderRadius: 999, background: fg }} />}\n <span style={{\n minWidth: 0,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}>{children}</span>\n </span>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport type { ReactNode } from \"react\";\n\nexport function Kbd({ children }: { children?: ReactNode }) {\n return (\n <span\n className=\"mono\"\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n minWidth: 18, height: 18, padding: \"0 5px\", borderRadius: 4,\n background: \"var(--surface-3)\", border: \"1px solid var(--border)\",\n color: \"var(--text-3)\", fontSize: 10.5,\n }}\n >\n {children}\n </span>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\n\nexport type AvatarProps = {\n name: string;\n size?: number;\n color?: string;\n};\n\nexport function Avatar({ name, size = 22, color }: AvatarProps) {\n const initials = name.split(/\\s+/).map(w => w[0]).slice(0, 2).join(\"\").toUpperCase();\n const hash = name.split(\"\").reduce((a, c) => a + c.charCodeAt(0), 0);\n const colors = [\"#DCE4F6\", \"#E4DCF6\", \"#F6DCE4\", \"#F6E4DC\", \"#DCF6E4\", \"#DCF6F1\", \"#F1F6DC\", \"#F6DCF1\"];\n const bg = color || colors[hash % colors.length];\n return (\n <span\n style={{\n display: \"inline-flex\", alignItems: \"center\", justifyContent: \"center\",\n width: size, height: size, borderRadius: 999, background: bg, color: \"#1E2A4A\",\n fontSize: size < 20 ? 9.5 : 10.5, fontWeight: 600, flexShrink: 0,\n }}\n >\n {initials}\n </span>\n );\n}\n","// BrandGlyph: Declarion's angular \"D=\" mark, themeable via currentColor.\n//\n// Geometry mirrors `public/declarion-glyph.svg` exactly so the static\n// asset (used as an `<img>` source) and the inline React component\n// render an identical mark. The mark encodes the product thesis: a\n// stylized letter D with an \"=\" sign in the negative space of the\n// counter (\"declaration equals behavior\"). Trademark distinctive,\n// reads as a letter rather than a UI hamburger icon, scales from\n// favicon (16px) through hero (96px+).\n//\n// Color: `currentColor` — inheritable from the host CSS context. The\n// static SVG file pins to accent purple (#5B5BD6) for `<img>` use where\n// currentColor doesn't propagate.\n\nexport interface BrandGlyphProps {\n /** Pixel edge of the rendered SVG. Defaults to 24. */\n size?: number;\n className?: string;\n /** ARIA label; omit for purely decorative usages. */\n title?: string;\n}\n\nexport function BrandGlyph({ size = 24, className, title }: BrandGlyphProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 64 64\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={className}\n role={title ? \"img\" : undefined}\n aria-label={title}\n aria-hidden={title ? undefined : true}\n >\n <path\n fillRule=\"evenodd\"\n fill=\"currentColor\"\n d=\"M 6 6 H 42 L 58 22 V 42 L 42 58 H 6 Z M 18 18 V 46 H 38 L 46 38 V 26 L 38 18 Z\"\n />\n <rect x=\"22\" y=\"28\" width=\"20\" height=\"3\" fill=\"currentColor\" />\n <rect x=\"22\" y=\"33\" width=\"20\" height=\"3\" fill=\"currentColor\" />\n </svg>\n );\n}\n","import { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { CSSProperties, ReactNode } from \"react\";\n\nexport type DropdownProps = {\n open: boolean;\n onClose?: () => void;\n anchor: HTMLElement | null;\n align?: \"start\" | \"end\";\n width?: number;\n style?: CSSProperties;\n children?: ReactNode;\n};\n\nexport function Dropdown({ open, onClose, anchor, children, align = \"start\", width, style }: DropdownProps) {\n const ref = useRef<HTMLDivElement | null>(null);\n const [pos, setPos] = useState<{ top: number; left: number; placement: \"below\" | \"above\" } | null>(null);\n // Layout effect runs only when the open/anchor/align/width change — NOT on\n // children reference changes. A new children reference on every render would\n // loop setPos → re-render → new children → effect → setPos (React error\n // #185: too many re-renders). Measure menu height twice: first render uses\n // an estimate (260px), subsequent runs read the mounted node's offsetHeight.\n useLayoutEffect(() => {\n if (!open || !anchor) return;\n const r = anchor.getBoundingClientRect();\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 0;\n const menuH = ref.current?.offsetHeight || 260;\n const spaceBelow = vh - r.bottom;\n const placement: \"below\" | \"above\" = spaceBelow < menuH + 12 && r.top > menuH + 12 ? \"above\" : \"below\";\n const top = placement === \"below\" ? r.bottom + 4 : r.top - 4 - menuH;\n const left = align === \"end\" ? r.right - (width || 200) : r.left;\n setPos((prev) => {\n if (\n prev &&\n prev.top === top &&\n prev.left === left &&\n prev.placement === placement\n ) {\n return prev;\n }\n return { top, left, placement };\n });\n }, [open, anchor, align, width]);\n useEffect(() => {\n if (!open) return;\n const h = (e: MouseEvent) => {\n const target = e.target as Node | null;\n if (ref.current && target && !ref.current.contains(target) && anchor && !anchor.contains(target)) {\n onClose && onClose();\n }\n };\n document.addEventListener(\"mousedown\", h);\n return () => document.removeEventListener(\"mousedown\", h);\n }, [open, anchor, onClose]);\n if (!open || !pos) return null;\n return createPortal(\n <div\n ref={ref}\n style={{\n position: \"fixed\", top: pos.top, left: pos.left, zIndex: 200, minWidth: width || 200,\n background: \"var(--surface)\", border: \"1px solid var(--border)\", borderRadius: 8,\n boxShadow: \"var(--shadow-lg)\", padding: 4, ...style,\n }}\n >\n {children}\n </div>,\n document.body,\n );\n}\n","// HoverCard — lightweight hover-to-reveal popover for richer-than-title\n// previews on truncated cell content (e.g. rendered markdown). Mirrors the\n// Dropdown anchor + position-math approach so we avoid a Radix/floating-ui\n// dependency for the same primitive shape.\n//\n// v1 contract:\n// - Hover only. Keyboard focus does NOT open the card (deferred to a\n// dedicated a11y plan; documented in\n// docs/plans/2026-05-09-list-cell-truncation-and-hover.md Open Questions).\n// - 400ms open delay so brief mouse traversal doesn't flash cards.\n// - 150ms close delay lets the cursor cross the gap into the card body.\n// - The card body itself catches mouseenter, so the user can scroll and\n// read without the card collapsing.\n// - Viewport-edge handling: if anchor + width overflows horizontally, the\n// card mirrors to the right edge; if bottom overflows AND there is room\n// above, it flips above the trigger.\n// - Position re-measures both on viewport changes (scroll, resize) AND on\n// card-body size changes (initial mount, content reflow). A ResizeObserver\n// attached to the card via a callback ref handles the first-paint case\n// where offsetHeight isn't readable until after the portal mounts.\n// - The card mounts hidden (visibility:hidden) so the browser can lay it\n// out and the ResizeObserver can read its real size. Only after that\n// first real measurement does the card flip to visibility:visible. This\n// avoids the \"card paints above, then snaps below\" flicker that the\n// conservative MAX_HEIGHT fallback would otherwise produce when the\n// real card height is much smaller.\n//\n// Caller responsibility: render the trigger via `children`. The component\n// wraps it in an inline span — text-truncating cells stay layout-stable\n// (no extra block).\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { CSSProperties, ReactNode } from \"react\";\n\nconst OPEN_DELAY_MS = 400;\nconst CLOSE_DELAY_MS = 150;\nconst DEFAULT_WIDTH = 320;\nconst MAX_HEIGHT = 240;\nconst VIEWPORT_PADDING = 4;\nconst ANCHOR_GAP = 4;\n\nexport type HoverCardAlign = \"start\" | \"center\" | \"end\";\n\nexport type HoverCardProps = {\n /** The card body shown on hover. Caller controls the rendered content. */\n content: ReactNode;\n /** The trigger node. Wrapped in an inline span. */\n children: ReactNode;\n /** Card width in pixels. Default 320. */\n width?: number;\n /** Horizontal alignment relative to the anchor. Default `center`. */\n align?: HoverCardAlign;\n /** Optional inline style overrides on the card body. */\n style?: CSSProperties;\n};\n\ntype Pos = { top: number; left: number; placement: \"below\" | \"above\" };\n\nexport function HoverCard({\n content,\n children,\n width = DEFAULT_WIDTH,\n align = \"center\",\n style,\n}: HoverCardProps) {\n const triggerRef = useRef<HTMLSpanElement | null>(null);\n const cardElRef = useRef<HTMLDivElement | null>(null);\n const openTimer = useRef<number | null>(null);\n const closeTimer = useRef<number | null>(null);\n const [open, setOpen] = useState(false);\n const [pos, setPos] = useState<Pos | null>(null);\n // measured: true once we have a real cardElRef.current.offsetHeight read,\n // either from the ResizeObserver's first delivery or from a synchronous\n // fallback in environments without ResizeObserver. Drives visibility so\n // the user never sees the card at a placeholder position.\n const [measured, setMeasured] = useState(false);\n\n // measure is identity-stable so it can be referenced by the ResizeObserver\n // callback ref AND scroll/resize listeners without churning observer wiring.\n const measure = useCallback(() => {\n const anchor = triggerRef.current;\n if (!anchor) return;\n const rect = anchor.getBoundingClientRect();\n const vw = typeof window !== \"undefined\" ? window.innerWidth : 0;\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 0;\n\n // Card height: real measurement when mounted, else fall back to MAX_HEIGHT\n // (the worst case for placement). Using MAX_HEIGHT as the fallback means\n // the first-paint placement decision is conservative — we'll choose\n // \"above\" if there's any chance of bottom overflow, then re-measure once\n // the card is in the DOM. Either we stay above (correct), or we flip\n // back to below once we see the real height fits below (correct).\n const cardH = cardElRef.current?.offsetHeight ?? MAX_HEIGHT;\n\n const spaceBelow = vh - rect.bottom;\n const placement: \"below\" | \"above\" =\n spaceBelow < cardH + ANCHOR_GAP * 2 && rect.top > cardH + ANCHOR_GAP * 2 ? \"above\" : \"below\";\n const top =\n placement === \"below\" ? rect.bottom + ANCHOR_GAP : rect.top - ANCHOR_GAP - cardH;\n\n let left: number;\n if (align === \"start\") left = rect.left;\n else if (align === \"end\") left = rect.right - width;\n else left = rect.left + rect.width / 2 - width / 2;\n if (left + width > vw - VIEWPORT_PADDING) left = Math.max(VIEWPORT_PADDING, rect.right - width);\n if (left < VIEWPORT_PADDING) left = VIEWPORT_PADDING;\n\n setPos((prev) => {\n if (prev && prev.top === top && prev.left === left && prev.placement === placement) {\n return prev;\n }\n return { top, left, placement };\n });\n }, [align, width]);\n\n // Card mounts/unmounts via this callback ref. Wiring the ResizeObserver\n // here (not in useLayoutEffect) ensures the observer attaches the moment\n // the portal commits — that first observed entry triggers a re-measure\n // with the real offsetHeight and flips the card to visible.\n const observerRef = useRef<ResizeObserver | null>(null);\n const setCardEl = useCallback(\n (node: HTMLDivElement | null) => {\n cardElRef.current = node;\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n if (!node) return;\n if (typeof ResizeObserver !== \"undefined\") {\n // First observation fires synchronously-from-microtask after observe;\n // re-measure picks up the real height and setMeasured reveals the card.\n const ro = new ResizeObserver(() => {\n measure();\n setMeasured(true);\n });\n ro.observe(node);\n observerRef.current = ro;\n } else {\n // Environments without ResizeObserver (jsdom): nothing to observe,\n // fall through to the conservative fallback placement and reveal.\n setMeasured(true);\n }\n },\n [measure],\n );\n\n const clearTimers = () => {\n if (openTimer.current !== null) {\n window.clearTimeout(openTimer.current);\n openTimer.current = null;\n }\n if (closeTimer.current !== null) {\n window.clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n };\n\n const scheduleOpen = () => {\n if (closeTimer.current !== null) {\n window.clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n if (open || openTimer.current !== null) return;\n openTimer.current = window.setTimeout(() => {\n openTimer.current = null;\n setOpen(true);\n }, OPEN_DELAY_MS);\n };\n\n const scheduleClose = () => {\n if (openTimer.current !== null) {\n window.clearTimeout(openTimer.current);\n openTimer.current = null;\n }\n if (closeTimer.current !== null) return;\n closeTimer.current = window.setTimeout(() => {\n closeTimer.current = null;\n setOpen(false);\n }, CLOSE_DELAY_MS);\n };\n\n // Cleanup timers AND any active observer on unmount.\n useEffect(\n () => () => {\n clearTimers();\n if (observerRef.current) {\n observerRef.current.disconnect();\n observerRef.current = null;\n }\n },\n [],\n );\n\n // Initial position pass when the card opens; reposition on viewport changes.\n // The ResizeObserver covers the \"real card height differs from fallback\"\n // case once the DOM commits.\n useEffect(() => {\n if (!open) {\n // Reset measured so the next open cycle hides the card again until the\n // first real measurement lands. Without this, a stale measured=true\n // would let a re-opened card flash at the previous open's coordinates\n // before the new measure() runs.\n setMeasured(false);\n return;\n }\n measure();\n window.addEventListener(\"scroll\", measure, true);\n window.addEventListener(\"resize\", measure);\n return () => {\n window.removeEventListener(\"scroll\", measure, true);\n window.removeEventListener(\"resize\", measure);\n };\n }, [open, measure]);\n\n const card =\n open && pos\n ? createPortal(\n <div\n ref={setCardEl}\n role=\"tooltip\"\n onMouseEnter={() => {\n if (closeTimer.current !== null) {\n window.clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n }}\n onMouseLeave={scheduleClose}\n style={{\n position: \"fixed\",\n top: pos.top,\n left: pos.left,\n width,\n maxHeight: MAX_HEIGHT,\n overflowY: \"auto\",\n zIndex: 250,\n background: \"var(--surface)\",\n border: \"1px solid var(--border)\",\n borderRadius: 8,\n boxShadow: \"var(--shadow-lg)\",\n padding: 10,\n fontSize: 13,\n color: \"var(--text)\",\n // Hidden until the first real height read lands. Card still\n // occupies layout so the ResizeObserver can deliver a size;\n // pointer-events:none avoids accidental hover capture during\n // the brief invisible frame.\n visibility: measured ? \"visible\" : \"hidden\",\n pointerEvents: measured ? \"auto\" : \"none\",\n ...style,\n }}\n >\n {content}\n </div>,\n document.body,\n )\n : null;\n\n return (\n <>\n <span\n ref={triggerRef}\n onMouseEnter={scheduleOpen}\n onMouseLeave={scheduleClose}\n // Display: inline preserves cell layout (table cells truncate via\n // their td CSS; the trigger wrapper does not introduce a block).\n style={{ display: \"inline\", maxWidth: \"100%\" }}\n >\n {children}\n </span>\n {card}\n </>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport type { ReactNode, MouseEvent } from \"react\";\nimport { Icon } from \"./Icons\";\n\nexport type ChipProps = {\n tone?: string;\n icon?: ReactNode;\n children?: ReactNode;\n onRemove?: () => void;\n onClick?: () => void;\n};\n\nexport function Chip({ icon, children, onRemove, onClick }: ChipProps) {\n return (\n <span onClick={onClick} style={{\n display: \"inline-flex\", alignItems: \"center\", gap: 6, height: 24,\n padding: \"0 8px\", borderRadius: 6, background: \"var(--surface-3)\",\n border: \"1px solid var(--border)\", fontSize: 12, color: \"var(--text-2)\",\n cursor: onClick ? \"pointer\" : \"default\",\n }}>\n {icon}\n {children}\n {onRemove && (\n <button\n type=\"button\"\n onClick={(e: MouseEvent<HTMLButtonElement>) => { e.stopPropagation(); onRemove(); }}\n style={{\n background: \"transparent\", border: 0, padding: 0, marginLeft: 2,\n color: \"var(--text-3)\", cursor: \"pointer\", display: \"flex\",\n }}\n >\n <Icon.x size={12} />\n </button>\n )}\n </span>\n );\n}\n","import { useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { Icon } from \"./Icons\";\nimport { IconBtn } from \"./IconBtn\";\nimport { Pill, type PillTone } from \"./Pill\";\n\nexport type SectionBadge = {\n text: string;\n tone?: PillTone;\n dot?: boolean;\n};\n\n// Visual weight of a section card. \"primary\" is a raised card for the page's\n// main content; \"secondary\" is a quieter recessed card for supporting detail.\n// Resolves the design-brief P2 \"sections are a stack of identical white boxes\".\nexport type SectionEmphasis = \"primary\" | \"secondary\";\n\nexport type SectionCardProps = {\n title: ReactNode;\n subtitle?: ReactNode;\n right?: ReactNode;\n badge?: SectionBadge;\n // Count chip after the title (e.g. number of child rows).\n count?: number;\n children?: ReactNode;\n // Pinned content below the body, above the card's bottom edge.\n footer?: ReactNode;\n collapsible?: boolean;\n defaultOpen?: boolean;\n icon?: ReactNode;\n emphasis?: SectionEmphasis;\n // Heading level (role=\"heading\" aria-level) for the section title: 2 for a\n // top-level section, 3 for a section nested inside another section or tab.\n // Keeps screen-reader heading navigation hierarchical.\n headingLevel?: number;\n padding?: string;\n};\n\nconst PALETTE: Record<SectionEmphasis, { surface: string; shadow: string }> = {\n primary: { surface: \"var(--surface)\", shadow: \"var(--shadow-xs)\" },\n secondary: { surface: \"var(--surface-2)\", shadow: \"none\" },\n};\n\nexport function SectionCard({\n title,\n subtitle,\n right,\n badge,\n count,\n children,\n footer,\n collapsible = true,\n defaultOpen = true,\n icon,\n emphasis = \"primary\",\n headingLevel = 2,\n padding = \"16px\",\n}: SectionCardProps) {\n const [open, setOpen] = useState(defaultOpen);\n // Unknown emphasis values fall back to primary (forward-compatible with\n // schema additions).\n const palette = PALETTE[emphasis] ?? PALETTE.primary;\n\n return (\n <div\n data-emphasis={emphasis}\n style={{\n background: palette.surface,\n border: \"1px solid var(--border)\",\n borderRadius: 10,\n overflow: \"hidden\",\n boxShadow: palette.shadow,\n // In a flex-column scroll container, `overflow: hidden` makes flexbox\n // treat `min-height: auto` as 0, so flex-shrink:1 (default) crushes the\n // card to a sliver. `flex-shrink: 0` keeps the card at content height;\n // the scroll container handles overflow.\n flexShrink: 0,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n padding: \"10px 14px\",\n borderBottom: open ? \"1px solid var(--divider)\" : \"none\",\n minHeight: 40,\n }}\n >\n {/* The section title is a heading (screen-reader landmark) wrapping the\n collapse toggle. The toggle is a role=\"button\" that fills the\n heading, so clicking anywhere on the title area opens/closes the\n section - the standard accordion pattern. Badge / header actions /\n chevron stay outside the heading so they remain independently\n clickable and a role=\"button\" never wraps another button. */}\n <div\n role=\"heading\"\n aria-level={headingLevel}\n style={{ display: \"flex\", flex: 1, minWidth: 0 }}\n >\n <div\n role={collapsible ? \"button\" : undefined}\n tabIndex={collapsible ? 0 : undefined}\n aria-expanded={collapsible ? open : undefined}\n onClick={collapsible ? () => setOpen((prev) => !prev) : undefined}\n onKeyDown={\n collapsible\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setOpen((prev) => !prev);\n }\n }\n : undefined\n }\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n flex: 1,\n minWidth: 0,\n cursor: collapsible ? \"pointer\" : \"default\",\n userSelect: \"none\",\n }}\n >\n {icon && (\n <span style={{ color: \"var(--text-3)\", display: \"flex\", flexShrink: 0 }}>{icon}</span>\n )}\n <div\n style={{\n fontSize: 12.5,\n fontWeight: 600,\n color: \"var(--text)\",\n letterSpacing: \"-0.005em\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n minWidth: 0,\n }}\n >\n {title}\n </div>\n {count !== undefined && (\n <span\n className=\"num\"\n style={{\n fontSize: 11,\n fontWeight: 600,\n color: \"var(--text-3)\",\n background: \"var(--surface-3)\",\n borderRadius: 999,\n padding: \"1px 7px\",\n minWidth: 20,\n textAlign: \"center\",\n flexShrink: 0,\n }}\n >\n {count}\n </span>\n )}\n {subtitle && (\n <div\n style={{\n fontSize: 11.5,\n color: \"var(--text-3)\",\n flexShrink: 0,\n borderLeft: \"1px solid var(--divider)\",\n paddingLeft: 8,\n marginLeft: 2,\n }}\n >\n {subtitle}\n </div>\n )}\n </div>\n </div>\n {badge && (\n <Pill tone={badge.tone ?? \"violet\"} size=\"xs\" dot={badge.dot}>\n {badge.text}\n </Pill>\n )}\n {right}\n {collapsible && (\n <IconBtn\n size={24}\n icon={open ? <Icon.up size={14} /> : <Icon.down size={14} />}\n onClick={() => setOpen((prev) => !prev)}\n title={open ? \"Collapse\" : \"Expand\"}\n />\n )}\n </div>\n {open && <div style={{ padding }}>{children}</div>}\n {footer && open && (\n <div\n style={{\n padding: \"8px 14px\",\n borderTop: \"1px solid var(--divider)\",\n background: \"var(--surface-2)\",\n fontSize: 11.5,\n color: \"var(--text-3)\",\n }}\n >\n {footer}\n </div>\n )}\n </div>\n );\n}\n","import { useState, useCallback } from \"react\";\nimport { Icon } from \"./Icons\";\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nconst COPY_FEEDBACK_MS = 1200;\n\nexport type RecordIdBadgeProps = {\n value: string;\n};\n\n/**\n * Compact record-ID badge. Truncates UUIDs to their first segment for readability\n * and copies the full value on click. Non-UUID ids render in full.\n */\nexport function RecordIdBadge({ value }: RecordIdBadgeProps) {\n const [copied, setCopied] = useState(false);\n const isUuid = UUID_RE.test(value);\n const display = isUuid ? `${value.slice(0, 8)}…` : value;\n\n const onCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n window.setTimeout(() => setCopied(false), COPY_FEEDBACK_MS);\n } catch {\n // Clipboard API unavailable (insecure context, permissions). Caller sees no feedback; acceptable.\n }\n }, [value]);\n\n return (\n <button\n type=\"button\"\n onClick={onCopy}\n title={copied ? \"Copied\" : `Copy ${value}`}\n className=\"mono inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[11px] text-text-4 hover:bg-surface-2 hover:text-text-3 transition-colors shrink-0 border border-transparent hover:border-border\"\n >\n <span>{display}</span>\n {copied ? <Icon.check size={10} /> : <Icon.copy size={10} style={{ opacity: 0.6 }} />}\n </button>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/detail.jsx\nimport type { ReactNode } from \"react\";\n\nexport type RowFieldProps = {\n label: ReactNode;\n children?: ReactNode;\n wide?: boolean;\n editing?: boolean;\n required?: boolean;\n hint?: string;\n};\n\nexport function RowField({ label, children, wide, editing, required }: RowFieldProps) {\n return (\n <div style={{\n display: \"flex\", flexDirection: wide ? \"column\" : \"row\", gap: wide ? 4 : 16,\n padding: \"4px 0\", gridColumn: wide ? \"1 / -1\" : \"auto\",\n alignItems: wide ? \"stretch\" : \"center\",\n }}>\n <div style={{\n width: wide ? \"auto\" : 140, flexShrink: 0, fontSize: 11.5, color: \"var(--text-3)\", fontWeight: 500,\n letterSpacing: \"0.005em\", display: \"flex\", alignItems: \"center\", gap: 4, minHeight: editing ? 30 : 24,\n }}>\n <span>{label}</span>\n {required && <span style={{ color: \"var(--danger)\" }}>*</span>}\n </div>\n <div style={{\n flex: 1, fontSize: 12.5, color: \"var(--text)\", minWidth: 0,\n overflow: \"hidden\", overflowWrap: \"anywhere\",\n }}>\n {children}\n </div>\n </div>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/fields.jsx\n\nexport type BoolToggleProps = {\n value?: boolean;\n onChange?: (v: boolean) => void;\n // Accessibility (Finding 2): this primitive is a <button role=\"checkbox\">,\n // not an <input>, so a <label htmlFor> cannot target it. ariaLabelledby\n // points at the form label's id instead. id keeps the control addressable.\n id?: string;\n ariaLabelledby?: string;\n};\n\nexport function BoolToggle({ value, onChange, id, ariaLabelledby }: BoolToggleProps) {\n return (\n <button\n type=\"button\"\n id={id}\n aria-labelledby={ariaLabelledby}\n role=\"checkbox\"\n aria-checked={!!value}\n onClick={() => onChange && onChange(!value)}\n style={{\n width: 32, height: 18, borderRadius: 999, border: \"none\", padding: 2, position: \"relative\",\n background: value ? \"var(--accent)\" : \"var(--border-strong)\",\n cursor: \"pointer\", transition: \"background .15s\",\n }}\n >\n <span style={{\n display: \"block\", width: 14, height: 14, borderRadius: 999, background: \"var(--accent-foreground)\",\n transform: value ? \"translateX(14px)\" : \"translateX(0)\",\n transition: \"transform .15s\", boxShadow: \"0 1px 2px rgba(0,0,0,.15)\",\n }} />\n </button>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport type { ReactNode } from \"react\";\nimport { Kbd } from \"./Kbd\";\n\nexport type MenuItemProps = {\n icon?: ReactNode;\n children?: ReactNode;\n onClick?: () => void;\n danger?: boolean;\n kbd?: ReactNode;\n active?: boolean;\n divider?: boolean;\n disabled?: boolean;\n title?: string;\n // Pass-through for test selectors. Without this, callers like TopBar's\n // \"Exit impersonation\" item silently drop their data-testid, breaking\n // RTL tests and any future automation that targets specific menu rows.\n \"data-testid\"?: string;\n};\n\nexport function MenuItem({ icon, children, onClick, danger, kbd, active, divider, disabled, title, \"data-testid\": dataTestId }: MenuItemProps) {\n if (divider) return <div style={{ height: 1, background: \"var(--divider)\", margin: \"4px 0\" }} />;\n return (\n <div\n onClick={disabled ? undefined : onClick}\n data-testid={dataTestId}\n aria-disabled={disabled || undefined}\n title={title}\n style={{\n display: \"flex\", alignItems: \"center\", gap: 8, padding: \"6px 10px\", borderRadius: 5,\n fontSize: 12.5, color: danger ? \"var(--danger)\" : \"var(--text-2)\", cursor: disabled ? \"not-allowed\" : \"pointer\",\n background: active ? \"var(--surface-3)\" : \"transparent\",\n opacity: disabled ? 0.45 : 1,\n }}\n onMouseEnter={(e) => { if (!disabled) e.currentTarget.style.background = \"var(--surface-3)\"; }}\n onMouseLeave={(e) => { e.currentTarget.style.background = active ? \"var(--surface-3)\" : \"transparent\"; }}\n >\n {icon && <span style={{ color: danger ? \"var(--danger)\" : \"var(--text-3)\", display: \"flex\" }}>{icon}</span>}\n <span style={{ flex: 1 }}>{children}</span>\n {kbd && <Kbd>{kbd}</Kbd>}\n </div>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\nimport type { MouseEvent } from \"react\";\n\nexport type CheckProps = {\n checked?: boolean;\n onChange?: (v: boolean) => void;\n indeterminate?: boolean;\n size?: number;\n};\n\nexport function Check({ checked, onChange, indeterminate, size = 14 }: CheckProps) {\n return (\n <span\n onClick={(e: MouseEvent<HTMLSpanElement>) => { e.stopPropagation(); onChange && onChange(!checked); }}\n style={{\n display: \"inline-flex\", width: size, height: size, borderRadius: 3,\n border: `1px solid ${checked || indeterminate ? \"var(--accent)\" : \"var(--border-strong)\"}`,\n background: checked || indeterminate ? \"var(--accent)\" : \"var(--surface)\",\n alignItems: \"center\", justifyContent: \"center\", cursor: \"pointer\", flexShrink: 0,\n }}\n >\n {checked && (\n <svg width={size - 4} height={size - 4} viewBox=\"0 0 10 10\" fill=\"none\" stroke=\"var(--accent-foreground)\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m2 5 2 2 4-5\" />\n </svg>\n )}\n {indeterminate && !checked && <span style={{ width: 6, height: 1.5, background: \"var(--accent-foreground)\" }} />}\n </span>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/primitives.jsx\n\nexport function Spinner({ size = 14 }: { size?: number }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" style={{ animation: \"spin 0.8s linear infinite\" }}>\n <style>{`@keyframes spin{to{transform:rotate(360deg);}}`}</style>\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"var(--border)\" strokeWidth=\"2.5\" fill=\"none\" />\n <path d=\"M12 3a9 9 0 0 1 9 9\" stroke=\"var(--accent)\" strokeWidth=\"2.5\" fill=\"none\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n","// Plan 2026-05-26 §B13 — stock visual treatment for a field/property\n// the current caller cannot read due to its classification tier.\n// Used by FieldsBlock + PropertiesBlock when entity.field_access[code]\n// reports read=\"denied\" (no plaintext sent over the wire).\n//\n// Renders a lock icon + the tier's localized display name (resolved\n// from schema.classifications), with a tooltip exposing the exact\n// permission grant string an administrator would need to add to the\n// caller's role. The grant string is the operator-facing hand-off\n// surface from B9: the user can copy/paste it into a support ticket.\n\nimport type { ClassificationTierDef } from \"@/types/schema\";\nimport { Icon } from \"./Icons\";\n\ninterface ClassifiedFieldLockedProps {\n // Tier code from FieldAccessInfo.classification. Used as fallback\n // label when the tier catalog isn't present in schema (e.g. test\n // harnesses) or carries no localized name.\n tier: string;\n // Tier catalog entry from schema.classifications[tier]. Optional;\n // when present, supplies localized name + audit_on_read hint that\n // sharpen the visual treatment.\n tierDef?: ClassificationTierDef;\n // Operator-facing permission string the admin needs to add to the\n // caller's role. From FieldAccessInfo.required_permission.\n requiredPermission?: string;\n // Locale for resolving tier.name; defaults to \"en\" when not passed.\n locale?: string;\n // Variant — \"value\" renders as a display-mode value placeholder\n // (used in FieldsBlock); \"input\" renders as a disabled-input\n // placeholder (used in FormField write-disabled). Both share the\n // lock icon + tier label; \"input\" gets a border to fit alongside\n // editable inputs.\n variant?: \"value\" | \"input\";\n}\n\nexport function ClassifiedFieldLocked({\n tier,\n tierDef,\n requiredPermission,\n locale = \"en\",\n variant = \"value\",\n}: ClassifiedFieldLockedProps) {\n const label = tierDef?.name?.[locale] ?? tierDef?.name?.en ?? tier;\n const title = requiredPermission\n ? `Locked: requires permission \"${requiredPermission}\". Ask your administrator to grant it to your role.`\n : `Locked: ${label} classification — requires explicit grant.`;\n const inputStyles =\n variant === \"input\"\n ? \"border border-divider rounded-md px-2 py-1 bg-surface\"\n : \"\";\n return (\n <span\n title={title}\n aria-label={title}\n className={`inline-flex items-center gap-1 text-muted-foreground italic select-none ${inputStyles}`}\n >\n <Icon.lock size={12} />\n <span>{label}</span>\n </span>\n );\n}\n","// Ported 1:1 from docs/plans/assets/2026-04-19-shell-design/project/decl/fields.jsx\n// Mock data references (APPDATA.COMPANIES) are replaced by passed-in props so the\n// design's RefField markup stays intact while the data layer is wired separately.\nimport { useMemo, useRef, useState } from \"react\";\nimport type {\n\tButtonHTMLAttributes,\n\tCSSProperties,\n\tInputHTMLAttributes,\n\tReactNode,\n} from \"react\";\nimport { Icon } from \"./Icons\";\nimport { Dropdown } from \"./Dropdown\";\nimport { MenuItem } from \"./MenuItem\";\nimport { Chip } from \"./Chip\";\nimport { Btn } from \"./Btn\";\nimport { IconBtn } from \"./IconBtn\";\nimport { BoolToggle } from \"./BoolToggle\";\n\nexport type FieldLabelProps = {\n\tchildren?: ReactNode;\n\trequired?: boolean;\n\thint?: string;\n};\n\nexport const FieldLabel = ({ children, required, hint }: FieldLabelProps) => (\n\t<div\n\t\tstyle={{\n\t\t\tdisplay: \"flex\",\n\t\t\talignItems: \"center\",\n\t\t\tgap: 4,\n\t\t\tfontSize: 11.5,\n\t\t\tcolor: \"var(--text-3)\",\n\t\t\tfontWeight: 500,\n\t\t\tmarginBottom: 4,\n\t\t\tletterSpacing: \"0.01em\",\n\t\t}}\n\t>\n\t\t<span>{children}</span>\n\t\t{required && (\n\t\t\t<span aria-hidden=\"true\" style={{ color: \"var(--danger)\" }}>\n\t\t\t\t*\n\t\t\t</span>\n\t\t)}\n\t\t{hint && (\n\t\t\t<span\n\t\t\t\ttitle={hint}\n\t\t\t\tstyle={{ cursor: \"help\", color: \"var(--text-4)\", display: \"flex\" }}\n\t\t\t>\n\t\t\t\t<Icon.info size={11} />\n\t\t\t</span>\n\t\t)}\n\t</div>\n);\n\nconst baseInput: CSSProperties = {\n\twidth: \"100%\",\n\theight: 30,\n\tpadding: \"0 10px\",\n\tfontSize: 12.5,\n\tlineHeight: \"28px\",\n\tbackground: \"var(--surface)\",\n\tcolor: \"var(--text)\",\n\tborder: \"1px solid var(--border)\",\n\tborderRadius: 6,\n\toutline: \"none\",\n\ttransition: \"border-color .12s, box-shadow .12s\",\n};\n\nexport type TextInputProps = Omit<\n\tInputHTMLAttributes<HTMLInputElement>,\n\t\"value\" | \"onChange\" | \"prefix\"\n> & {\n\tvalue?: string | null;\n\tonChange?: (v: string) => void;\n\tprefix?: ReactNode;\n\tsuffix?: ReactNode;\n\tstyle?: CSSProperties;\n};\n\nexport function TextInput({\n\tvalue,\n\tonChange,\n\tplaceholder,\n\tprefix,\n\tsuffix,\n\tstyle,\n\t...rest\n}: TextInputProps) {\n\tconst [focused, setFocused] = useState(false);\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\talignItems: \"center\",\n\t\t\t\tgap: 6,\n\t\t\t\t...baseInput,\n\t\t\t\tpadding: prefix || suffix ? \"0 8px\" : \"0 10px\",\n\t\t\t\tborderColor: focused ? \"var(--accent)\" : \"var(--border)\",\n\t\t\t\tboxShadow: focused ? `0 0 0 3px var(--accent-ring)` : \"none\",\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t{prefix && (\n\t\t\t\t<span style={{ color: \"var(--text-3)\", display: \"flex\" }}>\n\t\t\t\t\t{prefix}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t<input\n\t\t\t\tvalue={value ?? \"\"}\n\t\t\t\tonChange={(e) => onChange && onChange(e.target.value)}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tonFocus={() => setFocused(true)}\n\t\t\t\tonBlur={() => setFocused(false)}\n\t\t\t\tstyle={{\n\t\t\t\t\tborder: 0,\n\t\t\t\t\toutline: 0,\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tflex: 1,\n\t\t\t\t\tfontSize: 12.5,\n\t\t\t\t\tcolor: \"var(--text)\",\n\t\t\t\t\tpadding: 0,\n\t\t\t\t\tminWidth: 0,\n\t\t\t\t}}\n\t\t\t\t{...rest}\n\t\t\t/>\n\t\t\t{suffix && (\n\t\t\t\t<span style={{ color: \"var(--text-3)\", display: \"flex\" }}>\n\t\t\t\t\t{suffix}\n\t\t\t\t</span>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nexport type TextAreaProps = {\n\tvalue?: string | null;\n\tonChange?: (v: string) => void;\n\tplaceholder?: string;\n\trows?: number;\n\t// When true the textarea fills its flex parent (height:100%, minHeight:0)\n\t// and disables its own browser resize handle. Used inside the activity\n\t// composer so the outer drag handle is the single source of resize truth.\n\tfill?: boolean;\n\t// Accessibility: a stable id pairs the textarea with a <label htmlFor>,\n\t// name carries the field code into form payloads / a11y tooling, and\n\t// ariaRequired marks required fields for screen readers. Reason: the\n\t// create/edit form labels its fields via <label htmlFor> (Finding 2).\n\tid?: string;\n\tname?: string;\n\tariaRequired?: boolean;\n};\n\nexport function TextArea({\n\tvalue,\n\tonChange,\n\tplaceholder,\n\trows = 4,\n\tfill,\n\tid,\n\tname,\n\tariaRequired,\n}: TextAreaProps) {\n\tconst [focused, setFocused] = useState(false);\n\tconst fillStyle = fill\n\t\t? { flex: 1, height: \"100%\", minHeight: 0, resize: \"none\" as const }\n\t\t: { height: \"auto\", resize: \"vertical\" as const };\n\treturn (\n\t\t<textarea\n\t\t\tid={id}\n\t\t\tname={name}\n\t\t\taria-required={ariaRequired || undefined}\n\t\t\tvalue={value ?? \"\"}\n\t\t\tonChange={(e) => onChange && onChange(e.target.value)}\n\t\t\tplaceholder={placeholder}\n\t\t\trows={fill ? undefined : rows}\n\t\t\tonFocus={() => setFocused(true)}\n\t\t\tonBlur={() => setFocused(false)}\n\t\t\tstyle={{\n\t\t\t\t...baseInput,\n\t\t\t\tpadding: \"8px 10px\",\n\t\t\t\tlineHeight: 1.5,\n\t\t\t\t...fillStyle,\n\t\t\t\tborderColor: focused ? \"var(--accent)\" : \"var(--border)\",\n\t\t\t\tboxShadow: focused ? `0 0 0 3px var(--accent-ring)` : \"none\",\n\t\t\t\tfontFamily: \"inherit\",\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nexport type SelectOption = { value: string; label: ReactNode };\nexport type SelectProps = Omit<\n\tButtonHTMLAttributes<HTMLButtonElement>,\n\t\"value\" | \"onChange\"\n> & {\n\tvalue?: string;\n\toptions: SelectOption[];\n\tonChange: (v: string) => void;\n\tplaceholder?: string;\n};\n\nconst SELECT_SEARCH_THRESHOLD = 20;\nconst SELECT_MAX_VISIBLE_OPTIONS = 100;\n\nfunction optionSearchText(option: SelectOption): string {\n\tif (typeof option.label === \"string\" || typeof option.label === \"number\")\n\t\treturn String(option.label);\n\treturn option.value;\n}\n\nexport function Select({\n\tvalue,\n\toptions,\n\tonChange,\n\tplaceholder = \"Select...\",\n\t...rest\n}: SelectProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst [query, setQuery] = useState(\"\");\n\tconst ref = useRef<HTMLButtonElement | null>(null);\n\tconst opt = options.find((o) => o.value === value);\n\tconst searchable = options.length > SELECT_SEARCH_THRESHOLD;\n\tconst filteredOptions = useMemo(() => {\n\t\tconst needle = query.trim().toLowerCase();\n\t\tif (!needle) return options.slice(0, SELECT_MAX_VISIBLE_OPTIONS);\n\t\treturn options\n\t\t\t.filter((option) =>\n\t\t\t\toptionSearchText(option).toLowerCase().includes(needle),\n\t\t\t)\n\t\t\t.slice(0, SELECT_MAX_VISIBLE_OPTIONS);\n\t}, [options, query]);\n\treturn (\n\t\t<>\n\t\t\t{/* type=\"button\" is load-bearing: without it, a <button> inside a <form>\n defaults to type=\"submit\" and every dropdown click submits the form\n (which is how the TimelineComposer quick-add was firing on every\n combobox interaction). Keep this explicit on every primitive button.\n\n Spread `{...rest}` BEFORE onClick/aria-* so a caller cannot override\n our open/close handler. Functional `setOpen(prev => !prev)` instead of\n `setOpen(!open)` avoids stale-closure bugs when the parent re-renders\n between the click handler being created and being invoked (the\n symptom of the v0.1.85 Set Stage dropdown bug). */}\n\t\t\t<button\n\t\t\t\t{...rest}\n\t\t\t\ttype=\"button\"\n\t\t\t\tref={ref}\n\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\taria-expanded={open}\n\t\t\t\tonClick={() => {\n\t\t\t\t\tsetOpen((prev) => {\n\t\t\t\t\t\tconst next = !prev;\n\t\t\t\t\t\tif (next) setQuery(\"\");\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t}}\n\t\t\t\tstyle={{\n\t\t\t\t\t...baseInput,\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tjustifyContent: \"space-between\",\n\t\t\t\t\ttextAlign: \"left\",\n\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t\t...rest.style,\n\t\t\t\t\tcolor: opt ? \"var(--text)\" : \"var(--text-placeholder)\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\tgap: 6,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{opt ? opt.label : placeholder}\n\t\t\t\t</span>\n\t\t\t\t<Icon.down size={12} cls=\"\" style={{ color: \"var(--text-3)\" }} />\n\t\t\t</button>\n\t\t\t<Dropdown\n\t\t\t\topen={open}\n\t\t\t\tanchor={ref.current}\n\t\t\t\tonClose={() => setOpen(false)}\n\t\t\t\twidth={ref.current?.offsetWidth}\n\t\t\t\tstyle={{\n\t\t\t\t\tmaxHeight: \"min(360px, calc(100vh - 24px))\",\n\t\t\t\t\toverflowY: \"auto\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{searchable && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tpadding: 6,\n\t\t\t\t\t\t\tposition: \"sticky\",\n\t\t\t\t\t\t\ttop: -4,\n\t\t\t\t\t\t\tbackground: \"var(--surface)\",\n\t\t\t\t\t\t\tzIndex: 1,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TextInput\n\t\t\t\t\t\t\tvalue={query}\n\t\t\t\t\t\t\tonChange={setQuery}\n\t\t\t\t\t\t\tplaceholder=\"Search…\"\n\t\t\t\t\t\t\tprefix={<Icon.search size={12} />}\n\t\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t{filteredOptions.map((o) => (\n\t\t\t\t\t<MenuItem\n\t\t\t\t\t\tkey={o.value}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\tonChange(o.value);\n\t\t\t\t\t\t\tsetOpen(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tactive={o.value === value}\n\t\t\t\t\t>\n\t\t\t\t\t\t{o.label}\n\t\t\t\t\t</MenuItem>\n\t\t\t\t))}\n\t\t\t\t{filteredOptions.length === 0 && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tpadding: \"8px 10px\",\n\t\t\t\t\t\t\tfontSize: 12.5,\n\t\t\t\t\t\t\tcolor: \"var(--text-3)\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tNo matches\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</Dropdown>\n\t\t</>\n\t);\n}\n\nexport type DateInputProps = {\n\tvalue?: string | null;\n\tonChange?: (v: string) => void;\n};\n\nexport function DateInput({ value, onChange }: DateInputProps) {\n\treturn (\n\t\t<TextInput\n\t\t\tvalue={value || \"\"}\n\t\t\tonChange={onChange}\n\t\t\tplaceholder=\"YYYY-MM-DD HH:mm\"\n\t\t\tprefix={<Icon.calendar size={13} />}\n\t\t/>\n\t);\n}\n\nexport type PasswordInputProps = {\n\tvalue?: string | null;\n\tonChange?: (v: string) => void;\n\tplaceholder?: string;\n\tshowStrength?: boolean;\n\t// Accessibility: forwarded to the inner password <input> so the create/edit\n\t// form can pair it with a <label htmlFor> and mark required fields.\n\tid?: string;\n\tname?: string;\n\tariaRequired?: boolean;\n};\n\nfunction scorePassword(pw: string): number {\n\tif (!pw) return 0;\n\tlet s = 0;\n\tif (pw.length >= 8) s++;\n\tif (pw.length >= 12) s++;\n\tif (/[A-Z]/.test(pw) && /[a-z]/.test(pw)) s++;\n\tif (/\\d/.test(pw)) s++;\n\tif (/[^A-Za-z0-9]/.test(pw)) s++;\n\treturn Math.min(4, s);\n}\n\nconst STRENGTH_LABELS = [\"Too short\", \"Weak\", \"Fair\", \"Good\", \"Strong\"];\nconst STRENGTH_COLORS = [\n\t\"var(--danger)\",\n\t\"var(--danger)\",\n\t\"var(--warning, #B45309)\",\n\t\"var(--accent)\",\n\t\"var(--success, #3FBF8F)\",\n];\n\nexport function PasswordInput({\n\tvalue,\n\tonChange,\n\tplaceholder = \"Enter password\",\n\tshowStrength,\n\tid,\n\tname,\n\tariaRequired,\n}: PasswordInputProps) {\n\tconst [show, setShow] = useState(false);\n\tconst pw = value || \"\";\n\tconst score = scorePassword(pw);\n\treturn (\n\t\t<div>\n\t\t\t<TextInput\n\t\t\t\tid={id}\n\t\t\t\tname={name}\n\t\t\t\taria-required={ariaRequired || undefined}\n\t\t\t\ttype={show ? \"text\" : \"password\"}\n\t\t\t\tvalue={pw}\n\t\t\t\tonChange={onChange}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tsuffix={\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\taria-label={show ? \"Hide password\" : \"Show password\"}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tbackground: \"none\",\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t\t\t\tcolor: \"var(--text-3)\",\n\t\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonClick={() => setShow((prev) => !prev)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{show ? <Icon.eyeOff size={14} /> : <Icon.eye size={14} />}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t{showStrength && (\n\t\t\t\t<div\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tmarginTop: 6,\n\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\tgap: 8,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<div style={{ display: \"flex\", gap: 3, flex: 1 }}>\n\t\t\t\t\t\t{[0, 1, 2, 3].map((i) => (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tkey={i}\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\t\t\t\theight: 3,\n\t\t\t\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\t\t\t\tbackground:\n\t\t\t\t\t\t\t\t\t\ti < score ? STRENGTH_COLORS[score] : \"var(--surface-3)\",\n\t\t\t\t\t\t\t\t\ttransition: \"background .15s\",\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tfontSize: 10.5,\n\t\t\t\t\t\t\tcolor: \"var(--text-3)\",\n\t\t\t\t\t\t\tminWidth: 54,\n\t\t\t\t\t\t\ttextAlign: \"right\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{pw ? STRENGTH_LABELS[score] : \"\"}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nexport type TagsInputProps = {\n\tvalue?: string[];\n\tonChange: (v: string[]) => void;\n};\n\nexport function TagsInput({ value = [], onChange }: TagsInputProps) {\n\tconst [txt, setTxt] = useState(\"\");\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\t...baseInput,\n\t\t\t\theight: \"auto\",\n\t\t\t\tminHeight: 30,\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tflexWrap: \"wrap\",\n\t\t\t\tgap: 4,\n\t\t\t\tpadding: \"4px 6px\",\n\t\t\t\talignItems: \"center\",\n\t\t\t}}\n\t\t>\n\t\t\t{value.map((v, i) => (\n\t\t\t\t<Chip\n\t\t\t\t\tkey={i}\n\t\t\t\t\ttone=\"slate\"\n\t\t\t\t\tonRemove={() => onChange(value.filter((_, j) => j !== i))}\n\t\t\t\t>\n\t\t\t\t\t{v}\n\t\t\t\t</Chip>\n\t\t\t))}\n\t\t\t<input\n\t\t\t\tvalue={txt}\n\t\t\t\tonChange={(e) => setTxt(e.target.value)}\n\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\tif (e.key === \"Enter\" && txt.trim()) {\n\t\t\t\t\t\tonChange([...value, txt.trim()]);\n\t\t\t\t\t\tsetTxt(\"\");\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tif (e.key === \"Backspace\" && !txt && value.length)\n\t\t\t\t\t\tonChange(value.slice(0, -1));\n\t\t\t\t}}\n\t\t\t\tplaceholder={value.length ? \"\" : \"Add tag… (Enter)\"}\n\t\t\t\tstyle={{\n\t\t\t\t\tborder: 0,\n\t\t\t\t\toutline: 0,\n\t\t\t\t\tflex: 1,\n\t\t\t\t\tminWidth: 80,\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tfontSize: 12.5,\n\t\t\t\t\tpadding: \"4px 2px\",\n\t\t\t\t}}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nexport type JsonFieldProps = {\n\tvalue?: string;\n\tonChange?: (v: string) => void;\n};\n\nexport function JsonField({ value, onChange }: JsonFieldProps) {\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tborder: \"1px solid var(--border)\",\n\t\t\t\tborderRadius: 6,\n\t\t\t\tbackground: \"var(--surface-2)\",\n\t\t\t\toverflow: \"hidden\",\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tpadding: \"6px 10px\",\n\t\t\t\t\tbackground: \"var(--surface-3)\",\n\t\t\t\t\tborderBottom: \"1px solid var(--border)\",\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tgap: 8,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tclassName=\"mono\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tfontSize: 10.5,\n\t\t\t\t\t\tcolor: \"var(--text-3)\",\n\t\t\t\t\t\ttextTransform: \"uppercase\",\n\t\t\t\t\t\tletterSpacing: \"0.04em\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tJSON\n\t\t\t\t</span>\n\t\t\t\t<span style={{ flex: 1 }} />\n\t\t\t\t<Btn size=\"xs\" kind=\"ghost\">\n\t\t\t\t\tFormat\n\t\t\t\t</Btn>\n\t\t\t\t<Btn size=\"xs\" kind=\"ghost\">\n\t\t\t\t\tValidate\n\t\t\t\t</Btn>\n\t\t\t</div>\n\t\t\t<textarea\n\t\t\t\tclassName=\"mono\"\n\t\t\t\tvalue={value || \"\"}\n\t\t\t\tonChange={(e) => onChange && onChange(e.target.value)}\n\t\t\t\tstyle={{\n\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\tminHeight: 140,\n\t\t\t\t\tpadding: \"10px 12px\",\n\t\t\t\t\tfontSize: 12,\n\t\t\t\t\tlineHeight: 1.6,\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tborder: 0,\n\t\t\t\t\toutline: 0,\n\t\t\t\t\tresize: \"vertical\",\n\t\t\t\t\tcolor: \"var(--text)\",\n\t\t\t\t}}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nexport type RefFieldItem = { id: string; name: string };\nexport type RefFieldProps = {\n\tvalue?: string;\n\tentity?: string;\n\tonChange?: (v: string) => void;\n\titems?: RefFieldItem[];\n\t// Accessibility: this primitive renders a <button>, not an <input>, so it\n\t// cannot be paired with a <label htmlFor>. ariaLabelledby points at the\n\t// label element's id instead; ariaRequired marks required fields. id keeps\n\t// the control individually addressable (Finding 2).\n\tid?: string;\n\tariaLabelledby?: string;\n\tariaRequired?: boolean;\n};\n\nexport function RefField({\n\tvalue,\n\tentity = \"company\",\n\tonChange,\n\titems = [],\n\tid,\n\tariaLabelledby,\n\tariaRequired,\n}: RefFieldProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst ref = useRef<HTMLButtonElement | null>(null);\n\treturn (\n\t\t<>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tid={id}\n\t\t\t\taria-labelledby={ariaLabelledby}\n\t\t\t\taria-required={ariaRequired || undefined}\n\t\t\t\tref={ref}\n\t\t\t\tonClick={() => setOpen(true)}\n\t\t\t\tstyle={{\n\t\t\t\t\t...baseInput,\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tjustifyContent: \"space-between\",\n\t\t\t\t\ttextAlign: \"left\",\n\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\tgap: 8,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: 18,\n\t\t\t\t\t\t\theight: 18,\n\t\t\t\t\t\t\tborderRadius: 4,\n\t\t\t\t\t\t\tbackground: \"var(--accent-soft)\",\n\t\t\t\t\t\t\tcolor: \"var(--accent)\",\n\t\t\t\t\t\t\tdisplay: \"inline-flex\",\n\t\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\t\tjustifyContent: \"center\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon.link size={11} />\n\t\t\t\t\t</span>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tcolor: value ? \"var(--accent)\" : \"var(--text-placeholder)\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{value || `Link to ${entity}…`}\n\t\t\t\t\t</span>\n\t\t\t\t</span>\n\t\t\t\t<Icon.search size={12} cls=\"\" style={{ color: \"var(--text-3)\" }} />\n\t\t\t</button>\n\t\t\t<Dropdown\n\t\t\t\topen={open}\n\t\t\t\tanchor={ref.current}\n\t\t\t\tonClose={() => setOpen(false)}\n\t\t\t\twidth={ref.current?.offsetWidth}\n\t\t\t>\n\t\t\t\t<div style={{ padding: 4 }}>\n\t\t\t\t\t<TextInput\n\t\t\t\t\t\tplaceholder={`Search ${entity}…`}\n\t\t\t\t\t\tprefix={<Icon.search size={12} />}\n\t\t\t\t\t\tstyle={{ marginBottom: 4 }}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t{items.slice(0, 6).map((c) => (\n\t\t\t\t\t<MenuItem\n\t\t\t\t\t\tkey={c.id}\n\t\t\t\t\t\ticon={<Icon.building size={13} />}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\tonChange && onChange(c.name);\n\t\t\t\t\t\t\tsetOpen(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{c.name}\n\t\t\t\t\t</MenuItem>\n\t\t\t\t))}\n\t\t\t</Dropdown>\n\t\t</>\n\t);\n}\n\n// Display-mode field row (label + value)\nexport type ViewFieldProps = {\n\tlabel: ReactNode;\n\tchildren?: ReactNode;\n\tmono?: boolean;\n\twide?: boolean;\n\tempty?: boolean;\n};\n\nexport function ViewField({\n\tlabel,\n\tchildren,\n\tmono,\n\twide,\n\tempty,\n}: ViewFieldProps) {\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tflexDirection: wide ? \"column\" : \"row\",\n\t\t\t\tgap: wide ? 4 : 16,\n\t\t\t\tminHeight: 24,\n\t\t\t\talignItems: \"baseline\",\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\twidth: wide ? \"auto\" : 140,\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tfontSize: 11.5,\n\t\t\t\t\tcolor: \"var(--text-3)\",\n\t\t\t\t\tfontWeight: 500,\n\t\t\t\t\tletterSpacing: \"0.01em\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{label}\n\t\t\t</div>\n\t\t\t<div\n\t\t\t\tclassName={mono ? \"mono num\" : \"num\"}\n\t\t\t\tstyle={{\n\t\t\t\t\tflex: 1,\n\t\t\t\t\tfontSize: 12.5,\n\t\t\t\t\tcolor: empty ? \"var(--text-4)\" : \"var(--text)\",\n\t\t\t\t\tlineHeight: \"22px\",\n\t\t\t\t\tminWidth: 0,\n\t\t\t\t\twordBreak: \"break-word\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{empty ? \"—\" : children}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\n// Quick-edit cell — display by default, input on click.\nexport type QuickEditCellProps = {\n\tvalue?: string;\n\tonChange?: (v: string) => void;\n\ttype?: \"text\" | \"select\" | \"bool\";\n\toptions?: SelectOption[];\n\ttone?: string;\n};\n\nexport function QuickEditCell({\n\tvalue,\n\tonChange,\n\ttype = \"text\",\n\toptions,\n}: QuickEditCellProps) {\n\tconst [editing, setEditing] = useState(false);\n\tconst [tmp, setTmp] = useState<string | undefined>(value);\n\tconst save = () => {\n\t\tonChange && tmp !== undefined && onChange(tmp);\n\t\tsetEditing(false);\n\t};\n\tconst cancel = () => {\n\t\tsetTmp(value);\n\t\tsetEditing(false);\n\t};\n\tif (editing) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tstyle={{ display: \"flex\", alignItems: \"center\", gap: 4 }}\n\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\tif (e.key === \"Enter\") save();\n\t\t\t\t\tif (e.key === \"Escape\") cancel();\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{type === \"select\" ? (\n\t\t\t\t\t<Select\n\t\t\t\t\t\tvalue={tmp}\n\t\t\t\t\t\toptions={options || []}\n\t\t\t\t\t\tonChange={(v) => {\n\t\t\t\t\t\t\tsetTmp(v);\n\t\t\t\t\t\t\tonChange && onChange(v);\n\t\t\t\t\t\t\tsetEditing(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : type === \"bool\" ? (\n\t\t\t\t\t<BoolToggle\n\t\t\t\t\t\tvalue={tmp === \"true\"}\n\t\t\t\t\t\tonChange={(v) => {\n\t\t\t\t\t\t\tconst next = String(v);\n\t\t\t\t\t\t\tsetTmp(next);\n\t\t\t\t\t\t\tonChange && onChange(next);\n\t\t\t\t\t\t\tsetEditing(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<TextInput value={tmp ?? \"\"} onChange={setTmp} autoFocus />\n\t\t\t\t)}\n\t\t\t\t{type !== \"select\" && type !== \"bool\" && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<IconBtn\n\t\t\t\t\t\t\tsize={24}\n\t\t\t\t\t\t\ticon={<Icon.check size={13} />}\n\t\t\t\t\t\t\tonClick={save}\n\t\t\t\t\t\t\ttitle=\"Save\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<IconBtn\n\t\t\t\t\t\t\tsize={24}\n\t\t\t\t\t\t\ticon={<Icon.x size={13} />}\n\t\t\t\t\t\t\tonClick={cancel}\n\t\t\t\t\t\t\ttitle=\"Cancel\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t}\n\treturn (\n\t\t<div\n\t\t\tonClick={() => setEditing(true)}\n\t\t\tstyle={{\n\t\t\t\tpadding: \"4px 6px\",\n\t\t\t\tmargin: \"-4px -6px\",\n\t\t\t\tborderRadius: 4,\n\t\t\t\tcursor: \"text\",\n\t\t\t\tborder: \"1px dashed transparent\",\n\t\t\t\tminHeight: 24,\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\talignItems: \"center\",\n\t\t\t\tgap: 4,\n\t\t\t}}\n\t\t\tonMouseEnter={(e) => {\n\t\t\t\te.currentTarget.style.borderColor = \"var(--border)\";\n\t\t\t}}\n\t\t\tonMouseLeave={(e) => {\n\t\t\t\te.currentTarget.style.borderColor = \"transparent\";\n\t\t\t}}\n\t\t>\n\t\t\t{value || <span style={{ color: \"var(--text-4)\" }}>Click to edit</span>}\n\t\t</div>\n\t);\n}\n","/**\n * OrderedMap preserves the insertion order of a string-keyed map while\n * keeping O(1) lookup. It mirrors the Go `ordmap.OrderedMap[T]` container\n * on the server side. Use it for schema sub-maps (entity fields, handler\n * params, resolved_params) where YAML/JSON declaration order is part of\n * the UI contract.\n *\n * JS objects already preserve insertion order for string keys (ES2015+),\n * but the Go side emits JSON that is parsed into a plain object by\n * default — this class wraps the hydrated object so call sites get a\n * consistent API (`get`, `has`, iteration as `[name, value]` tuples) and\n * the type system enforces read-only access.\n */\nexport class OrderedMap<T extends { name?: string }> implements Iterable<[string, T]> {\n readonly #items: readonly T[];\n readonly #index: ReadonlyMap<string, number>;\n\n constructor(items: readonly T[]) {\n this.#items = items;\n const idx = new Map<string, number>();\n for (let i = 0; i < items.length; i++) {\n const n = items[i].name;\n if (n !== undefined) idx.set(n, i);\n }\n this.#index = idx;\n }\n\n /** Build from a `{ name: value }` object, populating each value's `name`\n * field from the object key. Insertion order is the JS property order. */\n static fromObject<T extends { name?: string }>(\n raw: Readonly<Record<string, unknown>> | null | undefined,\n ): OrderedMap<T> {\n if (!raw) return new OrderedMap<T>([]);\n const out: T[] = [];\n for (const [name, body] of Object.entries(raw)) {\n out.push({ ...(body as object), name } as T);\n }\n return new OrderedMap<T>(out);\n }\n\n get length(): number {\n return this.#items.length;\n }\n\n has(name: string): boolean {\n return this.#index.has(name);\n }\n\n get(name: string): T | undefined {\n const i = this.#index.get(name);\n return i === undefined ? undefined : this.#items[i];\n }\n\n /** Read-only items in declaration order. */\n items(): readonly T[] {\n return this.#items;\n }\n\n /** Names in declaration order. */\n names(): readonly string[] {\n return this.#items.map((it) => it.name ?? \"\");\n }\n\n *[Symbol.iterator](): IterableIterator<[string, T]> {\n for (const it of this.#items) {\n yield [it.name ?? \"\", it];\n }\n }\n}\n","import { OrderedMap } from \"./ordmap\";\nimport type { FileFieldDef } from \"./files\";\nexport { OrderedMap };\n\nexport type LocalizedString = Record<string, string>;\n\n/**\n * Per-entity empty-state copy declared in the manifest under\n * `display.empty_state`. Title and Body are localized; LearnMoreURL is a\n * plain string. The SDK falls back to a generic \"No <plural> yet\" derived\n * from `display.name_plural` when this is absent. Read-only entities never\n * render the legacy \"Create your first...\" copy regardless of EmptyStateDef.\n */\nexport interface EmptyStateDef {\n title?: LocalizedString;\n body?: LocalizedString;\n learn_more_url?: string;\n}\n\n/**\n * Reserved sentinel value for Screen.detail_screen (list screens). Disables\n * row-click navigation even when the entity declares a canonical detail. Paired\n * with Go's engine.DetailScreenNone - keep the literal \"none\" in sync.\n */\nexport const DETAIL_SCREEN_NONE = \"none\";\n\nexport function loc(ls: LocalizedString | undefined, lang = \"en\"): string {\n if (!ls) return \"\";\n return ls[lang] ?? Object.values(ls)[0] ?? \"\";\n}\n\n// DISPLAY_KEY is the synthetic row property where the server places a\n// rendered display.template. Read by getDisplayValue() below; the value is\n// always a string when present. Uses the `$`-prefix convention shared with\n// other engine-injected synthetic keys (`$row_version`, `$units`, `$refs`)\n// so it does not collide with consumer-defined field names. Mirrors\n// `engine.DisplayKey` in golang/internal/engine/display_templates.go — keep\n// the constants in sync.\nexport const DISPLAY_KEY = \"$display\";\n\n// getDisplayValue returns the string label for a row, preferring a rendered\n// template (`row.$display`, server-resolved when entity has display.template)\n// over the raw display_field column. Returns undefined when neither is\n// available so callers can decide on their own fallback (typically the row's\n// primary key).\n//\n// Ref-derived labels are NOT resolved here. By platform design, display is\n// declarative: an entity that needs to label itself by a referenced record\n// declares `display.template` (e.g. `${row.user_id}`), and the server's\n// display-template ref-recursion (docs/plans/completed/2026-04-27-display-\n// template-ref-recursion.md) renders the final string into `$display`. The\n// client just reads `$display`. `display.field` is for a scalar column on\n// the entity itself; pointing it at a ref is a schema misconfiguration, not\n// something the client papers over.\n//\n// Localized JSONB fields (e.g. `name: {en: \"...\", ru: \"...\"}`) are unwrapped\n// via loc() so callers do not need to handle the multilingual case\n// themselves. Without this unwrap, `String({...})` produces \"[object Object]\"\n// — a regression caught in review by codex.\nexport function getDisplayValue(\n row: Record<string, unknown> | null | undefined,\n entity: { display?: { display_field?: string } } | null | undefined,\n): string | undefined {\n if (!row) return undefined;\n const rendered = row[DISPLAY_KEY];\n if (typeof rendered === \"string\" && rendered !== \"\") return rendered;\n const field = entity?.display?.display_field;\n if (!field) return undefined;\n const v = row[field];\n if (v == null) return undefined;\n if (typeof v === \"object\" && !Array.isArray(v)) {\n const text = loc(v as LocalizedString);\n return text || undefined;\n }\n return String(v);\n}\n\n// resolveRefRecordLabel returns a human label for a server-embedded\n// referenced record (one entry of a `$refs` payload): its rendered\n// `$display` when present, else the value at `displayField` (localized-JSONB\n// unwrapped via loc()), else the `fallback` (typically the foreign-key value\n// itself).\n//\n// Single resolver for ref-record labels. The ref-field editor (RefField) and\n// the ref-link table cell (refLink) both route through it. Each previously\n// carried its own copy and they had drifted: RefField unwrapped a localized\n// object via Object.values()[0] (locale-blind, always the first key),\n// refLink preferred the \"en\" key. loc() is the correct locale-aware unwrap;\n// consolidating fixes both.\nexport function resolveRefRecordLabel(\n record: Record<string, unknown>,\n displayField: string | undefined,\n fallback: string,\n): string {\n const rendered = record[DISPLAY_KEY];\n if (typeof rendered === \"string\" && rendered !== \"\") return rendered;\n if (displayField) {\n const v = record[displayField];\n if (v != null) {\n if (typeof v === \"object\" && !Array.isArray(v)) {\n return loc(v as LocalizedString) || fallback;\n }\n return String(v);\n }\n }\n return fallback;\n}\n\n// routeToRegex turns a screen route pattern into an anchored matcher.\n// Literal segments are regex-escaped; `:param` segments match any single\n// non-slash path segment. A trailing slash on the route is ignored.\nfunction routeToRegex(route: string): RegExp {\n const segs = route\n .replace(/\\/+$/, \"\")\n .split(\"/\")\n .map((s) => (s.startsWith(\":\") ? \"[^/]+\" : s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")));\n return new RegExp(\"^\" + segs.join(\"/\") + \"$\");\n}\n\n// shortId trims a record id for use inside a tab title. UUIDs are unreadable\n// at full length in a 12-char tab; the first segment of a UUID (or the first\n// 8 chars of any other id) is enough to disambiguate two open detail tabs.\n// Reason: a detail tab labelled only \"User\" is ambiguous when several users\n// are open; the short id keeps each tab distinct without showing a full UUID.\nfunction shortId(segment: string): string {\n const decoded = (() => {\n try {\n return decodeURIComponent(segment);\n } catch {\n return segment;\n }\n })();\n const head = decoded.split(\"-\")[0];\n return head.length > 8 ? head.slice(0, 8) : head;\n}\n\n// screenTitleForPath resolves a human title (+ icon) for a router pathname by\n// matching it against the registered screen routes. An exact (wildcard-free)\n// route match wins over a `:param` match so `/admin/users` resolves to the\n// list screen even though the detail route `/admin/users/:id` also has the\n// same prefix. Returns undefined when no screen owns the path.\n//\n// Title resolution order for a matched screen:\n// 1. screen.display.name (the explicit screen title).\n// 2. For a detail (`:param`) route with no screen name: the bound entity's\n// display name plus a short record id (e.g. \"User a1b2c3d4\"). The engine\n// may register a detail screen without a display.name; without this\n// branch such a tab would fall back to the raw pathname (a bare UUID).\n// Reason: Finding 4 - a tab must never show a raw entity UUID.\n// Returns undefined only when no screen route matches the path at all.\n//\n// Reason: useTabNavigate opens a tab when navigating. Callers that don't\n// pass an explicit title (e.g. an href-mode action dispatched from the\n// toolbar) would otherwise get the raw URL as the tab label. Detail tabs get\n// this resolved title initially, then SmartDetailPage refines it to the\n// record label once the row loads.\nexport function screenTitleForPath(\n pathname: string,\n screens: Record<string, Screen> | undefined,\n entities?: Record<string, Entity>,\n): { title: string; icon?: string } | undefined {\n if (!screens) return undefined;\n const norm = pathname.replace(/\\/+$/, \"\") || \"/\";\n let wildcardMatch: { title: string; icon?: string } | undefined;\n for (const screen of Object.values(screens)) {\n if (!screen.route) continue;\n if (!routeToRegex(screen.route).test(norm)) continue;\n const isWildcard = screen.route.includes(\"/:\");\n const screenName = loc(screen.display?.name);\n // Resolve a title even when the screen itself is nameless: a detail\n // screen falls back to \"<EntityName> <shortId>\" so the tab is readable.\n let title = screenName;\n if (!title && isWildcard && entities && screen.entity) {\n const entityName = loc(entities[screen.entity]?.display?.name);\n if (entityName) {\n const lastSegment = norm.slice(norm.lastIndexOf(\"/\") + 1);\n title = lastSegment ? `${entityName} ${shortId(lastSegment)}` : entityName;\n }\n }\n if (!title) continue;\n const hit = { title, icon: screen.display?.icon };\n if (!isWildcard) return hit; // exact match wins\n wildcardMatch ??= hit;\n }\n return wildcardMatch;\n}\n\n// fieldDisplayName resolves a field's display label.\n// For ref fields without an explicit display.name, falls back to the\n// referenced entity's singular name (e.g. organization_id → \"Organization\").\nexport function fieldDisplayName(\n field: EntityField,\n fieldName: string,\n entities?: Record<string, Entity>,\n): string {\n const explicit = loc(field.display?.name);\n if (explicit) return explicit;\n if (field.type === \"ref\" && field.ref?.entity && entities) {\n const refEntity = entities[field.ref.entity];\n if (refEntity) {\n const entityName = loc(refEntity.display?.name);\n if (entityName) return entityName;\n }\n }\n return fieldName;\n}\n\nexport interface RefDisplay {\n field: string;\n}\n\nexport interface RefConfig {\n entity: string;\n field?: string; // lookup column on target entity (default: primary key)\n display?: RefDisplay;\n fields?: string[];\n}\n\nexport interface UnitConfig {\n storage: string;\n display?: string;\n}\n\nexport interface EntityField {\n /**\n * Populated by the schema hydrator from the enclosing map key. Tests and\n * fixtures may omit it; production code always receives it set.\n */\n name?: string;\n type: string;\n required?: boolean;\n primary?: boolean;\n auto?: boolean;\n // Server-owned value the user never types (e.g. last_login_at). Rendered\n // read-only in edit/create forms, same as `auto`.\n readonly?: boolean;\n timezone?: string;\n precision?: number;\n scale?: number;\n unit?: UnitConfig;\n default?: unknown;\n display?: {\n name: LocalizedString;\n description?: LocalizedString;\n width?: number;\n widget?: string;\n is_listable?: boolean;\n is_filterable?: boolean;\n list_preview?: { max_chars: number };\n ref_display_field?: string;\n span?: number | \"full\";\n // 1a.5 cell renderer hints. The engine fills `widget` with a smart default\n // at YAML-load time, so this object always carries a renderer hint by the\n // time it reaches the UI; these three are author-supplied overrides.\n bool_labels?: { true: LocalizedString; false: LocalizedString };\n value_map?: Record<string, { label?: LocalizedString; color?: string }>;\n currency?: string;\n currency_field?: string;\n currency_display?: \"symbol\" | \"narrow_symbol\" | \"code\" | \"name\";\n };\n values?: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n enum?: string;\n files?: FileFieldDef;\n ref?: RefConfig;\n structure?: string;\n array?: boolean;\n // copyable exposes a plain copy-to-clipboard icon next to the value in display mode.\n // Dumb by design: copies the field value as-is, no side effects.\n copyable?: boolean;\n /**\n * Plan 2026-05-26 §4 / B13. Names the data_classifications tier\n * gating reads + writes on this field. Read-side: stripped from the\n * row when the caller lacks `classification:<tier>:read`. Write-side:\n * 422 FIELDS_FORBIDDEN when the caller writes the key without\n * `classification:<tier>:write`. Frontend reads the tier's localized\n * display name from the top-level `classifications:` map and\n * cross-references `schema.entities.<code>.field_access.<field>` for\n * the per-caller decision.\n */\n classification?: string;\n}\n\n/**\n * Per-caller classification decision for one classified field on one\n * entity. Plan 2026-05-26 §8 / B9. Populated by the schema endpoint\n * from the caller's grants + authority tier; the frontend reads this\n * to render the locked-widget badge (\"🔒 Compensation\"), disable write\n * inputs, and surface the operator-facing `required_permission` hint\n * to the user (e.g. \"Ask your admin to grant you\n * classification:compensation:read\").\n */\nexport interface FieldAccessInfo {\n read: \"granted\" | \"denied\";\n write: \"granted\" | \"denied\";\n classification: string;\n /** Only set when read OR write is denied — the exact grant string an\n * administrator needs to add to a role to unlock this field. */\n required_permission?: string;\n}\n\nexport interface StructureDef {\n name: LocalizedString;\n description?: LocalizedString;\n fields: OrderedMap<EntityField>;\n}\n\nexport type ChildDisplayMode = \"table\" | \"timeline\" | \"list\" | \"cards\";\n\nexport interface TimelineConfig {\n type_field?: string;\n time_field?: string;\n summary_field?: string;\n content_field?: string;\n author_field?: string;\n direction_field?: string;\n intent_field?: string;\n scroll?: boolean;\n auto_scroll?: \"none\" | \"bottom\" | \"top\";\n}\n\nexport interface CardsConfig {\n columns_count?: number;\n header_field?: string;\n badge_field?: string;\n}\n\nexport interface ChildQuickAdd {\n fields: string[];\n defaults?: Record<string, unknown>;\n placeholder?: LocalizedString;\n}\n\nexport interface ChildDisplay {\n name: LocalizedString;\n icon?: string;\n mode?: ChildDisplayMode;\n columns?: string[];\n sort?: string;\n limit?: number;\n timeline?: TimelineConfig;\n cards?: CardsConfig;\n editable?: boolean;\n searchable?: boolean;\n filters?: string[];\n position_field?: string;\n /**\n * Row interaction for `mode: table`.\n * - `navigate`: identity cell (first column) is a link to the child's\n * detail; other cells read-only. Default for associated entities\n * (child has its own detail screen).\n * - `inline_edit`: click a cell to edit it; typing auto-saves after a\n * 500ms debounce. One active cell at a time.\n * - `row_edit`: a per-row Edit button puts the whole row into edit mode\n * (all editable cells become inputs); an explicit Confirm/Cancel pair\n * commits or discards. Nothing persists until Confirm - same flow as\n * the \"Add row\" draft.\n * - `readonly`: pure display.\n */\n interaction?: \"navigate\" | \"inline_edit\" | \"row_edit\" | \"readonly\";\n}\n\nexport interface ChildRelation {\n entity: string;\n foreign_key: string | string[];\n display?: ChildDisplay;\n quick_add?: ChildQuickAdd;\n}\n\nexport interface StatusDef {\n code: string;\n name: LocalizedString;\n description?: LocalizedString;\n color?: string;\n is_final?: boolean;\n}\n\nexport interface StatusGroupDef {\n name: LocalizedString;\n description?: LocalizedString;\n is_main?: boolean;\n initial: string;\n statuses: StatusDef[];\n transitions?: Record<string, string[]>;\n // How a detail page renders the group: \"pill\" (default - read-only pill /\n // editable dropdown) or \"stepper\" (an ordered-stage pipeline). Unknown\n // values fall back to \"pill\".\n display_mode?: \"pill\" | \"stepper\";\n}\n\nexport interface PropertyDef {\n name: LocalizedString;\n description?: LocalizedString;\n type: string;\n display?: EntityField[\"display\"];\n values?: EntityField[\"values\"];\n enum?: string;\n ref?: RefConfig;\n structure?: string;\n readonly?: boolean;\n}\n\n// propertyToField converts a PropertyDef to an EntityField for use with renderField().\n// Merges prop.name as fallback display name; prop.display.name wins if set.\nexport function propertyToField(prop: PropertyDef): EntityField {\n const baseName = prop.name;\n const display = prop.display\n ? { ...prop.display, name: prop.display.name ?? baseName }\n : { name: baseName };\n return {\n type: prop.type,\n display,\n values: prop.values,\n ref: prop.ref,\n structure: prop.structure,\n };\n}\n\nexport interface EnumDef {\n name: LocalizedString;\n description?: LocalizedString;\n values: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n}\n\nexport interface ParameterDef {\n name: LocalizedString;\n description?: LocalizedString;\n type: string;\n default?: unknown;\n is_public?: boolean;\n category?: string;\n /** Override scopes accepted on writes. Subset of: env, tenant, role, user, object. Empty = all. */\n scopes?: string[];\n}\n\nexport interface AssociationDisplay {\n name?: LocalizedString;\n icon?: string;\n}\n\nexport interface AssociationDef {\n target: string;\n display?: AssociationDisplay;\n source: string;\n code: string;\n}\n\nexport type EntityMutationOp = \"create\" | \"update\" | \"delete\" | \"restore\";\n\nexport interface EntityMutations {\n create?: boolean;\n update?: boolean;\n delete?: boolean;\n restore?: boolean;\n}\n\nexport interface Entity {\n table: string;\n primary_key?: string[];\n virtual?: boolean;\n readonly?: boolean;\n mutations?: EntityMutations;\n default_timezone?: string;\n display: {\n name: LocalizedString;\n name_plural: LocalizedString;\n description?: LocalizedString;\n icon: string;\n display_field?: string;\n // display_template, when set on the server, causes the data layer to\n // render a per-row label and ship it under the row's $display key.\n // The SDK doesn't need the template string itself — it only needs to\n // know whether to prefer $display over display_field. We expose the\n // raw template here so consumer apps can introspect / debug schemas.\n display_template?: string;\n empty_state?: EmptyStateDef;\n };\n fields: OrderedMap<EntityField>;\n soft_delete?: string;\n tenant_key?: string;\n children?: ChildRelation[];\n status_groups?: Record<string, StatusGroupDef>;\n properties?: Record<string, PropertyDef>;\n search_fields?: string[];\n actions?: Record<string, Action>;\n handlers?: Record<string, HandlerDef>;\n associations?: Record<string, AssociationDef>;\n files?: OrderedMap<FileFieldDef>;\n detail_screen?: string; // Canonical detail screen for records of this entity. Required when any detail screen targets the entity.\n /** Standard CSV export gate per docs/plans/2026-05-01-standard-table-export.md.\n * Absent block (or absent `enabled`) means export is enabled. Only an\n * explicit `enabled: false` opts out, mirroring the Go ExportEnabled()\n * helper. Same shape ships on Screen for per-screen overrides. */\n export?: ExportConfig;\n /** At most one row visible per caller. Loader requires either a\n * caller-bound `prefilter` or `access: self` to back this. Frontend\n * routes a singleton entity's detail screen at the screen's declared\n * `route:` without a `:id` segment, and skips list-route registration. */\n singleton?: boolean;\n /** Server-enforced WHERE applied unconditionally on every read/write\n * via server/handlers/data_prefilter.go. Values may be literal scalars\n * OR `$caller.*` expressions (`$caller.user_id`, `$caller.tenant_id`)\n * resolved at request time. Security boundary, not a UX hint. */\n prefilter?: Record<string, unknown>;\n /** Hard entity-wide access gate. `\"self\"` restricts every read/write\n * to rows where the field marked `owner: true` matches the caller's\n * user id (chokepoint + with_check). `\"platform_admin\"` restricts to\n * platform owner / superadmin roles. Empty = standard RBAC. */\n access?: \"self\" | \"platform_admin\";\n /** Whether the entity participates in RBAC permission gating\n * (`entity:<code>:<op>` grants). Mirrors engine.Entity.Permissions. */\n permissions?: boolean;\n /**\n * Optional structural tree for placing and grouping actions across all\n * placement slots. Absent = runtime composes a flat list from all actions\n * matching each slot's visibility[], sorted by position ascending.\n * Server delivers RBAC-pruned nodes in tagged-union wire format (plan §8).\n */\n action_layout?: ActionLayoutNode[];\n /**\n * Plan 2026-05-26 §B9 / §B13. Per-caller classification access\n * decision keyed by field name. Only present for entities that\n * declare at least one classified field; absent on non-classification\n * entities so the wire stays byte-equivalent for non-classification\n * deployments. Frontend reads this map to render the locked-widget\n * badge, disable write inputs, and surface the required_permission\n * hint to the user.\n */\n field_access?: Record<string, FieldAccessInfo>;\n /**\n * Per-entity realtime opt-in. When true the entity is in the CDC\n * publication, its list views auto-update from the SSE stream, and the\n * toolbar shows a green \"Live\" indicator. Absent or false (default OFF)\n * means the entity is not live: no indicator, and the always-present\n * manual refresh control is the only freshness mechanism. Server emits\n * this with `omitempty`, so `false` arrives as absent. See\n * docs/plans/completed/2026-05-18-realtime-cdc-redesign.md.\n */\n realtime?: boolean;\n /**\n * Per-entity row-count strategy for list views. \"exact\" (default, also\n * the meaning of absent) shows an exact total; \"estimated\" shows an\n * O(1) query-planner estimate, rendered coarse (~3.6M) for high-volume\n * tables. Independent of `realtime`. The SDK keys list-view count\n * precision on the response `meta.count_mode`, not this field, so a\n * forced exact count still renders precisely. See\n * docs/plans/2026-05-18-declarative-row-count.md.\n */\n count?: \"exact\" | \"estimated\";\n}\n\nexport interface ExportConfig {\n enabled?: boolean;\n}\n\nexport function entityAllowsMutation(\n entity: Pick<Entity, \"readonly\" | \"mutations\"> | undefined,\n op: EntityMutationOp,\n): boolean {\n if (!entity || entity.readonly) return false;\n return entity.mutations?.[op] ?? true;\n}\n\n// getPrimaryKeyFields returns the ordered list of primary key field names.\n// Checks entity.primary_key first (composite PK), falls back to scanning\n// fields for field.primary (single PK), defaults to [\"id\"].\nexport function getPrimaryKeyFields(entity: Entity): string[] {\n if (entity.primary_key && entity.primary_key.length > 0) {\n return entity.primary_key;\n }\n for (const [name, f] of entity.fields) {\n if (f.primary) return [name];\n }\n return [\"id\"];\n}\n\n// PkValues is a map of PK field names to their string values.\nexport type PkValues = Record<string, string>;\n\n// extractPkValues extracts PK field values from a record.\nexport function extractPkValues(entity: Entity, record: Record<string, unknown>): PkValues {\n const fields = getPrimaryKeyFields(entity);\n const values: PkValues = {};\n for (const f of fields) {\n values[f] = String(record[f] ?? \"\");\n }\n return values;\n}\n\nexport function pkValuePartsToId(values: string[]): string {\n if (values.length === 1) return values[0];\n return JSON.stringify(values);\n}\n\n// pkValuesToId converts PK values to a single string identifier for use as\n// cache keys, React keys, etc. For single PK returns the value directly.\n// For composite PK serializes an ordered JSON array so delimiter characters in\n// PK values cannot collide with the route/cache representation.\nexport function pkValuesToId(pkValues: PkValues): string {\n return pkValuePartsToId(Object.values(pkValues));\n}\n\n// pkValuesToDetailId serializes PK values in entity-declared PK order for\n// detail routes. This avoids relying on object insertion order for composite\n// keys supplied by consumer code.\nexport function pkValuesToDetailId(entity: Entity, pkValues: PkValues): string {\n const fields = getPrimaryKeyFields(entity);\n return pkValuePartsToId(fields.map((field) => pkValues[field] ?? \"\"));\n}\n\nexport function pkValuesFromId(id: string, expectedCount: number): string[] | null {\n if (expectedCount <= 1) return [id];\n try {\n const parsed = JSON.parse(id) as unknown;\n if (\n Array.isArray(parsed) &&\n parsed.length === expectedCount &&\n parsed.every((value) => typeof value === \"string\")\n ) {\n return parsed;\n }\n } catch {\n return null;\n }\n return null;\n}\n\n// resolveDetailRoute returns the route template of the detail screen that\n// records of `entity` should navigate to. Resolution order:\n// 1. `list.detail_screen` (per-list-screen override). `DETAIL_SCREEN_NONE`\n// explicitly disables navigation.\n// 2. `entity.detail_screen` (canonical pointer declared on the entity).\n// `list` is omitted by callers that have no list-screen context (e.g.\n// associated/children tables on a detail screen) — those callers use the\n// canonical pointer directly.\nexport function resolveDetailRoute(\n list: Pick<Screen, \"detail_screen\"> | undefined,\n entity: Pick<Entity, \"detail_screen\"> | undefined,\n allScreens: Record<string, { route?: string }> | undefined,\n): string | null {\n if (list?.detail_screen === DETAIL_SCREEN_NONE) return null;\n const code = list?.detail_screen ?? entity?.detail_screen;\n if (!code) return null;\n return allScreens?.[code]?.route ?? null;\n}\n\nexport function buildDetailHrefFromId(\n list: Pick<Screen, \"detail_screen\">,\n id: string,\n entity: Pick<Entity, \"detail_screen\"> | undefined,\n allScreens: Record<string, { route?: string }> | undefined,\n): string | null {\n if (!id) return null;\n const route = resolveDetailRoute(list, entity, allScreens);\n if (!route) return null;\n return route.replace(\":id\", encodeURIComponent(id));\n}\n\nexport function buildEntityDetailHref(\n list: Pick<Screen, \"detail_screen\">,\n entity: Entity | undefined,\n allScreens: Record<string, { route?: string }> | undefined,\n pkValues: PkValues,\n): string | null {\n if (!entity) return null;\n const fields = getPrimaryKeyFields(entity);\n if (fields.some((field) => !pkValues[field])) return null;\n return buildDetailHrefFromId(list, pkValuesToDetailId(entity, pkValues), entity, allScreens);\n}\n\nexport function buildRowDetailHref(\n list: Pick<Screen, \"detail_screen\">,\n entity: Entity | undefined,\n allScreens: Record<string, { route?: string }> | undefined,\n row: Record<string, unknown>,\n): string | null {\n if (!entity) return null;\n return buildEntityDetailHref(list, entity, allScreens, extractPkValues(entity, row));\n}\n\n// isCompositePk returns true if the entity has more than one PK field.\nexport function isCompositePk(entity: Entity): boolean {\n return getPrimaryKeyFields(entity).length > 1;\n}\n\nexport type SizeValue = string; // integer weight (as string), \"<n>px\", \"auto\", \"fill\"\n\nexport interface SectionBadgeConfig {\n text: LocalizedString;\n tone?: \"indigo\" | \"emerald\" | \"amber\" | \"rose\" | \"sky\" | \"violet\" | \"slate\" | \"teal\";\n dot?: boolean;\n}\n\nexport interface SectionNode {\n name: LocalizedString;\n items: LayoutNode[];\n collapsed?: boolean;\n columns?: number; // 1 or 2 (default: 2)\n icon?: string; // icon name from Icon registry\n badge?: SectionBadgeConfig;\n // Visual weight. \"primary\" (default) is a raised card; \"secondary\" is a\n // quieter recessed card for supporting detail. Unknown values fall back to\n // \"primary\".\n emphasis?: \"primary\" | \"secondary\";\n}\n\nexport interface RowConfig {\n items: LayoutNode[];\n gap?: number;\n resizable?: boolean;\n stack_below?: number | \"never\";\n width?: SizeValue;\n height?: SizeValue;\n}\n\nexport interface ColumnConfig {\n items: LayoutNode[];\n gap?: number;\n width?: SizeValue;\n height?: SizeValue;\n}\n\nexport interface TabsConfig {\n items: LayoutNode[];\n}\n\n// LayoutField is one entry in a screen's `fields:` layout block, carrying\n// the field name and any screen-scoped overrides (e.g. inline action buttons).\n// YAML also accepts a bare string, which the server normalizes to { name }.\nexport interface LayoutField {\n name: string;\n actions?: Action[];\n}\n\nexport interface LayoutNode {\n // Container kinds (exactly one, or none if leaf).\n row?: RowConfig;\n column?: ColumnConfig;\n tabs?: TabsConfig;\n\n section?: SectionNode;\n\n // Leaf kinds.\n children?: string;\n associated?: string; // associated entity code (independent entity with FK back)\n properties?: true | string[];\n statuses?: true | string[];\n fields?: LayoutField[];\n\n // Sizing (valid when nested inside row or column).\n width?: SizeValue;\n height?: SizeValue;\n min_width?: string;\n max_width?: string;\n\n // Child-override keys (only valid when children is set).\n label?: LocalizedString;\n icon?: string;\n mode?: ChildDisplayMode;\n columns?: string[];\n sort?: string;\n limit?: number;\n quick_add?: ChildQuickAdd;\n timeline?: TimelineConfig;\n cards?: CardsConfig;\n editable?: boolean;\n searchable?: boolean;\n filters?: string[];\n position_field?: string;\n interaction?: \"navigate\" | \"inline_edit\" | \"row_edit\" | \"readonly\";\n}\n\n// AuditLineDef is one declared provenance line for the detail-page audit\n// strip: a label plus a timestamp field code (`at`) and/or an actor field\n// code (`by`). Both codes render through the normal field-display pipeline.\nexport interface AuditLineDef {\n label: LocalizedString;\n at?: string;\n by?: string;\n}\n\n// AuditConfig configures the detail screen's record-provenance strip (the\n// created / updated footer). Omit the whole block = the automatic strip from\n// the platform convention fields. See docs/dsl.md.\nexport interface AuditConfig {\n // Default (omitted) is on; false hides the strip entirely.\n enabled?: boolean;\n // When non-empty, replaces the automatic created/updated lines.\n lines?: AuditLineDef[];\n}\n\nexport interface Screen {\n type: \"list\" | \"detail\" | \"custom\" | \"record_list\";\n entity?: string;\n route: string;\n component?: string;\n display?: {\n name: LocalizedString;\n icon: string;\n };\n columns?: string[];\n default_columns?: string[]; // Subset visible initially. Omit = all visible.\n filters?: string[];\n default_filters?: string[]; // Subset shown initially in filter panel. Omit = empty.\n search_fields?: string[];\n sort_default?: string;\n actions?: string[];\n row_actions?: string[];\n items?: LayoutNode[];\n sidebar?: LayoutNode[]; // right sidebar layout (always visible, independent of tabs)\n sidebar_width?: string; // sidebar CSS width (default: \"380px\")\n // Detail screens: field names and/or status group codes surfaced as a\n // compact summary strip in the record header. Omit = none.\n highlights?: string[];\n // Detail screens: configures the record-provenance strip at the foot of\n // the page. Omit = the automatic created/updated strip.\n audit?: AuditConfig;\n self?: boolean;\n list_width?: string; // record_list: CSS width of the left list panel (e.g. \"50%\", \"400px\")\n list_resizable?: boolean; // record_list: enable drag-to-resize the list panel\n // list only: tri-valued.\n // absent -> inherit entity.detail_screen\n // \"none\" -> explicit opt-out (row-click disabled)\n // any code -> override with that detail screen\n detail_screen?: string;\n fixed_filters?: Record<string, unknown>; // backend-injected WHERE clauses\n views?: ViewDefinition[]; // System views (presets) from DSL, read-only\n\n /** Action slot promotion for list screens (rule-of-2). UI honors first 2.\n * Note: primary_record_actions (detail header) was removed in Task 5 of plan\n * 2026-04-21-action-toolbar-priority-overflow. Use action_layout instead. */\n primary_actions?: string[];\n primary_bulk_actions?: string[];\n\n /** \"open\" (default) navigates to detail; \"peek\" opens QuickPeek drawer. */\n on_row_click?: \"open\" | \"peek\";\n\n quick_peek?: QuickPeekConfig;\n inline_edit?: InlineEditConfig;\n column_overrides?: Record<string, ColumnSpec>;\n activity_rail?: ActivityRailConfig;\n /** Per-screen override for the CSV export gate. Same shape as Entity.export.\n * Either gate being false hides the toolbar Export menu and makes the\n * POST endpoint return 403 EXPORT_DISABLED. */\n export?: ExportConfig;\n /**\n * Optional per-screen structural tree for placing and grouping actions.\n * When set, fully replaces entity.action_layout for this screen.\n * Absent = inherit entity.action_layout (then default-flat if also absent).\n * Server delivers RBAC-pruned nodes in tagged-union wire format (plan §8).\n */\n action_layout?: ActionLayoutNode[];\n}\n\nexport interface QuickPeekConfig {\n enabled?: boolean;\n width?: number;\n /**\n * Explicit list of field codes to show. Highest precedence. When absent,\n * `sections` is consulted; when that's also absent the platform falls back\n * to all simple scalar fields on the entity (capped at 8).\n */\n fields?: string[];\n /** Section names from the detail-layout. Their `fields:` get flattened. */\n sections?: string[];\n inline_editable?: boolean;\n primary_action?: string;\n}\n\nexport interface InlineEditConfig {\n enabled?: boolean;\n /** dblclick | enter | always */\n trigger?: string;\n}\n\nexport interface ColumnSpec {\n inline_edit?: boolean;\n width?: string;\n}\n\nexport interface ActivityRailConfig {\n children: string;\n /** left | right (default right) */\n position?: string;\n width?: number;\n}\n\n/** System view (preset) defined in screen YAML. Read-only. */\nexport interface ViewDefinition {\n code: string;\n name: LocalizedString;\n icon?: string;\n filters?: Array<{ field: string; op: string; value?: unknown }>;\n columns?: string[];\n sort?: string;\n}\n\nexport interface NavNode {\n screen?: string;\n name?: LocalizedString;\n icon?: string;\n items?: NavNode[];\n area?: string;\n badge?: string;\n children?: NavNode[];\n}\n\nexport interface AreaDef {\n code: string;\n name?: LocalizedString;\n icon?: string;\n position?: number;\n home_screen?: string;\n required_permission?: string;\n}\n\nexport interface AccentDef {\n color?: string;\n color_2?: string;\n soft?: string;\n ring?: string;\n on_dark?: string;\n on_light?: string;\n}\n\nexport interface HandlerParamDisplay {\n name?: LocalizedString;\n description?: LocalizedString;\n widget?: string;\n}\n\nexport interface HandlerParam {\n /** Populated by the schema hydrator from the enclosing map key. */\n name?: string;\n type?: string;\n required?: boolean;\n default?: unknown;\n hidden?: boolean;\n enum?: string;\n values?: Array<{ code: string; name: LocalizedString; description?: LocalizedString; color?: string }>;\n ref?: string;\n display?: HandlerParamDisplay;\n /**\n * Narrows the param's option set. Values may be literals or templates\n * using the ui_steps interpolation vocabulary (e.g. \"${params.other}\").\n * Semantics are type-specific: for type=\"status\", a \"status_group\" key\n * selects the group whose statuses are offered.\n */\n filter?: Record<string, string>;\n}\n\nexport interface ActionCondition {\n status?: string[];\n field?: string;\n op?: string;\n value?: unknown;\n}\n\nexport interface UISetFieldStep {\n target: string;\n // Value is propagated typed (booleans, numbers, Dates survive). When a string\n // value contains a template token (e.g. \"${now}\", \"${row.touch}\"), the\n // interpolator returns the raw resolved value for single-token templates.\n // Mixed strings (\"Hi ${row.name}\") stringify as usual.\n value: unknown;\n}\n\nexport interface UIShowToastStep {\n kind?: \"success\" | \"error\" | \"info\";\n message: string;\n}\n\n// UIStep is a tagged union - exactly one variant field is set per step.\nexport interface UIStep {\n copy_to_clipboard?: string;\n set_field?: UISetFieldStep;\n focus_field?: string;\n show_toast?: UIShowToastStep;\n}\n\n/**\n * Leaf node in an action_layout tree. References a single action by code.\n * Wire format (plan §8): {\"kind\": \"action\", \"code\": \"<code>\"}\n */\nexport interface ActionLayoutLeaf {\n kind: \"action\";\n code: string;\n}\n\n/**\n * Branch node in an action_layout tree. Groups child nodes under a labelled dropdown.\n * Wire format (plan §8): {\"kind\": \"group\", \"name\": {...}, \"icon\": \"...\", \"items\": [...]}\n * Items is always non-empty (enforced by loader).\n */\nexport interface ActionLayoutGroup {\n kind: \"group\";\n name?: LocalizedString;\n icon?: string;\n items: ActionLayoutNode[];\n}\n\n/**\n * Discriminated union of all action_layout tree nodes.\n * Narrow via `node.kind === \"action\"` (leaf) or `node.kind === \"group\"` (branch).\n */\nexport type ActionLayoutNode = ActionLayoutLeaf | ActionLayoutGroup;\n\n/**\n * Single row-state condition for visible_if / enabled_if / conditions.\n * Operators: eq | ne | in | not_in | gt | lt | ge | le.\n */\nexport interface ActionConditionEntry {\n field?: string;\n op?: string;\n value?: unknown;\n status?: string[];\n}\n\n/**\n * Array of row-state conditions with AND semantics. YAML accepts both single\n * object and array form (see Go ActionConditionList unmarshal); wire format\n * from server is always array (server normalizes during schema response).\n */\nexport type ActionConditionList = ActionConditionEntry[];\n\nexport interface Action {\n /**\n * Server-side handler code. One of four dispatch fields - see plan §1-§2.\n * Reason: the new wire format encodes dispatch mode by which field is set\n * (handler | association | widget | href), so an explicit `type` enum is\n * redundant and was removed. Exactly one of the four should be set per action.\n */\n handler?: string;\n /**\n * Association code for nav-only actions that navigate to a related list.\n * Reason: same dispatch-by-field-presence rule; see plan §1-§2.\n */\n association?: string;\n /**\n * SDK widget registry name. Phase 2 wires the registry; today the field\n * is plumbed through the schema and consumed by Task 38's toolbar pipeline.\n * Reason: lets actions render bespoke UI (e.g. inline picker) instead of\n * server-handled forms, without inventing a new entity per widget.\n */\n widget?: string;\n /**\n * Client-side navigation URL template (supports `${id}` and other row tokens).\n * Reason: replaces the implicit \"edit\"/\"create\" type enum - any href-driven\n * action (open a custom screen, deep-link a report) uses this field; the\n * server never dispatches it.\n */\n href?: string;\n /**\n * Widget-specific opaque metadata. Schema/Action loader passes through\n * untouched; the widget consumes its own keys.\n * Reason: keeps the Action shape stable as new widgets ship without\n * growing the typed surface for each one.\n */\n config?: Record<string, unknown>;\n entity?: string;\n display: {\n name: LocalizedString;\n icon: string;\n /**\n * Promotes the action to a header button (vs. dropdown item).\n * Reason: explicit per-action UX control replaces the old position<=10\n * heuristic, lets schema authors mark their headline action even when\n * other actions sort earlier.\n */\n primary?: boolean;\n /**\n * Render as icon-only button (no label text).\n * Reason: lets a dense toolbar host high-frequency actions without\n * cluttering the bar with labels; tooltip still shows display.name.\n */\n icon_only?: boolean;\n /**\n * Button size hint. Default \"md\".\n * Reason: secondary toolbars (associated blocks, inline editors) need\n * smaller buttons than primary header bars - the schema author picks.\n */\n size?: \"sm\" | \"md\" | \"lg\";\n /**\n * Keyboard shortcut hint (e.g. \"Cmd+S\"). Rendered in tooltip/menu.\n * Reason: discoverability for power users; binding is wired in Task 38.\n */\n shortcut?: string;\n /**\n * Localized help text for tooltip/popover.\n * Reason: separate from display.name so the title stays terse while a\n * longer explanation surfaces on hover.\n */\n help?: LocalizedString;\n };\n visibility?: string[];\n confirmation?: LocalizedString;\n conditions?: ActionCondition[];\n /**\n * Ordering within a placement slot and overflow priority. Lower = earlier\n * in bar AND last to overflow. Default 0; ties broken by declaration order.\n * Step-10 convention. See plan §1 and §3.\n */\n position?: number;\n /**\n * Hide the action when condition does not hold against current row.\n * Distinct from RBAC hide and from `enabled_if` disable. AND semantics\n * across array elements. See plan §1, §5.\n */\n visible_if?: ActionConditionList;\n /**\n * Disable the action (greyed out + tooltip) when condition does not hold.\n * For bulk-mode multi-row selection, disabled if ANY selected row fails.\n * See plan §1, §5.\n */\n enabled_if?: ActionConditionList;\n /**\n * Localized tooltip shown when action is disabled by `enabled_if`.\n * Required when `enabled_if` is set (loader validates in Task 3).\n */\n enabled_if_reason?: LocalizedString;\n /** Forces confirm + danger styling. */\n destructive?: boolean;\n /** UI shows a toast instead of a blocking result modal; adds a navigation link if progress_screen is set. */\n long_running?: boolean;\n /** Screen code to navigate to after a long_running action starts (resolved via schema.screens). */\n progress_screen?: string;\n resolved_params?: OrderedMap<HandlerParam>;\n /**\n * Default values of params marked hidden+default by the action. The UI\n * seeds formData with these so filter templates resolve references to\n * prefilled siblings (e.g. \"${params.status_group}\") and so the\n * submission payload includes them. Not rendered in the modal.\n */\n resolved_hidden_defaults?: Record<string, unknown>;\n ui_steps?: UIStep[];\n}\n\nexport interface LanguageDef {\n code: string;\n name: LocalizedString;\n}\n\nexport interface HandlerDef {\n code: string;\n type: string;\n entity?: string;\n display?: {\n name?: LocalizedString;\n icon?: string;\n };\n params?: OrderedMap<HandlerParam>;\n success_event?: string;\n}\n\nexport interface Branding {\n app_name?: string;\n app_logo?: string;\n app_initial?: string;\n accent_color?: string;\n ai_name?: string;\n wordmark?: string;\n version_label?: string;\n status_url?: string;\n auth_tagline?: LocalizedString;\n auth_subtagline?: LocalizedString;\n auth_badges?: LocalizedString[];\n // Optional consumer-app CSS override file, served relative to the UI\n // bundle root (e.g. \"/crm-brand.css\"). The SDK injects a <link> at\n // runtime. The file should override the narrow set of tokens that\n // differ from the base palette — never a full redefinition.\n css_url?: string;\n}\n\nexport interface Schema {\n languages: LanguageDef[];\n structures: Record<string, StructureDef>;\n entities: Record<string, Entity>;\n screens: Record<string, Screen>;\n navigation: NavNode[];\n actions: Record<string, Action>;\n handlers?: Record<string, HandlerDef>;\n enums: Record<string, EnumDef>;\n parameters: Record<string, ParameterDef>;\n messages?: Record<string, LocalizedString>;\n branding?: Branding;\n areas?: AreaDef[];\n accents?: Record<string, AccentDef>;\n /**\n * Plan 2026-05-26 §B9 / §B13. data_classifications catalog keyed by\n * tier code — display name + description + audit_on_read flag + icon\n * + sod_protected flag. Absent when the consumer declares no tiers\n * (preserves byte-equivalent wire shape for non-classification\n * deployments). Frontend resolves the localized tier name from this\n * map when rendering locked-widget badges.\n */\n classifications?: Record<string, ClassificationTierDef>;\n}\n\n/**\n * Plan 2026-05-26 §B9. One entry in the top-level classifications map.\n * Mirrors engine.DataClassification.\n */\nexport interface ClassificationTierDef {\n name: LocalizedString;\n description?: LocalizedString;\n audit_on_read?: boolean;\n icon?: string;\n /**\n * When true, the tier triggers stricter SoD controls: superadmin\n * reveals emit a distinct audit code, tenant param\n * `auth.superadmin_classification_bypass=false` disables the\n * implicit bypass, role self-assignment is refused, transitive role\n * inheritance is hard-errored at load. Plan §11 Decisions Log #20-22.\n */\n sod_protected?: boolean;\n}\n","import { apiFetch } from \"./client\";\nimport type {\n Schema,\n Entity,\n StructureDef,\n HandlerDef,\n Action,\n EntityField,\n HandlerParam,\n} from \"@/types/schema\";\nimport type { FileFieldDef } from \"@/types/files\";\nimport { OrderedMap } from \"@/types/schema\";\n\n// Raw JSON shape: Fields/Params arrive as plain JSON objects (insertion-\n// ordered by the Go marshaller). Hydrated into OrderedMap instances at\n// fetch time so call sites get O(1) lookup and ordered iteration.\n\n// Dynamic-cast boundary: raw schema JSON arrives untyped from the Go marshaller\n// and is hydrated field-by-field below. `unknown` would block every raw.* access\n// in the hydrators; this is the one place the untyped wire shape is handled.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- untyped wire boundary, narrowed by the hydrators below\ntype RawObj = Record<string, any>;\n\nfunction hydrateHandler(raw: RawObj): HandlerDef {\n return {\n ...(raw as HandlerDef),\n params: raw.params ? OrderedMap.fromObject<HandlerParam>(raw.params) : undefined,\n };\n}\n\nfunction hydrateAction(raw: RawObj): Action {\n return {\n ...(raw as Action),\n resolved_params: raw.resolved_params\n ? OrderedMap.fromObject<HandlerParam>(raw.resolved_params)\n : undefined,\n };\n}\n\nfunction hydrateEntity(raw: RawObj): Entity {\n const handlers: Record<string, HandlerDef> = {};\n if (raw.handlers) {\n for (const [k, v] of Object.entries(raw.handlers as RawObj)) handlers[k] = hydrateHandler(v as RawObj);\n }\n const actions: Record<string, Action> = {};\n if (raw.actions) {\n for (const [k, v] of Object.entries(raw.actions as RawObj)) actions[k] = hydrateAction(v as RawObj);\n }\n return {\n ...(raw as Entity),\n fields: OrderedMap.fromObject<EntityField>(raw.fields),\n files: raw.files ? OrderedMap.fromObject<FileFieldDef>(raw.files) : undefined,\n handlers: raw.handlers ? handlers : undefined,\n actions: raw.actions ? actions : undefined,\n };\n}\n\nfunction hydrateSchema(raw: RawObj): Schema {\n const entities: Record<string, Entity> = {};\n if (raw.entities) {\n for (const [k, v] of Object.entries(raw.entities as RawObj)) entities[k] = hydrateEntity(v as RawObj);\n }\n const structures: Record<string, StructureDef> = {};\n if (raw.structures) {\n for (const [k, v] of Object.entries(raw.structures as RawObj)) {\n structures[k] = { ...(v as StructureDef), fields: OrderedMap.fromObject<EntityField>((v as RawObj).fields) };\n }\n }\n const handlers: Record<string, HandlerDef> = {};\n if (raw.handlers) {\n for (const [k, v] of Object.entries(raw.handlers as RawObj)) handlers[k] = hydrateHandler(v as RawObj);\n }\n const actions: Record<string, Action> = {};\n if (raw.actions) {\n for (const [k, v] of Object.entries(raw.actions as RawObj)) actions[k] = hydrateAction(v as RawObj);\n }\n return {\n ...(raw as Schema),\n entities,\n structures,\n handlers,\n actions,\n };\n}\n\nexport async function fetchSchema(): Promise<Schema> {\n const raw = await apiFetch<RawObj>(\"/api/schema\");\n return hydrateSchema(raw);\n}\n","import { callHandler, scheduleProactiveRefresh } from \"./client\";\nimport type {\n CheckSetupResponse,\n LoginResponse,\n AuthUser,\n Tenant,\n SSOProvider,\n} from \"@/types/api\";\n\n// Every auth endpoint now dispatches through POST /api/actions/{code}.\n// The shared callHandler helper in client.ts wraps the envelope and\n// returns the typed handler result directly. Cookies are set by the\n// backend via the HTTPCustomizer interface on *auth.LoginResult, so the\n// client-side wrappers never see tokens - they return user + tenant only.\n\nexport async function checkSetup(): Promise<CheckSetupResponse> {\n return callHandler<CheckSetupResponse>(\"auth.check_setup\");\n}\n\nexport async function login(\n email: string,\n password: string,\n remember: boolean = true,\n): Promise<LoginResponse> {\n const res = await callHandler<LoginResponse>(\"auth.login\", { email, password, remember });\n scheduleProactiveRefresh(res.expires_at);\n return res;\n}\n\nexport async function signup(\n email: string,\n password: string,\n displayName: string,\n): Promise<LoginResponse> {\n const res = await callHandler<LoginResponse>(\"auth.signup\", {\n email,\n password,\n display_name: displayName,\n });\n scheduleProactiveRefresh(res.expires_at);\n return res;\n}\n\n// auth.me returns { ...user, tenant? } per MeResult. The AuthUser type\n// on the frontend already reflects that shape.\nexport async function getMe(): Promise<AuthUser> {\n return callHandler<AuthUser>(\"auth.me\");\n}\n\n// auth.list_tenants returns { tenants: [...] } from ListTenantsResult.\nexport async function listTenants(): Promise<Tenant[]> {\n const result = await callHandler<{ tenants: Tenant[] }>(\"auth.list_tenants\");\n return result.tenants;\n}\n\nexport async function switchTenant(tenantId: string): Promise<LoginResponse> {\n const res = await callHandler<LoginResponse>(\"auth.switch_tenant\", {\n tenant_id: tenantId,\n });\n scheduleProactiveRefresh(res.expires_at);\n return res;\n}\n\nexport async function createTenant(code: string, name: string): Promise<Tenant> {\n return callHandler<Tenant>(\"auth.create_tenant\", { code, name });\n}\n\nexport async function logout(): Promise<void> {\n await callHandler(\"auth.logout\");\n}\n\n// sso_provider.list is a global handler with AllowUnauthenticated - used\n// on the login page before the user has a session.\nexport async function listSSOProviders(tenantCode?: string): Promise<SSOProvider[]> {\n const result = await callHandler<{ providers: SSOProvider[] }>(\n \"sso_provider.list\",\n tenantCode ? { tenant_code: tenantCode } : {},\n );\n return result.providers;\n}\n\nexport function ssoAuthorizeUrl(\n slug: string,\n tenantCode?: string,\n redirect?: string,\n): string {\n const params = new URLSearchParams();\n if (tenantCode) params.set(\"tenant\", tenantCode);\n if (redirect) params.set(\"redirect\", redirect);\n const qs = params.toString();\n return `/api/auth/sso/authorize/${encodeURIComponent(slug)}${qs ? `?${qs}` : \"\"}`;\n}\n\n/**\n * Impersonation client surface. Each call dispatches through\n * POST /api/actions/{code} like every other auth handler. The server\n * sets / clears the impersonation cookies via the LoginResult\n * HTTPCustomizer; the client receives the public response shape\n * (user / tenant / expires_at) and reloads the auth context.\n */\nexport interface ImpersonationStartResponse extends LoginResponse {\n impersonation_session_id: string;\n session_expires_at: string;\n}\n\nexport async function impersonationStart(\n targetUserId: string,\n reason: string,\n durationMinutes?: number,\n): Promise<ImpersonationStartResponse> {\n const params: Record<string, unknown> = {\n target_user_id: targetUserId,\n reason,\n };\n if (durationMinutes != null) params.duration_minutes = durationMinutes;\n return callHandler<ImpersonationStartResponse>(\"impersonation.start\", params);\n}\n\nexport async function impersonationStop(): Promise<LoginResponse> {\n return callHandler<LoginResponse>(\"impersonation.stop\");\n}\n\nexport async function impersonationRevoke(sessionId: string): Promise<void> {\n await callHandler(\"impersonation.revoke\", { session_id: sessionId });\n}\n\nexport async function changePassword(\n currentPassword: string,\n newPassword: string,\n): Promise<void> {\n await callHandler(\"auth.change_password\", {\n current_password: currentPassword,\n new_password: newPassword,\n });\n}\n","import { create } from \"zustand\";\nimport type { AuthUser, Tenant } from \"@/types/api\";\nimport { getMe, listTenants, logout as logoutApi } from \"@/api/auth\";\nimport { cancelProactiveRefresh } from \"@/api/client\";\n\ninterface AuthState {\n user: AuthUser | null;\n isAuthenticated: boolean;\n isLoading: boolean;\n activeTenant: Tenant | null;\n tenants: Tenant[];\n initialize: () => Promise<void>;\n refreshMe: () => Promise<void>;\n setUser: (user: AuthUser, tenant?: Tenant) => void;\n setTenants: (tenants: Tenant[]) => void;\n setActiveTenant: (tenant: Tenant) => void;\n logout: () => Promise<void>;\n}\n\nexport const useAuthStore = create<AuthState>((set) => ({\n user: null,\n isAuthenticated: false,\n isLoading: true,\n activeTenant: null,\n tenants: [],\n\n initialize: async () => {\n // Session lives in httpOnly cookies the JS cannot see. Probe auth.me\n // (dispatched via POST /api/actions/auth.me) with the cookie attached;\n // 401 means unauthenticated.\n try {\n const user = await getMe();\n const tenant = user.tenant ?? null;\n\n let tenants: Tenant[] = [];\n try {\n tenants = await listTenants();\n } catch {\n // Non-critical - user may only have one tenant.\n }\n\n set({\n user,\n isAuthenticated: true,\n isLoading: false,\n activeTenant: tenant,\n tenants,\n });\n } catch {\n set({ user: null, isAuthenticated: false, isLoading: false });\n }\n },\n\n refreshMe: async () => {\n try {\n const user = await getMe();\n set({ user, activeTenant: user.tenant ?? null });\n } catch {\n // Non-critical - caller handles display fallback.\n }\n },\n\n setUser: (user: AuthUser, tenant?: Tenant) => {\n set({\n user,\n isAuthenticated: true,\n isLoading: false,\n activeTenant: tenant ?? null,\n });\n },\n\n setTenants: (tenants: Tenant[]) => {\n set({ tenants });\n },\n\n setActiveTenant: (tenant: Tenant) => {\n set({ activeTenant: tenant });\n },\n\n logout: async () => {\n // Stop the proactive refresh timer before tearing down the session, so\n // no renewal fires against an about-to-be-revoked refresh token.\n cancelProactiveRefresh();\n try {\n await logoutApi();\n } catch {\n // Best-effort - clear local state regardless.\n }\n set({\n user: null,\n isAuthenticated: false,\n activeTenant: null,\n tenants: [],\n });\n },\n}));\n","import { useQuery } from \"@tanstack/react-query\";\nimport { fetchSchema } from \"@/api/schema\";\nimport { useAuthStore } from \"@/stores/auth\";\n\nexport function useSchema() {\n const isAuthenticated = useAuthStore((s) => s.isAuthenticated);\n return useQuery({\n // isAuthenticated in the key gives authenticated and unauthenticated\n // requests separate cache entries. Without this, the unauthenticated\n // schema (no screens/navigation) would be cached and reused after login,\n // producing a 404 flash on every first page load until a hard refresh.\n queryKey: [\"schema\", isAuthenticated],\n queryFn: fetchSchema,\n staleTime: Infinity,\n enabled: isAuthenticated,\n });\n}\n","import { create } from \"zustand\";\n\n// Allowed values are deliberately narrow — stored and server-provided values\n// that fall outside the allowlist are normalized to DEFAULTS. This defends\n// against stale localStorage (e.g. legacy \"forest\" theme from a tenant that\n// no longer ships custom themes) and against malformed server params.\nexport type ThemeId = \"light\" | \"dark\";\nexport type AccentId = \"violet\" | \"blue\" | \"teal\" | \"amber\" | \"rose\";\nexport type Density = \"compact\" | \"comfortable\" | \"cozy\";\nexport type SidebarMode = \"wide\" | \"collapsed\";\nexport type TabsPosition = \"top\" | \"bottom\";\nexport type AiSurface = \"command\" | \"panel\" | \"both\" | \"off\";\nexport type FaviconSource = \"google\" | \"direct\" | \"none\";\nexport type ToastPosition =\n | \"top-left\"\n | \"top-center\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\";\n\nexport interface Appearance {\n theme: ThemeId;\n accent: AccentId;\n density: Density;\n sidebar: SidebarMode;\n tabsPosition: TabsPosition;\n tabsMaxOpen: number;\n /** When false, tabs are not persisted across reloads (mirrors ui_tabs_persist). */\n tabsPersist: boolean;\n radius: number;\n zebra: boolean;\n aiSurface: AiSurface;\n /** Favicon source for unknown hosts in URL cells. See ui_favicon_source. */\n faviconSource: FaviconSource;\n /** Where toasts appear. Read by <Toaster> in app.tsx. See ui_toast_position. */\n toastPosition: ToastPosition;\n}\n\nconst DEFAULTS: Appearance = {\n theme: \"light\",\n accent: \"violet\",\n density: \"compact\",\n sidebar: \"wide\",\n tabsPosition: \"top\",\n tabsMaxOpen: 12,\n tabsPersist: true,\n radius: 7,\n zebra: true,\n aiSurface: \"both\",\n faviconSource: \"google\",\n toastPosition: \"bottom-right\",\n};\n\nconst THEMES: readonly ThemeId[] = [\"light\", \"dark\"];\nconst ACCENTS: readonly AccentId[] = [\"violet\", \"blue\", \"teal\", \"amber\", \"rose\"];\nconst DENSITIES: readonly Density[] = [\"compact\", \"comfortable\", \"cozy\"];\nconst SIDEBARS: readonly SidebarMode[] = [\"wide\", \"collapsed\"];\nconst TAB_POSITIONS: readonly TabsPosition[] = [\"top\", \"bottom\"];\nconst AI_SURFACES: readonly AiSurface[] = [\"command\", \"panel\", \"both\", \"off\"];\nconst FAVICON_SOURCES: readonly FaviconSource[] = [\"google\", \"direct\", \"none\"];\nconst TOAST_POSITIONS: readonly ToastPosition[] = [\n \"top-left\",\n \"top-center\",\n \"top-right\",\n \"bottom-left\",\n \"bottom-center\",\n \"bottom-right\",\n];\n\nfunction oneOf<T extends string>(allowed: readonly T[], v: unknown): T | undefined {\n return typeof v === \"string\" && (allowed as readonly string[]).includes(v) ? (v as T) : undefined;\n}\n\n// Normalize an arbitrary partial object to a valid Appearance by dropping\n// unknown keys and out-of-range enum values. Applied to BOTH localStorage\n// reads and server-supplied params so stale or malformed data never lands\n// on <html>.\nfunction normalize(raw: Partial<Record<keyof Appearance, unknown>>): Partial<Appearance> {\n const out: Partial<Appearance> = {};\n const t = oneOf(THEMES, raw.theme); if (t) out.theme = t;\n const a = oneOf(ACCENTS, raw.accent); if (a) out.accent = a;\n const d = oneOf(DENSITIES, raw.density); if (d) out.density = d;\n const s = oneOf(SIDEBARS, raw.sidebar); if (s) out.sidebar = s;\n const tp = oneOf(TAB_POSITIONS, raw.tabsPosition); if (tp) out.tabsPosition = tp;\n const ai = oneOf(AI_SURFACES, raw.aiSurface); if (ai) out.aiSurface = ai;\n const fs = oneOf(FAVICON_SOURCES, raw.faviconSource); if (fs) out.faviconSource = fs;\n const tpos = oneOf(TOAST_POSITIONS, raw.toastPosition); if (tpos) out.toastPosition = tpos;\n if (typeof raw.tabsMaxOpen === \"number\" && raw.tabsMaxOpen > 0) out.tabsMaxOpen = raw.tabsMaxOpen;\n if (typeof raw.radius === \"number\" && raw.radius >= 0 && raw.radius <= 32) out.radius = raw.radius;\n if (typeof raw.zebra === \"boolean\") out.zebra = raw.zebra;\n if (typeof raw.tabsPersist === \"boolean\") out.tabsPersist = raw.tabsPersist;\n return out;\n}\n\nconst STORAGE_KEY = \"declarion-appearance\";\n\nfunction readStorageRaw(): Partial<Record<keyof Appearance, unknown>> | null {\n if (typeof window === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n return raw ? JSON.parse(raw) : null;\n } catch {\n return null;\n }\n}\n\nfunction writeStorage(a: Appearance) {\n if (typeof window === \"undefined\") return;\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(a));\n } catch {\n // ignore\n }\n}\n\n// applyAppearance is the ONLY writer of theme-related state on <html>. It\n// sets attributes the CSS cascade picks up (see globals.css [data-theme],\n// [data-accent], [data-density], [data-sidebar], [data-tabbar], [data-zebra],\n// [data-ai]) and two inline values for the border-radius slider. All built-in\n// palettes flip via the cascade; there is no JS-driven token rewriting.\nexport function applyAppearance(a: Appearance) {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n root.dataset.theme = a.theme;\n root.dataset.accent = a.accent;\n root.dataset.density = a.density;\n root.dataset.sidebar = a.sidebar;\n root.dataset.tabbar = a.tabsPosition;\n root.dataset.zebra = a.zebra ? \"on\" : \"off\";\n root.dataset.ai = a.aiSurface;\n root.style.setProperty(\"--radius-md\", `${a.radius}px`);\n root.style.setProperty(\"--radius-lg\", `${a.radius + 3}px`);\n}\n\n// Param-code → Appearance-key map. Owned here so Tweaks, the hydrator, and\n// future backend integrations share one source of truth.\nconst PARAM_MAP: Record<string, keyof Appearance> = {\n ui_theme: \"theme\",\n ui_accent: \"accent\",\n ui_density: \"density\",\n ui_sidebar: \"sidebar\",\n ui_tabs_position: \"tabsPosition\",\n ui_tabs_max_open: \"tabsMaxOpen\",\n ui_tabs_persist: \"tabsPersist\",\n ui_radius: \"radius\",\n ui_zebra_rows: \"zebra\",\n ui_ai_surface: \"aiSurface\",\n ui_favicon_source: \"faviconSource\",\n ui_toast_position: \"toastPosition\",\n};\n\ninterface AppearanceState extends Appearance {\n set: <K extends keyof Appearance>(key: K, value: Appearance[K]) => void;\n setMany: (patch: Partial<Appearance>) => void;\n /** Apply tenant defaults from server params. ONLY fills keys the user has\n * not already set locally — any field present in localStorage wins.\n * That preserves the user's Tweaks choices across reloads while still\n * picking up tenant defaults on first visit. */\n hydrateFromParams: (params: Record<string, unknown>) => void;\n}\n\nconst storedRaw = readStorageRaw();\nconst storedKeys = storedRaw ? new Set(Object.keys(storedRaw) as (keyof Appearance)[]) : new Set<keyof Appearance>();\nconst initial: Appearance = { ...DEFAULTS, ...(storedRaw ? normalize(storedRaw) : {}) };\nif (typeof window !== \"undefined\") applyAppearance(initial);\n\nexport const useAppearanceStore = create<AppearanceState>((set, get) => ({\n ...initial,\n set: (key, value) => {\n const patch = normalize({ [key]: value } as Partial<Record<keyof Appearance, unknown>>);\n if (patch[key] === undefined) return; // invalid value dropped silently\n const next = { ...get(), ...patch } as AppearanceState;\n applyAppearance(next);\n writeStorage(next);\n storedKeys.add(key);\n set(patch as Partial<AppearanceState>);\n },\n setMany: (rawPatch) => {\n const patch = normalize(rawPatch as Partial<Record<keyof Appearance, unknown>>);\n if (!Object.keys(patch).length) return;\n const next = { ...get(), ...patch } as AppearanceState;\n applyAppearance(next);\n writeStorage(next);\n for (const k of Object.keys(patch) as (keyof Appearance)[]) storedKeys.add(k);\n set(patch as Partial<AppearanceState>);\n },\n hydrateFromParams: (params) => {\n // Translate server param codes to appearance keys and drop anything the\n // user has already explicitly set locally. Without this guard, a reload\n // would overwrite user Tweaks with tenant defaults from /api/params/public.\n const candidate: Partial<Record<keyof Appearance, unknown>> = {};\n for (const [paramCode, appearanceKey] of Object.entries(PARAM_MAP)) {\n if (storedKeys.has(appearanceKey)) continue;\n if (params[paramCode] !== undefined) candidate[appearanceKey] = params[paramCode];\n }\n const patch = normalize(candidate);\n if (!Object.keys(patch).length) return;\n const next = { ...useAppearanceStore.getState(), ...patch } as AppearanceState;\n applyAppearance(next);\n // Intentionally DO NOT writeStorage here — tenant defaults are not user\n // choices, so they shouldn't populate localStorage. Next reload applies\n // the same path fresh from /api/params/public.\n set(patch as Partial<AppearanceState>);\n },\n}));\n","import type { CSSProperties } from \"react\";\nimport { Icon as DesignIcon, type IconName as DesignIconName } from \"@/components/primitives/Icons\";\n\ninterface DynamicIconProps {\n name: string;\n size?: number | string;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function DynamicIcon({ name, size, className, style }: DynamicIconProps) {\n const Comp = DesignIcon[name as DesignIconName] ?? DesignIcon.folder;\n const n = typeof size === \"number\" ? size : typeof size === \"string\" ? parseFloat(size) : undefined;\n return <Comp size={n} cls={className} style={style} />;\n}\n","import { apiFetch, apiFetchBlob } from \"./client\";\nimport { ApiError } from \"@/types/api\";\nimport type { ListParams, ListResponse, DataResponse } from \"@/types/api\";\nimport type { PkValues } from \"@/types/schema\";\nimport type { ExportRequest } from \"@/components/pages/exportRequest\";\n\nfunction buildListUrl(entity: string, params: ListParams): string {\n const url = new URL(`/api/data/${entity}`, window.location.origin);\n\n if (params.page) url.searchParams.set(\"page\", String(params.page));\n if (params.per_page) url.searchParams.set(\"per_page\", String(params.per_page));\n if (params.sort) url.searchParams.set(\"sort\", params.sort);\n if (params.search) url.searchParams.set(\"search\", params.search);\n\n if (params.filters && params.filters.length > 0) {\n url.searchParams.set(\"filters\", JSON.stringify(params.filters));\n }\n\n if (params.include_deleted) {\n url.searchParams.set(\"include_deleted\", \"true\");\n }\n\n if (params.expand) {\n for (const e of params.expand) {\n url.searchParams.append(\"expand\", e);\n }\n }\n\n if (params.select && params.select.length > 0) {\n url.searchParams.set(\"select\", params.select.join(\",\"));\n }\n\n if (params.screen) url.searchParams.set(\"screen\", params.screen);\n if (params.preview) url.searchParams.set(\"preview\", \"true\");\n\n // Row-count strategy. Omitted (the default) is window-only: rows without\n // a total, so the page never blocks on a slow COUNT(*). \"window\" is\n // emitted explicitly only when a caller passes it; it is equivalent to\n // omission server-side.\n if (params.count) url.searchParams.set(\"count\", params.count);\n\n return url.pathname + url.search;\n}\n\nexport async function listEntities(\n entity: string,\n params: ListParams = {},\n options: { signal?: AbortSignal } = {},\n): Promise<ListResponse> {\n return apiFetch<ListResponse>(buildListUrl(entity, params), { signal: options.signal });\n}\n\n// getEntity fetches a single record by primary key values.\n// Accepts either a PkValues object (composite PK support) or a plain string\n// (single-PK convenience - sent as query param `id=<value>`).\nexport async function getEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<DataResponse> {\n const params = new URLSearchParams();\n if (typeof pkValues === \"string\") {\n params.set(\"id\", pkValues);\n } else {\n for (const [key, value] of Object.entries(pkValues)) {\n params.set(key, value);\n }\n }\n return apiFetch<DataResponse>(`/api/data/${entity}?${params.toString()}`);\n}\n\n// createEntity routes through the platform-default __create action.\n// Plan 2026-06-01-write-api-final §1.2: writes leave the legacy CRUD\n// POST /api/data/{entity} route and dispatch via /api/actions/<entity>.__create\n// with a FLAT envelope ({entity, fields}). The server-side handler\n// (data_write_handlers.go::DataCreateParams) decodes those top-level keys\n// directly into its typed struct via JSON tags; there is NO `params:`\n// wrapper on the wire. The handler result is DataCreateResult{rows};\n// we unwrap rows[0] to preserve the DataResponse shape this function\n// has historically returned to its callers.\nexport async function createEntity(\n entity: string,\n data: Record<string, unknown>,\n): Promise<DataResponse> {\n const response = await executeAction(`${entity}.__create`, {\n entity,\n fields: data,\n });\n const result = response.result as { rows?: Record<string, unknown>[] } | undefined;\n const rows = result?.rows ?? [];\n return { data: rows[0] };\n}\n\n// updateEntity routes through the platform-default __update action.\n// Plan 2026-06-01-write-api-final §1.2: dispatches\n// /api/actions/<entity>.__update with a FLAT envelope\n// ({object_ids, entity, fields}). The server's data.update handler\n// (data_write_handlers.go::DataUpdateParams) decodes those top-level\n// keys directly; there is NO `params:` wrapper and NO `items[]` on the\n// wire — per-row variation composes through system.batch instead\n// (mirrors createMany / upsertMany / EntityClient.updateMany). The\n// handler result is DataUpdateResult{rows, rows_matched}; we unwrap\n// rows[0] to preserve the DataResponse shape this function has\n// historically returned.\n//\n// Accepts either a PkValues object (composite PK) or a plain string id\n// (single-PK convenience - encoded via encodeObjectId, mirroring delete\n// / restore).\nexport async function updateEntity(\n entity: string,\n pkValues: PkValues | string,\n data: Record<string, unknown>,\n): Promise<DataResponse> {\n const id = typeof pkValues === \"string\" ? pkValues : encodeObjectId(pkValues);\n const response = await executeAction(`${entity}.__update`, {\n object_ids: [id],\n entity,\n fields: data,\n });\n const result = response.result as\n | { rows?: Record<string, unknown>[]; rows_matched?: number }\n | undefined;\n const rows = result?.rows ?? [];\n return { data: rows[0] };\n}\n\n// deleteEntity routes through the platform-default __delete action.\n// Plan 2026-06-01-write-api-final §1.2: dispatches\n// /api/actions/<entity>.__delete with a FLAT envelope\n// ({object_ids, entity}). The reserved `object_ids` key populates\n// ctx.ObjectIDs; the dispatcher derives items from those IDs + the\n// entity's PK fields. NO `params:` wrapper, NO legacy `_ids` (rejected\n// 400 by parseActionBody as of Task 5).\n//\n// Accepts either a string id (single-column PK - the common case) or a\n// PkValues object (composite PK joined by U+001F to match the platform\n// object-id encoding the server expects, see store.SplitObjectID).\nexport async function deleteEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<void> {\n const id = typeof pkValues === \"string\" ? pkValues : encodeObjectId(pkValues);\n await executeAction(`${entity}.__delete`, {\n object_ids: [id],\n entity,\n });\n}\n\n// encodeObjectId joins composite-PK values into a single opaque string\n// using the platform Unit-Separator convention. Server-side inverse\n// lives at store.SplitObjectID; the per-field zip uses entity.\n// PrimaryKeyFields() declaration order. Iteration order on the input\n// must match that declaration order - PkValues is a Record so callers\n// must construct it field-by-field; for single-column PKs the\n// \"encoding\" is just the value verbatim.\nexport function encodeObjectId(pkValues: PkValues): string {\n const parts = Object.values(pkValues);\n if (parts.length === 1) return parts[0];\n // U+001F = ASCII Unit Separator; matches the Go-side ObjectID join.\n return parts.join(\"\u001f\");\n}\n\n// restoreEntity routes through the platform-default __restore action.\n// Plan 2026-06-01-write-api-final §1.2: the legacy CRUD route\n// POST /api/data/{entity}/restore is retired (returns 410); restores\n// now dispatch /api/actions/<entity>.__restore with a FLAT envelope\n// ({object_ids, entity}). Composite PKs encode to a single opaque\n// string via encodeObjectId (U+001F join); the server splits via\n// store.SplitObjectID.\nexport async function restoreEntity(\n entity: string,\n pkValues: PkValues | string,\n): Promise<void> {\n const id = typeof pkValues === \"string\" ? pkValues : encodeObjectId(pkValues);\n await executeAction(`${entity}.__restore`, {\n object_ids: [id],\n entity,\n });\n}\n\n/** Result of POST /api/data/{entity}/export. The server streams a CSV\n * blob; the client gets the bytes plus the server-resolved filename\n * (parsed from Content-Disposition by apiFetchBlob, with RFC 5987\n * filename* preferred). Triggering the actual download (anchor click)\n * is the caller's job — separation lets ExportMenu show the bytes in a\n * toast when the browser blocks the download. */\nexport interface ExportResponse {\n blob: Blob;\n filename: string;\n}\n\n// exportEntities POSTs the export request body and returns the streamed\n// CSV blob plus the filename to use on the resulting download. Server-side\n// errors propagate as ApiError so ExportMenu can show the {code, message}\n// envelope inline (the dropdown stays open per UX contract).\nexport async function exportEntities(\n entity: string,\n body: ExportRequest,\n): Promise<ExportResponse> {\n const result = await apiFetchBlob(`/api/data/${entity}/export`, {\n method: \"POST\",\n body: JSON.stringify(body),\n });\n return { blob: result.blob, filename: result.filename };\n}\n\n/**\n * Action request body is flat: top-level keys are handler params. The only\n * reserved control key is `object_ids` (array of object IDs for\n * single/batch scope). The server resolves entity from the action's\n * registration; the URL code is fully qualified (\"entity.action\" for\n * entity-scoped, \"action\" for global). Legacy `_ids` is rejected 400 by\n * the server (parseActionBody) — there is no compat shim.\n */\nexport type ActionExecuteRequest = Record<string, unknown>;\n\nexport interface ActionExecuteResponse {\n status: string;\n result?: unknown;\n audit_operation_id?: string;\n object_count?: number;\n /** IDs that succeeded (batch_mode: each responses). */\n success?: string[];\n /** Per-item errors (batch_mode: each responses with failures or partial). */\n errors?: ActionItemError[];\n /** Per-item skips (batch_mode: each responses where conditions filtered rows). */\n skipped?: ActionItemSkip[];\n}\n\nexport interface ActionItemError {\n id: string;\n error: string;\n /** Sidecar DeclarionCode when available (e.g. VALIDATION_ERROR), else \"\". */\n code?: string;\n}\n\nexport interface ActionItemSkip {\n id: string;\n reason: string;\n}\n\n/**\n * Thrown by executeAction when the platform returns 4xx with the invoke:each\n * batch shape (all items failed). Carries the per-item details so the UI can\n * render a meaningful toast instead of a generic \"request failed\".\n *\n * Pre-dispatch failures (auth, unknown action, invoke-shape mismatch) keep\n * throwing the standard ApiError; use `instanceof ActionBatchError` to\n * distinguish.\n */\nexport class ActionBatchError extends Error {\n readonly status: number;\n readonly response: ActionExecuteResponse;\n\n constructor(status: number, response: ActionExecuteResponse) {\n const first = response.errors && response.errors[0]?.error;\n super(first || \"Action failed\");\n this.name = \"ActionBatchError\";\n this.status = status;\n this.response = response;\n }\n}\n\nfunction isActionBatchBody(v: unknown): v is ActionExecuteResponse {\n if (!v || typeof v !== \"object\") return false;\n const r = v as Record<string, unknown>;\n return typeof r.status === \"string\" && Array.isArray(r.errors);\n}\n\n/**\n * Build a flat action body from handler params + optional object IDs.\n * Promotes `ids` to the reserved `object_ids` key. Throws if a caller\n * passes a param literally named `object_ids` (collision with the\n * reserved control key) or the now-rejected legacy `_ids` key.\n *\n * Plan 2026-06-01-write-api-final: the wire-level reserved key is\n * `object_ids` (server-side parseActionBody decodes it into\n * ctx.ObjectIDs). The legacy `_ids` envelope was removed in Task 5;\n * passing it triggers a 400 from the server.\n */\nexport function buildActionBody(\n params: Record<string, unknown> | undefined,\n ids?: string[] | undefined,\n): ActionExecuteRequest {\n const body: Record<string, unknown> = { ...(params ?? {}) };\n if (\"object_ids\" in body) {\n throw new Error('handler param \"object_ids\" collides with reserved key');\n }\n if (\"_ids\" in body) {\n throw new Error('handler param \"_ids\" is a removed legacy key; use object_ids');\n }\n if (ids !== undefined) {\n body.object_ids = ids;\n }\n return body;\n}\n\n/**\n * Invoke an action. The URL `code` must be fully qualified for\n * entity-scoped actions (e.g. `lead.archive`). For global actions it's the\n * action code on its own (e.g. `auth.login`).\n */\nexport async function executeAction(\n code: string,\n body: ActionExecuteRequest,\n): Promise<ActionExecuteResponse> {\n try {\n return await apiFetch<ActionExecuteResponse>(`/api/actions/${code}`, {\n method: \"POST\",\n body: JSON.stringify(body),\n });\n } catch (err) {\n // 4xx with invoke:each batch body (all items failed) → surface per-item\n // detail via ActionBatchError so toasts can show the real reason. Other\n // errors (pre-dispatch 4xx with standard envelope, 5xx, network) keep\n // propagating as ApiError unchanged.\n if (err instanceof ApiError && isActionBatchBody(err.raw)) {\n throw new ActionBatchError(err.status, err.raw);\n }\n throw err;\n }\n}\n\nexport interface AssociationResponse {\n target_entity: string;\n ids: string[];\n count: number;\n}\n\nexport async function resolveAssociation(\n code: string,\n ids: string[],\n): Promise<AssociationResponse> {\n const params = new URLSearchParams();\n params.set(\"ids\", ids.join(\",\"));\n return apiFetch<AssociationResponse>(`/api/associations/${code}?${params.toString()}`);\n}\n","// Markdown: the eager, lightweight entry point for markdown rendering. Every\n// feature module imports THIS, never react-markdown directly. The heavy\n// renderer + parser live in MarkdownRenderer.tsx, pulled in on demand via a\n// dynamic import so they form their own chunk outside the eager SDK bundle.\n// capabilityPrefetch warms that chunk during idle time after first paint, so\n// in practice the fallback below is rarely seen.\nimport { lazy, Suspense } from \"react\";\nimport type { MarkdownRendererProps } from \"./MarkdownRenderer\";\n\nconst LazyMarkdownRenderer = lazy(() =>\n import(\"./MarkdownRenderer\").then((m) => ({ default: m.MarkdownRenderer })),\n);\n\nfunction MarkdownFallback() {\n return <div className=\"h-4 w-2/3 rounded bg-muted animate-pulse\" />;\n}\n\nexport function Markdown(props: MarkdownRendererProps) {\n return (\n <Suspense fallback={<MarkdownFallback />}>\n <LazyMarkdownRenderer {...props} />\n </Suspense>\n );\n}\n\nexport type { MarkdownRendererProps } from \"./MarkdownRenderer\";\n","// FieldType is the SDK-side mirror of Go's engine.FieldType enum\n// (see golang/internal/engine/types.go:72-96).\n//\n// This union MUST stay character-identical to the Go enum. The CI sync gate\n// `TestExportFieldTypes` (golang/internal/engine) writes\n// `golang/.testdata/field_types.json`; the vitest suite reads that fixture and\n// asserts that this union's members exactly match.\n//\n// Adding a field type:\n// 1. Add the constant to golang/internal/engine/types.go.\n// 2. Add the literal here.\n// 3. Add the new key to `editRegistry` in components/fields/index.tsx.\n// 4. Add the new entry to `defaultWidgetForField` in\n// golang/internal/engine/registry.go (exhaustiveness lint will fail\n// otherwise).\nexport type FieldType =\n | \"uuid\"\n | \"string\"\n | \"text\"\n | \"rich_text\"\n | \"int\"\n | \"float\"\n | \"bool\"\n | \"date\"\n | \"time\"\n | \"timestamp\"\n | \"email\"\n | \"url\"\n | \"phone\"\n | \"enum\"\n | \"json\"\n | \"ref\"\n | \"tags\"\n | \"multilang\"\n | \"multilang_text\"\n | \"structure\"\n | \"secret\"\n | \"password\"\n | \"decimal\"\n | \"string_array\"\n | \"int_array\"\n | \"uuid_array\"\n | \"bytes\";\n\n// FIELD_TYPES is the runtime list of every FieldType, used by the CI sync\n// gate that compares against golang/.testdata/field_types.json. Order is\n// alphabetical to match the Go-side fixture writer (sort.Strings).\nexport const FIELD_TYPES: readonly FieldType[] = [\n \"bool\",\n \"bytes\",\n \"date\",\n \"decimal\",\n \"email\",\n \"enum\",\n \"float\",\n \"int\",\n \"int_array\",\n \"json\",\n \"multilang\",\n \"multilang_text\",\n \"password\",\n \"phone\",\n \"ref\",\n \"rich_text\",\n \"secret\",\n \"string\",\n \"string_array\",\n \"structure\",\n \"tags\",\n \"text\",\n \"time\",\n \"timestamp\",\n \"url\",\n \"uuid\",\n \"uuid_array\",\n] as const;\n","import { useState, useCallback } from \"react\";\nimport { Icon, IconBtn } from \"@/components/primitives\";\n\ninterface CopyButtonProps {\n value: string;\n title?: string;\n className?: string;\n size?: \"sm\" | \"icon\";\n}\n\nexport function CopyButton({ value, title, size = \"icon\" }: CopyButtonProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(\n async (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n // ignore\n }\n },\n [value],\n );\n\n const iconSize = size === \"sm\" ? 12 : 14;\n const btnSize = size === \"sm\" ? 22 : 28;\n\n return (\n <IconBtn\n size={btnSize}\n icon={\n copied ? (\n <Icon.check size={iconSize} style={{ color: \"var(--success)\" }} />\n ) : (\n <Icon.copy size={iconSize} />\n )\n }\n onClick={handleCopy}\n title={title ?? \"Copy to clipboard\"}\n />\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport { CopyButton } from \"@/components/shared/CopyButton\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function StringField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n if (mode === \"display\") {\n const text = String(value ?? \"\");\n if (field.copyable && text) {\n return (\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: 4 }}>\n <span style={{ fontSize: 12.5 }}>{text}</span>\n <CopyButton value={text} size=\"sm\" />\n </span>\n );\n }\n return <span style={{ fontSize: 12.5 }}>{text || <span style={{ color: \"var(--text-4)\" }}>—</span>}</span>;\n }\n\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n />\n );\n}\n","import { TextArea, TextInput } from \"@/components/primitives\";\nimport { CopyButton } from \"@/components/shared/CopyButton\";\nimport { Markdown } from \"@/components/shared/Markdown\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function TextField({ field, fieldName, value, mode, onChange, fill, compact, fieldId }: FieldRendererProps) {\n const widget = field.display?.widget;\n\n if (mode === \"display\") {\n const text = String(value ?? \"\");\n if (!text) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n\n const rendered = widget === \"markdown\" ? (\n <Markdown content={text} />\n ) : widget === \"code\" ? (\n <pre\n className=\"mono\"\n style={{\n fontSize: 12,\n background: \"var(--surface-2)\",\n color: \"var(--text)\",\n borderRadius: 6,\n border: \"1px solid var(--border)\",\n padding: 14,\n overflowX: \"auto\",\n maxHeight: 600,\n overflowY: \"auto\",\n whiteSpace: \"pre\",\n }}\n >\n {text}\n </pre>\n ) : (\n <p style={{ fontSize: 12.5, whiteSpace: \"pre-wrap\", wordBreak: \"break-word\", margin: 0 }}>{text}</p>\n );\n\n if (field.copyable) {\n return (\n <div style={{ position: \"relative\" }}>\n {rendered}\n <div style={{ position: \"absolute\", top: 0, right: 0 }}>\n <CopyButton value={text} size=\"sm\" />\n </div>\n </div>\n );\n }\n\n return rendered;\n }\n\n // Compact mode (inline table cell / draft row): render a single-line input\n // regardless of widget. A 4-row textarea inside a fixed-height row breaks\n // the layout; long text stays scrollable horizontally inside the input.\n if (compact) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n />\n );\n }\n const rows = widget === \"markdown\" || widget === \"code\" ? 10 : 4;\n return (\n <TextArea\n id={fieldId}\n name={fieldName}\n ariaRequired={field.required}\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n rows={rows}\n fill={fill}\n />\n );\n}\n","import { Pill, Select, type PillTone } from \"@/components/primitives\";\nimport { loc } from \"@/types/schema\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst NULL_SENTINEL = \"__declarion_enum_null__\";\n\nexport function EnumField({ field, value, mode, onChange, fieldId, labelId }: FieldRendererProps) {\n const values = field.values ?? [];\n const current = values.find((v) => v.code === value);\n\n if (mode === \"display\") {\n if (!current) {\n return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n }\n return (\n <Pill tone={(current.color as PillTone) ?? \"slate\"} size=\"xs\">\n {loc(current.name)}\n </Pill>\n );\n }\n\n const showClearOption = !field.required;\n const currentValue = value != null && value !== \"\" ? String(value) : NULL_SENTINEL;\n\n const options = [\n ...(showClearOption ? [{ value: NULL_SENTINEL, label: \"— None —\" }] : []),\n ...values.map((v) => ({ value: v.code, label: loc(v.name) || v.code })),\n ];\n\n return (\n <Select\n // Select renders a <button>, not an <input>: <label htmlFor> cannot\n // target it, so the form's label is wired via aria-labelledby instead\n // (Finding 2).\n id={fieldId}\n aria-labelledby={labelId}\n aria-required={field.required || undefined}\n value={currentValue}\n options={options}\n onChange={(v) => onChange?.(v === NULL_SENTINEL ? null : v)}\n placeholder=\"Select…\"\n />\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\n// EmailField is the EDIT-mode renderer for FieldType \"email\". Display-mode\n// rendering lives in the `email` cell factory (see cells/factories/email.tsx)\n// per the 2026-04-29-field-rendering-two-registry-cut plan §3 dispatcher\n// contract. `renderField` only routes edit-mode calls here, so this\n// component does not handle `mode === \"display\"`.\nexport function EmailField({ field, fieldName, value, onChange, fieldId }: FieldRendererProps) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"email\"\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n />\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\n// UrlField is the EDIT-mode renderer for FieldType \"url\". Display-mode\n// rendering lives in the `url` cell factory (see cells/factories/url.tsx)\n// per the 2026-04-29-field-rendering-two-registry-cut plan §3 dispatcher\n// contract: the display branch is a single source of truth and lives in\n// the cell registry, not in this component. `renderField` only routes\n// edit-mode calls here, so this component does not handle `mode === \"display\"`.\n//\n// The legacy display branch (anchor + favicon + LinkedIn slug) is preserved\n// in the cell factory; the URL parsing helpers it depends on are in\n// cells/factories/url-helpers.ts so both share the exact same parser.\nexport function UrlField({ field, fieldName, value, onChange, fieldId }: FieldRendererProps) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"url\"\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n placeholder=\"https://\"\n />\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\n// PhoneField is the EDIT-mode renderer for FieldType \"phone\". Display-mode\n// rendering lives in the `phone` cell factory (see cells/factories/phone.tsx).\n// `renderField` only routes edit-mode calls here, so this component does not\n// handle `mode === \"display\"`.\n//\n// Per plan §5: tel-keyboard <input>, no national-format mask. Region-aware\n// formatting waits on a region-metadata plan (see Open Questions Q5 in the\n// 2026-04-29-field-rendering-two-registry-cut plan).\nexport function PhoneField({ field, fieldName, value, onChange, fieldId }: FieldRendererProps) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"tel\"\n value={String(value ?? \"\")}\n onChange={(v) => onChange?.(v)}\n placeholder=\"+1 555 555 5555\"\n />\n );\n}\n","import { formatISO, formatDistanceToNowStrict } from \"date-fns\";\n\n/**\n * Wire format for outgoing datetime payloads: local wall-clock with offset,\n * e.g. \"2026-04-22T15:18:00-05:00\" (or \"...Z\" when local == UTC).\n *\n * Every API call that sends a timestamp value must go through this helper:\n * ui-actions `${now}`, TimestampField submit, quick-add defaults, status\n * history `set_at`. The offset makes the instant unambiguous for passthrough\n * fields and is stripped by the backend for fields with configured timezone.\n *\n * See docs/gotchas.md#timezone--unit-conversions.\n */\nexport function formatWireDateTime(date: Date = new Date()): string {\n return formatISO(date);\n}\n\n/**\n * Format an offset-aware timestamp string (e.g. \"2026-03-27T14:30:00+03:00\")\n * for display WITHOUT browser-local timezone conversion. The server returns\n * timestamps already converted to the target timezone - we display as-is.\n *\n * Falls back to browser-local formatting for bare datetime strings.\n */\nexport function formatOffsetTimestamp(raw: string): string {\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n\n if (offsetMatch || isUTC) {\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n\n let tz: string | undefined;\n if (isUTC) {\n tz = \"UTC\";\n } else if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0);\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n if (minutes === 0) {\n tz = hours === 0 ? \"UTC\" : `Etc/GMT${sign === \"+\" ? \"-\" : \"+\"}${hours}`;\n }\n }\n\n if (tz) {\n try {\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: tz,\n }).format(date);\n } catch {\n // Fall through.\n }\n }\n\n // Non-standard offset (e.g. +05:30): compute local time manually.\n if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localMs = date.getTime() + offsetMs;\n const localDate = new Date(localMs);\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\",\n }).format(localDate);\n }\n }\n\n // Bare datetime or unparseable: fall back to browser-local.\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n }).format(date);\n}\n\n/**\n * Relative-or-absolute timestamp formatting for the time_ago cell renderer.\n *\n * Returns a short relative phrase (\"5 minutes ago\", \"2 days ago\") when the\n * timestamp is within the last 30 days, and an ISO date (\"2026-01-15\") when\n * older. Linear / Stripe / Datadog convention — avoids the \"1y 4mo 12d ago\"\n * eyesore for stable historical data.\n *\n * `absolute` is the offset-aware long form intended for the cell's hover\n * tooltip; the user always has access to the precise timestamp.\n *\n * Bare or unparseable input falls back to the raw string for both fields.\n */\nexport function formatRelativeOrAbsolute(\n raw: string | Date | null | undefined,\n now: Date = new Date(),\n): { text: string; absolute: string } {\n if (raw == null || raw === \"\") return { text: \"—\", absolute: \"\" };\n const date = raw instanceof Date ? raw : new Date(String(raw));\n if (isNaN(date.getTime())) {\n const fallback = String(raw);\n return { text: fallback, absolute: fallback };\n }\n const absolute = typeof raw === \"string\" ? formatOffsetTimestamp(raw) : formatOffsetTimestamp(date.toISOString());\n const ageMs = now.getTime() - date.getTime();\n const thirtyDaysMs = 30 * 24 * 60 * 60 * 1000;\n if (Math.abs(ageMs) > thirtyDaysMs) {\n const text = formatISO(date, { representation: \"date\" });\n return { text, absolute };\n }\n const text = formatDistanceToNowStrict(date, { addSuffix: true });\n return { text, absolute };\n}\n","import { TextInput } from \"@/components/primitives\";\nimport { formatWireDateTime } from \"@/lib/timestamp\";\nimport type { FieldRendererProps } from \"./index\";\n\n// Declarion timestamp fields fall into two display modes:\n//\n// hasTz=true — field.timezone is configured (e.g. $user, $ref, \"Europe/Moscow\").\n// Server already converted the value into that zone and sends\n// an offset-suffixed string like \"2026-04-10T16:27:00+03:00\".\n// Display and the <datetime-local> input both render the wall-\n// clock component of that string verbatim. A tz abbreviation\n// hint is shown next to the value so users know which zone.\n//\n// hasTz=false — field has NO timezone source. Server passes the value\n// through; DB stores the UTC instant carried by the wire\n// payload's offset. Client reads the UTC string and renders\n// in the browser's local zone; onChange submits local wall-\n// clock with offset via formatWireDateTime.\n//\n// The two modes never mix: tz infrastructure lives on the server for hasTz\n// fields, on the client for hasTz=false fields.\n\nfunction formatTimestampWithTz(raw: string, isDateOnly: boolean): string {\n if (isDateOnly) {\n const d = new Date(raw + \"T00:00:00\");\n if (isNaN(d.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n }).format(d);\n }\n\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n\n let tz: string | undefined;\n if (isUTC) {\n tz = \"UTC\";\n } else if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0);\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n if (minutes === 0) {\n tz = hours === 0 ? \"UTC\" : `Etc/GMT${sign === \"+\" ? \"-\" : \"+\"}${hours}`;\n }\n }\n\n if (tz) {\n try {\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n hour: \"2-digit\", minute: \"2-digit\", timeZone: tz,\n }).format(date);\n } catch {\n // fall through\n }\n }\n\n if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localDate = new Date(date.getTime() + offsetMs);\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n hour: \"2-digit\", minute: \"2-digit\", timeZone: \"UTC\",\n }).format(localDate);\n }\n\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n hour: \"2-digit\", minute: \"2-digit\",\n }).format(date);\n}\n\nfunction formatTimestampLocal(raw: string, isDateOnly: boolean): string {\n if (isDateOnly) {\n const d = new Date(raw + \"T00:00:00\");\n if (isNaN(d.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n }).format(d);\n }\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n return new Intl.DateTimeFormat(undefined, {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n hour: \"2-digit\", minute: \"2-digit\",\n }).format(date);\n}\n\nfunction extractTzAbbrev(raw: string): string | null {\n if (raw.endsWith(\"Z\")) return \"UTC\";\n const m = raw.match(/([+-]\\d{2}:\\d{2})$/);\n if (!m) return null;\n const sign = m[1].charAt(0);\n const hours = parseInt(m[1].substring(1, 3), 10);\n const minutes = parseInt(m[1].substring(4, 6), 10);\n if (hours === 0 && minutes === 0) return \"UTC\";\n const minPart = minutes > 0 ? `:${String(minutes).padStart(2, \"0\")}` : \"\";\n return `UTC${sign}${hours}${minPart}`;\n}\n\nfunction toInputValueWithTz(raw: string, isDateOnly: boolean): string {\n const offsetMatch = raw.match(/([+-]\\d{2}:\\d{2})$/);\n const isUTC = raw.endsWith(\"Z\");\n const date = new Date(raw);\n if (isNaN(date.getTime())) return \"\";\n\n if (isUTC) {\n const y = date.getUTCFullYear();\n const mo = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n const d = String(date.getUTCDate()).padStart(2, \"0\");\n if (isDateOnly) return `${y}-${mo}-${d}`;\n const h = String(date.getUTCHours()).padStart(2, \"0\");\n const mi = String(date.getUTCMinutes()).padStart(2, \"0\");\n return `${y}-${mo}-${d}T${h}:${mi}`;\n }\n\n if (offsetMatch) {\n const sign = offsetMatch[1].charAt(0) === \"+\" ? 1 : -1;\n const hours = parseInt(offsetMatch[1].substring(1, 3), 10);\n const minutes = parseInt(offsetMatch[1].substring(4, 6), 10);\n const offsetMs = sign * (hours * 60 + minutes) * 60 * 1000;\n const localDate = new Date(date.getTime() + offsetMs);\n const y = localDate.getUTCFullYear();\n const mo = String(localDate.getUTCMonth() + 1).padStart(2, \"0\");\n const d = String(localDate.getUTCDate()).padStart(2, \"0\");\n if (isDateOnly) return `${y}-${mo}-${d}`;\n const h = String(localDate.getUTCHours()).padStart(2, \"0\");\n const mi = String(localDate.getUTCMinutes()).padStart(2, \"0\");\n return `${y}-${mo}-${d}T${h}:${mi}`;\n }\n\n if (isDateOnly) return raw.slice(0, 10);\n return raw.slice(0, 16);\n}\n\nfunction toInputValueLocal(raw: string, isDateOnly: boolean): string {\n const date = new Date(raw);\n if (isNaN(date.getTime())) return \"\";\n const y = date.getFullYear();\n const mo = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n if (isDateOnly) return `${y}-${mo}-${d}`;\n const h = String(date.getHours()).padStart(2, \"0\");\n const mi = String(date.getMinutes()).padStart(2, \"0\");\n return `${y}-${mo}-${d}T${h}:${mi}`;\n}\n\nexport function TimestampField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n const isDateOnly = field.type === \"date\";\n const hasTz = !!field.timezone;\n\n if (mode === \"display\") {\n if (!value) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n const raw = String(value);\n const formatted = hasTz\n ? formatTimestampWithTz(raw, isDateOnly)\n : formatTimestampLocal(raw, isDateOnly);\n const tzAbbrev = hasTz && !isDateOnly ? extractTzAbbrev(raw) : null;\n return (\n <span style={{ fontSize: 12.5 }}>\n {formatted}\n {tzAbbrev && <span style={{ marginLeft: 4, color: \"var(--text-3)\" }}>{tzAbbrev}</span>}\n </span>\n );\n }\n\n const inputValue = value\n ? (hasTz ? toInputValueWithTz(String(value), isDateOnly) : toInputValueLocal(String(value), isDateOnly))\n : \"\";\n\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type={isDateOnly ? \"date\" : \"datetime-local\"}\n value={inputValue}\n onChange={(v) => {\n if (!v) {\n onChange?.(null);\n return;\n }\n if (hasTz || isDateOnly) {\n // hasTz: server owns the zone; send the bare local wall-clock and\n // let the CUT+ATTACH pipeline re-zone it.\n // isDateOnly: server stores date (no tz), client sends YYYY-MM-DD.\n onChange?.(v);\n return;\n }\n // hasTz=false: send local wall-clock with offset. `new Date(v)` parses\n // the tz-less `datetime-local` value in the browser's local zone;\n // formatWireDateTime serializes it as \"YYYY-MM-DDTHH:mm:ss±HH:mm\".\n // The offset carries the unambiguous instant for passthrough storage.\n const d = new Date(v);\n if (isNaN(d.getTime())) {\n onChange?.(v);\n return;\n }\n onChange?.(formatWireDateTime(d));\n }}\n />\n );\n}\n","import { BoolToggle } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function BoolField({ value, mode, onChange, fieldId, labelId }: FieldRendererProps) {\n const checked = Boolean(value);\n\n if (mode === \"display\") {\n return (\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6, fontSize: 12.5 }}>\n <span\n style={{\n display: \"inline-block\",\n width: 6,\n height: 6,\n borderRadius: 999,\n background: checked ? \"var(--success)\" : \"var(--text-4)\",\n }}\n />\n {checked ? \"Yes\" : \"No\"}\n </span>\n );\n }\n\n return (\n <BoolToggle\n id={fieldId}\n ariaLabelledby={labelId}\n value={checked}\n onChange={(v) => onChange?.(v)}\n />\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nfunction formatDecimalString(value: string): string {\n const trimmed = value.trim();\n if (trimmed === \"\" || trimmed === \"-\") return trimmed;\n\n const negative = trimmed.startsWith(\"-\");\n const abs = negative ? trimmed.slice(1) : trimmed;\n const [intPart, fracPart] = abs.split(\".\");\n\n let formattedInt: string;\n try {\n formattedInt = new Intl.NumberFormat().format(BigInt(intPart || \"0\"));\n } catch {\n return value;\n }\n\n let result = negative ? `-${formattedInt}` : formattedInt;\n if (fracPart !== undefined) result += `.${fracPart}`;\n return result;\n}\n\nconst numFormatter = new Intl.NumberFormat();\n\nexport function NumberField({ field, fieldName, value, mode, onChange, record, fieldId }: FieldRendererProps) {\n const isMoney = field.display?.widget === \"money\";\n const isDecimal = field.type === \"decimal\" || isMoney;\n\n const units = record?.[\"$units\"] as Record<string, string> | undefined;\n const unitSuffix = units?.[fieldName];\n const staticUnit = !unitSuffix && field.unit ? (field.unit.display || field.unit.storage) : undefined;\n const displayUnit =\n unitSuffix || (staticUnit && !staticUnit.startsWith(\"$\") ? staticUnit : undefined);\n\n if (mode === \"display\") {\n if (value == null) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n\n let formatted: string | null;\n if (isDecimal && typeof value === \"string\") {\n formatted = formatDecimalString(value);\n } else {\n const num = Number(value);\n formatted = isNaN(num) ? null : numFormatter.format(num);\n }\n\n if (formatted == null) return <span style={{ fontSize: 12.5 }}>—</span>;\n\n return (\n <span className=\"num\" style={{ fontSize: 12.5, fontVariantNumeric: \"tabular-nums\" }}>\n {formatted}\n {displayUnit && (\n <span style={{ color: \"var(--text-3)\", marginLeft: 4 }}>{displayUnit}</span>\n )}\n </span>\n );\n }\n\n if (isDecimal) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"text\"\n inputMode=\"decimal\"\n pattern=\"-?\\d*\\.?\\d*\"\n value={value != null ? String(value) : \"\"}\n onChange={(v) => {\n if (v === \"\") onChange?.(null);\n else onChange?.(v);\n }}\n />\n );\n }\n\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"number\"\n step={field.type === \"float\" ? \"0.01\" : \"1\"}\n value={value != null ? String(value) : \"\"}\n onChange={(v) => {\n if (v === \"\") onChange?.(null);\n else onChange?.(field.type === \"int\" ? parseInt(v, 10) : parseFloat(v));\n }}\n />\n );\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { listEntities } from \"@/api/data\";\nimport type { ListParams, ListResponse } from \"@/types/api\";\n\n/**\n * useEntityData fetches one page-window of entity rows.\n *\n * Decoupled-count contract (docs/plans/2026-05-18-declarative-row-count.md):\n * this hook issues the WINDOW request only - `count: \"window\"`, so the\n * server returns the page of rows and never blocks on a COUNT(*). The total\n * is fetched separately by `useEntityCount`; the table renders rows the\n * moment this query resolves, independent of count latency.\n */\nexport function useEntityData(entity: string | undefined, params: ListParams) {\n const windowParams: ListParams = { ...params, count: \"window\" };\n return useQuery({\n queryKey: [\"entity-data\", entity, windowParams],\n queryFn: ({ signal }) => listEntities(entity!, windowParams, { signal }),\n enabled: !!entity,\n placeholderData: (prev, prevQuery) => {\n // Only reuse previous data within the same entity (pagination/sorting).\n // Cross-entity placeholder causes wrong rows/columns flash.\n const prevEntity = (prevQuery?.queryKey as unknown[])?.[1];\n return prevEntity === entity ? prev : undefined;\n },\n });\n}\n\n/**\n * useEntityCount fetches the total row count for a list view in a SEPARATE\n * request from the window (`count: \"only\"` - the server skips the data\n * query entirely and returns just `meta.total` + `meta.count_mode`).\n *\n * The count is page-independent: `page` and `sort` are stripped from the\n * params so a page change or a re-sort does not refetch the count - only a\n * filter / search / screen / include_deleted change invalidates it.\n *\n * The server picks exact vs estimated per the entity's declared `count`\n * strategy; the resolved `meta.count_mode` tells the caller which precision\n * to render. A count failure does NOT break the table: callers treat a\n * failed/absent count as \"unknown\" and fall back to the loaded row count.\n */\nexport function useEntityCount(entity: string | undefined, params: ListParams) {\n // Strip page-window knobs - the count describes the whole filtered set,\n // not one page, so it must not refetch when only the page or sort moves.\n const countParams: ListParams = {\n ...params,\n count: \"only\",\n page: undefined,\n per_page: undefined,\n sort: undefined,\n select: undefined,\n expand: undefined,\n };\n return useQuery<ListResponse>({\n queryKey: [\"entity-count\", entity, countParams],\n queryFn: ({ signal }) => listEntities(entity!, countParams, { signal }),\n enabled: !!entity,\n // The count is a slow, best-effort number; do not retry-storm a\n // multi-second estimate, and keep a resolved count warm across page\n // changes within the same filter set.\n retry: 1,\n staleTime: 30_000,\n placeholderData: (prev, prevQuery) => {\n const prevEntity = (prevQuery?.queryKey as unknown[])?.[1];\n return prevEntity === entity ? prev : undefined;\n },\n });\n}\n","import { useSchema } from \"./useSchema\";\nimport type { Entity } from \"@/types/schema\";\n\nexport function useEntity(entityCode: string | undefined): Entity | undefined {\n const { data: schema } = useSchema();\n if (!schema || !entityCode) return undefined;\n return schema.entities[entityCode];\n}\n","import { useMemo } from \"react\";\nimport { Select } from \"@/components/primitives\";\nimport { useEntityData } from \"@/hooks/useEntityData\";\nimport { useEntity } from \"@/hooks/useEntity\";\nimport { resolveRefRecordLabel } from \"@/types/schema\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function RefField({ field, value, mode, onChange, refs, fieldId, labelId }: FieldRendererProps) {\n const refEntityCode = field.ref?.entity;\n const entity = useEntity(refEntityCode);\n\n const displayField =\n field.display?.ref_display_field ?? field.ref?.display?.field ?? entity?.display?.display_field;\n const pk = useMemo(\n () => (entity ? ([...entity.fields].find(([, f]) => f.primary)?.[0] ?? \"id\") : \"id\"),\n [entity],\n );\n\n const { data: response, isLoading: optionsLoading } = useEntityData(\n mode === \"edit\" ? refEntityCode : undefined,\n { per_page: 200, sort: displayField ? `${displayField}:asc` : undefined },\n );\n const options = useMemo(() => response?.data ?? [], [response?.data]);\n\n const displayValue = useMemo(() => {\n if (value == null) return \"—\";\n const strVal = String(value);\n\n if (refs && refEntityCode) {\n const entityRefs = refs[refEntityCode];\n if (entityRefs) {\n const refRecord = entityRefs[strVal];\n if (refRecord) {\n return resolveRefRecordLabel(refRecord, displayField, strVal);\n }\n }\n }\n\n if (options.length > 0) {\n const match = options.find((r) => String(r[pk]) === strVal);\n if (match) return resolveRefRecordLabel(match, displayField, String(value));\n }\n\n return strVal;\n }, [value, refs, refEntityCode, displayField, options, pk]);\n\n if (mode === \"display\") {\n return <span style={{ fontSize: 12.5 }}>{displayValue}</span>;\n }\n\n const currentId = String(value ?? \"\");\n const hasCurrentInOptions = options.some((r) => String(r[pk]) === currentId);\n\n const selectOptions = [\n { value: \"\", label: \"Select…\" },\n ...(optionsLoading && currentId\n ? [{ value: currentId, label: displayValue }]\n : []),\n ...(!optionsLoading && currentId && !hasCurrentInOptions\n ? [{ value: currentId, label: displayValue }]\n : []),\n ...options.map((r) => {\n const id = String(r[pk]);\n const label = resolveRefRecordLabel(r, displayField, id);\n return { value: id, label };\n }),\n ];\n\n return (\n <Select\n // Select renders a <button>, not an <input>: <label htmlFor> cannot\n // target it, so the form's label is wired via aria-labelledby instead\n // (Finding 2).\n id={fieldId}\n aria-labelledby={labelId}\n aria-required={field.required || undefined}\n value={currentId}\n options={selectOptions}\n onChange={(v) => onChange?.(v || null)}\n placeholder=\"Select…\"\n />\n );\n}\n","import { lazy, Suspense } from \"react\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst JsonEditor = lazy(() =>\n import(\"./JsonEditor\").then((m) => ({ default: m.JsonEditor })),\n);\n\nfunction JsonEditorFallback() {\n return (\n <div className=\"h-20 rounded-md border border-border bg-muted animate-pulse\" />\n );\n}\n\n// isEmptyJsonValue reports whether a JSON field holds nothing worth showing:\n// null/undefined, a blank string, an empty object, or an empty array. The\n// readonly JSON editor renders a tall empty box for these, so display-mode\n// callers collapse to the empty token instead. Exported for the `json` cell\n// factory so list and detail surfaces agree on what \"empty\" means. A bare\n// `0` / `false` / non-empty string is a real value and is NOT empty.\nexport function isEmptyJsonValue(value: unknown): boolean {\n if (value == null) return true;\n if (typeof value === \"string\") return value.trim() === \"\";\n if (Array.isArray(value)) return value.length === 0;\n if (typeof value === \"object\") return Object.keys(value as object).length === 0;\n return false;\n}\n\nexport function JsonField({ value, mode, onChange, fieldId }: FieldRendererProps) {\n if (mode === \"display\") {\n if (isEmptyJsonValue(value)) {\n return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n }\n return (\n <Suspense fallback={<JsonEditorFallback />}>\n <JsonEditor value={value} readOnly />\n </Suspense>\n );\n }\n\n // The JSON editor is a CodeMirror surface, not a native <input>. id is set\n // on its container so the form's <label> association resolves to a real\n // element (Finding 2); the label is also wired via aria-labelledby on the\n // editor group, see JsonEditor.\n return (\n <Suspense fallback={<JsonEditorFallback />}>\n <JsonEditor value={value} onChange={onChange} id={fieldId} />\n </Suspense>\n );\n}\n","import { TextInput } from \"@/components/primitives\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport type { FieldRendererProps } from \"./index\";\n\ntype LangMap = Record<string, string>;\n\nfunction parseLangMap(value: unknown): LangMap {\n if (value == null) return {};\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as LangMap;\n }\n if (typeof value === \"string\") {\n return { en: value };\n }\n return {};\n}\n\nexport function MultilangField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n const { data: schema } = useSchema();\n const languages = schema?.languages?.length\n ? schema.languages\n : [{ code: \"en\", name: { en: \"English\" } }];\n const langMap = parseLangMap(value);\n\n if (mode === \"display\") {\n const displayVal = Object.values(langMap)[0] ?? \"—\";\n return <span style={{ fontSize: 12.5 }}>{displayVal}</span>;\n }\n\n const handleLangChange = (lang: string, text: string) => {\n const updated = { ...langMap, [lang]: text };\n for (const k of Object.keys(updated)) {\n if (!updated[k]) delete updated[k];\n }\n onChange?.(Object.keys(updated).length > 0 ? updated : null);\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n {languages.map((lang, i) => {\n // Per-language id: the first language carries the block's fieldId so\n // the form's <label htmlFor> resolves; the per-language code <label>\n // pairs each input with its own language tag (Finding 2).\n const langInputId = fieldId ? (i === 0 ? fieldId : `${fieldId}-${lang.code}`) : undefined;\n return (\n <div key={lang.code} style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <label\n htmlFor={langInputId}\n style={{\n width: 24,\n fontSize: 10.5,\n color: \"var(--text-3)\",\n textTransform: \"uppercase\",\n flexShrink: 0,\n letterSpacing: \"0.04em\",\n fontWeight: 500,\n }}\n >\n {lang.code}\n </label>\n <div style={{ flex: 1 }}>\n <TextInput\n id={langInputId}\n name={fieldName ? `${fieldName}.${lang.code}` : undefined}\n aria-required={field.required && i === 0 ? true : undefined}\n value={langMap[lang.code] ?? \"\"}\n onChange={(v) => handleLangChange(lang.code, v)}\n placeholder={`Value (${lang.code})`}\n />\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n","import { TextArea } from \"@/components/primitives\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport type { FieldRendererProps } from \"./index\";\n\ntype LangMap = Record<string, string>;\n\nfunction parseLangMap(value: unknown): LangMap {\n if (value == null) return {};\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as LangMap;\n }\n if (typeof value === \"string\") {\n return { en: value };\n }\n return {};\n}\n\nexport function MultilangTextField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n const { data: schema } = useSchema();\n const languages = schema?.languages?.length\n ? schema.languages\n : [{ code: \"en\", name: { en: \"English\" } }];\n const langMap = parseLangMap(value);\n\n if (mode === \"display\") {\n const displayVal = Object.values(langMap)[0] ?? \"—\";\n return <p style={{ fontSize: 12.5, whiteSpace: \"pre-wrap\", margin: 0 }}>{displayVal}</p>;\n }\n\n const handleLangChange = (lang: string, text: string) => {\n const updated = { ...langMap, [lang]: text };\n for (const k of Object.keys(updated)) {\n if (!updated[k]) delete updated[k];\n }\n onChange?.(Object.keys(updated).length > 0 ? updated : null);\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 10 }}>\n {languages.map((lang, i) => {\n // Per-language id: the first language carries the block's fieldId so\n // the form's <label htmlFor> resolves; the per-language code <label>\n // pairs each textarea with its own language tag (Finding 2).\n const langInputId = fieldId ? (i === 0 ? fieldId : `${fieldId}-${lang.code}`) : undefined;\n return (\n <div key={lang.code} style={{ display: \"flex\", flexDirection: \"column\", gap: 4 }}>\n <label\n htmlFor={langInputId}\n style={{\n fontSize: 10.5,\n color: \"var(--text-3)\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n fontWeight: 500,\n }}\n >\n {lang.code}\n </label>\n <TextArea\n id={langInputId}\n name={fieldName ? `${fieldName}.${lang.code}` : undefined}\n ariaRequired={field.required && i === 0}\n value={langMap[lang.code] ?? \"\"}\n onChange={(v) => handleLangChange(lang.code, v)}\n placeholder={`Value (${lang.code})`}\n rows={4}\n />\n </div>\n );\n })}\n </div>\n );\n}\n","import { Btn, FieldLabel, Icon, IconBtn } from \"@/components/primitives\";\nimport { useSchema } from \"@/hooks/useSchema\";\nimport { loc } from \"@/types/schema\";\nimport type { StructureDef } from \"@/types/schema\";\nimport type { FieldRendererProps } from \"./index\";\nimport { renderField } from \"./index\";\nimport { JsonField } from \"./JsonField\";\n\nexport function StructureField(props: FieldRendererProps) {\n const { field, value, mode, onChange, locale, fieldId } = props;\n const { data: schema } = useSchema();\n\n const structDef = field.structure ? schema?.structures?.[field.structure] : undefined;\n\n if (!structDef) return <JsonField {...props} />;\n\n // fieldId (Finding 2): a structure renders a labelled group of nested\n // fields, not a single input. It is placed on the group container so the\n // form's <label htmlFor> resolves to a real element. Array structures place\n // it on their outer wrapper; nested-field <label>s scope inside the group.\n if (field.array) {\n return <StructureArrayRenderer structDef={structDef} value={value} mode={mode} onChange={onChange} locale={locale} fieldId={fieldId} />;\n }\n\n return <StructureObjectRenderer structDef={structDef} value={value} mode={mode} onChange={onChange} locale={locale} fieldId={fieldId} />;\n}\n\nfunction StructureObjectRenderer({\n structDef,\n value,\n mode,\n onChange,\n locale,\n fieldId,\n}: {\n structDef: StructureDef;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n locale: string;\n fieldId?: string;\n}) {\n const obj = (typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? value\n : {}) as Record<string, unknown>;\n\n const fieldOrder = structDef.fields.names();\n\n const containerStyle = {\n display: \"flex\",\n flexDirection: \"column\" as const,\n gap: mode === \"display\" ? 8 : 12,\n border: \"1px solid var(--border)\",\n borderRadius: 8,\n padding: 12,\n background: \"var(--surface-2)\",\n };\n\n if (mode === \"display\") {\n const hasAnyValue = fieldOrder.some((key) => obj[key] != null && obj[key] !== \"\");\n if (!hasAnyValue) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n\n return (\n <div style={containerStyle}>\n {fieldOrder.map((key) => {\n const field = structDef.fields.get(key);\n if (!field) return null;\n const fieldValue = obj[key];\n if (fieldValue == null) return null;\n\n return (\n <div key={key} style={{ display: \"flex\", alignItems: \"baseline\", gap: 8 }}>\n <span\n style={{\n fontSize: 11.5,\n fontWeight: 500,\n color: \"var(--text-3)\",\n minWidth: 100,\n flexShrink: 0,\n }}\n >\n {field.display ? loc(field.display.name) : key}\n </span>\n <div style={{ minWidth: 0, flex: 1 }}>\n {field.type === \"structure\" && field.structure ? (\n <StructureField field={field} fieldName={key} value={fieldValue} mode=\"display\" locale={locale} />\n ) : (\n renderField({ field, fieldName: key, value: fieldValue, mode: \"display\", locale })\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n }\n\n const handleFieldChange = (key: string) => (fieldValue: unknown) => {\n onChange?.({ ...obj, [key]: fieldValue });\n };\n\n return (\n <div style={containerStyle} id={fieldId} role=\"group\">\n {fieldOrder.map((key) => {\n const field = structDef.fields.get(key);\n if (!field) return null;\n return (\n <div key={key} style={{ display: \"flex\", flexDirection: \"column\", gap: 2 }}>\n <FieldLabel required={field.required}>\n {field.display ? loc(field.display.name) : key}\n </FieldLabel>\n {field.type === \"structure\" && field.structure ? (\n <StructureField\n field={field}\n fieldName={key}\n value={obj[key]}\n mode=\"edit\"\n onChange={handleFieldChange(key)}\n locale={locale}\n />\n ) : (\n renderField({\n field,\n fieldName: key,\n value: obj[key],\n mode: \"edit\",\n onChange: handleFieldChange(key),\n locale,\n })\n )}\n </div>\n );\n })}\n </div>\n );\n}\n\nfunction StructureArrayRenderer({\n structDef,\n value,\n mode,\n onChange,\n locale,\n fieldId,\n}: {\n structDef: StructureDef;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n locale: string;\n fieldId?: string;\n}) {\n const items = Array.isArray(value) ? value : [];\n\n if (mode === \"display\") {\n if (items.length === 0) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n {items.map((item, idx) => (\n <StructureObjectRenderer key={idx} structDef={structDef} value={item} mode=\"display\" locale={locale} />\n ))}\n </div>\n );\n }\n\n const handleItemChange = (idx: number) => (itemValue: unknown) => {\n const next = [...items];\n next[idx] = itemValue;\n onChange?.(next);\n };\n\n const handleAdd = () => {\n onChange?.([...items, {}]);\n };\n\n const handleRemove = (idx: number) => () => {\n const next = items.filter((_, i) => i !== idx);\n onChange?.(next);\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }} id={fieldId} role=\"group\">\n {items.map((item, idx) => (\n <div key={idx} style={{ position: \"relative\" }}>\n <StructureObjectRenderer\n structDef={structDef}\n value={item}\n mode=\"edit\"\n onChange={handleItemChange(idx)}\n locale={locale}\n />\n <div style={{ position: \"absolute\", top: 6, right: 6 }}>\n <IconBtn\n size={24}\n icon={<Icon.trash size={12} />}\n onClick={handleRemove(idx)}\n title=\"Remove\"\n />\n </div>\n </div>\n ))}\n <div>\n <Btn icon={<Icon.plus size={13} />} onClick={handleAdd}>\n Add\n </Btn>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { PasswordInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst SECRET_SENTINEL = \"[SET]\";\n\nexport function SecretField({ field, fieldName, value, mode, onChange, record, fieldId }: FieldRendererProps) {\n const [inputValue, setInputValue] = useState(\"\");\n\n const isUpdate = record !== undefined;\n const hasExistingValue =\n value === SECRET_SENTINEL || (typeof value === \"string\" && value !== \"\");\n\n if (mode === \"display\") {\n if (hasExistingValue) {\n return (\n <span className=\"mono\" style={{ fontSize: 12.5, color: \"var(--text-3)\" }}>\n {SECRET_SENTINEL}\n </span>\n );\n }\n return (\n <span style={{ fontSize: 12.5, color: \"var(--text-4)\", fontStyle: \"italic\" }}>Not set</span>\n );\n }\n\n const handleChange = (v: string) => {\n setInputValue(v);\n if (isUpdate) {\n if (v === \"\") onChange?.(hasExistingValue ? SECRET_SENTINEL : \"\");\n else onChange?.(v);\n } else {\n onChange?.(v);\n }\n };\n\n return (\n <PasswordInput\n id={fieldId}\n name={fieldName}\n ariaRequired={field.required}\n value={inputValue}\n onChange={handleChange}\n placeholder={isUpdate ? \"Leave blank to keep existing value\" : \"Enter value\"}\n />\n );\n}\n","import { useState } from \"react\";\nimport { PasswordInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nconst SECRET_SENTINEL = \"[SET]\";\n\nexport function PasswordField({ field, fieldName, value, mode, onChange, record, fieldId }: FieldRendererProps) {\n const [inputValue, setInputValue] = useState(\"\");\n\n const isUpdate = record !== undefined;\n const hasExistingValue =\n value === SECRET_SENTINEL || (typeof value === \"string\" && value !== \"\");\n\n if (mode === \"display\") {\n if (hasExistingValue) {\n return (\n <span className=\"mono\" style={{ fontSize: 12.5, color: \"var(--text-3)\" }}>\n {SECRET_SENTINEL}\n </span>\n );\n }\n return (\n <span style={{ fontSize: 12.5, color: \"var(--text-4)\", fontStyle: \"italic\" }}>Not set</span>\n );\n }\n\n const handleChange = (v: string) => {\n setInputValue(v);\n if (isUpdate) {\n if (v === \"\") onChange?.(hasExistingValue ? SECRET_SENTINEL : \"\");\n else onChange?.(v);\n } else {\n onChange?.(v);\n }\n };\n\n return (\n <PasswordInput\n id={fieldId}\n name={fieldName}\n ariaRequired={field.required}\n value={inputValue}\n onChange={handleChange}\n placeholder={isUpdate ? \"Leave blank to keep existing value\" : \"Enter password\"}\n />\n );\n}\n","import { useState, type KeyboardEvent } from \"react\";\nimport { Btn, Chip, Icon, TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nfunction toStringArray(value: unknown): string[] {\n if (Array.isArray(value)) return value.filter((v) => v != null).map(String);\n return [];\n}\n\nexport function StringArrayField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n const items = toStringArray(value);\n const [draft, setDraft] = useState(\"\");\n\n if (mode === \"display\") {\n if (items.length === 0) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n return (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4 }}>\n {items.map((item, i) => (\n <Chip key={i} tone=\"slate\">{item}</Chip>\n ))}\n </div>\n );\n }\n\n const addItem = () => {\n const trimmed = draft.trim();\n if (!trimmed) return;\n onChange?.([...items, trimmed]);\n setDraft(\"\");\n };\n\n const removeItem = (index: number) => {\n onChange?.(items.filter((_, i) => i !== index));\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n addItem();\n }\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n {items.length > 0 && (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4 }}>\n {items.map((item, i) => (\n <Chip key={i} tone=\"slate\" onRemove={() => removeItem(i)}>{item}</Chip>\n ))}\n </div>\n )}\n <div style={{ display: \"flex\", gap: 4 }}>\n <div style={{ flex: 1 }}>\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n value={draft}\n onChange={setDraft}\n onKeyDown={handleKeyDown}\n placeholder=\"Add item…\"\n />\n </div>\n <Btn icon={<Icon.plus size={13} />} onClick={addItem}>Add</Btn>\n </div>\n </div>\n );\n}\n","import { useState, type KeyboardEvent } from \"react\";\nimport { Btn, Chip, Icon, TextInput } from \"@/components/primitives\";\nimport type { FieldRendererProps } from \"./index\";\n\nfunction toIntArray(value: unknown): number[] {\n if (Array.isArray(value)) {\n return value.filter((v) => v != null).map(Number).filter((n) => !isNaN(n));\n }\n return [];\n}\n\nexport function IntArrayField({ field, fieldName, value, mode, onChange, fieldId }: FieldRendererProps) {\n const items = toIntArray(value);\n const [draft, setDraft] = useState(\"\");\n\n if (mode === \"display\") {\n if (items.length === 0) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n return (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4 }}>\n {items.map((item, i) => (\n <Chip key={i} tone=\"slate\">{item}</Chip>\n ))}\n </div>\n );\n }\n\n const addItem = () => {\n const trimmed = draft.trim();\n if (!trimmed) return;\n const num = Number(trimmed);\n if (isNaN(num) || !Number.isInteger(num)) return;\n onChange?.([...items, num]);\n setDraft(\"\");\n };\n\n const removeItem = (index: number) => {\n onChange?.(items.filter((_, i) => i !== index));\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n addItem();\n }\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n {items.length > 0 && (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4 }}>\n {items.map((item, i) => (\n <Chip key={i} tone=\"slate\" onRemove={() => removeItem(i)}>{item}</Chip>\n ))}\n </div>\n )}\n <div style={{ display: \"flex\", gap: 4 }}>\n <div style={{ flex: 1 }}>\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n type=\"number\"\n value={draft}\n onChange={setDraft}\n onKeyDown={handleKeyDown}\n placeholder=\"Add number…\"\n />\n </div>\n <Btn icon={<Icon.plus size={13} />} onClick={addItem}>Add</Btn>\n </div>\n </div>\n );\n}\n","import type { FileWidget } from \"./types\";\n\n// Module-scope file widget registry. Consumer apps register custom widgets\n// via `registerFileWidget(\"math_figure\", MathFigureWidget)` before mount.\n// Built-in widgets (square_image, circle_image, wide_banner, grid,\n// document_card, file_list) are registered eagerly when their module loads.\nconst widgets = new Map<string, FileWidget>();\n\nexport function registerFileWidget(code: string, widget: FileWidget): void {\n widgets.set(code, widget);\n}\n\nexport function getFileWidget(code: string): FileWidget | undefined {\n return widgets.get(code);\n}\n\nexport function hasFileWidget(code: string): boolean {\n return widgets.has(code);\n}\n\n// Test-only: clear the registry between tests so re-registrations don't\n// accumulate. Production code never calls this.\nexport function __resetFileWidgetRegistryForTests(): void {\n widgets.clear();\n}\n","// Cropper indirection. The plan calls for `react-image-crop` when\n// `crop_on_upload: true`, but we keep that dependency out of the SDK core\n// so apps that don't need cropping pay no bundle cost. Consumer apps wire\n// their cropper of choice via `setImageCropper(fn)`; the default is a\n// pass-through that returns the original blob untouched.\n//\n// Tests can substitute a deterministic stub via setImageCropper to assert\n// the round-trip without a real cropper UI.\n\nimport type { ReactNode } from \"react\";\n\nexport interface CropperOptions {\n aspectRatio?: number;\n // file is the picked source. Returns a Blob (likely image/jpeg|png) plus\n // a final filename. The caller wraps it back into a File for upload.\n file: File;\n}\n\nexport interface CropperResult {\n blob: Blob;\n filename: string;\n}\n\nexport type ImageCropper = (opts: CropperOptions) => Promise<CropperResult>;\n\nconst passthroughCropper: ImageCropper = async ({ file }) => ({\n blob: file,\n filename: file.name,\n});\n\nlet activeCropper: ImageCropper = passthroughCropper;\n\nexport function setImageCropper(c: ImageCropper | null): void {\n activeCropper = c ?? passthroughCropper;\n}\n\nexport function getImageCropper(): ImageCropper {\n return activeCropper;\n}\n\n// Some host apps prefer a modal-based cropper. The renderer is optional and\n// unused by the built-in widgets in Wave 1 — exposed for forward-compat so\n// react-image-crop integrations can share infrastructure.\nlet cropperRenderer: ((node: ReactNode) => void) | null = null;\nexport function setCropperRenderer(fn: ((node: ReactNode) => void) | null): void {\n cropperRenderer = fn;\n}\nexport function getCropperRenderer(): ((node: ReactNode) => void) | null {\n return cropperRenderer;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { CSSProperties, DragEvent, KeyboardEvent } from \"react\";\nimport {\n uploadFile,\n discardFile,\n validateClientSide,\n formatBytes,\n UploadError,\n} from \"./upload\";\nimport { getImageCropper } from \"./cropper\";\nimport {\n focalPointObjectPosition,\n preferredListThumbnailURL,\n preferredThumbnailVariant,\n readFocalPoint,\n resolveFileAltText,\n withFocalPoint,\n} from \"./helpers\";\nimport { useDraftRegistration } from \"./draft-scope\";\nimport { useEmbedFileSrc } from \"./useEmbedFileSrc\";\nimport { singleFileFromValue } from \"./value\";\nimport type { FileWidgetProps, HydratedFile, UploadProgress } from \"./types\";\n\n// Internal state machine for an image-style file widget. Three stable\n// states: empty, populated, in-flight (upload running). Errors live on\n// the side and clear on retry.\ntype WidgetStatus = \"idle\" | \"uploading\" | \"error\";\n\nexport interface ImageWidgetVisualConfig {\n // shape: square or circle. Drives placeholder + clip-path.\n shape: \"square\" | \"circle\" | \"wide\";\n // CSS aspect-ratio (e.g. \"1 / 1\", \"16 / 9\"). Falls back per shape.\n aspectRatio?: string;\n // CSS width or undefined to let the parent decide.\n width?: string;\n}\n\nexport interface ImageWidgetInternalProps extends FileWidgetProps {\n visual: ImageWidgetVisualConfig;\n}\n\nfunction previewUrl(f: HydratedFile | null, preferredDerivationKey?: string): string | undefined {\n return preferredListThumbnailURL(f, preferredDerivationKey);\n}\n\n// initialsFromAlt extracts up to two initials from a label, falling back\n// to \"?\" if empty. Used by the placeholder when widget renders empty.\nfunction initialsFromAlt(label: string): string {\n const parts = label.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\n return (parts[0][0] + parts[1][0]).toUpperCase();\n}\n\nexport function ImageWidget(props: ImageWidgetInternalProps) {\n const { field, fieldName, value, onChange, mode, alt, disabled, visual, uploadFieldCode, uploadSlotCode } = props;\n const file = singleFileFromValue(value);\n const [status, setStatus] = useState<WidgetStatus>(\"idle\");\n const [progress, setProgress] = useState<UploadProgress | null>(null);\n const [error, setError] = useState<{ code: string; message: string } | null>(null);\n const [pendingDraftId, setPendingDraftId] = useState<string | null>(null);\n const [isEditingFocalPoint, setIsEditingFocalPoint] = useState(false);\n const abortRef = useRef<AbortController | null>(null);\n const cancelledUploadRef = useRef(false);\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n const { register, unregister, isDraft } = useDraftRegistration();\n\n // Cleanup on unmount: abort in-flight upload + discard registered draft.\n useEffect(() => {\n return () => {\n if (abortRef.current) abortRef.current.abort();\n };\n }, []);\n\n const ariaLabel = useMemo(() => {\n return resolveFileAltText(file, alt, field.display?.placeholder || fieldName);\n }, [alt, field.display?.placeholder, fieldName, file]);\n\n const accept = (field.accepts ?? [\"image/*\"]).join(\",\");\n\n const startUpload = useCallback(async (raw: File) => {\n // Client-side validation mirrors the server's accepts + max_size_bytes\n // checks so the user gets immediate feedback.\n const v = validateClientSide(raw, field.accepts, field.max_size_bytes);\n if (v) {\n setError(v);\n setStatus(\"error\");\n return;\n }\n\n let toUpload: File = raw;\n if (field.display?.crop_on_upload) {\n try {\n const cropper = getImageCropper();\n const aspect = parseAspect(field.display.aspect_ratio);\n const { blob, filename } = await cropper({ file: raw, aspectRatio: aspect });\n toUpload = new File([blob], filename, { type: blob.type || raw.type });\n } catch (err) {\n setError({ code: \"CROP_FAILED\", message: err instanceof Error ? err.message : \"Crop failed\" });\n setStatus(\"error\");\n return;\n }\n }\n\n setError(null);\n cancelledUploadRef.current = false;\n setStatus(\"uploading\");\n setProgress({ loaded: 0, total: toUpload.size, pct: 0 });\n const ctrl = new AbortController();\n abortRef.current = ctrl;\n\n try {\n const result = await uploadFile({\n file: toUpload,\n entityCode: props.entityCode,\n fieldCode: uploadFieldCode ?? fieldName,\n slotCode: uploadSlotCode,\n signal: ctrl.signal,\n onProgress: setProgress,\n });\n if (cancelledUploadRef.current) {\n void discardFile(result.id).catch(() => {});\n unregister(result.id);\n return;\n }\n if (file && isDraft(file.id)) {\n void discardFile(file.id).catch(() => {});\n unregister(file.id);\n }\n // Register the freshly-uploaded draft with the form scope so a\n // form Cancel can discard it. Stays registered until form save\n // (parent calls scope.markCommitted) or the user replaces/removes.\n register(result.id, () => discardFile(result.id));\n setPendingDraftId(result.id);\n setStatus(\"idle\");\n setProgress(null);\n // Materialize a HydratedFile from the upload result. Server returns\n // enough metadata to render the preview without a re-fetch.\n const next: HydratedFile = {\n id: result.id,\n filename: result.filename,\n content_type: result.content_type,\n size_bytes: result.size_bytes,\n sha256: result.sha256,\n width: result.width,\n height: result.height,\n url: result.url,\n metadata: result.metadata,\n };\n // Respect mode: array vs single. For these single-image widgets we\n // always emit a single object; array-mode widgets (Grid) use their\n // own append logic.\n onChange?.(field.mode === \"array\" ? [next] : next);\n } catch (err) {\n if (err instanceof UploadError && err.code === \"ABORTED\") {\n // User-initiated cancel — already handled in handleCancel.\n return;\n }\n const e = err instanceof UploadError\n ? { code: err.code, message: err.message }\n : { code: \"UNKNOWN\", message: err instanceof Error ? err.message : \"Upload failed\" };\n setError(e);\n setStatus(\"error\");\n setProgress(null);\n }\n }, [\n field.accepts,\n field.max_size_bytes,\n field.display?.crop_on_upload,\n field.display?.aspect_ratio,\n field.mode,\n fieldName,\n onChange,\n props.entityCode,\n register,\n isDraft,\n file,\n unregister,\n uploadFieldCode,\n uploadSlotCode,\n ]);\n\n const handleCancel = useCallback(() => {\n if (status === \"uploading\" && abortRef.current) {\n cancelledUploadRef.current = true;\n abortRef.current.abort();\n abortRef.current = null;\n setStatus(\"idle\");\n setProgress(null);\n }\n // Cancel mid-upload: if the server already created the row (e.g. body\n // streamed fully then we aborted reading the response), the GC sweep\n // catches the draft. We additionally fire discard if we have an id.\n if (pendingDraftId) {\n void discardFile(pendingDraftId).catch(() => {});\n unregister(pendingDraftId);\n setPendingDraftId(null);\n }\n }, [status, pendingDraftId, unregister]);\n\n const handleRemove = useCallback(() => {\n if (file && isDraft(file.id)) {\n void discardFile(file.id).catch(() => {});\n unregister(file.id);\n setPendingDraftId(null);\n }\n onChange?.(field.mode === \"array\" ? [] : null);\n }, [file, field.mode, isDraft, onChange, unregister]);\n\n const handleRetry = useCallback(() => {\n setError(null);\n setStatus(\"idle\");\n fileInputRef.current?.click();\n }, []);\n\n const onPick = useCallback(() => {\n if (disabled) return;\n fileInputRef.current?.click();\n }, [disabled]);\n\n const onKeyDown = useCallback((e: KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPick();\n }\n }, [disabled, onPick]);\n\n const onDragOver = useCallback((e: DragEvent<HTMLDivElement>) => {\n if (disabled) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"copy\";\n }, [disabled]);\n\n const onDrop = useCallback((e: DragEvent<HTMLDivElement>) => {\n if (disabled) return;\n e.preventDefault();\n const f = e.dataTransfer.files?.[0];\n if (f) void startUpload(f);\n }, [disabled, startUpload]);\n\n const onChangeFile = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const f = e.target.files?.[0];\n // Reset value so picking the same file twice still triggers change.\n e.target.value = \"\";\n if (f) void startUpload(f);\n }, [startUpload]);\n\n const aspect = visual.aspectRatio ?? defaultAspect(visual.shape, field.display?.aspect_ratio);\n const focalPoint = readFocalPoint(file);\n const containerStyle: CSSProperties = {\n aspectRatio: aspect,\n width: visual.width ?? (visual.shape === \"wide\" ? \"100%\" : \"120px\"),\n };\n\n const isPreview = !!file;\n // In normal cookie mode `previewUrl` is the static thumbnail URL and\n // `useEmbedFileSrc` returns it unchanged. In Bearer-only embed mode the hook\n // resolves the same thumbnail through the embed file URL endpoint and yields\n // a presigned or `blob:` URL a native `<img>` can load without a header.\n const staticPreview = previewUrl(file, field.display?.listable_thumbnail);\n const previewVariant = preferredThumbnailVariant(file, field.display?.listable_thumbnail);\n const preview = useEmbedFileSrc(file?.id, previewVariant, staticPreview);\n const displayMode = mode === \"display\";\n const handleSetFocalPoint = useCallback((e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n setIsEditingFocalPoint((value) => !value);\n }, []);\n\n const handlePickFocalPoint = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n if (!file || !isEditingFocalPoint) return;\n const rect = e.currentTarget.getBoundingClientRect();\n const x = rect.width > 0 ? (e.clientX - rect.left) / rect.width : 0.5;\n const y = rect.height > 0 ? (e.clientY - rect.top) / rect.height : 0.5;\n const next = withFocalPoint(file, {\n x: Math.max(0, Math.min(1, x)),\n y: Math.max(0, Math.min(1, y)),\n });\n onChange?.(field.mode === \"array\" ? [next] : next);\n setIsEditingFocalPoint(false);\n }, [field.mode, file, isEditingFocalPoint, onChange]);\n\n // Display mode is read-only: just the image (or placeholder). No drop zone,\n // no controls. Used when a record is rendered in a list cell.\n if (displayMode) {\n return (\n <div\n className={containerClass(visual.shape, false)}\n style={containerStyle}\n aria-label={ariaLabel}\n >\n {isPreview && preview ? (\n <img\n src={preview}\n alt={ariaLabel}\n className={imgClass(visual.shape)}\n style={{ objectPosition: focalPointObjectPosition(focalPoint) }}\n loading=\"lazy\"\n />\n ) : (\n <Placeholder shape={visual.shape} label={ariaLabel} placeholder={field.display?.placeholder} />\n )}\n </div>\n );\n }\n\n return (\n <div\n className={containerClass(visual.shape, !disabled)}\n style={containerStyle}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-label={ariaLabel}\n aria-disabled={disabled || undefined}\n aria-busy={status === \"uploading\" || undefined}\n aria-invalid={status === \"error\" || undefined}\n onClick={status === \"idle\" && !isPreview ? onPick : undefined}\n onMouseDown={isEditingFocalPoint ? handlePickFocalPoint : undefined}\n onKeyDown={onKeyDown}\n onDragOver={onDragOver}\n onDrop={onDrop}\n data-testid={isEditingFocalPoint ? \"focal-point-target\" : `file-widget-${fieldName}`}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n onChange={onChangeFile}\n style={{ display: \"none\" }}\n data-testid={`file-input-${fieldName}`}\n />\n\n {isPreview && preview ? (\n <img\n src={preview}\n alt={ariaLabel}\n className={imgClass(visual.shape)}\n style={{ objectPosition: focalPointObjectPosition(focalPoint) }}\n loading=\"lazy\"\n />\n ) : status !== \"uploading\" ? (\n <Placeholder shape={visual.shape} label={ariaLabel} placeholder={field.display?.placeholder} />\n ) : null}\n\n {status === \"uploading\" && (\n <ProgressRing pct={progress?.pct ?? 0} />\n )}\n\n {/* Pending-draft amber dot indicator. Visible until parent form\n markCommitted() the draft; hosts that don't use FileDraftScope\n still see the indicator while the widget owns a fresh draft. */}\n {pendingDraftId && (\n <span\n className=\"absolute right-1 top-1 h-2 w-2 rounded-full bg-warning\"\n aria-hidden=\"true\"\n data-testid=\"draft-indicator\"\n />\n )}\n\n {/* Hover overlay (Change / Remove) when populated. Click events\n stopPropagate so they don't trigger the picker open on the root. */}\n {isPreview && status === \"idle\" && !disabled && (\n <div className=\"absolute inset-0 flex items-center justify-center gap-2 bg-black/40 opacity-0 transition-opacity hover:opacity-100 focus-within:opacity-100\">\n {field.display?.focal_point && (\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={handleSetFocalPoint}\n data-testid=\"focal-point-toggle\"\n >\n {isEditingFocalPoint ? \"Cancel focus\" : \"Set focus\"}\n </button>\n )}\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={(e) => { e.stopPropagation(); onPick(); }}\n >\n Change\n </button>\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-destructive hover:bg-surface-2\"\n onClick={(e) => { e.stopPropagation(); handleRemove(); }}\n >\n Remove\n </button>\n </div>\n )}\n\n {focalPoint && isPreview && (\n <span\n className=\"absolute h-3 w-3 -translate-x-1/2 -translate-y-1/2 rounded-full border border-white bg-black/70\"\n style={{ left: `${focalPoint.x * 100}%`, top: `${focalPoint.y * 100}%` }}\n data-testid=\"focal-point-marker\"\n />\n )}\n\n {/* Cancel button while uploading. Sits as an overlay button. */}\n {status === \"uploading\" && (\n <button\n type=\"button\"\n className=\"absolute bottom-1 right-1 rounded-sm border border-border bg-card px-2 py-0.5 text-xs\"\n onClick={(e) => { e.stopPropagation(); handleCancel(); }}\n data-testid=\"cancel-upload\"\n >\n Cancel\n </button>\n )}\n\n {/* Error state. Shows message + Retry; the container also gets a\n destructive border via the error class above. */}\n {status === \"error\" && error && (\n <div\n className=\"absolute inset-x-0 bottom-0 flex items-center justify-between gap-2 bg-destructive-soft px-2 py-1 text-xs text-destructive\"\n role=\"alert\"\n >\n <span className=\"truncate\" title={error.message}>{error.message}</span>\n <button\n type=\"button\"\n className=\"underline\"\n onClick={(e) => { e.stopPropagation(); handleRetry(); }}\n data-testid=\"retry-upload\"\n >\n Retry\n </button>\n </div>\n )}\n </div>\n );\n}\n\nfunction containerClass(shape: ImageWidgetVisualConfig[\"shape\"], interactive: boolean): string {\n // Tailwind classes use semantic tokens (no hardcoded colors) per project\n // theming rules in CLAUDE.md. The container is positioned for overlay\n // children (progress ring, hover toolbar, error banner).\n const base = \"relative overflow-hidden border border-border bg-surface-2\";\n const shapeClass =\n shape === \"circle\" ? \"rounded-full\" :\n shape === \"wide\" ? \"rounded-md\" :\n \"rounded-md\";\n const interactiveClass = interactive\n ? \"cursor-pointer focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent\"\n : \"\";\n return [base, shapeClass, interactiveClass].filter(Boolean).join(\" \");\n}\n\nfunction imgClass(shape: ImageWidgetVisualConfig[\"shape\"]): string {\n // Cover the entire container so square/circle crops are visually clean.\n // Wide banners also use cover so the focal point stays centered.\n return shape === \"circle\"\n ? \"h-full w-full object-cover\"\n : \"h-full w-full object-cover\";\n}\n\nfunction defaultAspect(shape: ImageWidgetVisualConfig[\"shape\"], explicit?: string): string {\n if (explicit) return explicit.replace(\":\", \" / \");\n if (shape === \"wide\") return \"16 / 9\";\n return \"1 / 1\";\n}\n\nfunction parseAspect(value: string | undefined): number | undefined {\n if (!value) return undefined;\n const cleaned = value.replace(/\\s/g, \"\");\n const m = cleaned.match(/^(\\d+(?:\\.\\d+)?)[:/](\\d+(?:\\.\\d+)?)$/);\n if (!m) return undefined;\n const a = Number(m[1]);\n const b = Number(m[2]);\n if (!a || !b) return undefined;\n return a / b;\n}\n\nfunction Placeholder({\n shape,\n label,\n placeholder,\n}: {\n shape: ImageWidgetVisualConfig[\"shape\"];\n label: string;\n placeholder?: string;\n}) {\n if (placeholder === \"initials\") {\n return (\n <div className=\"flex h-full w-full items-center justify-center bg-surface-3 text-text-3\">\n <span className={shape === \"circle\" ? \"text-lg font-medium\" : \"text-base font-medium\"}>\n {initialsFromAlt(label)}\n </span>\n </div>\n );\n }\n return (\n <div className=\"flex h-full w-full items-center justify-center bg-surface-3 text-text-4\">\n <span className=\"text-xs\">{shape === \"wide\" ? \"Drop image here\" : \"+\"}</span>\n </div>\n );\n}\n\nfunction ProgressRing({ pct }: { pct: number }) {\n const radius = 18;\n const circumference = 2 * Math.PI * radius;\n const offset = circumference - (Math.max(0, Math.min(100, pct)) / 100) * circumference;\n return (\n <div\n className=\"absolute inset-0 flex items-center justify-center bg-black/30\"\n data-testid=\"upload-progress\"\n aria-label={`Uploading ${Math.round(pct)}%`}\n role=\"progressbar\"\n aria-valuenow={Math.round(pct)}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <svg width=\"48\" height=\"48\" viewBox=\"0 0 48 48\">\n <circle\n cx=\"24\"\n cy=\"24\"\n r={radius}\n stroke=\"currentColor\"\n strokeOpacity=\"0.25\"\n strokeWidth=\"4\"\n fill=\"none\"\n className=\"text-foreground\"\n />\n <circle\n cx=\"24\"\n cy=\"24\"\n r={radius}\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n fill=\"none\"\n strokeDasharray={circumference}\n strokeDashoffset={offset}\n strokeLinecap=\"round\"\n className=\"text-accent\"\n transform=\"rotate(-90 24 24)\"\n />\n </svg>\n <span className=\"absolute text-xs text-foreground\">{Math.round(pct)}%</span>\n </div>\n );\n}\n\n// Format helpers re-exported for tests + storybook-style consumers.\nexport { formatBytes };\n","import { ImageWidget } from \"./ImageWidget\";\nimport type { FileWidgetProps } from \"./types\";\n\n// SquareImage: 1:1 image upload widget. Use cases: contact avatars (admin\n// view), product square thumbnails, badge artwork. Per einstein §6.1.\n//\n// Behaviors (inherited from ImageWidget):\n// - empty placeholder (text or initials)\n// - hover overlay with Change/Remove\n// - drag-drop upload\n// - progress ring while in flight\n// - error border + Retry on failure\n// - amber dot when a draft is pending\nexport function SquareImage(props: FileWidgetProps) {\n return <ImageWidget {...props} visual={{ shape: \"square\" }} />;\n}\n","import { ImageWidget } from \"./ImageWidget\";\nimport type { FileWidgetProps } from \"./types\";\n\n// CircleImage: avatar variant of SquareImage with a circular CSS clip.\n// Used for user avatars, contact profile photos. Per einstein §6.2.\nexport function CircleImage(props: FileWidgetProps) {\n return <ImageWidget {...props} visual={{ shape: \"circle\" }} />;\n}\n","import { ImageWidget } from \"./ImageWidget\";\nimport type { FileWidgetProps } from \"./types\";\n\n// WideBanner: aspect-ratio rectangle for hero/banner imagery. Defaults to\n// 16:9 but the field's `display.aspect_ratio` overrides. Per einstein §6.3.\n//\n// `focal_point` is parsed and stored upstream; Wave-1 widget honors it as a\n// CSS object-position only when explicitly populated in metadata. The\n// in-widget focal-point picker UI is deferred to Wave 2 (skipping the\n// crosshair overlay keeps the Wave-1 surface narrow).\nexport function WideBanner(props: FileWidgetProps) {\n return <ImageWidget {...props} visual={{ shape: \"wide\" }} />;\n}\n","// GridLazy: the eager entry point for the `grid` file widget. The real Grid\n// pulls @dnd-kit (drag-to-reorder). Loading it lazily keeps @dnd-kit in its\n// own chunk, out of the eager SDK bundle. builtins.ts registers THIS wrapper,\n// and the file-widgets barrel re-exports it as `Grid`, so there is no static\n// import path to the heavy module.\nimport { lazy, Suspense } from \"react\";\nimport type { FileWidgetProps } from \"./types\";\n\nconst LazyGrid = lazy(() => import(\"./Grid\").then((m) => ({ default: m.Grid })));\n\nfunction GridFallback() {\n return <div className=\"h-24 w-full rounded-md bg-muted animate-pulse\" />;\n}\n\nexport function GridLazy(props: FileWidgetProps) {\n return (\n <Suspense fallback={<GridFallback />}>\n <LazyGrid {...props} />\n </Suspense>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n uploadFile,\n discardFile,\n validateClientSide,\n formatBytes,\n UploadError,\n} from \"./upload\";\nimport { useDraftRegistration } from \"./draft-scope\";\nimport { canPreviewFile, downloadFileURL, previewFileURL } from \"./helpers\";\nimport { useEmbedFileOpener } from \"./useEmbedFileSrc\";\nimport { singleFileFromValue } from \"./value\";\nimport type {\n FileWidgetProps,\n HydratedFile,\n UploadProgress,\n} from \"./types\";\n\n// DocumentCard widget: a single-file card for documents (PDF, DOCX, XLSX).\n// Per einstein §6.5.\n//\n// Layout: thumbnail (or generic file icon), filename (inline-editable),\n// size + upload metadata, action buttons (Download / Preview / Replace /\n// Remove). Wave-1 preview opens the file in a new tab; Wave-2 swaps in\n// pdf.js inline viewer.\n\ntype Status = \"idle\" | \"uploading\" | \"error\";\n\nfunction FileIcon({ contentType }: { contentType?: string }) {\n // Compact text-based file glyph keyed off the content type. Avoids pulling\n // in an SVG icon library; consumer apps that want richer icons swap the\n // widget out via registerFileWidget.\n const label = (() => {\n if (!contentType) return \"FILE\";\n if (contentType.includes(\"pdf\")) return \"PDF\";\n if (contentType.includes(\"word\")) return \"DOC\";\n if (contentType.includes(\"sheet\") || contentType.includes(\"excel\")) return \"XLS\";\n if (contentType.startsWith(\"image/\")) return \"IMG\";\n return contentType.split(\"/\")[1]?.slice(0, 4).toUpperCase() ?? \"FILE\";\n })();\n return (\n <div className=\"flex h-16 w-16 flex-none items-center justify-center rounded-md border border-border bg-surface-3 text-xs font-medium text-muted-foreground\">\n {label}\n </div>\n );\n}\n\nexport function DocumentCard(props: FileWidgetProps) {\n const { field, fieldName, value, onChange, mode, disabled, uploadFieldCode, uploadSlotCode } = props;\n const file = singleFileFromValue(value);\n const [status, setStatus] = useState<Status>(\"idle\");\n const [progress, setProgress] = useState<UploadProgress | null>(null);\n const [error, setError] = useState<{ code: string; message: string } | null>(\n null,\n );\n const [editingName, setEditingName] = useState(false);\n const [draftName, setDraftName] = useState(file?.filename ?? \"\");\n const abortRef = useRef<AbortController | null>(null);\n const cancelledUploadRef = useRef(false);\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n const { register, unregister, isDraft } = useDraftRegistration();\n // Cookie mode: opens the static URL directly. Embed mode: resolves the file\n // through the Bearer-authenticated endpoint first, then opens the presigned\n // or `blob:` URL - `window.open` cannot attach an `Authorization` header.\n const { open: openEmbedFile } = useEmbedFileOpener();\n\n useEffect(() => {\n return () => {\n if (abortRef.current) abortRef.current.abort();\n };\n }, []);\n\n useEffect(() => {\n setDraftName(file?.filename ?? \"\");\n }, [file?.filename]);\n\n const accept = (field.accepts ?? []).join(\",\");\n\n const startUpload = useCallback(\n async (raw: File) => {\n const v = validateClientSide(raw, field.accepts, field.max_size_bytes);\n if (v) {\n setError(v);\n setStatus(\"error\");\n return;\n }\n setError(null);\n cancelledUploadRef.current = false;\n setStatus(\"uploading\");\n setProgress({ loaded: 0, total: raw.size, pct: 0 });\n const ctrl = new AbortController();\n abortRef.current = ctrl;\n try {\n const result = await uploadFile({\n file: raw,\n entityCode: props.entityCode,\n fieldCode: uploadFieldCode ?? fieldName,\n slotCode: uploadSlotCode,\n signal: ctrl.signal,\n onProgress: setProgress,\n });\n if (cancelledUploadRef.current) {\n void discardFile(result.id).catch(() => {});\n unregister(result.id);\n return;\n }\n if (file && isDraft(file.id)) {\n void discardFile(file.id).catch(() => {});\n unregister(file.id);\n }\n register(result.id, () => discardFile(result.id));\n setStatus(\"idle\");\n setProgress(null);\n const next: HydratedFile = {\n id: result.id,\n filename: result.filename,\n content_type: result.content_type,\n size_bytes: result.size_bytes,\n sha256: result.sha256,\n width: result.width,\n height: result.height,\n url: result.url,\n metadata: result.metadata,\n };\n onChange?.(field.mode === \"array\" ? [next] : next);\n } catch (err) {\n if (err instanceof UploadError && err.code === \"ABORTED\") return;\n const e =\n err instanceof UploadError\n ? { code: err.code, message: err.message }\n : {\n code: \"UNKNOWN\",\n message: err instanceof Error ? err.message : \"Upload failed\",\n };\n setError(e);\n setStatus(\"error\");\n setProgress(null);\n }\n },\n [field.accepts, field.max_size_bytes, field.mode, fieldName, file, isDraft, onChange, props.entityCode, register, unregister, uploadFieldCode, uploadSlotCode],\n );\n\n const onPick = useCallback(() => {\n if (disabled) return;\n fileInputRef.current?.click();\n }, [disabled]);\n\n const onChangeFile = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const f = e.target.files?.[0];\n e.target.value = \"\";\n if (f) void startUpload(f);\n },\n [startUpload],\n );\n\n const handleRemove = useCallback(() => {\n if (file && isDraft(file.id)) {\n void discardFile(file.id).catch(() => {});\n unregister(file.id);\n }\n onChange?.(field.mode === \"array\" ? [] : null);\n }, [file, field.mode, isDraft, onChange, unregister]);\n\n const handleCancel = useCallback(() => {\n if (status === \"uploading\" && abortRef.current) {\n cancelledUploadRef.current = true;\n abortRef.current.abort();\n abortRef.current = null;\n setStatus(\"idle\");\n setProgress(null);\n }\n }, [status]);\n\n const handleDownload = useCallback(() => {\n if (!file) return;\n openEmbedFile(file.id, \"download\", downloadFileURL(file));\n }, [file, openEmbedFile]);\n\n const previewAllowed = file ? canPreviewFile(file) : false;\n const handlePreview = useCallback(() => {\n if (!file || !canPreviewFile(file)) return;\n openEmbedFile(file.id, \"preview\", previewFileURL(file));\n }, [file, openEmbedFile]);\n\n const commitFilename = useCallback(() => {\n if (!file) {\n setEditingName(false);\n return;\n }\n const trimmed = draftName.trim();\n setEditingName(false);\n if (!trimmed || trimmed === file.filename) {\n setDraftName(file.filename);\n return;\n }\n const next = { ...file, filename: trimmed };\n onChange?.(field.mode === \"array\" ? [next] : next);\n }, [draftName, file, onChange, field.mode]);\n\n const isDisplay = mode === \"display\";\n\n // Empty state: show a click/drop-to-upload card.\n if (!file && status !== \"uploading\") {\n return (\n <div\n data-testid={`file-widget-${fieldName}`}\n className=\"flex items-center gap-3 rounded-md border border-dashed border-border bg-surface p-3\"\n >\n <FileIcon />\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-sm text-foreground\">\n {field.display?.placeholder || \"No document attached\"}\n </span>\n {!isDisplay && (\n <button\n type=\"button\"\n className=\"self-start rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={onPick}\n disabled={disabled}\n data-testid=\"upload\"\n >\n Upload\n </button>\n )}\n </div>\n {!isDisplay && (\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept || undefined}\n onChange={onChangeFile}\n style={{ display: \"none\" }}\n data-testid={`file-input-${fieldName}`}\n />\n )}\n {status === \"error\" && error && (\n <div className=\"ml-auto text-xs text-destructive\" role=\"alert\">\n {error.message}\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div\n data-testid={`file-widget-${fieldName}`}\n className=\"flex items-center gap-3 rounded-md border border-border bg-surface p-3\"\n aria-busy={status === \"uploading\" || undefined}\n aria-invalid={status === \"error\" || undefined}\n >\n <FileIcon contentType={file?.content_type} />\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n {editingName && file ? (\n <input\n type=\"text\"\n className=\"rounded-sm border border-border bg-card px-1 py-0.5 text-sm text-foreground\"\n value={draftName}\n autoFocus\n onChange={(e) => setDraftName(e.target.value)}\n onBlur={commitFilename}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commitFilename();\n else if (e.key === \"Escape\") {\n setEditingName(false);\n setDraftName(file.filename);\n }\n }}\n data-testid=\"filename-input\"\n />\n ) : (\n <button\n type=\"button\"\n className=\"truncate text-left text-sm font-medium text-foreground hover:underline\"\n onClick={() => !isDisplay && file && setEditingName(true)}\n disabled={isDisplay || disabled || !file}\n title={file?.filename}\n data-testid=\"filename\"\n >\n {file?.filename ?? \"Uploading…\"}\n </button>\n )}\n <div className=\"flex flex-wrap gap-2 text-xs text-muted-foreground\">\n {file && <span>{formatBytes(file.size_bytes)}</span>}\n {file?.page_count != null && <span>{file.page_count} pages</span>}\n {file?.uploaded_at && <span>{formatDate(file.uploaded_at)}</span>}\n {file?.uploaded_by && <span>by {file.uploaded_by}</span>}\n {file?.version?.number != null && (\n <span data-testid=\"version-badge\">v{file.version.number}</span>\n )}\n </div>\n {status === \"uploading\" && (\n <div\n className=\"text-xs text-muted-foreground\"\n role=\"progressbar\"\n aria-valuenow={progress?.pct ?? 0}\n aria-valuemin={0}\n aria-valuemax={100}\n data-testid=\"upload-progress\"\n >\n Uploading {progress?.pct ?? 0}%\n </div>\n )}\n {status === \"error\" && error && (\n <div className=\"text-xs text-destructive\" role=\"alert\">\n {error.message}\n </div>\n )}\n </div>\n <div className=\"flex flex-none items-center gap-1\">\n {file && status !== \"uploading\" && (\n <>\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={handleDownload}\n data-testid=\"download\"\n >\n Download\n </button>\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2 disabled:cursor-not-allowed disabled:opacity-50\"\n onClick={handlePreview}\n disabled={!previewAllowed}\n title={previewAllowed ? undefined : \"Preview is available only for images and PDFs\"}\n data-testid=\"preview\"\n >\n Preview\n </button>\n {!isDisplay && (\n <>\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={onPick}\n disabled={disabled}\n data-testid=\"replace\"\n >\n Replace\n </button>\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs text-destructive hover:bg-surface-2\"\n onClick={handleRemove}\n disabled={disabled}\n data-testid=\"remove\"\n >\n Remove\n </button>\n </>\n )}\n </>\n )}\n {status === \"uploading\" && (\n <button\n type=\"button\"\n className=\"rounded-sm border border-border bg-card px-2 py-1 text-xs\"\n onClick={handleCancel}\n data-testid=\"cancel-upload\"\n >\n Cancel\n </button>\n )}\n </div>\n {!isDisplay && (\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept || undefined}\n onChange={onChangeFile}\n style={{ display: \"none\" }}\n data-testid={`file-input-${fieldName}`}\n />\n )}\n </div>\n );\n}\n\nfunction formatDate(iso: string): string {\n const d = new Date(iso);\n if (isNaN(d.getTime())) return iso;\n return d.toISOString().slice(0, 10);\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n uploadFile,\n discardFile,\n validateClientSide,\n formatBytes,\n UploadError,\n} from \"./upload\";\nimport { useDraftRegistration } from \"./draft-scope\";\nimport { downloadFileURL } from \"./helpers\";\nimport { useEmbedFileOpener } from \"./useEmbedFileSrc\";\nimport { fileArrayFromValue } from \"./value\";\nimport type {\n FileWidgetProps,\n HydratedFile,\n UploadProgress,\n} from \"./types\";\n\n// FileList widget: vertical list of files with per-row actions. Per einstein\n// §6.6. No thumbnails (use the Grid widget for image galleries). Each row\n// shows a small file-type label, the filename, size + content type, and the\n// Download / Remove actions.\n\ninterface InFlight {\n localId: string;\n filename: string;\n progress: UploadProgress | null;\n error: { code: string; message: string } | null;\n abort: () => void;\n}\n\nfunction shortType(ct: string): string {\n if (!ct) return \"\";\n const after = ct.split(\"/\")[1] ?? ct;\n return after.toUpperCase().slice(0, 6);\n}\n\nexport function FileList(props: FileWidgetProps) {\n const { field, fieldName, value, onChange, mode, disabled } = props;\n const items = fileArrayFromValue(value);\n const [tiles, setTiles] = useState<InFlight[]>([]);\n const { register, unregister, isDraft } = useDraftRegistration();\n const valueRef = useRef<HydratedFile[]>(items);\n valueRef.current = items;\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n const cancelledUploadsRef = useRef<Set<string>>(new Set());\n const tilesRef = useRef<InFlight[]>([]);\n tilesRef.current = tiles;\n // Cookie mode: opens the static download URL directly. Embed mode: resolves\n // the file through the Bearer-authenticated endpoint first, then opens the\n // presigned or `blob:` URL (`window.open` cannot send an auth header).\n const { open: openEmbedFile } = useEmbedFileOpener();\n\n useEffect(() => {\n return () => {\n tilesRef.current.forEach((t) => t.abort());\n };\n }, []);\n\n const accept = (field.accepts ?? []).join(\",\");\n const isDisplay = mode === \"display\";\n\n const startUpload = useCallback(\n async (raw: File) => {\n const v = validateClientSide(raw, field.accepts, field.max_size_bytes);\n const localId = `row-${Math.random().toString(36).slice(2)}-${Date.now()}`;\n const ctrl = new AbortController();\n if (v) {\n setTiles((prev) => [\n ...prev,\n {\n localId,\n filename: raw.name,\n progress: null,\n error: v,\n abort: () => {},\n },\n ]);\n return;\n }\n setTiles((prev) => [\n ...prev,\n {\n localId,\n filename: raw.name,\n progress: { loaded: 0, total: raw.size, pct: 0 },\n error: null,\n abort: () => ctrl.abort(),\n },\n ]);\n try {\n const result = await uploadFile({\n file: raw,\n entityCode: props.entityCode,\n fieldCode: fieldName,\n signal: ctrl.signal,\n onProgress: (p) =>\n setTiles((prev) =>\n prev.map((t) =>\n t.localId === localId ? { ...t, progress: p } : t,\n ),\n ),\n });\n if (cancelledUploadsRef.current.delete(localId)) {\n void discardFile(result.id).catch(() => {});\n unregister(result.id);\n return;\n }\n register(result.id, () => discardFile(result.id));\n const next: HydratedFile = {\n id: result.id,\n filename: result.filename,\n content_type: result.content_type,\n size_bytes: result.size_bytes,\n sha256: result.sha256,\n width: result.width,\n height: result.height,\n url: result.url,\n metadata: result.metadata,\n };\n const merged = [...valueRef.current, next];\n valueRef.current = merged;\n onChange?.(merged);\n setTiles((prev) => prev.filter((t) => t.localId !== localId));\n } catch (err) {\n if (err instanceof UploadError && err.code === \"ABORTED\") {\n setTiles((prev) => prev.filter((t) => t.localId !== localId));\n return;\n }\n const e =\n err instanceof UploadError\n ? { code: err.code, message: err.message }\n : {\n code: \"UNKNOWN\",\n message: err instanceof Error ? err.message : \"Upload failed\",\n };\n setTiles((prev) =>\n prev.map((t) =>\n t.localId === localId\n ? { ...t, error: e, progress: null, abort: () => {} }\n : t,\n ),\n );\n }\n },\n [field.accepts, field.max_size_bytes, fieldName, onChange, props.entityCode, register, unregister],\n );\n\n const handleFiles = useCallback(\n (files: FileList | File[]) => {\n Array.from(files).forEach((f) => void startUpload(f));\n },\n [startUpload],\n );\n\n const onPick = useCallback(() => {\n if (disabled) return;\n fileInputRef.current?.click();\n }, [disabled]);\n\n const onChangeFile = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files;\n e.target.value = \"\";\n if (files && files.length > 0) handleFiles(files);\n },\n [handleFiles],\n );\n\n const handleRemove = useCallback(\n (id: string) => {\n if (isDraft(id)) {\n void discardFile(id).catch(() => {});\n unregister(id);\n }\n onChange?.(items.filter((f) => f.id !== id));\n },\n [isDraft, items, onChange, unregister],\n );\n\n const handleDownload = useCallback(\n (f: HydratedFile) => {\n openEmbedFile(f.id, \"download\", downloadFileURL(f));\n },\n [openEmbedFile],\n );\n\n return (\n <div\n data-testid={`file-widget-${fieldName}`}\n className=\"flex flex-col gap-2\"\n >\n <ul className=\"flex flex-col divide-y divide-divider rounded-md border border-border bg-surface\">\n {items.length === 0 && tiles.length === 0 && (\n <li className=\"px-3 py-4 text-center text-sm text-muted-foreground\">\n {field.display?.placeholder || \"No files\"}\n </li>\n )}\n {items.map((f) => (\n <li\n key={f.id}\n className=\"flex items-center gap-3 px-3 py-2\"\n data-testid={`row-${f.id}`}\n >\n <span className=\"flex-none rounded-sm border border-border bg-surface-3 px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n {shortType(f.content_type)}\n </span>\n <button\n type=\"button\"\n onClick={() => handleDownload(f)}\n className=\"min-w-0 flex-1 truncate text-left text-sm text-foreground hover:underline\"\n title={f.filename}\n >\n {f.filename}\n </button>\n <span className=\"flex-none text-xs text-muted-foreground\">\n {formatBytes(f.size_bytes)}\n </span>\n <button\n type=\"button\"\n className=\"flex-none rounded-sm border border-border bg-card px-2 py-0.5 text-xs text-foreground hover:bg-surface-2\"\n onClick={() => handleDownload(f)}\n data-testid={`download-${f.id}`}\n >\n Download\n </button>\n {!isDisplay && (\n <button\n type=\"button\"\n className=\"flex-none rounded-sm border border-border bg-card px-2 py-0.5 text-xs text-destructive hover:bg-surface-2\"\n onClick={() => handleRemove(f.id)}\n disabled={disabled}\n data-testid={`remove-${f.id}`}\n >\n Remove\n </button>\n )}\n </li>\n ))}\n {tiles.map((t) => (\n <li\n key={t.localId}\n className=\"flex items-center gap-3 px-3 py-2\"\n data-testid={`pending-row-${t.localId}`}\n aria-busy={!t.error}\n aria-invalid={!!t.error || undefined}\n >\n <span className=\"flex-none truncate text-sm text-foreground\" title={t.filename}>\n {t.filename}\n </span>\n <span className=\"flex-1\" />\n {t.error ? (\n <span role=\"alert\" className=\"text-xs text-destructive\">\n {t.error.message}\n </span>\n ) : (\n <span\n className=\"text-xs text-muted-foreground\"\n role=\"progressbar\"\n aria-valuenow={t.progress?.pct ?? 0}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n {t.progress?.pct ?? 0}%\n </span>\n )}\n <button\n type=\"button\"\n className=\"flex-none rounded-sm border border-border bg-card px-2 py-0.5 text-xs\"\n onClick={() => {\n t.abort();\n cancelledUploadsRef.current.add(t.localId);\n setTiles((prev) =>\n prev.filter((x) => x.localId !== t.localId),\n );\n }}\n >\n {t.error ? \"Dismiss\" : \"Cancel\"}\n </button>\n </li>\n ))}\n </ul>\n {!isDisplay && (\n <>\n <button\n type=\"button\"\n className=\"self-start rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2\"\n onClick={onPick}\n disabled={disabled}\n data-testid=\"add-files\"\n >\n Add files\n </button>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept || undefined}\n multiple\n onChange={onChangeFile}\n style={{ display: \"none\" }}\n data-testid={`file-input-${fieldName}`}\n />\n </>\n )}\n </div>\n );\n}\n","import type { FileNamedSlotDef, FileFieldDef, HydratedFile, NamedFileFieldValue } from \"@/types/files\";\nimport type { FileWidgetProps } from \"./types\";\nimport { getFileWidget } from \"./registry\";\n\nfunction asNamedMap(value: FileWidgetProps[\"value\"]): NamedFileFieldValue {\n if (!value || Array.isArray(value) || typeof value !== \"object\") return {};\n return value as NamedFileFieldValue;\n}\n\nfunction humanizeSlot(code: string): string {\n return code\n .split(\"_\")\n .filter(Boolean)\n .map((part) => part.slice(0, 1).toUpperCase() + part.slice(1))\n .join(\" \");\n}\n\nfunction slotLooksLikeImage(slot: FileNamedSlotDef | undefined, file: HydratedFile | null | undefined): boolean {\n if (file?.content_type?.startsWith(\"image/\")) return true;\n return (slot?.accepts ?? []).some((mime) => mime === \"image/*\" || mime.startsWith(\"image/\"));\n}\n\nfunction buildSlotField(field: FileFieldDef, slotCode: string, slot: FileNamedSlotDef | undefined, file: HydratedFile | null | undefined): FileFieldDef {\n return {\n ...field,\n name: `${field.name}.${slotCode}`,\n mode: \"single\",\n accepts: slot?.accepts ?? field.accepts,\n max_size_bytes: slot?.max_size_bytes ?? field.max_size_bytes,\n slots: undefined,\n display: {\n ...(field.display ?? { widget: \"document_card\" }),\n widget: slotLooksLikeImage(slot, file) ? \"square_image\" : \"document_card\",\n aspect_ratio: slot?.aspect_ratio ?? field.display?.aspect_ratio,\n placeholder: field.display?.placeholder ?? humanizeSlot(slotCode),\n },\n };\n}\n\nexport function LabeledSlots(props: FileWidgetProps) {\n const { field, fieldName, entityCode, value, onChange, mode, disabled } = props;\n const slots = Object.entries(field.slots ?? {});\n const values = asNamedMap(value);\n\n if (slots.length === 0) {\n return <span className=\"text-sm text-muted-foreground\">No slots configured</span>;\n }\n\n return (\n <div style={{ display: \"grid\", gap: 12 }}>\n {slots.map(([slotCode, slot]) => {\n const file = values[slotCode] ?? null;\n const slotField = buildSlotField(field, slotCode, slot, file);\n const widgetCode = slotField.display?.widget ?? \"document_card\";\n const Widget = getFileWidget(widgetCode);\n if (!Widget) {\n return (\n <div key={slotCode} style={{ display: \"grid\", gap: 6 }}>\n <div style={{ fontSize: 12, fontWeight: 600, color: \"var(--text-2)\" }}>{humanizeSlot(slotCode)}</div>\n <span className=\"text-sm text-muted-foreground\">{`Unknown file widget: ${widgetCode}`}</span>\n </div>\n );\n }\n return (\n <div key={slotCode} style={{ display: \"grid\", gap: 6 }}>\n <div style={{ fontSize: 12, fontWeight: 600, color: \"var(--text-2)\" }}>{humanizeSlot(slotCode)}</div>\n <Widget\n field={slotField}\n fieldName={slotCode}\n entityCode={entityCode}\n value={file}\n mode={mode}\n disabled={disabled}\n uploadFieldCode={fieldName}\n uploadSlotCode={slotCode}\n onChange={(next) => {\n if (!onChange) return;\n onChange({\n ...values,\n [slotCode]: (next as HydratedFile | null) ?? null,\n });\n }}\n />\n </div>\n );\n })}\n </div>\n );\n}\n","import { registerFileWidget } from \"./registry\";\nimport { SquareImage } from \"./SquareImage\";\nimport { CircleImage } from \"./CircleImage\";\nimport { WideBanner } from \"./WideBanner\";\nimport { GridLazy } from \"./GridLazy\";\nimport { DocumentCard } from \"./DocumentCard\";\nimport { FileList } from \"./FileList\";\nimport { LabeledSlots } from \"./LabeledSlots\";\n\nlet builtinsRegistered = false;\n\nexport function registerBuiltinFileWidgets(): void {\n if (builtinsRegistered) return;\n registerFileWidget(\"square_image\", SquareImage);\n registerFileWidget(\"circle_image\", CircleImage);\n registerFileWidget(\"wide_banner\", WideBanner);\n registerFileWidget(\"grid\", GridLazy);\n registerFileWidget(\"document_card\", DocumentCard);\n registerFileWidget(\"file_list\", FileList);\n registerFileWidget(\"labeled_slots\", LabeledSlots);\n builtinsRegistered = true;\n}\n","import type { ReactNode } from \"react\";\nimport { fieldDisplayName } from \"@/types/schema\";\nimport type { Entity, Screen } from \"@/types/schema\";\nimport type { FileFieldDef, FileFieldValue } from \"@/types/files\";\nimport { renderField } from \"@/components/fields\";\nimport type { RefsMap } from \"@/components/fields\";\nimport { createRichTextValue, richTextMarkdown } from \"@/lib/rich-text\";\nimport { getFileWidget } from \"./registry\";\nimport { registerBuiltinFileWidgets } from \"./builtins\";\n\nregisterBuiltinFileWidgets();\n\nexport function getEntityFileField(\n entity: Pick<Entity, \"files\">,\n fieldName: string,\n): FileFieldDef | undefined {\n return entity.files?.get(fieldName);\n}\n\nexport function getFileFieldValue(\n record: Record<string, unknown>,\n fieldName: string,\n): FileFieldValue {\n if (Object.prototype.hasOwnProperty.call(record, fieldName)) {\n return (record[fieldName] as FileFieldValue) ?? null;\n }\n const files = record.$files as Record<string, FileFieldValue> | undefined;\n return files?.[fieldName] ?? null;\n}\n\nexport function getSchemaFieldValue(\n entity: Pick<Entity, \"fields\" | \"files\">,\n record: Record<string, unknown>,\n fieldName: string,\n): unknown {\n const fileField = getEntityFileField(entity, fieldName);\n if (fileField) return getFileFieldValue(record, fieldName);\n const field = entity.fields.get(fieldName);\n if (field?.type === \"rich_text\" && field.files?.mode === \"rich_text_inline\") {\n return createRichTextValue(record[fieldName], getFileFieldValue(record, fieldName));\n }\n return record[fieldName];\n}\n\nexport function serializeSchemaFieldValue(\n entity: Pick<Entity, \"fields\" | \"files\">,\n fieldName: string,\n value: unknown,\n): unknown {\n const field = entity.fields.get(fieldName);\n if (field?.type === \"rich_text\" && field.files?.mode === \"rich_text_inline\") {\n return richTextMarkdown(value);\n }\n return value;\n}\n\nexport function resolveSchemaFieldLabel(\n entity: Pick<Entity, \"fields\" | \"files\">,\n fieldName: string,\n entities?: Record<string, Entity>,\n): string {\n const fileField = getEntityFileField(entity, fieldName);\n if (fileField) return fileField.name || fieldName;\n const field = entity.fields.get(fieldName);\n return field ? fieldDisplayName(field, fieldName, entities) : fieldName;\n}\n\nexport function renderSchemaField(props: {\n entity: Pick<Entity, \"fields\" | \"files\">;\n entityCode?: string;\n fieldName: string;\n record: Record<string, unknown>;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n refs?: RefsMap;\n disabled?: boolean;\n surface?: \"list\" | \"detail\";\n // 1a.5: schema lookups for the cell registry. Optional - when omitted, the\n // cell registry path falls back gracefully (status_pill loses status group\n // colors, ref_link loses its display label). Detail/QuickPeek pass these via\n // the FieldsBlock LayoutContext.schema. ref_link navigation is owned by the\n // global link interceptor, not threaded here.\n entities?: Record<string, Entity>;\n screens?: Record<string, Screen>;\n // locale: required per plan §3 contract; callers thread it via useUserLocale().\n locale: string;\n // Accessibility (Finding 2): a stable per-field id and the id of its label\n // element. Threaded to field renderers / file widgets so edit-mode inputs\n // pair with their <label>. Optional - omit for standalone display rendering.\n fieldId?: string;\n labelId?: string;\n}): ReactNode {\n const {\n entity,\n entityCode,\n fieldName,\n record,\n mode,\n onChange,\n refs,\n disabled,\n surface,\n entities,\n screens,\n locale,\n fieldId,\n labelId,\n } = props;\n const fileField = getEntityFileField(entity, fieldName);\n if (fileField) {\n const widgetCode = fileField.display?.widget ?? \"\";\n const Widget = getFileWidget(widgetCode);\n if (!Widget) {\n return (\n <span className=\"text-sm text-muted-foreground\">\n {widgetCode ? `Unknown file widget: ${widgetCode}` : \"Missing file widget\"}\n </span>\n );\n }\n return (\n <Widget\n field={fileField}\n fieldName={fieldName}\n entityCode={entityCode}\n value={getFileFieldValue(record, fieldName)}\n mode={mode}\n onChange={onChange}\n disabled={disabled}\n fieldId={fieldId}\n />\n );\n }\n const field = entity.fields.get(fieldName);\n if (!field) return null;\n return renderField({\n field,\n entityCode,\n fieldName,\n value: getSchemaFieldValue(entity, record, fieldName),\n mode,\n onChange,\n record,\n refs,\n surface,\n entity: entityCode && entities ? entities[entityCode] : undefined,\n entities,\n screens,\n locale,\n fieldId,\n labelId,\n });\n}\n","import type { Entity } from \"@/types/schema\";\nimport type { FileFieldDef, FileFieldValue, HydratedFile, NamedFileFieldValue } from \"@/types/files\";\nimport { extractDeclarionFileIds, richTextMarkdown } from \"@/lib/rich-text\";\nimport { getEntityFileField, getFileFieldValue, getSchemaFieldValue } from \"./host\";\n\nexport interface FileSetItem {\n file_id: string;\n filename?: string;\n slot?: string;\n position?: number;\n metadata?: Record<string, unknown>;\n}\n\nexport interface FileFieldPatch {\n clear?: true;\n set?: FileSetItem[];\n}\n\nfunction normalizedSingleValue(value: unknown): HydratedFile | null {\n if (!value || Array.isArray(value)) return null;\n return value as HydratedFile;\n}\n\nfunction normalizedArrayValue(value: unknown): HydratedFile[] {\n if (!Array.isArray(value)) return [];\n return value as HydratedFile[];\n}\n\nfunction normalizedNamedMapValue(value: unknown): NamedFileFieldValue {\n if (!value || Array.isArray(value) || typeof value !== \"object\") return {};\n return value as NamedFileFieldValue;\n}\n\nfunction normalizeFileValue(field: FileFieldDef, value: unknown): FileFieldValue {\n if (field.mode === \"array\") return normalizedArrayValue(value);\n if (field.mode === \"named_map\") return normalizedNamedMapValue(value);\n return normalizedSingleValue(value);\n}\n\nfunction toSetItem(file: HydratedFile, index: number, includePosition: boolean, slot?: string): FileSetItem {\n const item: FileSetItem = { file_id: file.id, filename: file.filename };\n if (slot) item.slot = slot;\n if (includePosition) item.position = index;\n if (file.metadata !== undefined) {\n item.metadata = file.metadata;\n }\n return item;\n}\n\nexport function buildFileFieldPatch(field: FileFieldDef, value: FileFieldValue): FileFieldPatch {\n if (field.mode === \"array\") {\n const files = normalizedArrayValue(value);\n if (files.length === 0) return { clear: true };\n return { set: files.map((file, index) => toSetItem(file, index, true)) };\n }\n if (field.mode === \"named_map\") {\n const slots = normalizedNamedMapValue(value);\n const set = Object.entries(slots)\n .filter(([, file]) => file != null)\n .map(([slot, file]) => toSetItem(file as HydratedFile, 0, false, slot));\n if (set.length === 0) return { clear: true };\n return { set };\n }\n const file = normalizedSingleValue(value);\n if (!file) return { clear: true };\n return { set: [toSetItem(file, 0, true)] };\n}\n\nfunction stablePatchKey(patch: FileFieldPatch): string {\n return JSON.stringify(patch);\n}\n\nexport function buildFilesPayload(opts: {\n entity: Pick<Entity, \"files\"> & Partial<Pick<Entity, \"fields\">>;\n formData: Record<string, unknown>;\n record: Record<string, unknown> | undefined;\n isNew: boolean;\n}): Record<string, FileFieldPatch> {\n const { entity, formData, record, isNew } = opts;\n const payload: Record<string, FileFieldPatch> = {};\n for (const fieldName of entity.files?.names() ?? []) {\n if (!Object.prototype.hasOwnProperty.call(formData, fieldName)) continue;\n const field = getEntityFileField(entity, fieldName);\n if (!field) continue;\n const nextValue = normalizeFileValue(field, formData[fieldName]);\n if (isNew) {\n const isEmpty = field.mode === \"array\"\n ? normalizedArrayValue(nextValue).length === 0\n : field.mode === \"named_map\"\n ? Object.values(normalizedNamedMapValue(nextValue)).every((file) => file == null)\n : normalizedSingleValue(nextValue) == null;\n if (isEmpty) continue;\n payload[fieldName] = buildFileFieldPatch(field, nextValue);\n continue;\n }\n const previousValue = normalizeFileValue(field, record ? getFileFieldValue(record, fieldName) : null);\n const nextPatch = buildFileFieldPatch(field, nextValue);\n const previousPatch = buildFileFieldPatch(field, previousValue);\n if (stablePatchKey(nextPatch) !== stablePatchKey(previousPatch)) {\n payload[fieldName] = nextPatch;\n }\n }\n const fields = entity.fields;\n if (!fields) return payload;\n for (const fieldName of fields.names()) {\n const field = fields.get(fieldName);\n const fileDef = field?.files;\n if (!fileDef || fileDef.mode !== \"rich_text_inline\") continue;\n if (!Object.prototype.hasOwnProperty.call(formData, fieldName)) continue;\n const nextPatch = buildRichTextInlinePatch(fileDef, formData[fieldName]);\n if (isNew) {\n if (nextPatch.clear) continue;\n payload[fieldName] = nextPatch;\n continue;\n }\n const previousPatch = buildRichTextInlinePatch(fileDef, record ? getSchemaFieldValue({ ...entity, fields }, record, fieldName) : null);\n if (stablePatchKey(nextPatch) !== stablePatchKey(previousPatch)) {\n payload[fieldName] = nextPatch;\n }\n }\n return payload;\n}\n\nexport function collectCommittedFileIds(payload: Record<string, FileFieldPatch>): string[] {\n const ids: string[] = [];\n for (const patch of Object.values(payload)) {\n for (const item of patch.set ?? []) ids.push(item.file_id);\n }\n return ids;\n}\n\nfunction buildRichTextInlinePatch(field: FileFieldDef, value: unknown): FileFieldPatch {\n if (field.mode !== \"rich_text_inline\") return { clear: true };\n const ids = extractDeclarionFileIds(richTextMarkdown(value));\n if (ids.length === 0) return { clear: true };\n return {\n set: ids.map((file_id, index) => ({ file_id, position: index })),\n };\n}\n","// Public barrel for the file-widget subsystem. Built-in widgets register\n// themselves into the registry on import (side-effect below); consumer\n// apps can override or add custom widgets via `registerFileWidget`.\n\nimport { registerBuiltinFileWidgets } from \"./builtins\";\n\nregisterBuiltinFileWidgets();\n\nexport { SquareImage } from \"./SquareImage\";\nexport { CircleImage } from \"./CircleImage\";\nexport { WideBanner } from \"./WideBanner\";\nexport { GridLazy as Grid } from \"./GridLazy\";\nexport { DocumentCard } from \"./DocumentCard\";\nexport { FileList } from \"./FileList\";\nexport { LabeledSlots } from \"./LabeledSlots\";\nexport {\n registerFileWidget,\n getFileWidget,\n hasFileWidget,\n __resetFileWidgetRegistryForTests,\n} from \"./registry\";\nexport {\n getEntityFileField,\n getFileFieldValue,\n getSchemaFieldValue,\n serializeSchemaFieldValue,\n resolveSchemaFieldLabel,\n renderSchemaField,\n} from \"./host\";\nexport {\n buildFileFieldPatch,\n buildFilesPayload,\n collectCommittedFileIds,\n} from \"./payload\";\nexport {\n uploadFile,\n discardFile,\n validateClientSide,\n formatBytes,\n UploadError,\n} from \"./upload\";\nexport {\n setImageCropper,\n getImageCropper,\n setCropperRenderer,\n getCropperRenderer,\n} from \"./cropper\";\nexport type {\n ImageCropper,\n CropperOptions,\n CropperResult,\n} from \"./cropper\";\nexport {\n FileDraftScope,\n useFileDraftScope,\n useDraftRegistration,\n} from \"./draft-scope\";\nexport type {\n FileDraftScopeApi,\n DraftEntry,\n} from \"./draft-scope\";\nexport type {\n FileFieldDef,\n FileFieldDisplay,\n FileFieldMode,\n FileWidget,\n FileWidgetProps,\n HydratedFile,\n UploadProgress,\n UploadedFile,\n} from \"./types\";\n","import { useMemo, useRef, useState } from \"react\";\nimport { Btn, Icon, Spinner, TextInput } from \"@/components/primitives\";\nimport { Markdown } from \"@/components/shared/Markdown\";\nimport type { HydratedFile, UploadedFile } from \"@/types/files\";\nimport {\n createRichTextValue,\n extractDeclarionFileIds,\n richTextTokenForFile,\n withoutRichTextFiles,\n withRichTextFile,\n} from \"@/lib/rich-text\";\nimport { discardFile, uploadFile, UploadError, validateClientSide } from \"@/components/file-widgets\";\nimport { useDraftRegistration } from \"@/components/file-widgets\";\nimport type { FieldRendererProps } from \"./index\";\n\nexport function RichTextField(props: FieldRendererProps) {\n const { field, entityCode, fieldName, value, mode, onChange, record, compact, fieldId } = props;\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const previewUrlsRef = useRef<Map<string, string>>(new Map());\n const draftIdsRef = useRef<Set<string>>(new Set());\n const [uploading, setUploading] = useState(0);\n const [error, setError] = useState<string | null>(null);\n const { register, unregister } = useDraftRegistration();\n\n const inlineFilesValue = (record?.$files as Record<string, unknown> | undefined)?.[fieldName];\n const rich = useMemo(\n () => createRichTextValue(value, inlineFilesValue),\n [inlineFilesValue, value],\n );\n const markdown = rich.markdown;\n const accepts = field.files?.accepts;\n const maxBytes = field.files?.max_size_bytes;\n\n const changeValue = (nextMarkdown: string, nextFiles = rich.files) => {\n const referenced = new Set(extractDeclarionFileIds(nextMarkdown));\n const removedDraftIds: string[] = [];\n for (const fileId of draftIdsRef.current) {\n if (!referenced.has(fileId)) removedDraftIds.push(fileId);\n }\n if (removedDraftIds.length > 0) {\n for (const fileId of removedDraftIds) {\n draftIdsRef.current.delete(fileId);\n unregister(fileId);\n void discardFile(fileId).catch(() => {});\n const preview = previewUrlsRef.current.get(fileId);\n if (preview) {\n URL.revokeObjectURL(preview);\n previewUrlsRef.current.delete(fileId);\n }\n }\n onChange?.(withoutRichTextFiles({ markdown: nextMarkdown, files: nextFiles }, removedDraftIds));\n return;\n }\n onChange?.({ markdown: nextMarkdown, files: nextFiles });\n };\n\n const insertToken = (base: { markdown: string; files: Record<string, HydratedFile> }, token: string, file?: HydratedFile) => {\n const el = textareaRef.current;\n const start = el?.selectionStart ?? base.markdown.length;\n const end = el?.selectionEnd ?? base.markdown.length;\n const nextMarkdown = `${base.markdown.slice(0, start)}${token}${base.markdown.slice(end)}`;\n const nextFiles = file ? withRichTextFile(base, file).files : base.files;\n changeValue(nextMarkdown, nextFiles);\n requestAnimationFrame(() => {\n if (!el) return;\n const nextPos = start + token.length;\n el.focus();\n el.setSelectionRange(nextPos, nextPos);\n });\n };\n\n const handleFiles = async (files: FileList | File[]) => {\n if (!entityCode || !field.files) return;\n const queue = Array.from(files);\n if (queue.length === 0) return;\n setError(null);\n setUploading((count) => count + queue.length);\n let current = { markdown, files: rich.files };\n for (const file of queue) {\n const validation = validateClientSide(file, accepts, maxBytes);\n if (validation) {\n setError(validation.message);\n setUploading((count) => count - 1);\n continue;\n }\n try {\n const uploaded = await uploadFile({ file, entityCode, fieldCode: fieldName });\n const previewUrl = file.type.startsWith(\"image/\") ? URL.createObjectURL(file) : undefined;\n if (previewUrl) previewUrlsRef.current.set(uploaded.id, previewUrl);\n const hydrated = uploadedFileToHydrated(uploaded, previewUrl);\n register(uploaded.id, () => discardFile(uploaded.id));\n draftIdsRef.current.add(uploaded.id);\n if (queue.length === 1) {\n const token = withLeadingSpacing(current.markdown, richTextTokenForFile(hydrated));\n insertToken(current, token, hydrated);\n current = withRichTextFile({\n markdown: `${current.markdown}${token}`,\n files: current.files,\n }, hydrated);\n } else {\n const token = withLeadingSpacing(current.markdown, richTextTokenForFile(hydrated));\n current = withRichTextFile({\n markdown: `${current.markdown}${token}`,\n files: current.files,\n }, hydrated);\n changeValue(current.markdown, current.files);\n }\n } catch (err) {\n setError(err instanceof UploadError ? err.message : \"Upload failed\");\n } finally {\n setUploading((count) => count - 1);\n }\n }\n };\n\n if (mode === \"display\") {\n if (!markdown) return <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>—</span>;\n return <Markdown content={markdown} files={rich.files} />;\n }\n\n if (compact) {\n return (\n <TextInput\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n value={markdown}\n onChange={(next) => changeValue(next)}\n />\n );\n }\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 10 }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, flexWrap: \"wrap\" }}>\n <Btn\n kind=\"ghost\"\n size=\"xs\"\n icon={uploading > 0 ? <Spinner size={12} /> : <Icon.plus size={12} />}\n onClick={() => inputRef.current?.click()}\n disabled={!entityCode || !field.files || uploading > 0}\n >\n {uploading > 0 ? \"Uploading…\" : \"Insert file\"}\n </Btn>\n <span style={{ fontSize: 11.5, color: \"var(--text-3)\" }}>\n Stores markdown with inline declarion://file/<id> refs.\n </span>\n {!entityCode && (\n <span style={{ fontSize: 11.5, color: \"var(--warn)\" }}>Inline uploads need entity context.</span>\n )}\n </div>\n <input\n ref={inputRef}\n type=\"file\"\n hidden\n accept={accepts?.join(\",\")}\n multiple\n onChange={(event) => {\n if (event.target.files) void handleFiles(event.target.files);\n event.target.value = \"\";\n }}\n />\n <textarea\n ref={textareaRef}\n id={fieldId}\n name={fieldName}\n aria-required={field.required || undefined}\n value={markdown}\n onChange={(event) => changeValue(event.target.value)}\n onPaste={(event) => {\n const files = Array.from(event.clipboardData.files ?? []).filter((file) => file.size > 0);\n if (files.length === 0) return;\n event.preventDefault();\n void handleFiles(files);\n }}\n onDrop={(event) => {\n const files = Array.from(event.dataTransfer.files ?? []).filter((file) => file.size > 0);\n if (files.length === 0) return;\n event.preventDefault();\n void handleFiles(files);\n }}\n onDragOver={(event) => event.preventDefault()}\n rows={12}\n style={{\n width: \"100%\",\n minHeight: 220,\n border: \"1px solid var(--border)\",\n borderRadius: 8,\n padding: \"10px 12px\",\n lineHeight: 1.5,\n fontFamily: \"inherit\",\n resize: \"vertical\",\n background: \"var(--surface)\",\n color: \"var(--text)\",\n }}\n />\n {error && <div style={{ fontSize: 12, color: \"var(--danger)\" }}>{error}</div>}\n <div style={{ border: \"1px solid var(--border)\", borderRadius: 8, padding: 12, background: \"var(--surface-2)\" }}>\n <div style={{ fontSize: 11.5, color: \"var(--text-3)\", marginBottom: 8 }}>Preview</div>\n {markdown ? (\n <Markdown content={markdown} files={rich.files} />\n ) : (\n <span style={{ fontSize: 12.5, color: \"var(--text-4)\" }}>Empty</span>\n )}\n </div>\n </div>\n );\n}\n\nfunction withLeadingSpacing(markdown: string, token: string): string {\n if (!markdown) return `${token}\\n`;\n if (markdown.endsWith(\"\\n\\n\")) return token;\n if (markdown.endsWith(\"\\n\")) return `\\n${token}`;\n return `\\n\\n${token}`;\n}\n\nfunction uploadedFileToHydrated(uploaded: UploadedFile, previewUrl?: string): HydratedFile {\n return {\n id: uploaded.id,\n filename: uploaded.filename,\n content_type: uploaded.content_type,\n size_bytes: uploaded.size_bytes,\n sha256: uploaded.sha256,\n width: uploaded.width,\n height: uploaded.height,\n metadata: uploaded.metadata,\n url: previewUrl,\n };\n}\n","// text: trivial fallback renderer. Coerces value to string; null/undefined\n// renders an em-dash placeholder consistent with the rest of the SDK.\n//\n// Returns a plain string. The truncation tooltip on overflow:hidden cells is\n// owned by the `<td>` wrapper at the table-component layer (SmartListPage,\n// ChildrenTable), not by this factory. Wrapping every cell in a span here\n// produces 6,000 extra React elements on a 500x12 viewport - see\n// docs/plans/2026-05-09-virtual-list-100k.md §2.\nimport type { CellFactory, CellRenderer } from \"../registry\";\n\nexport const textFactory: CellFactory = (): CellRenderer => {\n return (value) => {\n if (value == null || value === \"\") return \"—\";\n if (typeof value === \"object\") {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n };\n};\n","// bool_pill: renders a colored Pill labeled by display.bool_labels (when set)\n// or a heuristic on the field's display.name / field code.\n//\n// Heuristic (factory time, run once per column):\n// - \"Is X\" / \"Has X\" → true: \"X\", false: \"Not X\" (e.g. \"Is Archived\" → \"Archived\" / \"Active\")\n// - field code \"is_x\" / \"has_x\" → strip prefix and titlecase\n// - otherwise → \"Yes\" / \"No\"\n//\n// True is emerald, false is slate. Authors who need different tones use\n// display.value_map, not bool_pill. We do not produce a third state for null —\n// nullable booleans render as em-dash via the text fallback path that any\n// good list filter avoids by hiding the column.\nimport { Pill } from \"@/components/primitives/Pill\";\nimport { loc } from \"@/types/schema\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nexport const boolPillFactory: CellFactory = (ctx): CellRenderer => {\n const { field, fieldName, locale = \"en\" } = ctx;\n const labels = resolveLabels(field, fieldName, locale);\n\n return (value: unknown): CellOutput => {\n if (value == null) return \"—\";\n const truthy = !!value;\n return (\n <Pill tone={truthy ? \"emerald\" : \"slate\"} size=\"xs\">\n {truthy ? labels.trueLabel : labels.falseLabel}\n </Pill>\n );\n };\n};\n\nfunction resolveLabels(\n field: { display?: { bool_labels?: { true: Record<string,string>; false: Record<string,string> }; name?: Record<string,string> } },\n fieldName: string,\n locale: string,\n): { trueLabel: string; falseLabel: string } {\n if (field.display?.bool_labels) {\n return {\n trueLabel: loc(field.display.bool_labels.true, locale) || \"Yes\",\n falseLabel: loc(field.display.bool_labels.false, locale) || \"No\",\n };\n }\n const dispName = field.display?.name ? loc(field.display.name, locale) : \"\";\n if (dispName.startsWith(\"Is \")) {\n const stem = dispName.slice(3).trim();\n return { trueLabel: stem || \"Yes\", falseLabel: stem ? `Not ${stem}` : \"No\" };\n }\n if (dispName.startsWith(\"Has \")) {\n const stem = dispName.slice(4).trim();\n return { trueLabel: stem || \"Yes\", falseLabel: stem ? `No ${stem}` : \"No\" };\n }\n if (fieldName.startsWith(\"is_\")) {\n const stem = titleCase(fieldName.slice(3));\n return { trueLabel: stem, falseLabel: `Not ${stem}` };\n }\n if (fieldName.startsWith(\"has_\")) {\n const stem = titleCase(fieldName.slice(4));\n return { trueLabel: stem, falseLabel: `No ${stem}` };\n }\n return { trueLabel: \"Yes\", falseLabel: \"No\" };\n}\n\nfunction titleCase(s: string): string {\n return s\n .split(\"_\")\n .map((p) => (p ? p[0].toUpperCase() + p.slice(1) : p))\n .join(\" \");\n}\n","// badge: renders a colored Pill for enum-shaped strings. Color and label are\n// resolved at factory time from (in priority order):\n// 1. display.value_map[code] — explicit author override\n// 2. field.values[].color — inline enum / referenced enum\n// 3. fallback slate, raw value\n//\n// The factory builds a Map<code, {tone, label}> once per column. The cell hot\n// path is one map lookup.\nimport { Pill, type PillTone } from \"@/components/primitives/Pill\";\nimport { loc } from \"@/types/schema\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\ntype LookupEntry = { tone: PillTone; label: string };\n\nconst VALID_TONES: ReadonlySet<PillTone> = new Set([\n \"indigo\", \"emerald\", \"amber\", \"rose\", \"sky\", \"violet\", \"slate\", \"teal\",\n]);\n\nfunction asTone(c?: string): PillTone {\n if (!c) return \"slate\";\n return VALID_TONES.has(c as PillTone) ? (c as PillTone) : \"slate\";\n}\n\nexport const badgeFactory: CellFactory = (ctx): CellRenderer => {\n const { field, locale = \"en\" } = ctx;\n const lookup = new Map<string, LookupEntry>();\n\n // Inline enum / resolved enum values.\n if (field.values) {\n for (const v of field.values) {\n lookup.set(v.code, { tone: asTone(v.color), label: loc(v.name, locale) || v.code });\n }\n }\n // value_map overrides. Color and label override INDEPENDENTLY: omitting\n // `color` keeps the inline-enum color (or slate fallback); omitting `label`\n // keeps the inline-enum label.\n if (field.display?.value_map) {\n for (const [code, entry] of Object.entries(field.display.value_map)) {\n const existing = lookup.get(code);\n const tone = entry.color ? asTone(entry.color) : (existing?.tone ?? \"slate\");\n const overrideLabel = entry.label ? loc(entry.label, locale) : \"\";\n const label = overrideLabel || existing?.label || code;\n lookup.set(code, { tone, label });\n }\n }\n\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const code = String(value);\n const hit = lookup.get(code);\n return (\n <Pill tone={hit?.tone ?? \"slate\"} size=\"xs\">\n {hit?.label ?? code}\n </Pill>\n );\n };\n};\n","// status_pill: renders a colored Pill for fields whose value is a status code\n// from one of the entity's status_groups. Color and label come from the group\n// definition (StatusDef.color, StatusDef.name).\n//\n// Author opts in via display.widget: status_pill on the field. The factory\n// flattens every status_group's statuses into a single Map<code, {tone,\n// label}> at factory time so the hot path is one map lookup.\n//\n// If multiple status groups expose the same code, the LAST one wins (rare;\n// authors should declare disjoint domains).\nimport { Pill, type PillTone } from \"@/components/primitives/Pill\";\nimport { loc } from \"@/types/schema\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\ntype LookupEntry = { tone: PillTone; label: string };\n\nconst VALID_TONES: ReadonlySet<PillTone> = new Set([\n \"indigo\", \"emerald\", \"amber\", \"rose\", \"sky\", \"violet\", \"slate\", \"teal\",\n]);\n\nfunction asTone(c?: string): PillTone {\n if (!c) return \"slate\";\n return VALID_TONES.has(c as PillTone) ? (c as PillTone) : \"slate\";\n}\n\nexport const statusPillFactory: CellFactory = (ctx): CellRenderer => {\n const { entity, locale = \"en\" } = ctx;\n const lookup = new Map<string, LookupEntry>();\n\n if (entity?.status_groups) {\n for (const group of Object.values(entity.status_groups)) {\n for (const status of group.statuses) {\n lookup.set(status.code, {\n tone: asTone(status.color),\n label: loc(status.name, locale) || status.code,\n });\n }\n }\n }\n\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const code = String(value);\n const hit = lookup.get(code);\n return (\n <Pill tone={hit?.tone ?? \"slate\"} size=\"xs\">\n {hit?.label ?? code}\n </Pill>\n );\n };\n};\n","// tag_list: renders array values as a row of Chips. Per-tag color/label via\n// optional display.value_map. The hot path is a single .map(); no per-tag\n// schema lookups beyond the prebuilt value-map.\nimport { Chip } from \"@/components/primitives/Chip\";\nimport { Pill, type PillTone } from \"@/components/primitives/Pill\";\nimport { loc } from \"@/types/schema\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nconst VALID_TONES: ReadonlySet<PillTone> = new Set([\n \"indigo\", \"emerald\", \"amber\", \"rose\", \"sky\", \"violet\", \"slate\", \"teal\",\n]);\n\nfunction asTone(c?: string): PillTone | null {\n if (!c) return null;\n return VALID_TONES.has(c as PillTone) ? (c as PillTone) : null;\n}\n\nexport const tagListFactory: CellFactory = (ctx): CellRenderer => {\n const { field, locale = \"en\" } = ctx;\n type Entry = { label: string; tone: PillTone | null };\n const lookup = new Map<string, Entry>();\n if (field.display?.value_map) {\n for (const [code, entry] of Object.entries(field.display.value_map)) {\n lookup.set(code, {\n label: (entry.label && loc(entry.label, locale)) || code,\n tone: asTone(entry.color),\n });\n }\n }\n\n return (value: unknown): CellOutput => {\n if (!Array.isArray(value) || value.length === 0) return \"—\";\n return (\n <span style={{ display: \"inline-flex\", gap: 4, flexWrap: \"wrap\" }}>\n {value.map((item, idx) => {\n const code = String(item);\n const hit = lookup.get(code);\n if (hit?.tone) {\n return (\n <Pill key={`${code}-${idx}`} tone={hit.tone} size=\"xs\">\n {hit.label}\n </Pill>\n );\n }\n return <Chip key={`${code}-${idx}`}>{hit?.label ?? code}</Chip>;\n })}\n </span>\n );\n };\n};\n","// time_ago: relative phrase for ≤30d, ISO date for older. Hover tooltip shows\n// the absolute offset-aware timestamp.\n//\n// timestamp_full: always shows the absolute offset-aware timestamp. Used when\n// authors set display.widget: timestamp_full to override the smart default.\nimport { formatOffsetTimestamp, formatRelativeOrAbsolute } from \"@/lib/timestamp\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nexport const timeAgoFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const raw = typeof value === \"string\" ? value : String(value);\n const { text, absolute } = formatRelativeOrAbsolute(raw);\n return <span title={absolute}>{text}</span>;\n };\n};\n\nexport const timestampFullFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const raw = typeof value === \"string\" ? value : String(value);\n return formatOffsetTimestamp(raw);\n };\n};\n","// next_run: domain-specific cell for the schedule entity's next_run_at field.\n//\n// Why a custom widget? `time_ago` renders any past timestamp as \"X ago\",\n// which for a SCHEDULER's next-run field reads as failure (\"we missed it\"),\n// when in reality cron schedules whose tick interval is non-zero will\n// briefly show next_run_at in the past — between the cron boundary firing\n// and the scheduler's next claim tick. That's the expected operating state,\n// not a problem. Surfacing it as \"X ago\" produces a constant stream of\n// false-alarm reads in production dashboards.\n//\n// State mapping (same approach as Oracle EM Scheduler / SAP CCMS / Quartz):\n// - future → \"in Xs\" (no badge)\n// - past, ≤ 60s ago → \"due\" (slate badge — about to fire)\n// - past, ≤ 5m ago → \"overdue Xs\" (amber badge — scheduler may be slow)\n// - past, > 5m ago → \"overdue Xm\" (rose badge — likely real problem)\n// - empty / unparsed → \"—\"\n//\n// Threshold rationale: 60s = 2× default scheduler tick interval (30s) so\n// the \"due\" window covers any tick alignment. 5m = scheduler's stale-lock\n// recovery threshold; past that, recoverStaleLocks should have re-armed\n// the row, so persistent overdue is a real signal worth flagging.\n//\n// `is_running`, `enabled`, `last_error` have their own columns; this cell\n// only interprets next_run_at. The hover tooltip carries the absolute\n// offset-aware timestamp so operators can read the literal value when\n// debugging timezone or cron-expression issues.\n\nimport { Pill } from \"@/components/primitives/Pill\";\nimport { formatOffsetTimestamp } from \"@/lib/timestamp\";\nimport { formatDistanceStrict } from \"date-fns\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nconst DUE_WINDOW_MS = 60 * 1000; // one-tick alignment buffer (default tick = 30s)\nconst OVERDUE_WARN_MS = 5 * 60 * 1000; // matches scheduler stale-lock threshold\n\nexport const nextRunFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const raw = typeof value === \"string\" ? value : String(value);\n const date = new Date(raw);\n if (isNaN(date.getTime())) return raw;\n\n const absolute = formatOffsetTimestamp(raw);\n const ageMs = Date.now() - date.getTime();\n\n if (ageMs <= 0) {\n // Future — render as \"in X\" with the absolute timestamp on hover.\n const distance = formatDistanceStrict(date, new Date(), { addSuffix: false });\n return <span title={absolute}>in {distance}</span>;\n }\n\n if (ageMs <= DUE_WINDOW_MS) {\n return (\n <span title={absolute}>\n <Pill tone=\"slate\" size=\"xs\">due</Pill>\n </span>\n );\n }\n\n const distance = formatDistanceStrict(date, new Date(), { addSuffix: false });\n const tone = ageMs <= OVERDUE_WARN_MS ? \"amber\" : \"rose\";\n return (\n <span title={absolute}>\n <Pill tone={tone} size=\"xs\">overdue {distance}</Pill>\n </span>\n );\n };\n};\n","// money: currency-aware Intl.NumberFormat. Currency comes from\n// field.display.currency_field on the row when present, otherwise from\n// field.display.currency, then USD. Fraction digits derive from field.scale\n// (set on the typedef, e.g. money has scale: 4) and clamp to [0, 6].\nimport type { CellFactory, CellRenderer } from \"../registry\";\n\nexport const moneyFactory: CellFactory = (ctx): CellRenderer => {\n\tconst { field, locale = \"en\" } = ctx;\n\tconst staticCurrency = field.display?.currency || \"USD\";\n\tconst currencyField = field.display?.currency_field;\n\tconst currencyDisplay = normalizeCurrencyDisplay(\n\t\tfield.display?.currency_display,\n\t);\n\tconst scale = clamp(typeof field.scale === \"number\" ? field.scale : 2, 0, 6);\n\tconst formatterCache = new Map<string, Intl.NumberFormat>();\n\n\treturn (value: unknown, record = {}) => {\n\t\tif (value == null || value === \"\") return \"—\";\n\t\tconst n = typeof value === \"number\" ? value : Number(value);\n\t\tif (!Number.isFinite(n)) return String(value);\n\t\tconst rowCurrency = currencyField ? record[currencyField] : undefined;\n\t\tconst currency =\n\t\t\ttypeof rowCurrency === \"string\" && rowCurrency !== \"\"\n\t\t\t\t? rowCurrency\n\t\t\t\t: staticCurrency;\n\t\tconst cacheKey = `${locale}:${currency}:${currencyDisplay}:${scale}`;\n\t\tlet formatter = formatterCache.get(cacheKey);\n\t\tif (!formatter) {\n\t\t\tformatter = new Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency,\n\t\t\t\tcurrencyDisplay,\n\t\t\t\tminimumFractionDigits: scale,\n\t\t\t\tmaximumFractionDigits: scale,\n\t\t\t});\n\t\t\tformatterCache.set(cacheKey, formatter);\n\t\t}\n\t\treturn formatter.format(n);\n\t};\n};\n\nfunction normalizeCurrencyDisplay(\n\tvalue: unknown,\n): \"symbol\" | \"narrowSymbol\" | \"code\" | \"name\" {\n\tswitch (value) {\n\t\tcase \"narrow_symbol\":\n\t\t\treturn \"narrowSymbol\";\n\t\tcase \"code\":\n\t\tcase \"name\":\n\t\tcase \"symbol\":\n\t\t\treturn value;\n\t\tdefault:\n\t\t\treturn \"symbol\";\n\t}\n}\n\nfunction clamp(n: number, lo: number, hi: number): number {\n\tif (n < lo) return lo;\n\tif (n > hi) return hi;\n\treturn n;\n}\n","// ref_link: renders a foreign-key value as a link to the target entity's\n// canonical detail page. Display value comes from the row's `$refs` map\n// (server-rendered, includes the display.template result), or falls back to\n// the resolved display field, or the raw FK if neither is available.\n//\n// Two surfaces:\n// - list → an underlined inline link, compact for a dense table cell.\n// - detail → a bordered, navigable entity chip (icon + label) per the\n// design brief §9 (\"refs as entity chips, navigable\").\n//\n// Navigation: the link is a PLAIN real `<a href>` carrying the canonical\n// standalone detail route. It owns no click handler - the global link\n// interceptor (mounted in Layout) catches the plain left-click and routes it\n// through the embed navigation chokepoint, so the link stays embedded in an\n// iframe and SPA-navigates standalone, while copy-link / new-tab / middle-click\n// keep working natively off the real href. This is uniform with every other\n// anchor in the app (including markdown), which is what makes the embed\n// boundary total - a cell can no longer forget to wire navigation.\n//\n// All schema lookups (target entity, detail screen, route, display field,\n// entity icon) happen at factory time. The render path is pure.\nimport { resolveRefRecordLabel } from \"@/types/schema\";\nimport { DynamicIcon } from \"@/components/shared/DynamicIcon\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nexport const refLinkFactory: CellFactory = (ctx): CellRenderer => {\n const { field, entities, screens, refs, surface } = ctx;\n const refEntityCode = field.ref?.entity;\n const targetEntity = refEntityCode ? entities?.[refEntityCode] : undefined;\n const getRefs = typeof refs === \"function\" ? refs : () => refs;\n const isDetail = surface === \"detail\";\n const iconName = targetEntity?.display?.icon;\n\n // Resolve display field for the target entity (priority: field-level\n // override → ref.display.field → entity.display.display_field).\n const displayField =\n field.display?.ref_display_field ??\n field.ref?.display?.field ??\n targetEntity?.display?.display_field;\n\n // Resolve href template once per column.\n const detailScreenCode = targetEntity?.detail_screen;\n const detailScreen = detailScreenCode ? screens?.[detailScreenCode] : undefined;\n const route = detailScreen?.route;\n\n return (value: unknown, _record: RowRecord): CellOutput => {\n if (value == null || value === \"\") return \"—\";\n const raw = String(value);\n const display = resolveDisplayString(raw, refEntityCode, getRefs(), displayField);\n const href = route ? route.replace(\":id\", encodeURIComponent(raw)) : undefined;\n\n // Detail surface: a bordered entity chip - icon + label, navigable.\n if (isDetail) {\n const inner = (\n <>\n {iconName && (\n <span style={{ color: \"var(--text-3)\", display: \"flex\", flexShrink: 0 }}>\n <DynamicIcon name={iconName} size={13} />\n </span>\n )}\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>\n {display}\n </span>\n </>\n );\n // Plan §9: every link factory MUST emit `rel=\"noopener noreferrer\"`.\n if (href) {\n return (\n <a href={href} rel=\"noopener noreferrer\" className=\"detail-ref-chip\">\n {inner}\n </a>\n );\n }\n return <span className=\"detail-ref-chip\">{inner}</span>;\n }\n\n // List surface: compact underlined link.\n if (!href) return display;\n return (\n <a\n href={href}\n rel=\"noopener noreferrer\"\n style={{ color: \"inherit\", textDecoration: \"underline\", textUnderlineOffset: 2 }}\n >\n {display}\n </a>\n );\n };\n};\n\ntype RowRecord = Record<string, unknown>;\ntype RefsMap = Record<string, Record<string, Record<string, unknown>>>;\n\n// resolveDisplayString looks the FK value up in the request's $refs payload\n// and resolves the embedded record to a label via the shared\n// resolveRefRecordLabel (types/schema.ts). Returns the raw FK when the ref\n// is not embedded.\nfunction resolveDisplayString(\n raw: string,\n refEntityCode: string | undefined,\n refsRoot: RefsMap | undefined,\n displayField: string | undefined,\n): string {\n const refRecord =\n refEntityCode && refsRoot ? refsRoot[refEntityCode]?.[raw] : undefined;\n return refRecord ? resolveRefRecordLabel(refRecord, displayField, raw) : raw;\n}\n","// URL parsing/normalization helpers extracted from the legacy UrlField.\n// Used by the `url` cell factory and (via re-export) by `UrlInput`.\n//\n// Contract: pure functions, no DOM, no side effects. Safe to call from\n// factory build time or per-cell render.\n\nconst SAFE_PROTOCOLS = /^(https?|ftps?|ssh|mailto|tel):/i;\nexport const LONG_TLD = /^(info|name|tech|site|cloud|online|store|shop|blog|space|world|link|live|page|zone|life|team|work|host|land|news|wiki|mobi|coop|aero|asia)$/i;\n\nfunction looksLikeTLD(label: string): boolean {\n return /^[a-z]{2,3}$/i.test(label) || LONG_TLD.test(label);\n}\n\nexport function looksLikeHostname(candidate: string): boolean {\n if (!candidate.includes(\".\")) return false;\n const labels = candidate.split(\".\");\n if (labels.length < 3) return true;\n const first = labels[0].toLowerCase();\n if (/^(com|org|net|edu|gov)$/.test(first)) return false;\n if (/^(io|app|dev)$/.test(first)) {\n return looksLikeTLD(labels[labels.length - 1]);\n }\n return true;\n}\n\nexport function normalizeUrl(raw: string): string | null {\n if (SAFE_PROTOCOLS.test(raw)) return raw;\n const schemeMatch = raw.match(/^([a-z][a-z0-9+.-]*):/i);\n if (schemeMatch) {\n const scheme = schemeMatch[1];\n const afterColon = raw.slice(schemeMatch[0].length);\n if (/^\\d+([/?#]|$)/.test(afterColon) && looksLikeHostname(scheme)) {\n const port = parseInt(afterColon, 10);\n if (port >= 1 && port <= 65535) return `https://${raw}`;\n }\n if (scheme.toLowerCase() === \"localhost\") return `https://${raw}`;\n return null;\n }\n return `https://${raw}`;\n}\n\nexport function parseDomain(href: string): string | null {\n try {\n const hostname = new URL(href).hostname.replace(/^www\\./i, \"\");\n return hostname || null;\n } catch {\n return null;\n }\n}\n\n/**\n * LinkedIn is the only host we special-case. Recognized path prefixes\n * `/in/<slug>`, `/company/<slug>`, `/school/<slug>` render as `<prefix>/<slug>`.\n * Any other linkedin.com URL (feed, jobs, posts, bare host) falls through to\n * the default hostname rendering.\n */\nexport function linkedinLabel(href: string, domain: string): string | null {\n if (domain !== \"linkedin.com\") return null;\n try {\n const m = new URL(href).pathname.match(/^\\/(in|company|school)\\/([^/]+)/i);\n if (m) return `${m[1].toLowerCase()}/${decodeURIComponent(m[2])}`;\n } catch {\n // fall through\n }\n return null;\n}\n\nexport function isValidUrl(href: string): boolean {\n try {\n new URL(href);\n return true;\n } catch {\n return false;\n }\n}\n","// Inline-SVG host icons + configurable favicon fallback for unknown hosts.\n//\n// Curated brand SVGs always render for the well-known host set\n// (linkedin/github/x/youtube/gmail/slack/notion). Anything else routes\n// through `HostIcon`, which honors the `ui_favicon_source` user/tenant\n// parameter and falls back to a generic globe SVG on load failure.\n//\n// Source modes (see core_parameters.yaml `ui_favicon_source`):\n// google = www.google.com/s2/favicons (sharp; leaks host to Google)\n// direct = https://<host>/favicon.ico (no third party; leaks user IP\n// to each host and misses sites that only declare the icon\n// in <link>)\n// none = generic globe SVG (no external fetch)\n//\n// Adding a new well-known brand: extend the inline-SVG set below and\n// add the canonical (after-www) hostname to HOST_ICONS.\nimport { useEffect, useState, type FC, type SVGProps } from \"react\";\nimport { useAppearanceStore, type FaviconSource } from \"@/stores/appearance\";\n\ntype IconFC = FC<SVGProps<SVGSVGElement>>;\n\n// All icons share the same 16x16 box and inherit currentColor for stroke/fill\n// where applicable. Brand-colored fills are baked in for legibility.\nfunction svg(child: React.ReactNode, viewBox = \"0 0 24 24\"): IconFC {\n const Component: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox={viewBox}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n {child}\n </svg>\n );\n return Component;\n}\n\n// Generic globe (fallback for unknown hosts when source = \"none\" or when\n// an external favicon fetch fails).\nconst Globe = svg(\n <>\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M3 12h18M12 3c3 3 3 15 0 18-3-3-3-15 0-18\" />\n </>,\n);\n\n// linkedin.com\nconst LinkedIn: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"#0A66C2\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M20.45 20.45h-3.55v-5.57c0-1.33-.02-3.04-1.85-3.04-1.85 0-2.13 1.45-2.13 2.94v5.67H9.36V9h3.41v1.56h.05c.48-.9 1.64-1.85 3.37-1.85 3.6 0 4.27 2.37 4.27 5.46v6.28zM5.34 7.43a2.06 2.06 0 1 1 0-4.12 2.06 2.06 0 0 1 0 4.12zM7.12 20.45H3.56V9h3.56v11.45zM22.22 0H1.77C.79 0 0 .77 0 1.72v20.56C0 23.23.79 24 1.77 24h20.45c.98 0 1.78-.77 1.78-1.72V1.72C24 .77 23.2 0 22.22 0z\" />\n </svg>\n);\n\n// github.com\nconst GitHub: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M12 .5a11.5 11.5 0 0 0-3.64 22.41c.58.1.79-.25.79-.56 0-.27-.01-1-.02-1.96-3.21.7-3.89-1.55-3.89-1.55-.52-1.34-1.28-1.7-1.28-1.7-1.05-.72.08-.7.08-.7 1.16.08 1.77 1.2 1.77 1.2 1.03 1.77 2.71 1.26 3.37.96.1-.75.4-1.26.73-1.55-2.56-.29-5.26-1.28-5.26-5.71 0-1.26.45-2.3 1.19-3.11-.12-.29-.52-1.46.11-3.05 0 0 .97-.31 3.18 1.19a11.05 11.05 0 0 1 5.79 0c2.21-1.5 3.18-1.19 3.18-1.19.63 1.59.23 2.76.11 3.05.74.81 1.19 1.85 1.19 3.11 0 4.44-2.71 5.42-5.29 5.7.41.36.78 1.07.78 2.16 0 1.56-.01 2.81-.01 3.19 0 .31.21.68.8.56A11.5 11.5 0 0 0 12 .5z\" />\n </svg>\n);\n\n// x.com / twitter.com\nconst X: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M18.244 2H21.5l-7.62 8.71L23 22h-7.05l-5.52-7.21L4.07 22H.81l8.18-9.34L1 2h7.22l5 6.59L18.244 2zm-2.47 18h1.95L7.32 4h-2.1l10.55 16z\" />\n </svg>\n);\n\n// youtube.com\nconst YouTube: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"#FF0000\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M23.5 6.2a3 3 0 0 0-2.1-2.1C19.5 3.6 12 3.6 12 3.6s-7.5 0-9.4.5A3 3 0 0 0 .5 6.2C0 8.1 0 12 0 12s0 3.9.5 5.8a3 3 0 0 0 2.1 2.1c1.9.5 9.4.5 9.4.5s7.5 0 9.4-.5a3 3 0 0 0 2.1-2.1c.5-1.9.5-5.8.5-5.8s0-3.9-.5-5.8zM9.6 15.6V8.4l6.2 3.6-6.2 3.6z\" />\n </svg>\n);\n\n// gmail / mail.google.com\nconst Gmail: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"#EA4335\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M24 5.45v13.1A1.45 1.45 0 0 1 22.55 20H19.5V9.27L12 14.7 4.5 9.27V20H1.45A1.45 1.45 0 0 1 0 18.55V5.45A1.45 1.45 0 0 1 1.45 4h.5l10.05 7.27L22.05 4h.5A1.45 1.45 0 0 1 24 5.45z\" />\n </svg>\n);\n\n// slack.com\nconst Slack: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path fill=\"#E01E5A\" d=\"M5.04 15.12a2.52 2.52 0 1 1-2.52-2.52h2.52v2.52zm1.27 0a2.52 2.52 0 1 1 5.04 0v6.32a2.52 2.52 0 1 1-5.04 0v-6.32z\" />\n <path fill=\"#36C5F0\" d=\"M8.83 5.04a2.52 2.52 0 1 1 2.52-2.52v2.52H8.83zm0 1.27a2.52 2.52 0 1 1 0 5.04H2.52a2.52 2.52 0 1 1 0-5.04h6.31z\" />\n <path fill=\"#2EB67D\" d=\"M18.96 8.83a2.52 2.52 0 1 1 2.52 2.52h-2.52V8.83zm-1.27 0a2.52 2.52 0 1 1-5.04 0V2.52a2.52 2.52 0 1 1 5.04 0v6.31z\" />\n <path fill=\"#ECB22E\" d=\"M15.17 18.96a2.52 2.52 0 1 1-2.52 2.52v-2.52h2.52zm0-1.27a2.52 2.52 0 1 1 0-5.04h6.31a2.52 2.52 0 1 1 0 5.04h-6.31z\" />\n </svg>\n);\n\n// notion.so / notion.com\nconst Notion: IconFC = (props) => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n {...props}\n >\n <path d=\"M4.46 3.83 14.94 3a3.7 3.7 0 0 1 2.5.62l3 2.16a1.4 1.4 0 0 1 .56 1.31v13.06a1.7 1.7 0 0 1-1.66 1.7l-12.5.78a2.4 2.4 0 0 1-1.85-.62L2.5 19.7a1.7 1.7 0 0 1-.5-1.2V5.16c0-.74.6-1.27 1.46-1.33l1-.01zm.46 1.86c-.31 0-.46.16-.46.47v12.25c0 .31.16.47.46.47l11.62-.7c.31 0 .46-.16.46-.47V6c0-.32-.16-.47-.46-.47L4.92 5.7zm5.57 2.32c.16 0 .31.16.31.31v.46l3.7.23c.31 0 .46.16.46.47v8.32c0 .31-.16.47-.46.47l-3.7.23c-.31 0-.46-.16-.46-.47V8.78c0-.16.15-.32.15-.46l-.04-.31z\" />\n </svg>\n);\n\n// Map of canonical domain -> icon component. Lookup keys are after-www\n// hostnames (parseDomain strips the leading www.).\nconst HOST_ICONS: Record<string, IconFC> = {\n \"linkedin.com\": LinkedIn,\n \"github.com\": GitHub,\n \"x.com\": X,\n \"twitter.com\": X,\n \"youtube.com\": YouTube,\n \"youtu.be\": YouTube,\n \"gmail.com\": Gmail,\n \"mail.google.com\": Gmail,\n \"slack.com\": Slack,\n \"notion.so\": Notion,\n \"notion.com\": Notion,\n};\n\n// Build the external favicon URL for a host given the active source mode.\n// Returns null when the source is \"none\" or the host is empty (callers\n// fall back to the generic globe).\nfunction externalFaviconUrl(domain: string, source: FaviconSource): string | null {\n if (!domain || source === \"none\") return null;\n if (source === \"google\") {\n return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=32`;\n }\n // direct: load /favicon.ico from the origin. Misses sites that only\n // declare the icon via <link rel=\"icon\">; the onError fallback covers it.\n return `https://${domain}/favicon.ico`;\n}\n\nconst ICON_BOX_STYLE: React.CSSProperties = {\n width: 16,\n height: 16,\n flexShrink: 0,\n objectFit: \"contain\",\n};\n\nexport interface HostIconProps {\n /** Canonical (after-www) hostname; pass null/empty to render the globe. */\n domain: string | null | undefined;\n}\n\n// HostIcon is the public renderer used by URL cells. For known brands it\n// returns the inline SVG. For unknown hosts it renders an <img> per the\n// `ui_favicon_source` setting and gracefully falls back to the globe on\n// load failure (no image at the URL, network error, blocked, etc).\nexport function HostIcon({ domain }: HostIconProps): React.ReactElement {\n const source = useAppearanceStore((s) => s.faviconSource);\n const key = domain ? domain.toLowerCase() : \"\";\n const Curated = key ? HOST_ICONS[key] : undefined;\n if (Curated) return <Curated />;\n\n const url = externalFaviconUrl(key, source);\n if (!url) return <Globe />;\n return <FaviconImg src={url} />;\n}\n\n// FaviconImg renders an <img> and reverts to the globe on error. Resets\n// state when src changes (column re-renders with a different host).\nfunction FaviconImg({ src }: { src: string }): React.ReactElement {\n const [failed, setFailed] = useState(false);\n useEffect(() => { setFailed(false); }, [src]);\n if (failed) return <Globe />;\n return (\n <img\n src={src}\n alt=\"\"\n width={16}\n height={16}\n loading=\"lazy\"\n decoding=\"async\"\n referrerPolicy=\"no-referrer\"\n style={ICON_BOX_STYLE}\n onError={() => setFailed(true)}\n />\n );\n}\n\nexport const GENERIC_GLOBE = Globe;\n","// The one empty-value token for cell renderers.\n//\n// The design brief mandates a single shared empty marker so every blank cell\n// reads identically - a muted em-dash in the `var(--text-4)` tone. Before this\n// the same `{ fontSize: 12.5, color: var(--text-4) }` style object was\n// copy-pasted into eight factory files, and one (richTextPreview) had drifted\n// to a plain hyphen. Import EMPTY_CELL instead of re-declaring it.\n//\n// passwordMask keeps its own \"Not set\" italic marker on purpose - an unset\n// secret is a distinct state, not a blank value.\n\nimport type { ReactElement } from \"react\";\n\nconst EMPTY_STYLE = { fontSize: 12.5, color: \"var(--text-4)\" } as const;\n\n// EMPTY_CELL is a static element; React reconciles it per cell location, so\n// one shared instance is safe and avoids a per-cell allocation.\nexport const EMPTY_CELL: ReactElement = <span style={EMPTY_STYLE}>—</span>;\n","// url: anchor with safe-protocol normalization, hostname label (with LinkedIn\n// slug special-case), and host icon. Curated brands (linkedin/github/x/...)\n// always render an inline SVG. Other hosts honor the `ui_favicon_source`\n// param (see HostIcon).\n//\n// `link` widget shares this factory's normalization but renders the full URL\n// as the label and skips the host icon. See linkFactory.\nimport { Icon } from \"@/components/primitives\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport {\n isValidUrl,\n linkedinLabel,\n normalizeUrl,\n parseDomain,\n} from \"./url-helpers\";\nimport { HostIcon } from \"./host-icons\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst ANCHOR_STYLE = {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n fontSize: 12.5,\n color: \"var(--accent)\",\n textDecoration: \"none\",\n} as const;\n\nconst PLAIN_STYLE = { fontSize: 12.5 } as const;\n\nexport const urlFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n const str = value == null ? \"\" : String(value);\n if (!str) return EMPTY_CELL;\n\n const href = normalizeUrl(str);\n if (href == null || !isValidUrl(href)) {\n return <span style={PLAIN_STYLE}>{str}</span>;\n }\n\n const domain = parseDomain(href);\n const linkText = linkedinLabel(href, domain ?? \"\") ?? domain ?? str;\n\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title={str}\n className=\"mono\"\n style={ANCHOR_STYLE}\n >\n <HostIcon domain={domain} />\n {linkText}\n <Icon.external size={11} />\n </a>\n );\n };\n};\n","// email: mailto anchor on the raw value. Display-mode only; edit affordance\n// is owned by `editRegistry[email]`.\n//\n// Parity contract with legacy EmailField.tsx:7-18: byte-equivalent output for\n// the same inputs (asserted by the snapshot test). Notably the raw value is\n// preserved verbatim — a \"mailto:foo@bar.com\" input therefore produces\n// href=\"mailto:mailto:foo@bar.com\". Any change is a separate product plan.\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst ANCHOR_STYLE = {\n fontSize: 12.5,\n color: \"var(--accent)\",\n textDecoration: \"none\",\n} as const;\n\nexport const emailFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n const str = value == null ? \"\" : String(value);\n if (!str) return EMPTY_CELL;\n return (\n <a href={`mailto:${str}`} className=\"mono\" style={ANCHOR_STYLE}>\n {str}\n </a>\n );\n };\n};\n","// phone: safe `tel:` link wrapping the raw value. No national formatting in\n// v1 — the platform has no per-field country/region metadata, and current UI\n// treats phone as plain text. Region-metadata-driven formatting is a separate\n// plan (see plan §4).\n//\n// On values that contain characters not safe for a tel: scheme (anything\n// outside [+0-9 ()-.]), the factory falls back to plain text — this is the\n// \"parse failure\" path called out in plan §4.\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst ANCHOR_STYLE = {\n fontSize: 12.5,\n color: \"var(--accent)\",\n textDecoration: \"none\",\n} as const;\n\nconst PLAIN_STYLE = { fontSize: 12.5 } as const;\n\n// Tel-safe characters per RFC 3966's visual-separator/global-number subset.\n// Also tolerate trailing/leading whitespace; we trim before checking.\nconst TEL_SAFE = /^[+()\\-.\\s\\d]+$/;\n\nexport const phoneFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n const str = value == null ? \"\" : String(value);\n if (!str) return EMPTY_CELL;\n\n const trimmed = str.trim();\n if (!TEL_SAFE.test(trimmed)) {\n return <span style={PLAIN_STYLE}>{str}</span>;\n }\n\n // Strip whitespace for the tel: target, keep raw label for display.\n const tel = trimmed.replace(/\\s+/g, \"\");\n return (\n <a href={`tel:${tel}`} className=\"mono\" style={ANCHOR_STYLE}>\n {str}\n </a>\n );\n };\n};\n","// number: locale-aware numeric formatter. Mirrors the legacy NumberField\n// display branch.\n//\n// String-backed decimals are formatted exactly: trailing zeros preserved,\n// fractional part copied verbatim, never coerced through JS Number (which\n// would lose precision for values past 2^53). Native numeric (int/float) and\n// non-string decimals format through Intl.NumberFormat using the resolved\n// locale.\n//\n// Unit suffix follows the legacy precedence: per-row $units override → static\n// field.unit (display preferred over storage; suppressed when it starts with\n// \"$\" because that range belongs to money widgets). Locale defaults to \"en\"\n// when not provided.\nimport type { CellFactory, CellRenderer, CellOutput, RowRecord } from \"../registry\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst VALUE_STYLE = {\n fontSize: 12.5,\n fontVariantNumeric: \"tabular-nums\" as const,\n};\nconst UNIT_STYLE = { color: \"var(--text-3)\", marginLeft: 4 } as const;\nconst PLAIN_STYLE = { fontSize: 12.5 } as const;\n\nfunction formatDecimalString(value: string, formatter: Intl.NumberFormat): string {\n const trimmed = value.trim();\n if (trimmed === \"\" || trimmed === \"-\") return trimmed;\n\n const negative = trimmed.startsWith(\"-\");\n const abs = negative ? trimmed.slice(1) : trimmed;\n const [intPart, fracPart] = abs.split(\".\");\n\n let formattedInt: string;\n try {\n formattedInt = formatter.format(BigInt(intPart || \"0\"));\n } catch {\n return value;\n }\n\n let result = negative ? `-${formattedInt}` : formattedInt;\n if (fracPart !== undefined) result += `.${fracPart}`;\n return result;\n}\n\nexport const numberFactory: CellFactory = (ctx): CellRenderer => {\n const { field, fieldName, locale = \"en\" } = ctx;\n // Build the formatter once per column. Decimal-string formatting only uses\n // it for the integer portion, so default options are fine.\n const formatter = new Intl.NumberFormat(locale);\n const isDecimal = field.type === \"decimal\";\n const staticUnit = field.unit ? field.unit.display || field.unit.storage : undefined;\n\n return (value: unknown, record: RowRecord): CellOutput => {\n if (value == null) return EMPTY_CELL;\n\n const units = record[\"$units\"] as Record<string, string> | undefined;\n const unitSuffix = units?.[fieldName];\n const displayUnit =\n unitSuffix || (staticUnit && !staticUnit.startsWith(\"$\") ? staticUnit : undefined);\n\n let formatted: string | null;\n if (isDecimal && typeof value === \"string\") {\n formatted = formatDecimalString(value, formatter);\n } else {\n const num = typeof value === \"number\" ? value : Number(value);\n formatted = Number.isFinite(num) ? formatter.format(num) : null;\n }\n\n if (formatted == null) return <span style={PLAIN_STYLE}>—</span>;\n\n return (\n <span className=\"num\" style={VALUE_STYLE}>\n {formatted}\n {displayUnit && <span style={UNIT_STYLE}>{displayUnit}</span>}\n </span>\n );\n };\n};\n","// code: wraps the value in a <code> element and applies the SDK's \"mono\"\n// utility so the typeface lines up with other code-shaped affordances\n// (UrlField hostnames, ref_link IDs, tag chips). Styling delegated to the\n// existing class so theme tokens stay the source of truth.\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst CODE_STYLE = { fontSize: 12.5 } as const;\n\nexport const codeFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n if (value == null || value === \"\") return EMPTY_CELL;\n return (\n <code className=\"mono\" style={CODE_STYLE}>\n {String(value)}\n </code>\n );\n };\n};\n","// link: bare anchor for URLs that the author wants rendered verbatim (full\n// URL as label, no host icon, no LinkedIn slug rewrite). Safe-protocol check\n// shared with the `url` factory via normalizeUrl. Used by widget: link.\nimport { Icon } from \"@/components/primitives\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { isValidUrl, normalizeUrl } from \"./url-helpers\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst ANCHOR_STYLE = {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n fontSize: 12.5,\n color: \"var(--accent)\",\n textDecoration: \"none\",\n} as const;\n\nconst PLAIN_STYLE = { fontSize: 12.5 } as const;\n\nexport const linkFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n const str = value == null ? \"\" : String(value);\n if (!str) return EMPTY_CELL;\n\n const href = normalizeUrl(str);\n if (href == null || !isValidUrl(href)) {\n return <span style={PLAIN_STYLE}>{str}</span>;\n }\n\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title={str}\n className=\"mono\"\n style={ANCHOR_STYLE}\n >\n {str}\n <Icon.external size={11} />\n </a>\n );\n };\n};\n","import { JsonField, isEmptyJsonValue } from \"../../JsonField\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nconst DEFAULT_LIST_JSON_MAX_CHARS = 400;\nconst HARD_LIST_JSON_MAX_CHARS = 2000;\n\nfunction clampMaxChars(value: unknown): number {\n const configured = typeof value === \"number\" && Number.isFinite(value)\n ? Math.floor(value)\n : DEFAULT_LIST_JSON_MAX_CHARS;\n return Math.max(1, Math.min(configured, HARD_LIST_JSON_MAX_CHARS));\n}\n\nfunction truncateText(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text;\n return `${text.slice(0, maxChars)}...`;\n}\n\nfunction boundedJsonText(value: unknown, maxChars: number, seen: WeakSet<object>, depth = 0): string {\n if (value == null || value === \"\") return \"\";\n if (typeof value === \"string\") return truncateText(value, maxChars);\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n if (typeof value !== \"object\") return truncateText(String(value), maxChars);\n if (seen.has(value)) return \"[Circular]\";\n if (depth >= 3) return Array.isArray(value) ? \"[...]\" : \"{...}\";\n\n seen.add(value);\n const close = Array.isArray(value) ? \"]\" : \"}\";\n const open = Array.isArray(value) ? \"[\" : \"{\";\n const parts: string[] = [open];\n const entries = Array.isArray(value)\n ? value.map((item, index) => [String(index), item] as const)\n : Object.entries(value as Record<string, unknown>);\n\n for (const [key, child] of entries) {\n const current = parts.join(\"\");\n const separator = parts.length > 1 ? \",\" : \"\";\n const prefix = Array.isArray(value) ? separator : `${separator}${JSON.stringify(key)}:`;\n const remaining = maxChars - current.length - prefix.length - close.length;\n if (remaining <= 0) {\n parts.push(parts.length > 1 ? \",...\" : \"...\");\n break;\n }\n const rendered = boundedJsonText(child, remaining, seen, depth + 1);\n parts.push(prefix, rendered);\n if (parts.join(\"\").length >= maxChars) {\n parts.push(\",...\");\n break;\n }\n }\n parts.push(close);\n seen.delete(value);\n return truncateText(parts.join(\"\"), maxChars);\n}\n\nfunction jsonText(value: unknown, maxChars: number): string {\n return boundedJsonText(value, maxChars, new WeakSet<object>());\n}\n\nexport const jsonFactory: CellFactory = (ctx): CellRenderer => {\n const surface = ctx.surface ?? \"detail\";\n const maxChars = clampMaxChars(ctx.field.display?.list_preview?.max_chars);\n return (value: unknown): CellOutput => {\n // null, \"\", {}, [] all collapse to the shared empty token - on the list\n // surface a literal \"{}\" is noise, on detail the readonly editor would\n // render a tall empty box.\n if (isEmptyJsonValue(value)) return EMPTY_CELL;\n if (surface === \"list\") {\n const text = jsonText(value, maxChars);\n return (\n <span className=\"font-mono text-xs text-muted-foreground\" title={text}>\n {text}\n </span>\n );\n }\n return (\n <JsonField\n field={ctx.field}\n fieldName={ctx.fieldName}\n value={value}\n mode=\"display\"\n locale={ctx.locale}\n />\n );\n };\n};\n","// markdownPreview: strip markdown source to a single-line plain-text\n// preview using cheap regex passes - no parser. Used by the `markdown` and\n// `rich_text_preview` cell factories for the in-cell preview line; the full\n// formatted render is carried by a HoverCard on hover and by the detail\n// screen, so a regex strip is sufficient here.\n//\n// Why regex and not the unified/remark parser: the parser is the bulk of the\n// markdown bundle weight (~100 kB). The cell-factory registry is eager, so\n// importing the parser here would pin it into the eager SDK bundle and defeat\n// the lazy split of the markdown renderer. A preview is a one-line teaser;\n// minor imperfection on exotic constructs (tables, fenced code) is acceptable.\n//\n// Length is NOT capped here: the server caps the preview at SQL select time\n// (display.list_preview.max_chars + DECLARION_LIST_PREVIEW_DEFAULT_CHARS) and\n// the cell's CSS ellipsis bounds the visual width.\n\nexport interface MarkdownPreview {\n // Single-line plain text: markup removed, whitespace collapsed.\n text: string;\n // True when the source carried no markdown structure. In that case a\n // HoverCard popover would show nothing the in-cell span does not, so the\n // caller skips the popover. Detection is intentionally biased toward\n // false (treat ambiguous input as marked-up): an unnecessary popover is\n // harmless, a missing one hides the rich view.\n isPlain: boolean;\n}\n\ninterface StripRule {\n pattern: RegExp;\n replacement: string;\n // When false, the rule cleans cosmetic noise (e.g. a stray pipe) and does\n // NOT mark the source as non-plain. Defaults to true: a match means real\n // markdown structure, so a HoverCard popover is worth showing.\n structural?: boolean;\n}\n\n// Each rule strips one markdown construct, applied in order. A structural rule\n// that changes the text marks the source as non-plain.\nconst RULES: StripRule[] = [\n // fenced code blocks: drop the fences, keep the inner text\n { pattern: /```[^\\n]*\\n?([\\s\\S]*?)```/g, replacement: \"$1\" },\n // inline code: keep inner text\n { pattern: /`([^`]+)`/g, replacement: \"$1\" },\n // images: keep alt text\n { pattern: /!\\[([^\\]]*)\\]\\([^)]*\\)/g, replacement: \"$1\" },\n // inline links: keep link text\n { pattern: /\\[([^\\]]+)\\]\\([^)]*\\)/g, replacement: \"$1\" },\n // reference links: keep link text\n { pattern: /\\[([^\\]]+)\\]\\[[^\\]]*\\]/g, replacement: \"$1\" },\n // reference link definitions: drop the whole line\n { pattern: /^[ \\t]*\\[[^\\]]+\\]:[ \\t]*\\S.*$/gm, replacement: \"\" },\n // bold / italic / strikethrough with * or ~ (may sit intraword)\n { pattern: /(\\*\\*\\*|\\*\\*|\\*|~~)(?=\\S)([\\s\\S]*?\\S)\\1/g, replacement: \"$2\" },\n // emphasis with _ - only at word boundaries. CommonMark does not treat\n // intraword underscores as emphasis, so identifiers like first_name stay\n // intact (and stay \"plain\"). $1 keeps the boundary char, $3 the inner text.\n {\n pattern: /(^|[^A-Za-z0-9])(___|__|_)(?=\\S)([\\s\\S]*?\\S)\\2(?![A-Za-z0-9])/g,\n replacement: \"$1$3\",\n },\n // headings: drop the leading marker\n { pattern: /^[ \\t]*#{1,6}[ \\t]+/gm, replacement: \"\" },\n // blockquote markers\n { pattern: /^[ \\t]*>[ \\t]?/gm, replacement: \"\" },\n // list markers (bullet and ordered)\n { pattern: /^[ \\t]*(?:[-*+]|\\d+[.)])[ \\t]+/gm, replacement: \"\" },\n // table separator rows: |---|:--:| etc\n { pattern: /^[ \\t]*\\|?[ \\t]*:?-{2,}[-| :]*$/gm, replacement: \"\" },\n // remaining table pipes - cosmetic only: a lone pipe in prose is not a\n // table, so this rule does not flag the source as non-plain.\n { pattern: /\\|/g, replacement: \" \", structural: false },\n // raw HTML tags\n { pattern: /<\\/?[a-zA-Z][^>]*>/g, replacement: \"\" },\n // horizontal rules\n { pattern: /^[ \\t]*(?:[-*_][ \\t]*){3,}$/gm, replacement: \"\" },\n];\n\n/**\n * Convert markdown source to a single-line plain-text preview plus an\n * `isPlain` signal. One synchronous pass, no parser.\n */\nexport function markdownPreview(src: string): MarkdownPreview {\n if (!src) return { text: \"\", isPlain: true };\n let working = src;\n let hadMarkup = false;\n for (const rule of RULES) {\n const next = working.replace(rule.pattern, rule.replacement);\n if (next !== working && rule.structural !== false) hadMarkup = true;\n working = next;\n }\n const text = working.replace(/\\s+/g, \" \").trim();\n return { text, isPlain: !hadMarkup };\n}\n","// markdown: render a plain-string field as sanitized markdown. Distinct from\n// `rich_text_preview` (which renders the file-aware RichTextField shape with\n// {markdown, files}). This factory is the one consumer YAMLs reach for when\n// they want a simple markdown column on a `type: string`/`type: text` field.\n//\n// List vs detail surface:\n// - In list cells (ctx.surface === \"list\") rendering full markup inside a\n// narrow column produces cropped headings and half-rendered links; a\n// one-line plain-text preview goes in the cell (regex strip, no parser),\n// with the full rendered markup carried by a HoverCard popover on hover.\n// - In detail surfaces (ctx.surface \"detail\" or undefined), the inline\n// prose render is preserved.\n//\n// The `Markdown` wrapper is lazy: the heavy renderer + parser load on demand,\n// never in the eager bundle. Sanitization (skipHtml, javascript:-URI strip)\n// lives inside MarkdownRenderer.\nimport type { ReactElement } from \"react\";\nimport { HoverCard } from \"@/components/primitives\";\nimport { Markdown } from \"@/components/shared/Markdown\";\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\nimport { markdownPreview } from \"./markdownPreview\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nfunction renderMarkdown(src: string): ReactElement {\n return <Markdown content={src} />;\n}\n\nexport const markdownFactory: CellFactory = (ctx): CellRenderer => {\n const isList = ctx.surface === \"list\";\n return (value: unknown): CellOutput => {\n const str = value == null ? \"\" : String(value);\n if (!str) return EMPTY_CELL;\n if (!isList) return renderMarkdown(str);\n\n // List surface: plain-text preview in the cell. Plain content (no\n // markup) gets a native `title=` tooltip so we don't spawn a HoverCard\n // for cells that don't need a rich preview.\n const { text, isPlain } = markdownPreview(str);\n if (isPlain) {\n return <span title={text}>{text}</span>;\n }\n return (\n <HoverCard content={renderMarkdown(str)}>\n <span title={text}>{text}</span>\n </HoverCard>\n );\n };\n};\n","// password_mask: stateless display-mode renderer for secret-shaped fields.\n// Parity contract with legacy PasswordField.tsx:14: byte-equivalent output for\n// the same inputs (asserted by snapshot test). Render rules:\n// - empty / null value → \"Not set\" (italic, var(--text-4))\n// - \"[SET]\" sentinel OR any\n// non-empty string value → \"[SET]\" (mono, var(--text-3))\n//\n// MUST never emit the underlying value to the DOM, even in data-* attributes.\n// Any product change to this rendering (e.g. compact mask) is a separate plan.\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\nconst SECRET_SENTINEL = \"[SET]\";\n\nconst SET_STYLE = { fontSize: 12.5, color: \"var(--text-3)\" } as const;\nconst EMPTY_STYLE = {\n fontSize: 12.5,\n color: \"var(--text-4)\",\n fontStyle: \"italic\",\n} as const;\n\nexport const passwordMaskFactory: CellFactory = (): CellRenderer => {\n return (value: unknown): CellOutput => {\n const hasExistingValue =\n value === SECRET_SENTINEL || (typeof value === \"string\" && value !== \"\");\n if (hasExistingValue) {\n return (\n <span className=\"mono\" style={SET_STYLE}>\n {SECRET_SENTINEL}\n </span>\n );\n }\n return <span style={EMPTY_STYLE}>Not set</span>;\n };\n};\n","// rich_text_preview: full sanitized markdown render for the RichText shape.\n// Parity contract with RichTextField's display branch: same `Markdown` wrapper,\n// same props, so output stays equivalent (asserted by parity.test.tsx).\n// - empty value renders a hyphen \"-\" (NOT em-dash) inside a span with\n// var(--text-4) color.\n// - non-empty value renders through the shared `Markdown` wrapper.\n// - sanitization (skipHtml, javascript:-URI strip) and declarion://file/<id>\n// resolution live inside MarkdownRenderer; passing `files` enables it.\n//\n// List vs detail surface:\n// - In list cells (ctx.surface === \"list\") rendering full markup with\n// possibly large image/link refs in a narrow column is unreadable; we\n// emit a plain-text preview span (regex strip, no parser) and carry the\n// rendered file-aware markup inside a HoverCard popover.\n// - In detail surfaces (ctx.surface \"detail\" or undefined), the inline\n// prose render is preserved.\n//\n// The `Markdown` wrapper is lazy: the heavy renderer + parser load on demand.\nimport type { ReactElement } from \"react\";\nimport { createRichTextValue } from \"@/lib/rich-text\";\nimport { HoverCard } from \"@/components/primitives\";\nimport type { HydratedFile } from \"@/types/files\";\nimport { Markdown } from \"@/components/shared/Markdown\";\nimport type { CellFactory, CellRenderer, CellOutput, RowRecord } from \"../registry\";\nimport { markdownPreview } from \"./markdownPreview\";\nimport { EMPTY_CELL } from \"./emptyCell\";\n\nfunction renderRichMarkdown(\n markdown: string,\n files: Record<string, HydratedFile>,\n): ReactElement {\n return <Markdown content={markdown} files={files} />;\n}\n\nexport const richTextPreviewFactory: CellFactory = (ctx): CellRenderer => {\n const { fieldName } = ctx;\n const isList = ctx.surface === \"list\";\n return (value: unknown, record: RowRecord): CellOutput => {\n const inlineFilesValue = (record?.$files as Record<string, unknown> | undefined)?.[fieldName];\n const rich = createRichTextValue(value, inlineFilesValue);\n if (!rich.markdown) {\n return EMPTY_CELL;\n }\n if (!isList) return renderRichMarkdown(rich.markdown, rich.files);\n\n // List surface: plain-text preview in the cell. Plain content (no\n // markup) gets a native title-only tooltip; marked-up content gets a\n // HoverCard with the file-aware markdown render.\n const { text, isPlain } = markdownPreview(rich.markdown);\n if (isPlain) {\n return <span title={text}>{text}</span>;\n }\n return (\n <HoverCard content={renderRichMarkdown(rich.markdown, rich.files)}>\n <span title={text}>{text}</span>\n </HoverCard>\n );\n };\n};\n","// multilang_inline: render the first available locale value of a LangMap-shaped\n// value (multilang / multilang_text). Parity contract with legacy\n// MultilangField.tsx:25 / MultilangTextField.tsx:25:\n// - object value: render the caller-locale entry if non-empty, else the\n// first non-empty entry, else em-dash.\n// - bare-string value: coerce to { en: <value> } before lookup, mirroring\n// legacy parseLangMap (locked in for byte-equivalence).\n// - null / undefined: em-dash.\n//\n// Wrapper element follows field.type:\n// - multilang → <span> with `font-size: 12.5px`\n// - multilang_text → <p> with `white-space: pre-wrap; margin: 0px`\n//\n// Per plan §9, `lang` and `dir=\"auto\"` MUST be set on the wrapper so RTL/LTR\n// mixed content resolves correctly. `lang` follows the locale that supplied\n// the displayed text (which may be the fallback, not ctx.locale).\nimport type { CellFactory, CellRenderer, CellOutput } from \"../registry\";\n\ntype LangMap = Record<string, string>;\n\nconst SPAN_STYLE = { fontSize: 12.5 } as const;\nconst PARA_STYLE = { fontSize: 12.5, whiteSpace: \"pre-wrap\", margin: 0 } as const;\n\nfunction parseLangMap(value: unknown): LangMap {\n if (value == null) return {};\n if (typeof value === \"object\" && !Array.isArray(value)) {\n return value as LangMap;\n }\n if (typeof value === \"string\") {\n return { en: value };\n }\n return {};\n}\n\n// pickEntry returns [locale, text] for the entry the cell should display, or\n// null if no non-empty entry exists. Preference order:\n// 1. ctx.locale (if non-empty for that key)\n// 2. first non-empty entry (insertion order, mirrors Object.values()[0]).\nfunction pickEntry(map: LangMap, preferred?: string): [string, string] | null {\n if (preferred && typeof map[preferred] === \"string\" && map[preferred] !== \"\") {\n return [preferred, map[preferred]];\n }\n for (const [key, val] of Object.entries(map)) {\n if (typeof val === \"string\" && val !== \"\") return [key, val];\n }\n return null;\n}\n\nexport const multilangInlineFactory: CellFactory = (ctx): CellRenderer => {\n const { field, locale } = ctx;\n const isLong = field.type === \"multilang_text\";\n return (value: unknown): CellOutput => {\n const map = parseLangMap(value);\n const entry = pickEntry(map, locale);\n if (!entry) {\n // Empty case: keep wrapper element + style consistent with legacy\n // snapshots (span vs p). lang/dir are intentionally omitted on the\n // dash placeholder — there is no language to declare.\n if (isLong) {\n return <p style={PARA_STYLE}>—</p>;\n }\n return <span style={SPAN_STYLE}>—</span>;\n }\n const [lang, text] = entry;\n if (isLong) {\n return (\n <p style={PARA_STYLE} lang={lang} dir=\"auto\">\n {text}\n </p>\n );\n }\n return (\n <span style={SPAN_STYLE} lang={lang} dir=\"auto\">\n {text}\n </span>\n );\n };\n};\n","// Cell-renderer registry (1a.5).\n//\n// Display-mode rendering for entity table cells, detail-page fields, and\n// QuickPeek bodies. Keyed on `field.display.widget` (engine fills smart\n// defaults at YAML-load time, so this lookup never falls back to type-based\n// dispatch in the hot path).\n//\n// Architecture:\n// - Each renderer is a *factory* that closes over schema lookups\n// (status-group palette, currency formatter, bool labels, value_map)\n// and returns a `(value, record) => ReactNode` closure.\n// - `resolveCellRenderer(ctx)` looks up the factory by widget, calls it\n// once per column / per detail field, and is cached by EntityField\n// identity via a WeakMap so repeated calls during a render reuse the\n// same closure.\n// - The cell hot path is a single bound-function call. No per-row\n// `field.type` dispatch, no per-row schema traversal.\n\nimport type { ReactElement } from \"react\";\nimport type { EntityField, Entity, Screen } from \"@/types/schema\";\n\nexport type RowRecord = Record<string, unknown>;\n\n// CellOutput narrows the renderer return to the perf-correct shape.\n//\n// - `string` and `number` commit as text nodes with no fiber overhead. ~90%\n// of cells (text, number-formatted, date-formatted, code, badge labels)\n// should return one of these.\n// - `ReactElement` is the deliberate path for cells that need DOM (markdown\n// HoverCard, image, link with onClick, badge with color). One element per\n// cell, not a wrapping `<span>` around plain text - the latter is a 2x\n// mount-time regression at viewport scale (caught by sync.test.tsx perf\n// gate; see docs/plans/2026-05-09-virtual-list-100k.md §1).\n//\n// `ReactNode` (the React-default) also includes arrays, fragments, booleans,\n// null, undefined. Those legal but expensive shapes are deliberately excluded\n// here. Factories that need a multi-element output MUST wrap in `<>...</>`\n// (a Fragment is a ReactElement). Factories that previously returned `null`\n// MUST return the `\"—\"` em-dash placeholder string instead.\nexport type CellOutput = string | number | ReactElement;\n\nexport type CellRenderer = (value: unknown, record: RowRecord) => CellOutput;\n\nexport type RefsMap = Record<string, Record<string, Record<string, unknown>>>;\n\nexport interface CellResolveCtx {\n field: EntityField;\n fieldName: string;\n // surface: \"list\" indicates the cell is rendered inside a row in a table.\n // Branch-aware factories (markdown, rich_text_preview) emit a plain-text\n // preview + HoverCard for marked-up content in this surface; plain content\n // uses a native title-only tooltip. Undefined or \"detail\" preserves the\n // legacy inline render. Callers that render lists MUST pass \"list\"; detail\n // surfaces may omit. See docs/list-rendering.md.\n surface?: \"list\" | \"detail\";\n entity?: Entity;\n entities?: Record<string, Entity>;\n screens?: Record<string, Screen>;\n // refs: $refs payload from the current list/detail response. Pass either a\n // snapshot or a getter - list pages typically pass a getter (() =>\n // refsRef.current) so the cached factory reads the latest refs after a\n // refetch without rebuilding columns.\n refs?: RefsMap | (() => RefsMap | undefined);\n // locale: user's resolved language code (non-empty per plan §3 contract).\n // Every direct caller MUST supply this via useUserLocale() so factories\n // (time_ago, multilang_inline, money, ...) format consistently. The hook\n // guarantees a non-empty string; CI gate enforces propagation.\n locale: string;\n // No `navigate`: cells render plain real `<a href>` and the global link\n // interceptor (Layout) owns the click. This removed the per-cell drift\n // vector that let ref_link cells forget navigation and full-load the app.\n}\n\nexport type CellFactory = (ctx: CellResolveCtx) => CellRenderer;\n\nimport { textFactory } from \"./factories/text\";\nimport { boolPillFactory } from \"./factories/boolPill\";\nimport { badgeFactory } from \"./factories/badge\";\nimport { statusPillFactory } from \"./factories/statusPill\";\nimport { tagListFactory } from \"./factories/tagList\";\nimport { timeAgoFactory, timestampFullFactory } from \"./factories/timestamp\";\nimport { nextRunFactory } from \"./factories/nextRun\";\nimport { moneyFactory } from \"./factories/money\";\nimport { refLinkFactory } from \"./factories/refLink\";\nimport { urlFactory } from \"./factories/url\";\nimport { emailFactory } from \"./factories/email\";\nimport { phoneFactory } from \"./factories/phone\";\nimport { numberFactory } from \"./factories/number\";\nimport { codeFactory } from \"./factories/code\";\nimport { linkFactory } from \"./factories/link\";\nimport { jsonFactory } from \"./factories/json\";\nimport { markdownFactory } from \"./factories/markdown\";\nimport { passwordMaskFactory } from \"./factories/passwordMask\";\nimport { richTextPreviewFactory } from \"./factories/richTextPreview\";\nimport { multilangInlineFactory } from \"./factories/multilangInline\";\n\nconst REGISTRY: Record<string, CellFactory> = {\n text: textFactory,\n bool_pill: boolPillFactory,\n badge: badgeFactory,\n status_pill: statusPillFactory,\n tag_list: tagListFactory,\n time_ago: timeAgoFactory,\n timestamp_full: timestampFullFactory,\n next_run: nextRunFactory,\n money: moneyFactory,\n ref_link: refLinkFactory,\n url: urlFactory,\n email: emailFactory,\n phone: phoneFactory,\n number: numberFactory,\n code: codeFactory,\n link: linkFactory,\n json: jsonFactory,\n markdown: markdownFactory,\n password_mask: passwordMaskFactory,\n rich_text_preview: richTextPreviewFactory,\n multilang_inline: multilangInlineFactory,\n};\n\n// REGISTRY_WIDGETS is the sorted list of registered widget names. Exported so\n// the cross-language sync test can compare TS widget keys against\n// golang/.testdata/display_widgets.json without duplicating the list.\nexport const REGISTRY_WIDGETS: readonly string[] = Object.keys(REGISTRY).sort();\n\n// resolveCellRenderer instantiates a fresh renderer closure per call. We\n// intentionally do NOT cache by EntityField identity: the closure captures\n// ctx-derived values (entities, screens, locale, refs accessor) at\n// build time, and a key that ignored those would return a closure built with\n// stale or missing context — e.g. a ref_link resolved before $refs arrived\n// would keep using the empty refs forever. Hot paths (SmartListPage column\n// useMemo, ChildrenTable column useMemo, FieldsBlock per-field meta) already\n// memoize at the right granularity; layering an identity-only cache here\n// would only re-introduce the staleness bug.\nexport function resolveCellRenderer(ctx: CellResolveCtx): CellRenderer {\n const widget = ctx.field.display?.widget ?? \"text\";\n const factory = REGISTRY[widget];\n if (!factory) {\n throw new Error(\n `resolveCellRenderer: no factory registered for widget \"${widget}\" (field \"${ctx.fieldName}\"). The engine must stamp a smart default at YAML-load time; an unknown widget here indicates an out-of-sync allow-list.`,\n );\n }\n return factory(ctx);\n}\n","import type { EntityField, Entity, Screen } from \"@/types/schema\";\nimport { FIELD_TYPES, type FieldType } from \"@/types/fieldType\";\nimport { StringField } from \"./StringField\";\nimport { TextField } from \"./TextField\";\nimport { EnumField } from \"./EnumField\";\nimport { EmailField } from \"./EmailField\";\nimport { UrlField } from \"./UrlField\";\nimport { PhoneField } from \"./PhoneField\";\nimport { TimestampField } from \"./TimestampField\";\nimport { BoolField } from \"./BoolField\";\nimport { NumberField } from \"./NumberField\";\nimport { RefField } from \"./RefField\";\nimport { JsonField } from \"./JsonField\";\nimport { MultilangField } from \"./MultilangField\";\nimport { MultilangTextField } from \"./MultilangTextField\";\nimport { StructureField } from \"./StructureField\";\nimport { SecretField } from \"./SecretField\";\nimport { PasswordField } from \"./PasswordField\";\nimport { StringArrayField } from \"./StringArrayField\";\nimport { IntArrayField } from \"./IntArrayField\";\nimport { RichTextField } from \"./RichTextField\";\nimport { resolveCellRenderer } from \"./cells/registry\";\n\n// RefsMap is the $refs structure from list/detail API responses.\n// Shape: { entityCode: { recordId: { field: value, ... } } }\nexport type RefsMap = Record<string, Record<string, Record<string, unknown>>>;\n\nexport interface FieldRendererProps {\n field: EntityField;\n entityCode?: string;\n fieldName: string;\n value: unknown;\n mode: \"display\" | \"edit\";\n onChange?: (value: unknown) => void;\n // Accessibility (Finding 2): a stable per-field id used to pair a form input\n // with its <label htmlFor>. Edit-mode renderers MUST forward it as `id` on\n // the <input>/<textarea> they own (and `name={fieldName}`). Button-based\n // renderers (EnumField/RefField render a <button>, which cannot be the\n // target of htmlFor) instead point `aria-labelledby` at `labelId`.\n // Both are optional: standalone callers (StructureField nested fields,\n // tests) may omit them, in which case renderers fall back to no id/name.\n fieldId?: string;\n labelId?: string;\n record?: Record<string, unknown>;\n refs?: RefsMap;\n // fill: renderer should stretch to fill its flex parent (relevant for\n // resizable containers like the activity composer). Currently honored by\n // TextField edit mode.\n fill?: boolean;\n // compact: renderer is inside a fixed-height row (table cell, inline edit).\n // Multi-line-capable renderers (TextField for type:text) MUST render a\n // single-line input in this mode so the row height stays predictable.\n // Honored by TextField; other renderers may ignore it.\n compact?: boolean;\n surface?: \"list\" | \"detail\";\n // 1a.5 cell-renderer ctx. Display-mode rendering for fields whose\n // display.widget names a registered cell renderer (badge, bool_pill,\n // tag_list, time_ago, money, ref_link, …) goes through the cell registry.\n // entity/entities/screens are the schema lookups the registry closes over\n // once per column. Edit mode ignores all of these.\n entity?: Entity;\n entities?: Record<string, Entity>;\n screens?: Record<string, Screen>;\n // locale: user-resolved language code, required per plan §3 (\"CellResolveCtx.locale\n // is mandatory, not optional\"). Callers supply it via useUserLocale(). The\n // dispatcher passes it through to the cell registry; edit-mode renderers\n // generally ignore it (single-locale form inputs).\n locale: string;\n}\n\ntype FieldRenderer = React.ComponentType<FieldRendererProps>;\n\n// editRegistry: edit-mode dispatcher keyed by FieldType (not display.widget).\n// Populated per plan §5 of 2026-04-29-field-rendering-two-registry-cut.\n//\n// MUST be total over `FieldType`. The CI sync gate\n// (`golang/.testdata/field_types.json`) asserts that\n// `Object.keys(editRegistry).sort()` matches Go's enum exactly. Adding a new\n// FieldType requires a corresponding entry here; the dispatcher below throws\n// (no fallback) when this lookup misses.\nexport const editRegistry: Record<FieldType, FieldRenderer> = {\n string: StringField,\n text: TextField,\n rich_text: RichTextField,\n int: NumberField,\n float: NumberField,\n decimal: NumberField,\n bool: BoolField,\n timestamp: TimestampField,\n date: TimestampField,\n time: TimestampField,\n enum: EnumField,\n email: EmailField,\n url: UrlField,\n phone: PhoneField,\n uuid: StringField,\n // bytes is a bytea column surfaced as a lowercase-hex string; it edits as a\n // plain text input, same as uuid and tags.\n bytes: StringField,\n ref: RefField,\n json: JsonField,\n tags: StringField,\n string_array: StringArrayField,\n int_array: IntArrayField,\n // uuid_array is a UUID[] column; uuids are strings at the UI level, so it\n // edits with the same component as string_array.\n uuid_array: StringArrayField,\n multilang: MultilangField,\n multilang_text: MultilangTextField,\n structure: StructureField,\n secret: SecretField,\n password: PasswordField,\n};\n\n// Startup-time totality check (plan §3: \"Lookup misses MUST throw at startup,\n// not at render\"). The TS compiler narrowing on `Record<FieldType, …>` already\n// covers compile-time totality, but the runtime list mirrors the Go enum and\n// re-asserting equality here catches drift introduced by deliberate `any`\n// casts or merge conflicts in the registry literal.\nfor (const t of FIELD_TYPES) {\n if (!editRegistry[t]) {\n throw new Error(\n `editRegistry: missing entry for FieldType \"${t}\". The TS union (types/fieldType.ts) and editRegistry must stay in sync with golang/internal/engine/types.go.`,\n );\n }\n}\n\n// renderField is the dispatcher. Per plan §3 the rule chain is exactly:\n// 1. field.type === \"json\" && field.structure -> StructureField\n// 2. mode === \"edit\" -> editRegistry[field.type]\n// 3. otherwise (display mode) -> displayRegistry (cells)\n// No fallback. Lookup misses MUST throw, surfacing engine/SDK drift loudly\n// instead of demoting fields to plain text (which is the original-sin\n// regression this plan closes).\nexport function renderField(props: FieldRendererProps): React.ReactNode {\n // Rule 1: structured JSON renders via StructureField in BOTH edit and\n // display modes (it owns its own layout for both). Must run before rule 2\n // so structure-typed fields don't fall into editRegistry[\"json\"].\n if (props.field.type === \"json\" && props.field.structure) {\n return <StructureField {...props} />;\n }\n\n // Rule 2: edit dispatch by FieldType. Widget never re-routes edit mode.\n if (props.mode === \"edit\") {\n const t = props.field.type as FieldType;\n const Editor = editRegistry[t];\n if (!Editor) {\n throw new Error(\n `renderField: no edit-mode renderer for FieldType \"${props.field.type}\" (field \"${props.fieldName}\"). editRegistry must be total over FieldType; check types/fieldType.ts and components/fields/index.tsx.`,\n );\n }\n return <Editor {...props} />;\n }\n\n // Rule 3: display dispatch by widget through the cell registry. The engine\n // stamps a smart default at YAML-load time, so `widget` is non-empty for\n // every entity field; resolveCellRenderer throws on unknown widgets.\n const widget = props.field.display?.widget;\n if (!widget) {\n throw new Error(\n `renderField: display mode requires a non-empty field.display.widget (field \"${props.fieldName}\", type \"${props.field.type}\"). The engine must stamp a smart default; an empty widget here means the field bypassed ResolveDefaultWidgets.`,\n );\n }\n const renderer = resolveCellRenderer({\n field: props.field,\n fieldName: props.fieldName,\n surface: props.surface ?? \"detail\",\n entity: props.entity,\n entities: props.entities,\n screens: props.screens,\n // Pass through the refs payload (snapshot or getter) verbatim; the\n // factory closes over it and per-cell rendering is a single bound call.\n refs: props.refs as Record<string, Record<string, Record<string, unknown>>> | undefined,\n locale: props.locale,\n });\n return renderer(props.value, props.record ?? {});\n}\n","// useUserLocale resolves the active language code threaded through cell\n// factories' CellResolveCtx.locale. Per the\n// 2026-04-29-field-rendering-two-registry-cut plan (\"Locale source\n// contract\"), CellResolveCtx.locale is mandatory; every direct caller of\n// resolveCellRenderer (SmartListPage, ChildrenTable, the renderField\n// dispatcher) MUST consume this hook and pass the result.\n//\n// Resolution order (first non-empty wins):\n// 1. The authenticated user's preferred language, if surfaced on AuthUser.\n// The platform does not yet ship a profile field for this; the hook\n// reads `(user as { language?: string }).language` defensively so the\n// moment a profile field lands the resolution path lights up without\n// another change here.\n// 2. The first entry of `schema.languages` (always populated for a loaded\n// schema; this is the consumer-app default language).\n// 3. `navigator.language` reduced to its primary subtag (en-US -> en) as a\n// last-resort browser fallback.\n// 4. Hard-coded \"en\" if everything above is unavailable (e.g. SSR before\n// schema loads, no navigator). Returning a non-empty string is part of\n// the public contract; factories MAY assume it.\n\nimport { useAuthStore } from \"@/stores/auth\";\nimport { useSchema } from \"./useSchema\";\n\nconst DEFAULT_LOCALE = \"en\";\n\nfunction navigatorPrimarySubtag(): string | undefined {\n if (typeof navigator === \"undefined\") return undefined;\n const raw = navigator.language;\n if (!raw) return undefined;\n const primary = raw.split(\"-\")[0];\n return primary || undefined;\n}\n\nexport function useUserLocale(): string {\n const user = useAuthStore((s) => s.user);\n const { data: schema } = useSchema();\n\n // Step 1: authenticated user profile language (forward-compat: not yet on\n // the AuthUser interface but tolerated here so the moment we add it the\n // resolution lights up).\n const profile = (user as { language?: string } | null)?.language;\n if (profile && profile.trim()) return profile;\n\n // Step 2: first language declared by the consumer schema.\n const first = schema?.languages?.[0]?.code;\n if (first && first.trim()) return first;\n\n // Step 3: browser default.\n const nav = navigatorPrimarySubtag();\n if (nav) return nav;\n\n // Step 4: hard fallback.\n return DEFAULT_LOCALE;\n}\n","// Shared chrome for the platform's detail-page data tables - the child-entity\n// tables (ChildrenTable / EditableChildrenTable / DraggableChildrenTable), the\n// associated-entity tables (AssociatedBlock) and the association-tab tables\n// (AssociationTabs).\n//\n// Single source of truth: a styling decision (column-header case, spacing,\n// borders, colors) is one edit here, not one edit per table. Before this,\n// the same <table>/<th>/<td> styles were copy-pasted across five components.\n\nimport type { CSSProperties } from \"react\";\n\n// The <table> element.\nexport const dataTableStyle: CSSProperties = {\n width: \"100%\",\n fontSize: 12.5,\n borderCollapse: \"separate\",\n borderSpacing: 0,\n};\n\n// Column-header cell (<th>). Sentence case - never all-caps.\nexport const dataTableHeadCellStyle: CSSProperties = {\n height: 30,\n padding: \"0 12px\",\n textAlign: \"left\",\n fontWeight: 600,\n fontSize: 11,\n color: \"var(--text-3)\",\n borderBottom: \"1px solid var(--divider)\",\n};\n\n// Body cell (<td>). Compact-action cells (row kebabs, drag handles) spread\n// this and override `padding` / `width`.\nexport const dataTableCellStyle: CSSProperties = {\n padding: \"6px 12px\",\n borderBottom: \"1px solid var(--divider)\",\n color: \"var(--text-2)\",\n verticalAlign: \"middle\",\n};\n"],"mappings":"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"}
|