aktion-runtime 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +1246 -0
  2. package/dist/aktion.iife.js +8431 -0
  3. package/dist/aktion.iife.js.map +1 -0
  4. package/dist/aktion.js +22594 -0
  5. package/dist/aktion.js.map +1 -0
  6. package/dist/aktion.umd.cjs +8431 -0
  7. package/dist/aktion.umd.cjs.map +1 -0
  8. package/dist/index.cjs +3 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.js +5 -0
  11. package/dist/system_prompt.txt +1095 -0
  12. package/dist/system_prompt_chat.txt +404 -0
  13. package/dist/types/element.d.ts +175 -0
  14. package/dist/types/icons/index.d.ts +45 -0
  15. package/dist/types/index.d.ts +15 -0
  16. package/dist/types/language/builtins.d.ts +33 -0
  17. package/dist/types/language/components.d.ts +28 -0
  18. package/dist/types/language/grammar.d.ts +121 -0
  19. package/dist/types/language/index.d.ts +41 -0
  20. package/dist/types/language/snippets.d.ts +17 -0
  21. package/dist/types/library/components/_internal.d.ts +56 -0
  22. package/dist/types/library/components/advanced-charts.d.ts +6 -0
  23. package/dist/types/library/components/advanced-data.d.ts +6 -0
  24. package/dist/types/library/components/advanced-forms.d.ts +12 -0
  25. package/dist/types/library/components/advanced-patterns.d.ts +13 -0
  26. package/dist/types/library/components/charts.d.ts +5 -0
  27. package/dist/types/library/components/chat.d.ts +6 -0
  28. package/dist/types/library/components/content.d.ts +33 -0
  29. package/dist/types/library/components/data.d.ts +9 -0
  30. package/dist/types/library/components/editors.d.ts +5 -0
  31. package/dist/types/library/components/feedback.d.ts +14 -0
  32. package/dist/types/library/components/forms-shared.d.ts +7 -0
  33. package/dist/types/library/components/forms.d.ts +21 -0
  34. package/dist/types/library/components/helpers.d.ts +33 -0
  35. package/dist/types/library/components/layout.d.ts +20 -0
  36. package/dist/types/library/components/media.d.ts +7 -0
  37. package/dist/types/library/components/menu.d.ts +5 -0
  38. package/dist/types/library/components/navigation.d.ts +6 -0
  39. package/dist/types/library/components/new-components.d.ts +13 -0
  40. package/dist/types/library/components/patterns.d.ts +39 -0
  41. package/dist/types/library/components/router.d.ts +2 -0
  42. package/dist/types/library/components/theme.d.ts +2 -0
  43. package/dist/types/library/index.d.ts +5 -0
  44. package/dist/types/library/registry.d.ts +15 -0
  45. package/dist/types/library/types.d.ts +140 -0
  46. package/dist/types/library/utils.d.ts +73 -0
  47. package/dist/types/library/validate.d.ts +27 -0
  48. package/dist/types/parser/frontier.d.ts +65 -0
  49. package/dist/types/parser/index.d.ts +4 -0
  50. package/dist/types/parser/lexer.d.ts +46 -0
  51. package/dist/types/parser/parser.d.ts +2 -0
  52. package/dist/types/parser/types.d.ts +349 -0
  53. package/dist/types/prompt/generator.d.ts +33 -0
  54. package/dist/types/prompt/index.d.ts +1 -0
  55. package/dist/types/renderer/index.d.ts +1 -0
  56. package/dist/types/renderer/morph.d.ts +42 -0
  57. package/dist/types/renderer/renderer.d.ts +73 -0
  58. package/dist/types/runtime/builtins.d.ts +27 -0
  59. package/dist/types/runtime/console.d.ts +21 -0
  60. package/dist/types/runtime/effects.d.ts +69 -0
  61. package/dist/types/runtime/evaluator.d.ts +151 -0
  62. package/dist/types/runtime/http.d.ts +85 -0
  63. package/dist/types/runtime/i18n.d.ts +40 -0
  64. package/dist/types/runtime/index.d.ts +9 -0
  65. package/dist/types/runtime/router.d.ts +105 -0
  66. package/dist/types/runtime/state.d.ts +84 -0
  67. package/dist/types/runtime/storage.d.ts +50 -0
  68. package/dist/types/theme/index.d.ts +175 -0
  69. package/dist/types/theme/styles.d.ts +9 -0
  70. package/dist/types/tooling/codemod.d.ts +36 -0
  71. package/dist/types/tooling/delta.d.ts +74 -0
  72. package/dist/types/tooling/formatter.d.ts +8 -0
  73. package/dist/types/tooling/index.d.ts +29 -0
  74. package/dist/types/tooling/inspector.d.ts +49 -0
  75. package/dist/types/tooling/language-service.d.ts +57 -0
  76. package/package.json +63 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aktion.umd.cjs","sources":["../src/parser/lexer.ts","../src/parser/parser.ts","../src/parser/frontier.ts","../src/tooling/delta.ts","../src/library/registry.ts","../src/library/types.ts","../src/library/validate.ts","../src/runtime/builtins.ts","../src/runtime/state.ts","../src/runtime/http.ts","../src/runtime/router.ts","../src/runtime/storage.ts","../src/runtime/console.ts","../src/runtime/evaluator.ts","../src/runtime/i18n.ts","../src/runtime/effects.ts","../src/icons/index.ts","../src/library/utils.ts","../src/library/components/layout.ts","../src/library/components/content.ts","../src/library/components/_internal.ts","../src/library/components/forms-shared.ts","../src/library/components/forms.ts","../src/library/components/patterns.ts","../src/library/components/data.ts","../src/library/components/charts.ts","../src/library/components/chat.ts","../src/library/components/feedback.ts","../src/library/components/navigation.ts","../src/library/components/menu.ts","../src/library/components/advanced-data.ts","../src/library/components/media.ts","../src/library/components/editors.ts","../src/library/components/advanced-charts.ts","../src/library/components/advanced-forms.ts","../src/library/components/advanced-patterns.ts","../src/library/components/theme.ts","../src/library/components/router.ts","../src/library/components/new-components.ts","../src/library/components/helpers.ts","../src/library/index.ts","../src/renderer/renderer.ts","../src/renderer/morph.ts","../src/language/builtins.ts","../src/prompt/generator.ts","../src/theme/index.ts","../src/theme/styles.ts","../src/element.ts","../src/language/grammar.ts","../src/language/components.ts","../src/language/snippets.ts","../src/language/index.ts","../src/index.ts"],"sourcesContent":["/**\n * Tokenizer for Aktion.\n *\n * The language is line-oriented. We tokenize into a flat stream of tokens\n * including NEWLINE markers so that the parser can recover at line boundaries.\n */\n\nexport type TokenType =\n | \"Identifier\"\n | \"Keyword\"\n | \"StateIdentifier\"\n | \"BuiltinIdentifier\"\n | \"Number\"\n | \"String\"\n /**\n * Backtick-quoted template literal — carries alternating raw chunks and\n * embedded expression source strings via `parts`.\n * `parts[0]` is always a string chunk; positions then alternate between\n * `{kind:\"expr\", source}` and `{kind:\"str\", text}`.\n */\n | \"TemplateString\"\n /**\n * `js{ … }` opaque block. The body is captured verbatim (with balanced\n * brace tracking) so it can be passed through to the runtime without\n * re-parsing.\n */\n | \"JsBlock\"\n | \"Boolean\"\n | \"Null\"\n | \"Punctuation\"\n | \"Operator\"\n | \"Newline\"\n | \"EOF\";\n\n/**\n * Keywords reserved by Aktion. The lexer recognises them so the\n * parser can dispatch on `Keyword` tokens directly instead of second-guessing\n * every identifier. `$name` is lexed as a `StateIdentifier` token whose\n * `value` is the bare name; there is only one reactive atom kind so no\n * additional disambiguation is needed.\n */\nexport const KEYWORDS_AKTION = new Set([\n \"component\",\n \"effect\",\n \"action\",\n \"if\",\n \"else\",\n \"match\",\n \"for\",\n \"in\",\n \"await\",\n \"return\",\n \"cleanup\",\n \"optimistic\",\n \"on\",\n \"emit\",\n \"bind\",\n \"default\",\n]);\n\nexport type TemplatePart =\n | { kind: \"str\"; text: string }\n | { kind: \"expr\"; source: string; line: number; column: number };\n\nexport interface Token {\n type: TokenType;\n value: string;\n line: number;\n column: number;\n /** Set on `TemplateString` tokens to carry the alternating parts. */\n parts?: TemplatePart[];\n}\n\nconst SINGLE_CHAR_PUNCT = new Set([\"(\", \")\", \"[\", \"]\", \"{\", \"}\", \",\", \":\", \"?\", \".\"]);\nconst KEYWORDS: Record<string, TokenType> = {\n true: \"Boolean\",\n false: \"Boolean\",\n null: \"Null\",\n};\n\nexport function tokenize(source: string): Token[] {\n const tokens: Token[] = [];\n let i = 0;\n let line = 1;\n let column = 1;\n\n const peek = (offset = 0) => source[i + offset];\n const push = (type: TokenType, value: string, startLine: number, startCol: number) => {\n tokens.push({ type, value, line: startLine, column: startCol });\n };\n const advance = () => {\n const ch = source[i];\n i += 1;\n if (ch === \"\\n\") {\n line += 1;\n column = 1;\n } else {\n column += 1;\n }\n return ch;\n };\n\n while (i < source.length) {\n const ch = peek();\n\n if (ch === undefined) break;\n\n // Newline.\n if (ch === \"\\n\") {\n const startLine = line;\n const startCol = column;\n advance();\n push(\"Newline\", \"\\n\", startLine, startCol);\n continue;\n }\n\n // Whitespace (excluding newline).\n if (ch === \" \" || ch === \"\\t\" || ch === \"\\r\") {\n advance();\n continue;\n }\n\n // Line comments: //...\n if (ch === \"/\" && peek(1) === \"/\") {\n while (i < source.length && peek() !== \"\\n\") advance();\n continue;\n }\n\n // `#`-style comment. The Aktion 0.5 surface does not have\n // pragmas — every `#…` line is a comment. This keeps the language\n // simple and avoids a \"version negotiation\" the LLM would otherwise\n // have to remember.\n if (ch === \"#\") {\n while (i < source.length && peek() !== \"\\n\") advance();\n continue;\n }\n\n // Block comments: /* ... */\n if (ch === \"/\" && peek(1) === \"*\") {\n advance();\n advance();\n while (i < source.length && !(peek() === \"*\" && peek(1) === \"/\")) {\n advance();\n }\n if (i < source.length) {\n advance();\n advance();\n }\n continue;\n }\n\n // String literal:\n // - \"...\" / '...' — single-line strings with escape support\n // - `...` — multi-line template literals: support `${expr}`\n // interpolation, real newlines, and unescaped `\"`.\n // Escape `\\${` to embed a literal `${` in JS bodies.\n if (ch === '\"' || ch === \"'\") {\n const quote = ch;\n const startLine = line;\n const startCol = column;\n advance();\n let value = \"\";\n while (i < source.length && peek() !== quote) {\n if (peek() === \"\\\\\" && peek(1) !== undefined) {\n advance();\n const escaped = advance();\n switch (escaped) {\n case \"n\": value += \"\\n\"; break;\n case \"t\": value += \"\\t\"; break;\n case \"r\": value += \"\\r\"; break;\n case \"\\\\\": value += \"\\\\\"; break;\n case '\"': value += '\"'; break;\n case \"'\": value += \"'\"; break;\n case \"`\": value += \"`\"; break;\n default: value += escaped ?? \"\";\n }\n continue;\n }\n if (peek() === \"\\n\") {\n // Quoted strings stop at newlines so a half-written line never\n // swallows the rest of the program.\n break;\n }\n value += advance();\n }\n if (peek() === quote) advance();\n push(\"String\", value, startLine, startCol);\n continue;\n }\n if (ch === \"`\") {\n const startLine = line;\n const startCol = column;\n advance();\n const parts: TemplatePart[] = [];\n let chunk = \"\";\n let sawExpr = false;\n while (i < source.length && peek() !== \"`\") {\n if (peek() === \"\\\\\" && peek(1) !== undefined) {\n advance();\n const escaped = advance();\n switch (escaped) {\n case \"n\": chunk += \"\\n\"; break;\n case \"t\": chunk += \"\\t\"; break;\n case \"r\": chunk += \"\\r\"; break;\n case \"\\\\\": chunk += \"\\\\\"; break;\n case '\"': chunk += '\"'; break;\n case \"'\": chunk += \"'\"; break;\n case \"`\": chunk += \"`\"; break;\n case \"$\": chunk += \"$\"; break;\n default: chunk += escaped ?? \"\";\n }\n continue;\n }\n // `${expression}` interpolation. Scan the source inside `${...}` —\n // balanced braces are tracked so JS object literals inside the\n // expression don't terminate the substitution prematurely.\n if (peek() === \"$\" && peek(1) === \"{\") {\n parts.push({ kind: \"str\", text: chunk });\n chunk = \"\";\n const exprLine = line;\n const exprCol = column;\n advance();\n advance();\n let depth = 1;\n let source2 = \"\";\n while (i < source.length && depth > 0) {\n const next = peek();\n if (next === undefined) break;\n // Mirror JS: a nested template literal inside `${...}` shouldn't\n // greedily consume `}`s belonging to *its* substitutions, so we\n // skip over nested template strings as opaque text.\n if (next === \"`\") {\n source2 += advance();\n while (i < source.length && peek() !== \"`\") {\n if (peek() === \"\\\\\" && peek(1) !== undefined) {\n source2 += advance();\n source2 += advance();\n continue;\n }\n source2 += advance();\n }\n if (peek() === \"`\") source2 += advance();\n continue;\n }\n // Skip past quoted strings without counting their internal braces.\n if (next === '\"' || next === \"'\") {\n const q = next;\n source2 += advance();\n while (i < source.length && peek() !== q) {\n if (peek() === \"\\\\\" && peek(1) !== undefined) {\n source2 += advance();\n source2 += advance();\n continue;\n }\n if (peek() === \"\\n\") break;\n source2 += advance();\n }\n if (peek() === q) source2 += advance();\n continue;\n }\n if (next === \"{\") {\n depth += 1;\n source2 += advance();\n continue;\n }\n if (next === \"}\") {\n depth -= 1;\n if (depth === 0) {\n advance();\n break;\n }\n source2 += advance();\n continue;\n }\n source2 += advance();\n }\n parts.push({ kind: \"expr\", source: source2, line: exprLine, column: exprCol });\n sawExpr = true;\n continue;\n }\n chunk += advance();\n }\n if (peek() === \"`\") advance();\n parts.push({ kind: \"str\", text: chunk });\n if (!sawExpr) {\n // Plain backtick string with no interpolation — emit as a regular\n // string so downstream consumers see the same shape as before. This\n // preserves backward compatibility for Script() / @Js() bodies.\n push(\"String\", chunk, startLine, startCol);\n continue;\n }\n tokens.push({\n type: \"TemplateString\",\n value: \"\",\n line: startLine,\n column: startCol,\n parts,\n });\n continue;\n }\n\n // Number literal.\n //\n // We accept a leading `-` only when the previous token is empty, a\n // newline, or a non-value token (operator, punctuation start). That\n // keeps `$x-1` parseable as `$x - 1` instead of `$x` followed by a\n // bare `-1` literal (which the parser would reject as two adjacent\n // values).\n const lastToken = tokens[tokens.length - 1];\n const allowSignedNumber =\n !lastToken ||\n lastToken.type === \"Newline\" ||\n lastToken.type === \"Operator\" ||\n (lastToken.type === \"Punctuation\" &&\n (lastToken.value === \"(\" || lastToken.value === \"[\" ||\n lastToken.value === \",\" || lastToken.value === \":\" ||\n lastToken.value === \"?\" || lastToken.value === \"{\"));\n if (isDigit(ch) || (ch === \"-\" && isDigit(peek(1) ?? \"\") && allowSignedNumber)) {\n const startLine = line;\n const startCol = column;\n let raw = \"\";\n if (ch === \"-\") raw += advance();\n let sawDot = false;\n while (i < source.length) {\n const next = peek() ?? \"\";\n if (isDigit(next)) {\n raw += advance();\n continue;\n }\n // Only accept a single decimal point; subsequent dots terminate\n // the number so identifiers like `arr.length` after a digit-only\n // member access stay well-formed.\n if (next === \".\" && !sawDot && isDigit(peek(1) ?? \"\")) {\n sawDot = true;\n raw += advance();\n continue;\n }\n break;\n }\n push(\"Number\", raw, startLine, startCol);\n continue;\n }\n\n // Builtin identifier: @Name\n if (ch === \"@\") {\n const startLine = line;\n const startCol = column;\n advance();\n let name = \"\";\n while (i < source.length && isIdentifierChar(peek() ?? \"\")) {\n name += advance();\n }\n push(\"BuiltinIdentifier\", name, startLine, startCol);\n continue;\n }\n\n // State identifier: $name. Reactive atoms are declared with `$name = value`\n // and referenced as `$name`. The legacy `$$name` persistent sigil was\n // removed — throw a clear migration error so any surviving `$$x` doesn't\n // silently lex to two separate tokens.\n if (ch === \"$\") {\n const startLine = line;\n const startCol = column;\n advance();\n if (peek() === \"$\") {\n const err = new Error(\n 'Legacy \"$$x\" persistent reference is removed. ' +\n 'Reactive state is declared with \"$x = value\" and referenced as \"$x\".',\n ) as Error & { line?: number; column?: number };\n err.line = startLine;\n err.column = startCol;\n throw err;\n }\n let name = \"\";\n while (i < source.length && isIdentifierChar(peek() ?? \"\")) {\n name += advance();\n }\n push(\"StateIdentifier\", name, startLine, startCol);\n continue;\n }\n\n // Identifier or keyword.\n if (isIdentifierStart(ch)) {\n const startLine = line;\n const startCol = column;\n let name = \"\";\n while (i < source.length && isIdentifierChar(peek() ?? \"\")) {\n name += advance();\n }\n\n // `js{ … }` opaque blocks (also accepts `js { … }` with whitespace\n // between the keyword and the brace — easier on hand-written code).\n // The body is captured verbatim with balanced-brace tracking so the\n // runtime can pass it through to the `js` capability without\n // re-parsing.\n if (name === \"js\") {\n // Skip horizontal whitespace (but NOT newlines) between `js` and\n // `{`. Newlines terminate the keyword early — `js\\n{ ... }` is\n // not a JsBlock, just an identifier reference followed by an\n // unrelated block.\n let lookahead = 0;\n while (\n peek(lookahead) === \" \" || peek(lookahead) === \"\\t\"\n ) lookahead += 1;\n if (peek(lookahead) === \"{\") {\n // Consume the gap, then fall into the JsBlock body capture.\n for (let s = 0; s < lookahead; s += 1) advance();\n }\n }\n if (name === \"js\" && peek() === \"{\") {\n advance(); // consume `{`\n let body = \"\";\n let depth = 1;\n while (i < source.length && depth > 0) {\n const next = peek();\n if (next === undefined) break;\n if (next === \"\\\\\" && peek(1) !== undefined) {\n body += advance();\n body += advance();\n continue;\n }\n // Skip past quoted strings without counting their internal braces.\n if (next === '\"' || next === \"'\") {\n const q = next;\n body += advance();\n while (i < source.length && peek() !== q) {\n if (peek() === \"\\\\\" && peek(1) !== undefined) {\n body += advance();\n body += advance();\n continue;\n }\n if (peek() === \"\\n\") break;\n body += advance();\n }\n if (peek() === q) body += advance();\n continue;\n }\n // Skip past template literals as opaque text.\n if (next === \"`\") {\n body += advance();\n while (i < source.length && peek() !== \"`\") {\n if (peek() === \"\\\\\" && peek(1) !== undefined) {\n body += advance();\n body += advance();\n continue;\n }\n body += advance();\n }\n if (peek() === \"`\") body += advance();\n continue;\n }\n // Track nested {} so `function foo(){...}` works.\n if (next === \"{\") {\n depth += 1;\n body += advance();\n continue;\n }\n if (next === \"}\") {\n depth -= 1;\n if (depth === 0) {\n advance();\n break;\n }\n body += advance();\n continue;\n }\n body += advance();\n }\n push(\"JsBlock\", body, startLine, startCol);\n continue;\n }\n\n const keyword = KEYWORDS[name];\n if (keyword === \"Boolean\") {\n push(\"Boolean\", name, startLine, startCol);\n } else if (keyword === \"Null\") {\n push(\"Null\", name, startLine, startCol);\n } else if (KEYWORDS_AKTION.has(name)) {\n push(\"Keyword\", name, startLine, startCol);\n } else {\n push(\"Identifier\", name, startLine, startCol);\n }\n continue;\n }\n\n // Spread operator `...` (must come before single-dot punctuation).\n if (ch === \".\" && peek(1) === \".\" && peek(2) === \".\") {\n const startLine = line;\n const startCol = column;\n advance();\n advance();\n advance();\n push(\"Operator\", \"...\", startLine, startCol);\n continue;\n }\n\n // Multi-character operators: ==, !=, >=, <=, &&, ||, ??, ?., ->, =>,\n // +=, -=, *=, /=, ??=, ++, --.\n const two = ch + (peek(1) ?? \"\");\n const three = two + (peek(2) ?? \"\");\n if (three === \"??=\") {\n const startLine = line;\n const startCol = column;\n advance(); advance(); advance();\n push(\"Operator\", \"??=\", startLine, startCol);\n continue;\n }\n if (\n two === \"==\" || two === \"!=\" || two === \">=\" || two === \"<=\" ||\n two === \"&&\" || two === \"||\" || two === \"??\" || two === \"?.\" ||\n two === \"->\" || two === \"=>\" ||\n two === \"+=\" || two === \"-=\" || two === \"*=\" || two === \"/=\" ||\n two === \"++\" || two === \"--\"\n ) {\n const startLine = line;\n const startCol = column;\n advance();\n advance();\n push(\"Operator\", two, startLine, startCol);\n continue;\n }\n\n // Single-char operators.\n if (\"+-*/%!=<>\".includes(ch)) {\n const startLine = line;\n const startCol = column;\n advance();\n push(\"Operator\", ch, startLine, startCol);\n continue;\n }\n\n // Punctuation.\n if (SINGLE_CHAR_PUNCT.has(ch)) {\n const startLine = line;\n const startCol = column;\n advance();\n push(\"Punctuation\", ch, startLine, startCol);\n continue;\n }\n\n // Unknown char: skip with no token (parser surfaces errors per line).\n advance();\n }\n\n tokens.push({ type: \"EOF\", value: \"\", line, column });\n return tokens;\n}\n\nfunction isDigit(ch: string): boolean {\n return ch >= \"0\" && ch <= \"9\";\n}\n\nfunction isIdentifierStart(ch: string): boolean {\n return (ch >= \"a\" && ch <= \"z\") || (ch >= \"A\" && ch <= \"Z\") || ch === \"_\";\n}\n\nfunction isIdentifierChar(ch: string): boolean {\n return isIdentifierStart(ch) || isDigit(ch);\n}\n","/**\n * Parser for Aktion.\n *\n * Grammar (informal, line-oriented):\n *\n * program := (statement NEWLINE)*\n * statement := assignment\n * assignment := (Identifier | StateIdentifier) \"=\" expression\n * expression := ternary\n * ternary := logicalOr (\"?\" expression \":\" expression)?\n * logicalOr := logicalAnd (\"||\" logicalAnd)*\n * logicalAnd := equality (\"&&\" equality)*\n * equality := comparison ((\"==\" | \"!=\") comparison)*\n * comparison := additive ((\">\" | \"<\" | \">=\" | \"<=\") additive)*\n * additive := multiplicative ((\"+\" | \"-\") multiplicative)*\n * multiplicative := unary ((\"*\" | \"/\" | \"%\") unary)*\n * unary := (\"!\" | \"-\") unary | postfix\n * postfix := primary (\".\" Identifier)*\n * primary := Literal\n * | Identifier (\"(\" args \")\")? ; component or reference\n * | StateIdentifier\n * | \"@\" Identifier \"(\" args \")\" ; builtin call\n * | \"[\" args \"]\" ; array\n * | \"{\" objectProps \"}\" ; object literal\n * | \"(\" expression \")\"\n *\n * Errors per line are collected; the parser tries to recover at NEWLINE.\n */\n\nimport { tokenize, type Token } from \"./lexer.js\";\nimport type {\n Program,\n Statement,\n Expression,\n ParseError,\n ObjectProperty,\n BlockExpr,\n DeclParam,\n EffectRateLimit,\n EffectTrigger,\n} from \"./types.js\";\n\nexport function parse(source: string): Program {\n const tokens = tokenize(source);\n const ctx = new ParserContext(tokens);\n const statements: Statement[] = [];\n const errors: ParseError[] = [];\n\n while (!ctx.isEnd()) {\n if (ctx.match(\"Newline\")) continue;\n\n try {\n const stmt = parseStatement(ctx, true);\n if (stmt) statements.push(stmt);\n } catch (err) {\n const error = err as ParseError;\n errors.push(error);\n ctx.recoverToNextLine();\n }\n }\n\n return { statements, errors };\n}\n\n/**\n * Top-level statement dispatcher. Recognises the language declaration\n * keywords first, then falls back to bare assignments and expression\n * statements.\n *\n * `topLevel` distinguishes program-level statements from block-internal\n * ones (inside `component` / `effect` / `action` bodies). Bare `$x = …`\n * is allowed both at top-level and inside blocks — every `$x = expr`\n * declares (or re-assigns) a reactive state atom.\n */\nfunction parseStatement(ctx: ParserContext, _topLevel: boolean): Statement | null {\n const head = ctx.peek();\n if (head.type === \"Keyword\") {\n switch (head.value) {\n case \"component\": return parseComponentDecl(ctx);\n case \"effect\": return parseEffectDecl(ctx);\n case \"action\": return parseActionDecl(ctx);\n case \"emit\": return parseEmit(ctx);\n case \"cleanup\": return parseCleanup(ctx);\n case \"await\": return parseAwait(ctx);\n case \"return\": return parseReturn(ctx);\n }\n }\n // Try parseAssignment speculatively. If the head is `Identifier \"=\"` /\n // `Identifier \"(\" ... \")\" \"=\"` / `StateIdentifier \"=\"`, parseAssignment\n // succeeds. Otherwise rewind and parse as a bare expression statement —\n // free-standing component calls inside `component { ... }` bodies are\n // the common case (the last expression is the component's render).\n const saved = ctx.snapshot();\n if (couldStartAssignment(ctx)) {\n try {\n return parseAssignment(ctx);\n } catch (err) {\n // Definitive migration errors must bubble — they are intentionally\n // raised by parseAssignment when the user wrote a removed legacy\n // construct (e.g. `Name(args) = expr`). Recovery would mask them\n // behind a generic \"Unexpected token\" error.\n if (err && typeof err === \"object\" && (err as { __definitive?: boolean }).__definitive) {\n throw err;\n }\n ctx.restore(saved);\n // Fall through to expression statement.\n }\n }\n return parseExpressionStatement(ctx);\n}\n\n/**\n * Cheap check: does the immediate token stream look like an assignment\n * (`name =`, `$name =`, or `name(args) =`) rather than an expression\n * statement? A definitive yes returns true; ambiguous cases return true\n * and rely on the speculative parser to recover.\n */\nfunction couldStartAssignment(ctx: ParserContext): boolean {\n const head = ctx.peek();\n if (head.type === \"StateIdentifier\") {\n const next = ctx.peek(1);\n return next.type === \"Operator\" && next.value === \"=\";\n }\n if (head.type !== \"Identifier\") return false;\n const next = ctx.peek(1);\n if (next.type === \"Operator\" && next.value === \"=\") return true;\n // `name(args) = …` is a local-helper definition. Walking the parameter\n // list is expensive; the speculative parser handles it.\n if (next.type === \"Punctuation\" && next.value === \"(\") return true;\n return false;\n}\n\nfunction parseExpressionStatement(ctx: ParserContext): Statement {\n const start = ctx.peek();\n const expression = parseExpression(ctx);\n if (!ctx.isEnd()) ctx.match(\"Newline\");\n return {\n kind: \"ExpressionStatement\",\n expression,\n loc: { line: start.line, column: start.column },\n };\n}\n\nfunction parseComponentDecl(ctx: ParserContext): Statement {\n const start = ctx.expect(\"Keyword\", \"component\");\n const nameTok = ctx.expect(\"Identifier\");\n const { params, slots } = parseComponentSignature(ctx);\n const body = parseBlock(ctx);\n if (!ctx.isEnd()) ctx.match(\"Newline\");\n // Components MUST end in an explicit `return` so the rendered tree is\n // unambiguous; bare last-expression bodies were a 0.5-era convenience\n // that hid intent and made action-returning components confusing.\n const hasReturn = body.body.some((s) => s.kind === \"Return\");\n if (!hasReturn) {\n const err: ParseError & { __definitive?: boolean } = {\n message: `component \"${nameTok.value}\" must end with an explicit \\`return\\` statement.`,\n line: start.line,\n column: start.column,\n };\n err.__definitive = true;\n throw err;\n }\n return {\n kind: \"ComponentDeclaration\",\n name: nameTok.value,\n params,\n slots,\n body,\n loc: { line: start.line, column: start.column },\n };\n}\n\nfunction parseComponentSignature(ctx: ParserContext): {\n params: DeclParam[];\n slots: string[];\n} {\n ctx.expect(\"Punctuation\", \"(\");\n const params: DeclParam[] = [];\n const slots: string[] = [];\n while (ctx.match(\"Newline\")) {/* skip */}\n if (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \")\")) {\n while (true) {\n while (ctx.match(\"Newline\")) {/* skip */}\n const tok = ctx.peek();\n // `slots: { footer?, header? }` declaration. `slots` is a contextual\n // keyword that only matters in the component signature position;\n // elsewhere it parses as an ordinary identifier so `slots.footer`\n // works inside the body.\n if (tok.type === \"Identifier\" && tok.value === \"slots\") {\n ctx.consume();\n ctx.expect(\"Punctuation\", \":\");\n ctx.expect(\"Punctuation\", \"{\");\n while (ctx.match(\"Newline\")) {/* skip */}\n while (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"}\")) {\n const slotTok = ctx.expect(\"Identifier\");\n slots.push(slotTok.value);\n // Optional `?`.\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"?\") {\n ctx.consume();\n }\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") {\n ctx.consume();\n while (ctx.match(\"Newline\")) {/* skip */}\n }\n }\n ctx.expect(\"Punctuation\", \"}\");\n } else if (tok.type === \"Identifier\" || tok.type === \"Keyword\") {\n // Accept keywords as component parameter names so component bodies\n // can take props like `action`, `effect`, `query`, etc. without\n // forcing the author to rename them.\n const nameTok = ctx.consume();\n let defaultValue: Expression | undefined;\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \":\") {\n ctx.consume();\n defaultValue = parseExpression(ctx);\n }\n params.push({ name: nameTok.value, defaultValue });\n } else {\n throw {\n message: `Expected parameter name, got ${tok.type} \"${tok.value}\"`,\n line: tok.line,\n column: tok.column,\n } satisfies ParseError;\n }\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") {\n ctx.consume();\n continue;\n }\n break;\n }\n }\n ctx.expect(\"Punctuation\", \")\");\n return { params, slots };\n}\n\nfunction parseEffectDecl(ctx: ParserContext): Statement {\n const start = ctx.expect(\"Keyword\", \"effect\");\n const triggers: EffectTrigger[] = [];\n let rateLimit: EffectRateLimit | undefined;\n\n // New canonical form: `effect [ ...deps ] { body }` or `effect { body }`.\n // The dependency list is a square-bracket array whose entries can be:\n // - `$name` → state trigger\n // - `on:mount` / `on:unmount`→ lifecycle trigger\n // - `on:every(N)` → interval trigger\n // - `debounce(N)` / `throttle(N)` → rate-limit modifier\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"[\") {\n ctx.consume();\n while (ctx.match(\"Newline\")) { /* skip */ }\n while (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"]\")) {\n parseEffectDependency(ctx, triggers, (rl) => { rateLimit = rl; });\n while (ctx.match(\"Newline\")) { /* skip */ }\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") {\n ctx.consume();\n while (ctx.match(\"Newline\")) { /* skip */ }\n }\n }\n ctx.expect(\"Punctuation\", \"]\");\n }\n\n const body = parseBlock(ctx);\n if (!ctx.isEnd()) ctx.match(\"Newline\");\n const decl: Statement = {\n kind: \"EffectDeclaration\",\n name: `__effect_L${start.line}_C${start.column}`,\n triggers,\n body,\n loc: { line: start.line, column: start.column },\n };\n if (rateLimit) decl.rateLimit = rateLimit;\n return decl;\n}\n\n/**\n * Parse a single dependency entry inside `effect [ … ]`. Each entry\n * commits either a trigger (state / lifecycle / every) or a rate-limit\n * modifier (debounce / throttle).\n */\nfunction parseEffectDependency(\n ctx: ParserContext,\n triggers: EffectTrigger[],\n setRateLimit: (rl: EffectRateLimit) => void,\n): void {\n const head = ctx.peek();\n\n // `$state` reference → state trigger.\n if (head.type === \"StateIdentifier\") {\n ctx.consume();\n triggers.push({ kind: \"state\", name: head.value });\n return;\n }\n\n // `on:mount` / `on:unmount` / `on:every(N)`.\n if (head.type === \"Keyword\" && head.value === \"on\") {\n ctx.consume();\n ctx.expect(\"Punctuation\", \":\");\n const lifecycle = ctx.expect(\"Identifier\").value;\n if (lifecycle === \"mount\" || lifecycle === \"unmount\") {\n triggers.push({ kind: \"lifecycle\", name: lifecycle });\n return;\n }\n if (lifecycle === \"every\") {\n ctx.expect(\"Punctuation\", \"(\");\n const arg = ctx.expect(\"Number\");\n ctx.expect(\"Punctuation\", \")\");\n triggers.push({ kind: \"every\", intervalMs: Number(arg.value) });\n return;\n }\n throw {\n message: `Unknown lifecycle trigger \"on:${lifecycle}\" inside effect dependency list`,\n line: head.line,\n column: head.column,\n } satisfies ParseError;\n }\n\n // `debounce(N)` / `throttle(N)` modifier.\n if (head.type === \"Identifier\" && (head.value === \"debounce\" || head.value === \"throttle\")) {\n const kind = ctx.consume().value as \"debounce\" | \"throttle\";\n ctx.expect(\"Punctuation\", \"(\");\n const arg = ctx.expect(\"Number\");\n ctx.expect(\"Punctuation\", \")\");\n setRateLimit({ kind, ms: Number(arg.value) });\n return;\n }\n\n throw {\n message:\n `Unexpected ${head.type} \"${head.value}\" inside effect dependency list. ` +\n `Expected $state, on:mount, on:unmount, on:every(N), debounce(N), or throttle(N).`,\n line: head.line,\n column: head.column,\n } satisfies ParseError;\n}\n\nfunction parseActionDecl(ctx: ParserContext): Statement {\n const start = ctx.expect(\"Keyword\", \"action\");\n const nameTok = ctx.expect(\"Identifier\");\n let params: DeclParam[] = [];\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"(\") {\n params = parseComponentSignature(ctx).params;\n }\n consumeLegacyUsesClause(ctx);\n let optimistic = false;\n if (ctx.peek().type === \"Keyword\" && ctx.peek().value === \"optimistic\") {\n ctx.consume();\n optimistic = true;\n }\n const body = parseBlock(ctx);\n if (!ctx.isEnd()) ctx.match(\"Newline\");\n return {\n kind: \"ActionDeclaration\",\n name: nameTok.value,\n params,\n optimistic,\n body,\n loc: { line: start.line, column: start.column },\n };\n}\n\n/**\n * Aktion does not carry a `uses { … }` capability clause on `action`\n * declarations — every runtime primitive (timers, network, DOM, storage,\n * clipboard, `js{}` blocks, …) is available unconditionally. Silently\n * swallow a stray `uses { … }` clause so older programs keep parsing.\n */\nfunction consumeLegacyUsesClause(ctx: ParserContext): EffectRateLimit | undefined {\n const tok = ctx.peek();\n if (tok.type !== \"Identifier\" || tok.value !== \"uses\") return undefined;\n ctx.consume();\n ctx.expect(\"Punctuation\", \"{\");\n let rateLimit: EffectRateLimit | undefined;\n while (ctx.match(\"Newline\")) {/* skip */}\n while (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"}\")) {\n const head = ctx.peek();\n if (head.type !== \"Identifier\" && head.type !== \"Keyword\") {\n throw {\n message: `Expected capability name inside legacy \"uses { … }\" clause, got ${head.type} \"${head.value}\"`,\n line: head.line,\n column: head.column,\n } satisfies ParseError;\n }\n let name = ctx.consume().value;\n while (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \".\") {\n ctx.consume();\n name += `.${ctx.expect(\"Identifier\").value}`;\n }\n let firstArg: number | undefined;\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"(\") {\n ctx.consume();\n if (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \")\")) {\n const arg = ctx.peek();\n if (arg.type === \"Number\") {\n firstArg = Number(arg.value);\n }\n // Discard remaining args inside the (...).\n let depth = 1;\n while (!ctx.isEnd() && depth > 0) {\n const next = ctx.consume();\n if (next.type === \"Punctuation\" && next.value === \"(\") depth += 1;\n else if (next.type === \"Punctuation\" && next.value === \")\") depth -= 1;\n }\n } else {\n ctx.expect(\"Punctuation\", \")\");\n }\n }\n if ((name === \"debounce\" || name === \"throttle\") && firstArg !== undefined) {\n rateLimit = { kind: name, ms: firstArg };\n }\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") {\n ctx.consume();\n while (ctx.match(\"Newline\")) {/* skip */}\n }\n }\n ctx.expect(\"Punctuation\", \"}\");\n return rateLimit;\n}\n\n\nfunction parseBlock(ctx: ParserContext): BlockExpr {\n const start = ctx.expect(\"Punctuation\", \"{\");\n const body: Statement[] = [];\n while (ctx.match(\"Newline\")) {/* skip */}\n while (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"}\")) {\n const stmt = parseStatement(ctx, false);\n if (stmt) body.push(stmt);\n while (ctx.match(\"Newline\")) {/* skip */}\n }\n ctx.expect(\"Punctuation\", \"}\");\n return {\n kind: \"Block\",\n body,\n loc: { line: start.line, column: start.column },\n };\n}\n\nfunction parseEmit(ctx: ParserContext): Statement {\n const start = ctx.expect(\"Keyword\", \"emit\");\n const nameTok = ctx.expect(\"String\");\n let detail: Expression = { kind: \"Object\", properties: [] };\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"{\") {\n ctx.consume();\n const props = parseObjectProps(ctx);\n ctx.expect(\"Punctuation\", \"}\");\n detail = { kind: \"Object\", properties: props };\n }\n if (!ctx.isEnd()) ctx.match(\"Newline\");\n return {\n kind: \"Emit\",\n eventName: nameTok.value,\n detail,\n loc: { line: start.line, column: start.column },\n };\n}\n\nfunction parseCleanup(ctx: ParserContext): Statement {\n const start = ctx.expect(\"Keyword\", \"cleanup\");\n ctx.expect(\"Punctuation\", \"(\");\n const callback = parseExpression(ctx);\n ctx.expect(\"Punctuation\", \")\");\n if (!ctx.isEnd()) ctx.match(\"Newline\");\n return {\n kind: \"Cleanup\",\n callback,\n loc: { line: start.line, column: start.column },\n };\n}\n\nfunction parseAwait(ctx: ParserContext): Statement {\n const start = ctx.expect(\"Keyword\", \"await\");\n const argument = parseExpression(ctx);\n if (!ctx.isEnd()) ctx.match(\"Newline\");\n return {\n kind: \"Await\",\n argument,\n loc: { line: start.line, column: start.column },\n };\n}\n\nfunction parseReturn(ctx: ParserContext): Statement {\n const start = ctx.expect(\"Keyword\", \"return\");\n let argument: Expression | undefined;\n const next = ctx.peek();\n if (next.type !== \"Newline\" && !(next.type === \"Punctuation\" && next.value === \"}\")) {\n argument = parseExpression(ctx);\n }\n if (!ctx.isEnd()) ctx.match(\"Newline\");\n return {\n kind: \"Return\",\n argument,\n loc: { line: start.line, column: start.column },\n };\n}\n\nclass ParserContext {\n private index = 0;\n constructor(private readonly tokens: Token[]) {}\n\n isEnd(): boolean {\n return this.peek().type === \"EOF\";\n }\n\n peek(offset = 0): Token {\n return this.tokens[this.index + offset] ?? { type: \"EOF\", value: \"\", line: 0, column: 0 };\n }\n\n consume(): Token {\n const tok = this.tokens[this.index] ?? { type: \"EOF\", value: \"\", line: 0, column: 0 };\n this.index += 1;\n return tok;\n }\n\n /** Skip a token only if it matches the given type/value, returning true. */\n match(type: Token[\"type\"], value?: string): boolean {\n const tok = this.peek();\n if (tok.type !== type) return false;\n if (value !== undefined && tok.value !== value) return false;\n this.consume();\n return true;\n }\n\n expect(type: Token[\"type\"], value?: string): Token {\n const tok = this.peek();\n if (tok.type !== type || (value !== undefined && tok.value !== value)) {\n throw {\n message: `Expected ${type}${value !== undefined ? ` \"${value}\"` : \"\"} but got ${tok.type} \"${tok.value}\"`,\n line: tok.line,\n column: tok.column,\n } satisfies ParseError;\n }\n return this.consume();\n }\n\n recoverToNextLine(): void {\n while (!this.isEnd() && this.peek().type !== \"Newline\") this.consume();\n if (this.peek().type === \"Newline\") this.consume();\n }\n\n /** Capture the current token cursor for speculative parsing. */\n snapshot(): number {\n return this.index;\n }\n\n /** Restore the cursor to a previous snapshot — see `parseAssignment`. */\n restore(index: number): void {\n this.index = index;\n }\n}\n\nfunction parseAssignment(ctx: ParserContext): Statement | null {\n const head = ctx.peek();\n let identifier = \"\";\n let isState = false;\n if (head.type === \"Identifier\") {\n identifier = ctx.consume().value;\n // The legacy `Name(args) = expr` macro shorthand was removed in Streaming\n // UI Script 0.5. We still recognise the pattern so we can surface a\n // clear migration error pointing the author at `component` blocks for\n // top-level reusables or at lambdas (`name = (args) => …`) for local\n // helpers — silently falling through would produce a confusing\n // \"expected =, got (\" message instead.\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"(\") {\n const savedIndex = ctx.snapshot();\n ctx.consume();\n const parsedParams: string[] = [];\n let ok = true;\n while (ctx.match(\"Newline\")) {/* skip */}\n if (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \")\")) {\n while (true) {\n while (ctx.match(\"Newline\")) {/* skip */}\n const tok = ctx.peek();\n if (tok.type !== \"Identifier\") { ok = false; break; }\n parsedParams.push(ctx.consume().value);\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") {\n ctx.consume();\n continue;\n }\n break;\n }\n }\n if (ok && ctx.peek().type === \"Punctuation\" && ctx.peek().value === \")\") {\n ctx.consume();\n if (ctx.peek().type === \"Operator\" && ctx.peek().value === \"=\") {\n // Surface a *definitive* migration error so the speculative\n // statement dispatcher does not swallow it and retry as an\n // expression statement (which would produce a generic\n // \"Unexpected token\" instead of the helpful guidance below).\n const err: ParseError & { __definitive?: boolean } = {\n message:\n `Legacy \"${identifier}(...) = expr\" macro shorthand is removed in ` +\n `Aktion 0.5. Use \"component ${identifier}(` +\n `${parsedParams.join(\", \")}) { ... }\" for reusables, or ` +\n `\"${identifier} = (${parsedParams.join(\", \")}) => ...\" for ` +\n `local helpers.`,\n line: head.line,\n column: head.column,\n };\n err.__definitive = true;\n throw err;\n }\n ctx.restore(savedIndex);\n } else {\n ctx.restore(savedIndex);\n }\n }\n } else if (head.type === \"StateIdentifier\") {\n identifier = ctx.consume().value;\n isState = true;\n } else {\n throw {\n message: `Expected identifier at start of statement, got ${head.type} \"${head.value}\"`,\n line: head.line,\n column: head.column,\n } satisfies ParseError;\n }\n\n const eq = ctx.expect(\"Operator\", \"=\");\n const expression = parseExpression(ctx);\n\n // Trailing newline (or EOF).\n if (!ctx.isEnd()) ctx.match(\"Newline\");\n\n return {\n kind: \"Assignment\",\n identifier,\n isState,\n expression,\n loc: { line: eq.line, column: eq.column },\n };\n}\n\nfunction parseExpression(ctx: ParserContext): Expression {\n return parseTernary(ctx);\n}\n\nfunction parseTernary(ctx: ParserContext): Expression {\n const test = parseLogicalOr(ctx);\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"?\") {\n ctx.consume();\n const consequent = parseExpression(ctx);\n ctx.expect(\"Punctuation\", \":\");\n const alternate = parseExpression(ctx);\n return { kind: \"Ternary\", test, consequent, alternate };\n }\n return test;\n}\n\nfunction parseLogicalOr(ctx: ParserContext): Expression {\n let left = parseLogicalAnd(ctx);\n // `??` shares precedence with `||` here for simplicity — authors who want\n // to mix `??` and `||` in the same expression should parenthesise.\n while (\n ctx.peek().type === \"Operator\" &&\n (ctx.peek().value === \"||\" || ctx.peek().value === \"??\")\n ) {\n const op = ctx.consume().value as \"||\" | \"??\";\n const right = parseLogicalAnd(ctx);\n left = { kind: \"Binary\", operator: op, left, right };\n }\n return left;\n}\n\nfunction parseLogicalAnd(ctx: ParserContext): Expression {\n let left = parseEquality(ctx);\n while (ctx.peek().type === \"Operator\" && ctx.peek().value === \"&&\") {\n ctx.consume();\n const right = parseEquality(ctx);\n left = { kind: \"Binary\", operator: \"&&\", left, right };\n }\n return left;\n}\n\nfunction parseEquality(ctx: ParserContext): Expression {\n let left = parseComparison(ctx);\n while (ctx.peek().type === \"Operator\" && (ctx.peek().value === \"==\" || ctx.peek().value === \"!=\")) {\n const op = ctx.consume().value as \"==\" | \"!=\";\n const right = parseComparison(ctx);\n left = { kind: \"Binary\", operator: op, left, right };\n }\n return left;\n}\n\nfunction parseComparison(ctx: ParserContext): Expression {\n let left = parseAdditive(ctx);\n while (\n ctx.peek().type === \"Operator\" &&\n [\">\", \"<\", \">=\", \"<=\"].includes(ctx.peek().value)\n ) {\n const op = ctx.consume().value as \">\" | \"<\" | \">=\" | \"<=\";\n const right = parseAdditive(ctx);\n left = { kind: \"Binary\", operator: op, left, right };\n }\n return left;\n}\n\nfunction parseAdditive(ctx: ParserContext): Expression {\n let left = parseMultiplicative(ctx);\n while (ctx.peek().type === \"Operator\" && (ctx.peek().value === \"+\" || ctx.peek().value === \"-\")) {\n const op = ctx.consume().value as \"+\" | \"-\";\n const right = parseMultiplicative(ctx);\n left = { kind: \"Binary\", operator: op, left, right };\n }\n return left;\n}\n\nfunction parseMultiplicative(ctx: ParserContext): Expression {\n let left = parseUnary(ctx);\n while (\n ctx.peek().type === \"Operator\" &&\n (ctx.peek().value === \"*\" || ctx.peek().value === \"/\" || ctx.peek().value === \"%\")\n ) {\n const op = ctx.consume().value as \"*\" | \"/\" | \"%\";\n const right = parseUnary(ctx);\n left = { kind: \"Binary\", operator: op, left, right };\n }\n return left;\n}\n\nfunction parseUnary(ctx: ParserContext): Expression {\n const tok = ctx.peek();\n if (tok.type === \"Operator\" && (tok.value === \"!\" || tok.value === \"-\")) {\n ctx.consume();\n const argument = parseUnary(ctx);\n return { kind: \"Unary\", operator: tok.value as \"!\" | \"-\", argument };\n }\n return parsePostfix(ctx);\n}\n\nfunction parsePostfix(ctx: ParserContext): Expression {\n let expr = parsePrimary(ctx);\n while (true) {\n const tok = ctx.peek();\n if (tok.type === \"Punctuation\" && tok.value === \".\") {\n ctx.consume();\n const propTok = ctx.consume();\n if (propTok.type !== \"Identifier\" && propTok.type !== \"Keyword\") {\n throw {\n message: `Expected Identifier but got ${propTok.type} \"${propTok.value}\"`,\n line: propTok.line,\n column: propTok.column,\n } satisfies ParseError;\n }\n const after = ctx.peek();\n if (after.type === \"Punctuation\" && after.value === \"(\") {\n ctx.consume();\n const args = parseCallArgs(ctx, { named: true });\n ctx.expect(\"Punctuation\", \")\");\n expr = {\n kind: \"MethodCall\",\n object: expr,\n method: propTok.value,\n arguments: args,\n loc: { line: propTok.line, column: propTok.column },\n };\n continue;\n }\n expr = { kind: \"Member\", object: expr, property: propTok.value };\n continue;\n }\n if (tok.type === \"Operator\" && tok.value === \"?.\") {\n ctx.consume();\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"[\") {\n ctx.consume();\n const computed = parseExpression(ctx);\n ctx.expect(\"Punctuation\", \"]\");\n expr = { kind: \"Member\", object: expr, computed, optional: true };\n } else {\n const propTok = ctx.consume();\n if (propTok.type !== \"Identifier\" && propTok.type !== \"Keyword\") {\n throw {\n message: `Expected Identifier but got ${propTok.type} \"${propTok.value}\"`,\n line: propTok.line,\n column: propTok.column,\n } satisfies ParseError;\n }\n const after = ctx.peek();\n if (after.type === \"Punctuation\" && after.value === \"(\") {\n ctx.consume();\n const args = parseCallArgs(ctx, { named: true });\n ctx.expect(\"Punctuation\", \")\");\n expr = {\n kind: \"MethodCall\",\n object: expr,\n method: propTok.value,\n arguments: args,\n optional: true,\n loc: { line: propTok.line, column: propTok.column },\n };\n continue;\n }\n expr = { kind: \"Member\", object: expr, property: propTok.value, optional: true };\n }\n continue;\n }\n if (tok.type === \"Punctuation\" && tok.value === \"[\") {\n ctx.consume();\n const computed = parseExpression(ctx);\n ctx.expect(\"Punctuation\", \"]\");\n expr = { kind: \"Member\", object: expr, computed };\n continue;\n }\n break;\n }\n return expr;\n}\n\nfunction parsePrimary(ctx: ParserContext): Expression {\n const tok = ctx.peek();\n\n // Aktion 0.5 expression forms — `if`, `match`, `for` evaluate to ComponentNodes.\n if (tok.type === \"Keyword\") {\n if (tok.value === \"if\") return parseIfExpression(ctx);\n if (tok.value === \"match\") return parseMatchExpression(ctx);\n if (tok.value === \"for\") return parseForExpression(ctx);\n // Keywords that are also valid component-parameter / object-key names\n // may appear in identifier position inside expressions (e.g. a body\n // that re-emits a `action` parameter). Treat them as identifiers when\n // not followed by tokens that would start a declaration.\n if (tok.value === \"action\" || tok.value === \"effect\") {\n const nxt = ctx.peek(1);\n const looksLikeDecl = nxt && nxt.type === \"Identifier\";\n if (!looksLikeDecl) {\n ctx.consume();\n return { kind: \"Identifier\", name: tok.value, loc: { line: tok.line, column: tok.column } };\n }\n }\n }\n\n if (tok.type === \"JsBlock\") {\n ctx.consume();\n return {\n kind: \"JsBlock\",\n body: tok.value,\n loc: { line: tok.line, column: tok.column },\n };\n }\n\n if (tok.type === \"Number\") {\n ctx.consume();\n const value = Number(tok.value);\n return { kind: \"Literal\", value };\n }\n if (tok.type === \"String\") {\n ctx.consume();\n return { kind: \"Literal\", value: tok.value };\n }\n if (tok.type === \"TemplateString\") {\n ctx.consume();\n const parts = tok.parts ?? [];\n const quasis: string[] = [];\n const expressions: Expression[] = [];\n let pendingChunk = \"\";\n let hasPendingChunk = false;\n const flushChunk = (): void => {\n quasis.push(pendingChunk);\n pendingChunk = \"\";\n hasPendingChunk = false;\n };\n for (const part of parts) {\n if (part.kind === \"str\") {\n pendingChunk += part.text;\n hasPendingChunk = true;\n continue;\n }\n if (!hasPendingChunk) {\n // Interpolation runs back-to-back (e.g. `${a}${b}`). The template\n // literal grammar requires a quasi between every expression so we\n // emit an empty chunk to keep the invariant.\n quasis.push(\"\");\n } else {\n flushChunk();\n }\n // Parse the substring as a standalone expression by feeding it\n // through `parse` wrapped in a synthetic assignment. We can't call\n // `parseExpression` directly because it expects a token stream and\n // the substring still needs its own lexer pass.\n const sub = parse(`__rui_tmpl__ = ${part.source}`);\n const firstStmt = sub.statements[0];\n if (firstStmt && firstStmt.kind === \"Assignment\") {\n expressions.push(firstStmt.expression);\n } else {\n expressions.push({ kind: \"Literal\", value: \"\" });\n }\n }\n if (hasPendingChunk || quasis.length === 0) {\n quasis.push(pendingChunk);\n }\n while (quasis.length <= expressions.length) quasis.push(\"\");\n return {\n kind: \"Template\",\n quasis,\n expressions,\n loc: { line: tok.line, column: tok.column },\n };\n }\n if (tok.type === \"Boolean\") {\n ctx.consume();\n return { kind: \"Literal\", value: tok.value === \"true\" };\n }\n if (tok.type === \"Null\") {\n ctx.consume();\n return { kind: \"Literal\", value: null };\n }\n if (tok.type === \"StateIdentifier\") {\n ctx.consume();\n return { kind: \"StateRef\", name: tok.value };\n }\n if (tok.type === \"BuiltinIdentifier\") {\n ctx.consume();\n ctx.expect(\"Punctuation\", \"(\");\n const args = parseCallArgs(ctx, { named: true });\n ctx.expect(\"Punctuation\", \")\");\n return {\n kind: \"BuiltinCall\",\n name: tok.value,\n arguments: args,\n loc: { line: tok.line, column: tok.column },\n };\n }\n if (tok.type === \"Identifier\") {\n ctx.consume();\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"(\") {\n ctx.consume();\n const args = parseCallArgs(ctx, { named: true });\n ctx.expect(\"Punctuation\", \")\");\n return {\n kind: \"Call\",\n callee: tok.value,\n arguments: args,\n loc: { line: tok.line, column: tok.column },\n };\n }\n return {\n kind: \"Identifier\",\n name: tok.value,\n loc: { line: tok.line, column: tok.column },\n };\n }\n if (tok.type === \"Punctuation\" && tok.value === \"[\") {\n ctx.consume();\n const elements = parseCallArgs(ctx);\n ctx.expect(\"Punctuation\", \"]\");\n return { kind: \"Array\", elements };\n }\n if (tok.type === \"Punctuation\" && tok.value === \"{\") {\n ctx.consume();\n const properties = parseObjectProps(ctx);\n ctx.expect(\"Punctuation\", \"}\");\n return { kind: \"Object\", properties };\n }\n if (tok.type === \"Punctuation\" && tok.value === \"(\") {\n // Could be either a parenthesised expression OR a lambda parameter\n // list. Speculatively try lambda first by walking ahead to find a\n // matching `)` followed by `=>`. If matched, parse as lambda;\n // otherwise rewind and parse as a normal grouping.\n const saved = ctx.snapshot();\n const lambda = tryParseLambdaFromParenList(ctx);\n if (lambda) return lambda;\n ctx.restore(saved);\n ctx.consume(); // (\n const expr = parseExpression(ctx);\n ctx.expect(\"Punctuation\", \")\");\n return expr;\n }\n\n throw {\n message: `Unexpected token ${tok.type} \"${tok.value}\"`,\n line: tok.line,\n column: tok.column,\n } satisfies ParseError;\n}\n\nfunction parseCallArgs(ctx: ParserContext, opts?: { named?: boolean }): Expression[] {\n const args: Expression[] = [];\n const allowNamed = opts?.named === true;\n // Allow newlines/whitespace inside argument lists for multi-line forms.\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && (ctx.peek().value === \")\" || ctx.peek().value === \"]\")) {\n return args;\n }\n args.push(allowNamed ? parseCallArgItem(ctx) : parseArgItem(ctx));\n while (ctx.match(\"Newline\")) {/* skip */}\n while (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") {\n ctx.consume();\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && (ctx.peek().value === \")\" || ctx.peek().value === \"]\")) {\n break;\n }\n args.push(allowNamed ? parseCallArgItem(ctx) : parseArgItem(ctx));\n while (ctx.match(\"Newline\")) {/* skip */}\n }\n while (ctx.match(\"Newline\")) {/* skip */}\n return args;\n}\n\n/**\n * Single argument or array element. Recognises the spread form `...expr`\n * which is valid inside `[...]` only — callers that don't want spread will\n * receive a `SpreadExpr` they can reject. We keep the validation in the\n * evaluator so the parser stays small.\n */\nfunction parseArgItem(ctx: ParserContext): Expression {\n if (ctx.peek().type === \"Operator\" && ctx.peek().value === \"...\") {\n const tok = ctx.consume();\n const argument = parseExpression(ctx);\n return { kind: \"Spread\", argument, loc: { line: tok.line, column: tok.column } };\n }\n return parseExpression(ctx);\n}\n\n/**\n * Call-list argument: optional `name: expr` / `bind:prop: stateRef` before\n * falling back to a full expression. Named args are only allowed in `(...)`\n * lists, not `[...]`.\n *\n * The legacy `name=expr` form has been removed in Aktion 0.5 —\n * the parser surfaces a definitive migration error pointing the author at\n * the canonical `name: expr` form. Silently accepting both would let LLM\n * outputs keep drifting and would re-introduce the very ambiguity the\n * \"named args with `:`, defaults with `:`\" rule exists to resolve.\n */\nfunction parseCallArgItem(ctx: ParserContext): Expression {\n if (ctx.peek().type === \"Operator\" && ctx.peek().value === \"...\") {\n const tok = ctx.consume();\n const argument = parseExpression(ctx);\n return { kind: \"Spread\", argument, loc: { line: tok.line, column: tok.column } };\n }\n // `bind:prop: stateRef` two-way binding sugar.\n if (ctx.peek().type === \"Keyword\" && ctx.peek().value === \"bind\") {\n const start = ctx.consume();\n ctx.expect(\"Punctuation\", \":\");\n const propTok = ctx.expect(\"Identifier\");\n ctx.expect(\"Punctuation\", \":\");\n const target = parseExpression(ctx);\n return {\n kind: \"Bind\",\n prop: propTok.value,\n target,\n loc: { line: start.line, column: start.column },\n };\n }\n // Reject legacy `name=expr` form with a clear migration error before\n // attempting to parse it as an expression. The error is marked\n // `__definitive` so the speculative statement dispatcher does not\n // swallow it and retry as a bare expression statement (which would\n // produce a misleading \"Unexpected token\" error instead).\n if (\n ctx.peek().type === \"Identifier\" &&\n ctx.peek(1).type === \"Operator\" &&\n ctx.peek(1).value === \"=\"\n ) {\n const nameTok = ctx.peek();\n const err: ParseError & { __definitive?: boolean } = {\n message:\n `Legacy \"name=value\" named-arg form is removed in Aktion 0.5. ` +\n `Use \"${nameTok.value}: value\" instead.`,\n line: nameTok.line,\n column: nameTok.column,\n };\n err.__definitive = true;\n throw err;\n }\n // `name: expr` — the canonical Aktion 0.5 named-arg form.\n // Distinguish from a free-standing ternary by requiring the\n // `Identifier \":\"` (or `Keyword \":\"`) pair to be a clean prefix. We\n // accept keyword tokens as prop names so component authors can use\n // names like `action`, `effect`, `query`, `mutation`, `subscription`,\n // `component`, `then` as props without escaping (matches the\n // object-literal parser's behaviour for keys).\n const head = ctx.peek();\n if (\n (head.type === \"Identifier\" || head.type === \"Keyword\") &&\n ctx.peek(1).type === \"Punctuation\" &&\n ctx.peek(1).value === \":\"\n ) {\n const nameTok = ctx.consume();\n ctx.consume(); // :\n const value = parseExpression(ctx);\n return {\n kind: \"NamedArg\",\n name: nameTok.value,\n value,\n loc: { line: nameTok.line, column: nameTok.column },\n };\n }\n return parseExpression(ctx);\n}\n\n/**\n * Parse an `if cond { ... } [else (if-expr | block)]` expression. The\n * `if` keyword has already been peeked but not consumed.\n */\nfunction parseIfExpression(ctx: ParserContext): Expression {\n const start = ctx.expect(\"Keyword\", \"if\");\n const test = parseExpression(ctx);\n const consequent = parseBlock(ctx);\n let alternate: Expression | undefined;\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Keyword\" && ctx.peek().value === \"else\") {\n ctx.consume();\n if (ctx.peek().type === \"Keyword\" && ctx.peek().value === \"if\") {\n alternate = parseIfExpression(ctx);\n } else {\n alternate = parseBlock(ctx);\n }\n }\n return {\n kind: \"If\",\n test,\n consequent,\n alternate: alternate as never,\n loc: { line: start.line, column: start.column },\n };\n}\n\nfunction parseMatchExpression(ctx: ParserContext): Expression {\n const start = ctx.expect(\"Keyword\", \"match\");\n const discriminant = parseExpression(ctx);\n ctx.expect(\"Punctuation\", \"{\");\n const arms: { pattern: Expression | \"_\"; body: Expression }[] = [];\n while (ctx.match(\"Newline\")) {/* skip */}\n while (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"}\")) {\n let pattern: Expression | \"_\";\n const tok = ctx.peek();\n if (tok.type === \"Keyword\" && tok.value === \"default\") {\n ctx.consume();\n pattern = \"_\";\n } else {\n pattern = parseExpression(ctx);\n }\n ctx.expect(\"Punctuation\", \":\");\n const body = parseExpression(ctx);\n arms.push({ pattern, body });\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") {\n ctx.consume();\n while (ctx.match(\"Newline\")) {/* skip */}\n }\n }\n ctx.expect(\"Punctuation\", \"}\");\n return {\n kind: \"Match\",\n discriminant,\n arms,\n loc: { line: start.line, column: start.column },\n };\n}\n\nfunction parseForExpression(ctx: ParserContext): Expression {\n const start = ctx.expect(\"Keyword\", \"for\");\n let item: string;\n let index: string | undefined;\n let destructure: string[] | undefined;\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"(\") {\n ctx.consume();\n item = ctx.expect(\"Identifier\").value;\n ctx.expect(\"Punctuation\", \",\");\n index = ctx.expect(\"Identifier\").value;\n ctx.expect(\"Punctuation\", \")\");\n } else if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"{\") {\n ctx.consume();\n const fields: string[] = [];\n while (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"}\")) {\n fields.push(ctx.expect(\"Identifier\").value);\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") ctx.consume();\n }\n ctx.expect(\"Punctuation\", \"}\");\n item = \"__row\";\n destructure = fields;\n } else {\n item = ctx.expect(\"Identifier\").value;\n }\n ctx.expect(\"Keyword\", \"in\");\n const iterable = parseExpression(ctx);\n const body = parseBlock(ctx);\n return {\n kind: \"For\",\n item,\n index,\n destructure,\n iterable,\n body,\n loc: { line: start.line, column: start.column },\n };\n}\n\n/**\n * Speculatively try to parse a parenthesised lambda parameter list.\n * Returns a lambda expression when the trailing `=>` is found, otherwise\n * `null` (the caller restores the cursor and parses a normal grouping).\n *\n * Accepted forms: `()`, `(x)`, `(x, y)`, `(x: 0, y: 1)` (defaults),\n * followed by `=>` and a body expression OR a `js{ … }` block.\n */\nfunction tryParseLambdaFromParenList(ctx: ParserContext): Expression | null {\n const start = ctx.peek();\n if (start.type !== \"Punctuation\" || start.value !== \"(\") return null;\n ctx.consume();\n const params: { name: string; defaultValue?: Expression }[] = [];\n while (ctx.match(\"Newline\")) {/* skip */}\n if (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \")\")) {\n while (true) {\n while (ctx.match(\"Newline\")) {/* skip */}\n const tok = ctx.peek();\n if (tok.type !== \"Identifier\") return null;\n ctx.consume();\n const param: { name: string; defaultValue?: Expression } = { name: tok.value };\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \":\") {\n ctx.consume();\n try {\n param.defaultValue = parseExpression(ctx);\n } catch {\n return null;\n }\n }\n params.push(param);\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") {\n ctx.consume();\n continue;\n }\n break;\n }\n }\n while (ctx.match(\"Newline\")) {/* skip */}\n if (!(ctx.peek().type === \"Punctuation\" && ctx.peek().value === \")\")) {\n return null;\n }\n ctx.consume();\n if (!(ctx.peek().type === \"Operator\" && ctx.peek().value === \"=>\")) {\n return null;\n }\n ctx.consume();\n // Body: a JS block, a `{ ... }` block, or a single expression /\n // assignment statement (the spec permits a lone assignment here).\n let body: Expression;\n if (ctx.peek().type === \"JsBlock\") {\n const tok = ctx.consume();\n body = { kind: \"JsBlock\", body: tok.value, loc: { line: tok.line, column: tok.column } };\n } else if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"{\") {\n body = parseBlock(ctx);\n } else {\n body = parseAssignmentLikeExpression(ctx);\n }\n return {\n kind: \"Lambda\",\n params,\n body: body as never,\n loc: { line: start.line, column: start.column },\n };\n}\n\n/**\n * Parse a single expression OR an assignment statement as a synthetic\n * builtin call. Used inside lambda bodies (`() => $x = 1`,\n * `() => count++`) where the Aktion 0.5 spec accepts a single statement form.\n *\n * The runtime recognises the following synthetic builtins:\n * `@__rui_assign__($name, value, op)` — `op` is `\"=\"`, `\"+=\"`, `\"-=\"`, etc.\n * `@__rui_postfix__($name, op)` — `op` is `\"++\"` or `\"--\"`.\n */\nfunction parseAssignmentLikeExpression(ctx: ParserContext): Expression {\n const expression = parseExpression(ctx);\n const next = ctx.peek();\n if (next.type === \"Operator\") {\n const ops = [\"=\", \"+=\", \"-=\", \"*=\", \"/=\", \"??=\"];\n if (ops.includes(next.value)) {\n ctx.consume();\n const value = parseExpression(ctx);\n return {\n kind: \"BuiltinCall\",\n name: \"__rui_assign__\",\n arguments: [\n expression,\n value,\n { kind: \"Literal\", value: next.value },\n ],\n loc: { line: next.line, column: next.column },\n };\n }\n if (next.value === \"++\" || next.value === \"--\") {\n ctx.consume();\n return {\n kind: \"BuiltinCall\",\n name: \"__rui_postfix__\",\n arguments: [\n expression,\n { kind: \"Literal\", value: next.value },\n ],\n loc: { line: next.line, column: next.column },\n };\n }\n }\n return expression;\n}\n\nfunction parseObjectProps(ctx: ParserContext): ObjectProperty[] {\n const props: ObjectProperty[] = [];\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"}\") return props;\n\n while (true) {\n while (ctx.match(\"Newline\")) {/* skip */}\n const keyTok = ctx.peek();\n // Object spread: `{...source, key: value}`. The spread expression's\n // resolved value is merged into the object during evaluation.\n if (keyTok.type === \"Operator\" && keyTok.value === \"...\") {\n ctx.consume();\n const value = parseExpression(ctx);\n props.push({ key: \"\", value, spread: true });\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") {\n ctx.consume();\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"}\") break;\n continue;\n }\n break;\n }\n let key: string;\n // Accept identifiers, strings, AND most keywords (so component code can\n // freely use names like `action`, `effect`, `query` as object keys).\n if (keyTok.type === \"Identifier\" || keyTok.type === \"String\" || keyTok.type === \"Keyword\") {\n key = ctx.consume().value;\n } else {\n throw {\n message: `Expected object key, got ${keyTok.type} \"${keyTok.value}\"`,\n line: keyTok.line,\n column: keyTok.column,\n } satisfies ParseError;\n }\n // Property shorthand: `{ name }` desugars to `{ name: name }`. Only\n // valid when the key is a bare identifier and the next token closes\n // the property (comma or `}`).\n const after = ctx.peek();\n let value: Expression;\n if (\n keyTok.type === \"Identifier\" &&\n after.type === \"Punctuation\" &&\n (after.value === \",\" || after.value === \"}\")\n ) {\n value = { kind: \"Identifier\", name: key, loc: { line: keyTok.line, column: keyTok.column } };\n } else {\n ctx.expect(\"Punctuation\", \":\");\n value = parseExpression(ctx);\n }\n props.push({ key, value });\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \",\") {\n ctx.consume();\n while (ctx.match(\"Newline\")) {/* skip */}\n if (ctx.peek().type === \"Punctuation\" && ctx.peek().value === \"}\") break;\n continue;\n }\n break;\n }\n while (ctx.match(\"Newline\")) {/* skip */}\n return props;\n}\n","/**\n * Streaming Coherence Contract (SCC) — formal frontier API for Aktion 0.5.\n *\n * The spec (§1, §2) talks about a Drafting AST and a Committed AST. In the\n * current implementation the parser is already line-oriented and\n * error-tolerant, so the \"committed\" frontier is the longest prefix of the\n * input where every line parses cleanly. This module turns that informal\n * behaviour into a small, observable API.\n *\n * Why this matters: hosts (and tests) need to know which bindings are\n * stable vs in-flight so they can:\n *\n * - SCC-2: enumerate the set `U` of *known-incomplete* bindings.\n * - SCC-3: gate side effects on quiescence — never fire an effect that\n * depends on a binding still in `U`.\n * - SCC-4: verify identity stability across re-emissions of the same\n * program prefix.\n *\n * The frontier is computed by parsing the input as-is, walking the\n * statements, and treating any statement whose source spans an error line\n * as drafting. Everything else commits.\n */\n\nimport { parse } from \"./parser.js\";\nimport type { ParseError, Program, Statement } from \"./types.js\";\n\nexport interface FrontierResult {\n /**\n * Longest prefix of `source` (line-aligned) where every statement\n * parsed without errors. Always ends on a newline boundary, or equals\n * the empty string when no committed prefix exists yet.\n */\n committedSource: string;\n /** Tail of `source` past the committed prefix — the \"in-flight\" lines. */\n draftingSource: string;\n /**\n * Names declared inside the committed prefix. Top-level identifiers\n * only — block-local bindings (component params, $state inside a\n * component body) are not included.\n */\n committedBindings: ReadonlyArray<string>;\n /**\n * The set `U` (SCC-2): top-level names that appear inside the drafting\n * tail but have not yet committed. Includes:\n *\n * - Identifiers on the left of an assignment (`foo = …`).\n * - State assignments (`$x = …`).\n * - Component / effect / action / router declarations.\n *\n * Names that only appear as call expressions (`Button(…)`) inside the\n * drafting tail are not listed — those are dependencies, not bindings.\n */\n uncommittedBindings: ReadonlyArray<string>;\n /**\n * Statements that parsed cleanly in the committed prefix. Hosts can\n * walk this list to enumerate the committed surface (components,\n * effects, actions, endpoints, router declarations) without having to\n * re-parse.\n */\n committedStatements: ReadonlyArray<Statement>;\n /** Errors reported by the parser. Empty when the whole input parses cleanly. */\n errors: ReadonlyArray<ParseError>;\n}\n\n/**\n * Compute the streaming frontier for `source`. Cheap — runs a single\n * `parse(source)` pass and walks the resulting statements once.\n *\n * Example:\n *\n * const f = computeFrontier(\n * \"$state count = 0\\n\" +\n * \"component Counter() {\\n\" +\n * \" Stack(Te\" // mid-stream: half-written `Text`\n * );\n * // f.committedBindings = [\"count\"]\n * // f.uncommittedBindings = [\"Counter\"]\n * // f.committedSource ends just before \"component Counter() {…\"\n */\nexport function computeFrontier(source: string): FrontierResult {\n const program = parse(source);\n return buildFrontier(source, program);\n}\n\n/**\n * Build a frontier result from an already-parsed program. Exposed so\n * hosts that already call `parse(...)` once don't have to repeat the\n * work.\n */\nexport function buildFrontier(source: string, program: Program): FrontierResult {\n const errorLines = new Set(program.errors.map((e) => e.line));\n const committed: Statement[] = [];\n const drafting: Statement[] = [];\n for (const stmt of program.statements) {\n const stmtLine = (stmt as { loc?: { line: number } }).loc?.line ?? 0;\n // A statement commits when:\n // (a) it parsed without contributing to an error line, AND\n // (b) its source range does not touch the active drafting tail.\n //\n // We approximate (b) with \"no later-or-equal line carried a parse\n // error\" — line-oriented recovery means an earlier error never\n // bleeds forward, but an error on the same line marks the\n // statement as in-flight.\n if (errorLines.has(stmtLine)) {\n drafting.push(stmt);\n continue;\n }\n committed.push(stmt);\n }\n\n // Find the line of the first error (if any). Everything before that\n // line is the committed source; everything from that line onwards is\n // the drafting tail.\n let committedSource = source;\n let draftingSource = \"\";\n if (program.errors.length > 0) {\n const firstErrorLine = Math.min(...program.errors.map((e) => e.line));\n const split = splitSourceAtLine(source, firstErrorLine);\n committedSource = split.before;\n draftingSource = split.after;\n // Anything declared on or after that boundary is \"in-flight\" even if\n // the parser happened to recognise its name.\n const splitIndex = committed.findIndex(\n (s) => ((s as { loc?: { line: number } }).loc?.line ?? 0) >= firstErrorLine,\n );\n if (splitIndex >= 0) {\n for (const stmt of committed.splice(splitIndex)) {\n drafting.push(stmt);\n }\n }\n }\n\n return {\n committedSource,\n draftingSource,\n committedBindings: committed.map(bindingNameOf).filter((n): n is string => n !== null),\n uncommittedBindings: drafting.map(bindingNameOf).filter((n): n is string => n !== null),\n committedStatements: committed,\n errors: program.errors,\n };\n}\n\n/**\n * SCC-3 helper: returns `true` when every name in `deps` lives in the\n * committed prefix (so a side effect depending on them is safe to fire).\n */\nexport function isQuiescent(frontier: FrontierResult, deps: ReadonlyArray<string>): boolean {\n if (deps.length === 0) return true;\n const committed = new Set(frontier.committedBindings);\n for (const name of deps) {\n if (!committed.has(name)) return false;\n }\n return true;\n}\n\nfunction bindingNameOf(stmt: Statement): string | null {\n switch (stmt.kind) {\n case \"Assignment\": return stmt.identifier;\n case \"ComponentDeclaration\":\n case \"EffectDeclaration\":\n case \"ActionDeclaration\":\n return stmt.name;\n default: return null;\n }\n}\n\nfunction splitSourceAtLine(\n source: string,\n line: number,\n): { before: string; after: string } {\n if (line <= 1) return { before: \"\", after: source };\n // Find the offset of the start of `line` (1-indexed).\n let offset = 0;\n let current = 1;\n while (offset < source.length && current < line) {\n if (source[offset] === \"\\n\") current += 1;\n offset += 1;\n }\n return { before: source.slice(0, offset), after: source.slice(offset) };\n}\n","/**\n * Aktion 0.5 §14 — Delta Protocol.\n *\n * In v1 every LLM turn replaced the entire program. SUIS/2 ships a\n * structured delta surface so a \"tweak the UI\" turn can stay tiny:\n * a handful of typed operations applied to the previous program's\n * Committed AST. The runtime mounts the patched program with the\n * user's `$state` preserved across the diff.\n *\n * The spec's original pragma signalling (`#sus/2 delta`) was retired\n * along with every other pragma in 0.5 (`#…` lines are comments). The\n * delta is therefore expressed as **structured operations** — hosts\n * call `el.applyDelta(ops)` directly, no in-language pragma required.\n *\n * Operations\n * ----------\n *\n * { kind: \"patch\", target: \"stateName\", value: 50 }\n * Update a `$state` atom in place. Does not touch the program\n * text. Use for \"set the slider to 50\", \"expand the panel\", etc.\n *\n * { kind: \"replace\", binding: \"header\", source: \"PageHeader(\\\"Sales\\\")\" }\n * Replace a top-level binding's RHS. Equivalent to deleting and\n * re-emitting the line(s).\n *\n * { kind: \"append\", binding: \"items\", item: \"{ label: \\\"Reports\\\" }\" }\n * Append an item to a top-level array binding. `binding`'s RHS\n * must be a literal array expression.\n *\n * { kind: \"new\", source: \"component ReportCard(r) { Card([Text(r.title)]) }\" }\n * Append a new top-level statement to the program.\n *\n * { kind: \"delete\", binding: \"legacyWidget\" }\n * Remove a top-level binding (or component / action / effect /\n * endpoint declaration) by name.\n *\n * Op application is best-effort: each op that does not match its\n * target surfaces an advisory warning and is skipped. The runtime\n * still mounts the rest of the patched program — partial deltas\n * never strand the user with no UI.\n *\n * The function is pure: feed in `(source, ops)`, get back\n * `(programText, stateUpdates, warnings)`. State application is the\n * caller's responsibility (the host element wires it up — see\n * `AktionElement.applyDelta`).\n */\n\nimport { parse } from \"../parser/index.js\";\nimport type { Expression, Program, Statement } from \"../parser/types.js\";\n\nexport type DeltaOp =\n | { kind: \"patch\"; target: string; value: unknown }\n | { kind: \"replace\"; binding: string; source: string }\n | { kind: \"append\"; binding: string; item: string }\n | { kind: \"new\"; source: string }\n | { kind: \"delete\"; binding: string };\n\nexport interface DeltaResult {\n /** Source text after every structural op (replace/append/new/delete) lands. */\n programText: string;\n /** `patch` ops collected as a name→value map; the caller applies these to its state store. */\n stateUpdates: Record<string, unknown>;\n /** Advisory diagnostics for ops that became no-ops. */\n warnings: string[];\n}\n\nexport function applyDelta(\n source: string,\n ops: readonly DeltaOp[],\n): DeltaResult {\n const warnings: string[] = [];\n const stateUpdates: Record<string, unknown> = {};\n let programText = source;\n\n for (const op of ops) {\n if (op.kind === \"patch\") {\n stateUpdates[op.target] = op.value;\n continue;\n }\n const result = applyStructural(programText, op);\n programText = result.programText;\n if (result.warning) warnings.push(result.warning);\n }\n\n return { programText, stateUpdates, warnings };\n}\n\ninterface StructuralResult {\n programText: string;\n warning?: string;\n}\n\nfunction applyStructural(\n source: string,\n op: Exclude<DeltaOp, { kind: \"patch\" }>,\n): StructuralResult {\n const program = parse(source);\n if (program.errors.length > 0) {\n return {\n programText: source,\n warning: `delta(${op.kind}): source did not parse cleanly (${program.errors[0]!.message}); op skipped`,\n };\n }\n\n switch (op.kind) {\n case \"new\": {\n const sub = parse(op.source);\n if (sub.errors.length > 0 || sub.statements.length === 0) {\n return {\n programText: source,\n warning: `delta(new): could not parse \"${snippet(op.source)}\" — op skipped`,\n };\n }\n const sep = source.endsWith(\"\\n\") ? \"\" : \"\\n\";\n return { programText: source + sep + op.source.trim() + \"\\n\" };\n }\n case \"delete\": {\n const idx = findBindingIndex(program, op.binding);\n if (idx < 0) {\n return {\n programText: source,\n warning: `delta(delete): binding \"${op.binding}\" not found — op skipped`,\n };\n }\n return { programText: spliceLines(source, program, idx, null) };\n }\n case \"replace\": {\n const idx = findBindingIndex(program, op.binding);\n if (idx < 0) {\n return {\n programText: source,\n warning: `delta(replace): binding \"${op.binding}\" not found — op skipped`,\n };\n }\n const sub = parse(`${op.binding} = ${op.source}`);\n if (sub.errors.length > 0) {\n return {\n programText: source,\n warning: `delta(replace): could not parse new source for \"${op.binding}\" — op skipped`,\n };\n }\n return {\n programText: spliceLines(source, program, idx, `${op.binding} = ${op.source.trim()}`),\n };\n }\n case \"append\": {\n const idx = findBindingIndex(program, op.binding);\n if (idx < 0) {\n return {\n programText: source,\n warning: `delta(append): binding \"${op.binding}\" not found — op skipped`,\n };\n }\n const target = program.statements[idx]!;\n if (target.kind !== \"Assignment\" || target.expression.kind !== \"Array\") {\n return {\n programText: source,\n warning: `delta(append): binding \"${op.binding}\" is not an array literal — op skipped`,\n };\n }\n const sub = parse(`__rui_delta_item__ = ${op.item}`);\n const itemStmt = sub.statements[0];\n if (sub.errors.length > 0 || !itemStmt || itemStmt.kind !== \"Assignment\") {\n return {\n programText: source,\n warning: `delta(append): could not parse item \"${snippet(op.item)}\" — op skipped`,\n };\n }\n const elements = target.expression.elements;\n const rebuilt = `${op.binding} = [${[...elements.map(stringifyExpression), op.item.trim()].join(\", \")}]`;\n return { programText: spliceLines(source, program, idx, rebuilt) };\n }\n }\n}\n\nfunction findBindingIndex(program: Program, name: string): number {\n return program.statements.findIndex((s) => bindingName(s) === name);\n}\n\nfunction bindingName(stmt: Statement): string | null {\n switch (stmt.kind) {\n case \"Assignment\":\n return stmt.identifier;\n case \"ComponentDeclaration\":\n case \"EffectDeclaration\":\n case \"ActionDeclaration\":\n return stmt.name;\n default:\n return null;\n }\n}\n\n/**\n * Replace lines `[startLine .. endLine]` (1-indexed, inclusive) with\n * `replacement`, where the start line is the source location of\n * statement `idx` and the end line is the line *before* statement\n * `idx + 1` (or end of file).\n *\n * Passing `replacement: null` deletes the line range entirely.\n */\nfunction spliceLines(\n source: string,\n program: Program,\n idx: number,\n replacement: string | null,\n): string {\n const lines = source.split(\"\\n\");\n const target = program.statements[idx]!;\n const next = program.statements[idx + 1];\n const startLine = (target.loc?.line ?? 1) - 1;\n const endLine = next ? (next.loc?.line ?? lines.length + 1) - 1 : lines.length;\n const before = lines.slice(0, startLine);\n const after = lines.slice(endLine);\n if (replacement === null) {\n return [...before, ...after].join(\"\\n\");\n }\n return [...before, replacement, ...after].join(\"\\n\");\n}\n\nfunction stringifyExpression(expr: Expression): string {\n switch (expr.kind) {\n case \"Literal\":\n if (typeof expr.value === \"string\") {\n return `\"${expr.value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`;\n }\n return String(expr.value);\n case \"Identifier\":\n return expr.name;\n case \"StateRef\":\n return `$${expr.name}`;\n case \"Call\":\n return `${expr.callee}(${expr.arguments.map(stringifyExpression).join(\", \")})`;\n case \"MethodCall\":\n return `${stringifyExpression(expr.object)}${expr.optional ? \"?.\" : \".\"}${expr.method}(${expr.arguments.map(stringifyExpression).join(\", \")})`;\n case \"NamedArg\":\n return `${expr.name}: ${stringifyExpression(expr.value)}`;\n case \"Array\":\n return `[${expr.elements.map(stringifyExpression).join(\", \")}]`;\n case \"Object\":\n return `{ ${expr.properties.map((p) =>\n p.spread\n ? `...${stringifyExpression(p.value)}`\n : `${p.key}: ${stringifyExpression(p.value)}`,\n ).join(\", \")} }`;\n case \"Member\": {\n const obj = stringifyExpression(expr.object);\n if (expr.property) return `${obj}${expr.optional ? \"?.\" : \".\"}${expr.property}`;\n if (expr.computed) return `${obj}${expr.optional ? \"?.\" : \"\"}[${stringifyExpression(expr.computed)}]`;\n return obj;\n }\n case \"Binary\":\n return `${stringifyExpression(expr.left)} ${expr.operator} ${stringifyExpression(expr.right)}`;\n case \"Template\": {\n const parts: string[] = [];\n for (let i = 0; i < expr.quasis.length; i += 1) {\n parts.push(expr.quasis[i] ?? \"\");\n if (i < expr.expressions.length) {\n parts.push(\"${\");\n parts.push(stringifyExpression(expr.expressions[i]!));\n parts.push(\"}\");\n }\n }\n return `\\`${parts.join(\"\")}\\``;\n }\n default:\n // Less-common expression kinds — `if` / `match` / `for` /\n // lambdas / `js{}` blocks. These would need a full pretty-\n // printer to round-trip safely; we treat them as opaque\n // and surface a placeholder so the caller can detect the\n // limitation.\n return \"/* unprintable */\";\n }\n}\n\nfunction snippet(s: string): string {\n return s.length > 40 ? `${s.slice(0, 37)}...` : s;\n}\n","import type { ComponentLibrary, ComponentSpec } from \"./types.js\";\n\n/**\n * Cache of Map<name, spec> indexes keyed by the `components` array reference.\n * Lets `findComponent` run in O(1) while still treating libraries as\n * immutable arrays — when the library is replaced (e.g. after\n * `registerComponents`), the new array gets its own index automatically.\n */\nconst indexCache = new WeakMap<ReadonlyArray<ComponentSpec>, Map<string, ComponentSpec>>();\n\nfunction getIndex(library: ComponentLibrary): Map<string, ComponentSpec> {\n let index = indexCache.get(library.components);\n if (!index) {\n index = new Map();\n for (const spec of library.components) {\n if (spec?.name) index.set(spec.name, spec);\n }\n indexCache.set(library.components, index);\n }\n return index;\n}\n\n/**\n * Combines two libraries by name. Components from `extra` win on collision.\n * Useful when a consumer registers their own components alongside the\n * built-ins via `<aktion-app>.registerComponents([...])`.\n */\nexport function mergeLibraries(\n base: ComponentLibrary,\n extra: { components: ReadonlyArray<ComponentSpec>; root?: string },\n): ComponentLibrary {\n const map = new Map<string, ComponentSpec>();\n for (const c of base.components) map.set(c.name, c);\n for (const c of extra.components) map.set(c.name, c);\n return {\n root: extra.root ?? base.root,\n components: [...map.values()],\n componentGroups: base.componentGroups,\n };\n}\n\n/**\n * Resolve a component spec by name. O(1) thanks to the lazily-built index\n * cached against the library's `components` array.\n */\nexport function findComponent(library: ComponentLibrary, name: string): ComponentSpec | undefined {\n return getIndex(library).get(name);\n}\n","/**\n * Component library schema types.\n *\n * Components are described by:\n * - `name`: identifier used in Aktion (e.g. `Stack`, `Button`).\n * - `props`: ordered prop list. Order defines positional argument mapping.\n * - `description`: shown in the generated system prompt.\n * - `render`: produces a DOM node from resolved prop values.\n */\n\nimport type { ComponentNode } from \"../runtime/evaluator.js\";\nimport type { Router } from \"../runtime/router.js\";\n\nexport type PrimitiveType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"any\"\n | \"callable\"\n | \"Node\"\n | \"Node[]\";\n\nexport interface PropSpec {\n name: string;\n type: PrimitiveType | string; // accept named types like \"Series[]\"\n optional?: boolean;\n /**\n * Aktion 0.5 §19.1 — at most one prop per spec may be marked\n * positional. Authors may pass exactly one positional argument at the\n * call site; it lands in this prop's slot regardless of its position in\n * the `props` array. Every other prop must be provided as a named\n * argument (`prop: value`). Specs without any `positional: true` flag\n * reject every positional argument at evaluation time.\n */\n positional?: boolean;\n /**\n * Marker only — recorded so the schema-driven prompt generator can render\n * required props without an `?` suffix. Not enforced by the runtime.\n */\n required?: boolean;\n description?: string;\n /** Accepted enum values, formatted as a comma-separated list in the prompt. */\n enum?: readonly string[];\n /**\n * Optional alternative names that route to this prop when used as a\n * `name: value` named argument at the call site. Lets the same prop be\n * called by its canonical name *and* a synonym so authors writing\n * `Badge(\"Live\", tone: \"success\")` and `Badge(\"Live\", variant: \"success\")`\n * both land in the same slot. Aliases never change the runtime prop name\n * — renderers continue to read `props[spec.name]`.\n */\n aliases?: readonly string[];\n}\n\nexport interface ComponentSpec {\n name: string;\n description: string;\n props: readonly PropSpec[];\n render: ComponentRenderFn;\n}\n\n/**\n * Aktion 0.5 §19.1 — locate the canonical positional prop\n * for a spec. A spec opts in by marking exactly one prop with\n * `positional: true`. Specs that omit the marker fall back to \"first prop\n * is positional\", which is the convention every legacy library component\n * was authored with.\n *\n * `findPositionalIndex` is consumed by the evaluator (to route the single\n * positional argument to the right slot regardless of where in `props`\n * the positional prop lives — e.g. `Portal(target?, children)` keeps\n * `children` as the positional but it lives at index 1).\n *\n * `findPositionalProp` returns the resolved prop or `undefined` for void\n * components (zero props).\n */\nexport function findPositionalIndex(spec: ComponentSpec): number {\n const explicit = spec.props.findIndex((p) => p.positional === true);\n if (explicit >= 0) return explicit;\n return spec.props.length > 0 ? 0 : -1;\n}\n\nexport function findPositionalProp(spec: ComponentSpec): PropSpec | undefined {\n const idx = findPositionalIndex(spec);\n return idx >= 0 ? spec.props[idx] : undefined;\n}\n\n/**\n * Asserts that every spec in the library declares at most one positional\n * prop. Surfaces inconsistencies as a `SyntaxError` at module load so the\n * library never ships a contradictory spec.\n */\nexport function assertOnePositionalMax(specs: ReadonlyArray<ComponentSpec>): void {\n for (const spec of specs) {\n const positional = spec.props.filter((p) => p.positional === true);\n if (positional.length > 1) {\n const names = positional.map((p) => p.name).join(\", \");\n throw new SyntaxError(\n `Component \"${spec.name}\" declares ${positional.length} positional ` +\n `props (${names}). Aktion 0.5 §19.1 allows at most one.`,\n );\n }\n }\n}\n\n/**\n * Stable, component-local state slot. Returned by\n * `RenderHelpers.useInstanceState`. Keep the reference for the lifetime of\n * a single render — the renderer wires it to a long-lived storage cell so\n * subsequent renders read the value the previous click handler wrote.\n */\nexport interface InstanceStateSlot<T> {\n get(): T;\n set(value: T): void;\n}\n\nexport interface RenderHelpers {\n /** Render a child node tree (a ComponentNode or array of nodes). */\n renderNode: (node: unknown) => Node;\n /**\n * Invoke a user-supplied callable (e.g. a lambda passed as an `onClick`\n * prop, or a bare `action` declaration reference). Safe to call with\n * `undefined` / `null` — silently no-ops. Returned values are ignored.\n *\n * This is the single dispatch path for user-authored event handlers in\n * Aktion 0.5. The legacy `Action([@Set, @Run, ...])` payload\n * is no longer accepted.\n */\n invoke: (callable: unknown, ...args: unknown[]) => void;\n /** Set a state value. Used by library primitives for their own internal state writes. */\n setState: (name: string, value: unknown) => void;\n /** Reset state values back to their initial declared value. */\n resetState: (...names: string[]) => void;\n /** Dispatch an `assistant-message` CustomEvent on the host element. */\n sendToAssistant: (message: string) => void;\n /** Open a URL (sanitised against `javascript:` payloads). */\n openUrl: (url: string) => void;\n /** Bind a `$variable` to an HTML form element. */\n bindState: (\n element: HTMLElement,\n name: string,\n options?: { event?: string; getValue?: (el: HTMLElement) => unknown },\n ) => void;\n /**\n * Persist component-local state across re-renders. The slot is keyed by\n * the component's position in the tree (its source location plus its\n * path through sibling iterations), so independent instances never share\n * a value. Used by stateful primitives like `Tabs` so user-driven UI\n * state (active tab, expanded row, …) survives a re-render triggered by\n * unrelated state changes.\n */\n useInstanceState: <T>(key: string, initialValue: T) => InstanceStateSlot<T>;\n /**\n * Register a cleanup callback tied to this component instance. The renderer\n * invokes the callback once the instance disappears from the tree (e.g. a\n * Toast finishes auto-dismissing or the parent re-renders without it).\n * Use for `setTimeout` / `setInterval` handles and external resources so we\n * never accumulate work for components the user can no longer see.\n *\n * Calling this multiple times during a single render replaces any previous\n * disposer for the same `key` (cancelling the prior cleanup runs immediately\n * via that callback's caller). If `key` is omitted, each call registers an\n * independent disposer.\n */\n registerDisposer: (cleanup: () => void, key?: string) => void;\n /**\n * Hash-based router instance, always provided. Components such as `NavLink`\n * call `router.navigate(path)` directly to change the active route.\n */\n router: Router;\n}\n\nexport type ComponentRenderFn = (\n node: ComponentNode,\n props: Record<string, unknown>,\n helpers: RenderHelpers,\n) => Node;\n\nexport interface ComponentGroup {\n name: string;\n components: readonly string[];\n notes?: readonly string[];\n}\n\nexport interface ComponentLibrary {\n root: string;\n components: ReadonlyArray<ComponentSpec>;\n componentGroups?: ReadonlyArray<ComponentGroup>;\n}\n\n/** Resolve positional args from Aktion into named props. */\nexport function mapPositionalArgs(\n spec: ComponentSpec,\n args: ReadonlyArray<unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n spec.props.forEach((prop, index) => {\n if (index < args.length) out[prop.name] = args[index];\n });\n return out;\n}\n","/**\n * Schema-as-truth validation (§15).\n *\n * Walks a parsed `Program` and reports advisory diagnostics for:\n *\n * - Closed-token enum mismatches (`Button(\"Save\", tone: \"magic\")` →\n * \"magic\" is not in the `tone` enum).\n * - Unknown named args (`Stack(gap: \"md\", junk: 1)` → no such prop).\n *\n * The diagnostics are *warnings*, not errors — the runtime still\n * evaluates the program. Hosts may surface them as a banner or ignore\n * them entirely. The goal is to give authors (and LLMs) a clear signal\n * that they are reaching outside the documented surface.\n */\n\nimport type {\n Expression,\n ParseError,\n Program,\n Statement,\n} from \"../parser/types.js\";\nimport { parse } from \"../parser/index.js\";\nimport type { ComponentLibrary } from \"./types.js\";\nimport { findPositionalProp } from \"./types.js\";\nimport { findComponent } from \"./registry.js\";\n\n/**\n * Combined entry point for hosts: parse the source and merge any\n * schema-level violations into `program.errors`. The element calls\n * this so the on-screen error banner surfaces *every* Aktion 0.5\n * violation, not just the syntactic ones. Returning the\n * parsed program lets the caller render the committed prefix when\n * the input still parses cleanly.\n */\nexport function validateProgram(\n source: string,\n library: ComponentLibrary,\n): Program {\n const program = parse(source);\n const schemaErrors = validateProgramSchema(program, library);\n if (schemaErrors.length > 0) {\n program.errors = [...program.errors, ...schemaErrors];\n }\n return program;\n}\n\n/**\n * Schema-as-truth validation (§15).\n *\n * Walks a parsed `Program` and returns every Aktion 0.5\n * schema violation as a `ParseError`. In 0.5 these are **fatal** — the\n * host should merge them into `program.errors` (see\n * `validateProgram(source, library)` for the combined entry point) and\n * surface the error banner instead of rendering. There are no longer\n * any \"advisory warnings\" — every legacy v1 surface either:\n *\n * - produces a parser-level migration error at parse time, or\n * - produces a schema-validator error here when library knowledge is\n * required (multi-positional calls, unknown props, enum mismatches,\n * legacy Theme tokens, …).\n */\nexport function validateProgramSchema(\n program: Program,\n library: ComponentLibrary,\n): ParseError[] {\n const errors: ParseError[] = [];\n for (const stmt of program.statements) {\n walkStatement(stmt, library, errors);\n }\n return errors;\n}\n\nfunction walkStatement(\n stmt: Statement,\n library: ComponentLibrary,\n out: ParseError[],\n): void {\n switch (stmt.kind) {\n case \"Assignment\":\n walkExpression(stmt.expression, library, out);\n return;\n case \"ExpressionStatement\":\n walkExpression(stmt.expression, library, out);\n return;\n case \"ComponentDeclaration\":\n case \"ActionDeclaration\":\n case \"EffectDeclaration\":\n for (const inner of stmt.body.body) walkStatement(inner, library, out);\n return;\n case \"Return\":\n if (stmt.argument) walkExpression(stmt.argument, library, out);\n return;\n default:\n return;\n }\n}\n\nfunction walkExpression(\n expr: Expression,\n library: ComponentLibrary,\n out: ParseError[],\n): void {\n if (!expr) return;\n switch (expr.kind) {\n case \"Call\": {\n validateCall(expr, library, out);\n for (const arg of expr.arguments) walkExpression(arg, library, out);\n return;\n }\n case \"MethodCall\": {\n // Method calls on namespace globals (`storage.set`, `console.log`,\n // resource bag callables like `$res.refetch()`) are validated at\n // runtime — the schema validator just walks the children.\n walkExpression(expr.object, library, out);\n for (const arg of expr.arguments) walkExpression(arg, library, out);\n return;\n }\n case \"BuiltinCall\": {\n validateBuiltinCall(expr, out);\n for (const arg of expr.arguments) walkExpression(arg, library, out);\n return;\n }\n case \"Array\":\n for (const e of expr.elements) walkExpression(e, library, out);\n return;\n case \"Object\":\n for (const prop of expr.properties) walkExpression(prop.value, library, out);\n return;\n case \"Template\":\n for (const e of expr.expressions) walkExpression(e, library, out);\n return;\n case \"Binary\":\n walkExpression(expr.left, library, out);\n walkExpression(expr.right, library, out);\n return;\n case \"Unary\":\n walkExpression(expr.argument, library, out);\n return;\n case \"Ternary\":\n walkExpression(expr.test, library, out);\n walkExpression(expr.consequent, library, out);\n walkExpression(expr.alternate, library, out);\n return;\n case \"Member\":\n walkExpression(expr.object, library, out);\n if (expr.computed) walkExpression(expr.computed, library, out);\n return;\n case \"Spread\":\n walkExpression(expr.argument, library, out);\n return;\n case \"NamedArg\":\n walkExpression(expr.value, library, out);\n return;\n case \"If\":\n walkExpression(expr.test, library, out);\n for (const inner of expr.consequent.body) walkStatement(inner, library, out);\n if (expr.alternate) {\n if (expr.alternate.kind === \"If\") {\n walkExpression(expr.alternate, library, out);\n } else {\n for (const inner of expr.alternate.body) walkStatement(inner, library, out);\n }\n }\n return;\n case \"Match\":\n walkExpression(expr.discriminant, library, out);\n for (const arm of expr.arms) walkExpression(arm.body, library, out);\n return;\n case \"For\":\n walkExpression(expr.iterable, library, out);\n for (const inner of expr.body.body) walkStatement(inner, library, out);\n return;\n case \"Lambda\":\n // Lambda body might be an expression or a JsBlock — only walk\n // expressions; JsBlocks are opaque to schema validation.\n if ((expr.body as Expression).kind !== \"JsBlock\") {\n walkExpression(expr.body as Expression, library, out);\n }\n return;\n case \"Bind\":\n walkExpression(expr.target, library, out);\n return;\n default:\n return;\n }\n}\n\n/**\n * Appendix-A legacy call sites. Each entry is a v1 form that the 0.5\n * surface explicitly removed (see `language-update-final.md`,\n * Appendix A). The parser accepts the *syntax* (a call expression is\n * syntactically fine), so without an explicit guard here the runtime\n * would silently render `null` and the author would have no signal\n * that the code is rejected. The error message points at the canonical\n * 0.5 replacement.\n */\nconst LEGACY_V1_CALLS: Record<string, string> = {\n Script:\n `Script(\"id\", body, deps?) is not supported. Use an \\`effect [$deps] { js{ … } }\\` block (see §9 — effect declarations).`,\n Action:\n `Action([@Set, @Run, …]) payloads are removed in 0.5. Use \\`action <Name>() { … }\\` declarations and reference them by name (e.g. \\`Button(\"Save\", action: save)\\`) — see §10.`,\n Routes:\n `Routes(items, default?) is removed in 0.5. Use \\`pages = _router_({ \"/\": Home(), default: NotFound() })\\` (see §12 — outlet-first router).`,\n Route:\n `Route(path, content) is only valid inside a v1 \\`Routes(...)\\` outlet, which has been removed. Use \\`\"/path\": content\\` arms inside a \\`_router_({ … })\\` call (see §12).`,\n Query:\n `Query(\"name\", args, placeholder, refreshSec?) is removed in 0.5. Declare a top-level \\`query <Name>(args) { url, method, … }\\` block and bind it with \\`$query foo = <Name>(args)\\` (see §11.2).`,\n Mutation:\n `Mutation(\"name\", args) is removed in 0.5. Declare a top-level \\`mutation <Name>(args) { url, method, body, … }\\` block and bind it with \\`$mutation save = <Name>\\` (see §11.3).`,\n NavLinkRoute:\n `NavLinkRoute is removed in 0.5. Use \\`NavLink(label, to: \"/path\")\\` (see §12 — Outlet-first router).`,\n useInstanceState:\n `useInstanceState(...) is removed in 0.5. Declare per-instance state inside the component body with \\`$state name = init\\` — identity is content-addressed (§13).`,\n};\n\nfunction validateCall(\n expr: Extract<Expression, { kind: \"Call\" }>,\n library: ComponentLibrary,\n out: ParseError[],\n): void {\n const legacy = LEGACY_V1_CALLS[expr.callee];\n if (legacy) {\n out.push({\n message: `${expr.callee}(...) — ${legacy}`,\n line: expr.loc?.line ?? 0,\n column: expr.loc?.column ?? 0,\n });\n return;\n }\n if (expr.callee === \"Theme\") {\n validateThemeCall(expr, out);\n return;\n }\n const spec = findComponent(library, expr.callee);\n if (!spec) return; // User-declared or unknown — skip silently.\n const propNames = new Set<string>();\n for (const p of spec.props) {\n propNames.add(p.name);\n if (p.aliases) {\n for (const alias of p.aliases) propNames.add(alias);\n }\n }\n // Allow `key:` everywhere (content-addressed identity, §13).\n propNames.add(\"key\");\n\n // Aktion 0.5 §19.1 — components allow at most one\n // positional argument (the canonical primary slot). Additional\n // positional args surface as advisory warnings naming the prop the\n // author should switch to a `prop: value` form.\n const positionalArgs: Expression[] = [];\n for (const arg of expr.arguments) {\n if (arg.kind === \"NamedArg\") continue;\n positionalArgs.push(arg);\n }\n if (positionalArgs.length > 1) {\n const positionalProp = findPositionalProp(spec);\n const positionalName = positionalProp?.name ?? \"(none)\";\n // Hint the next props the author should switch to a `prop: value` form\n // — skip the canonical positional (already filled by the first arg)\n // and any prop already consumed by a named arg.\n const namedNames = new Set(\n expr.arguments\n .filter((a): a is Extract<Expression, { kind: \"NamedArg\" }> => a.kind === \"NamedArg\")\n .map((a) => a.name),\n );\n const extras = spec.props\n .filter((p) => p.name !== positionalName && !namedNames.has(p.name))\n .slice(0, positionalArgs.length - 1)\n .map((p) => p.name);\n const hints = extras.length > 0\n ? extras.map((n) => `${n}: …`).join(\", \")\n : \"use named arguments\";\n out.push({\n message:\n `${expr.callee}(...) — Aktion 0.5 §19.1 allows at most ` +\n `one positional argument (the \"${positionalName}\" prop). The extra ` +\n `${positionalArgs.length - 1} positional argument(s) must be passed ` +\n `as named arguments: ${hints}. Multi-positional calls are removed.`,\n line: expr.loc?.line ?? 0,\n column: expr.loc?.column ?? 0,\n });\n }\n\n for (const arg of expr.arguments) {\n if (arg.kind !== \"NamedArg\") continue;\n if (!propNames.has(arg.name)) {\n out.push({\n message: `Unknown prop \"${arg.name}\" on <${expr.callee}>. Known props: ${spec.props.map((p) => p.name).join(\", \")}.`,\n line: arg.loc?.line ?? expr.loc?.line ?? 0,\n column: arg.loc?.column ?? expr.loc?.column ?? 0,\n });\n continue;\n }\n const prop = spec.props.find(\n (p) => p.name === arg.name || (p.aliases?.includes(arg.name) ?? false),\n );\n if (prop?.enum && arg.value.kind === \"Literal\" && typeof arg.value.value === \"string\") {\n const value = arg.value.value;\n if (!prop.enum.includes(value)) {\n out.push({\n message: `<${expr.callee}> ${arg.name}=\"${value}\" — must be one of ${prop.enum.map((v) => `\"${v}\"`).join(\", \")}.`,\n line: arg.loc?.line ?? expr.loc?.line ?? 0,\n column: arg.loc?.column ?? expr.loc?.column ?? 0,\n });\n }\n }\n }\n}\n\n/**\n * Theme token validation (§16).\n *\n * SUIS/2 only accepts the structured form:\n *\n * Theme({ name?, direction?, colors: {...}, radius: {...},\n * font: {...}, motion: {...}, elevation: {...} })\n *\n * Any other top-level key is either a legacy flat-shape token\n * (`colorPrimary`, `radiusMd`) or a free-form CSS variable\n * (`--color-x`). Both forms surface as advisory warnings so the runtime\n * can keep streaming partial themes without crashing.\n */\nconst STRUCTURED_THEME_GROUPS = new Set([\"colors\", \"radius\", \"font\", \"motion\", \"elevation\"]);\nconst THEME_METADATA_KEYS = new Set([\"name\", \"direction\"]);\n\nfunction validateThemeCall(\n expr: Extract<Expression, { kind: \"Call\" }>,\n out: ParseError[],\n): void {\n const arg = expr.arguments[0];\n if (!arg || arg.kind !== \"Object\") return;\n for (const prop of arg.properties) {\n if (prop.spread) continue;\n if (STRUCTURED_THEME_GROUPS.has(prop.key)) continue;\n if (THEME_METADATA_KEYS.has(prop.key)) continue;\n const suggestion = suggestStructuredKey(prop.key);\n const message = prop.key.startsWith(\"--\")\n ? `Theme({\"${prop.key}\": ...}) — free-form CSS variable keys are removed in Aktion 0.5. Use the structured form: Theme({ colors: {...}, radius: {...}, font: {...} }).`\n : `Theme({${prop.key}: ...}) — legacy flat-shape token is removed in Aktion 0.5. Use ${suggestion}.`;\n out.push({\n message,\n line: expr.loc?.line ?? 0,\n column: expr.loc?.column ?? 0,\n });\n }\n}\n\n/**\n * Appendix-A legacy `@`-builtins. Each entry is a v1 helper that the\n * 0.5 surface explicitly removed. The parser accepts the *syntax*\n * (a `BuiltinCall` is just `@<Name>(args)`), so without an explicit\n * guard here a v1 program with e.g. `@Const(...)` would silently\n * evaluate to `null`. The error message points at the canonical 0.5\n * replacement.\n */\nconst LEGACY_V1_BUILTINS: Record<string, string> = {\n // Action steps (removed — actions are now `action Name() { … }` blocks).\n Set:\n `@Set($x, value) is removed in 0.5. Inside an \\`action Name() { … }\\` body, assign directly: \\`$x = value\\`.`,\n Reset:\n `@Reset($x) is removed in 0.5. Inside an \\`action Name() { … }\\` body, assign the default explicitly: \\`$x = defaultValue\\`.`,\n Run:\n `@Run(name) is removed in 0.5. Inside an \\`action Name() { … }\\` body, call the mutation: \\`await $mutation.foo.call(args)\\` (see §11.3).`,\n ToAssistant:\n `@ToAssistant(\"text\") is removed in 0.5. Use \\`emit \"assistant-message\" { message: \"...\" }\\` inside an \\`action Name() { … }\\` body (see §22.2).`,\n OpenUrl:\n `@OpenUrl(\"https://…\") is removed in 0.5. Inside an \\`action Name() { js{ … } }\\` body, call \\`window.open(url, \"_blank\", \"noopener,noreferrer\")\\`.`,\n Navigate:\n `@Navigate(\"/path\") is removed in 0.5. Use \\`pages = _router_({ … })\\` (see §12) and navigate via the host (\\`el.navigate(\"/path\")\\`), \\`_route_.navigate(\"/path\")\\` from inside an action, or by linking to the path with \\`NavLink(label, \"/path\")\\`.`,\n Js:\n `@Js(body, args?) is removed in 0.5. Use \\`effect <id> on $deps { js{ … } }\\` or \\`action Name() { js{ … } }\\` (see §9, §10).`,\n // Derived-value helpers (subsumed by `$computed`).\n Const:\n `@Const(expr) is removed in 0.5. Use \\`$computed name = expr\\` (see §4 — state tiers).`,\n Memo:\n `@Memo(expr) is removed in 0.5. Use \\`$computed name = expr\\` (see §4 — state tiers).`,\n // Array helpers (subsumed by spread + builtins).\n Push:\n `@Push(arr, value) is removed in 0.5. Use spread: \\`[...arr, value]\\`.`,\n Concat:\n `@Concat(a, b) is removed in 0.5. Use spread: \\`[...a, ...b]\\`.`,\n Map:\n `@Map(arr, \"field\") is removed in 0.5. Use array pluck shorthand: \\`arr.field\\` (yields \\`[arr[0].field, arr[1].field, …]\\`).`,\n Take:\n `@Take(arr, n) is removed in 0.5. Use @Slice(arr, 0, n) or array shortcuts like \\`arr.first\\` / \\`arr.last\\`.`,\n // Formatters (subsumed by @Format(value, \"currency\"/\"number\")).\n FormatCurrency:\n `@FormatCurrency(value, opts?) is removed in 0.5. Use \\`@Format(value, \"currency\", opts?)\\`.`,\n FormatNumber:\n `@FormatNumber(value, opts?) is removed in 0.5. Use \\`@Format(value, \"number\", opts?)\\`.`,\n // Control-flow helpers (subsumed by expression-form if/match/for).\n Each:\n `@Each(items, \"x\", template) is removed in 0.5. Use the expression-form loop: \\`for x in items { template }\\` (see §8.3).`,\n If:\n `@If(cond, then, else?) is removed in 0.5. Use the expression-form conditional: \\`if cond { then } else { else }\\` (see §8.1).`,\n Switch:\n `@Switch(value, cases, default?) is removed in 0.5. Use the expression-form match: \\`match value { \"a\" -> A() _ -> Default() }\\` (see §8.2).`,\n};\n\nfunction validateBuiltinCall(\n expr: Extract<Expression, { kind: \"BuiltinCall\" }>,\n out: ParseError[],\n): void {\n const legacy = LEGACY_V1_BUILTINS[expr.name];\n if (legacy) {\n out.push({\n message: `@${expr.name}(...) — ${legacy}`,\n line: expr.loc?.line ?? 0,\n column: expr.loc?.column ?? 0,\n });\n }\n}\n\nfunction suggestStructuredKey(flatKey: string): string {\n // `colorPrimary` -> `colors: { primary: ... }`\n // `radiusMd` -> `radius: { md: ... }`\n // `fontHeading` -> `font: { heading: ... }`\n // `motionSlow` -> `motion: { slow: ... }`\n // `elevation2` -> `elevation: { 2: ... }`\n const groups: Array<{ prefix: string; group: string }> = [\n { prefix: \"color\", group: \"colors\" },\n { prefix: \"radius\", group: \"radius\" },\n { prefix: \"font\", group: \"font\" },\n { prefix: \"motion\", group: \"motion\" },\n { prefix: \"elevation\", group: \"elevation\" },\n ];\n for (const { prefix, group } of groups) {\n if (flatKey === prefix) continue;\n if (flatKey.startsWith(prefix) && flatKey.length > prefix.length) {\n const tail = flatKey.slice(prefix.length);\n const inner = tail.charAt(0).toLowerCase() + tail.slice(1);\n return `Theme({ ${group}: { ${inner}: ... } })`;\n }\n }\n return `Theme({ colors: {...}, radius: {...}, font: {...}, motion: {...}, elevation: {...} })`;\n}\n","/**\n * Built-in `@Name(...)` functions for Aktion.\n *\n * These are pure data transformations. The legacy action-step builtins\n * (`@Run`, `@Set`, `@Reset`, `@ToAssistant`, `@OpenUrl`, `@Navigate`,\n * `@Js`) and the `@Const` memo helper were removed. Use `action <Name>() {\n * … }` declarations + lambda handlers (`onClick: save`) instead, and just\n * `$name = expression` for plain reactive bindings.\n */\n\nexport type BuiltinFn = (args: unknown[]) => unknown;\n\nconst toNumber = (v: unknown): number => {\n if (typeof v === \"number\") return v;\n if (typeof v === \"string\" && v.trim() !== \"\" && !Number.isNaN(Number(v))) return Number(v);\n return 0;\n};\n\nconst toArray = (v: unknown): unknown[] => (Array.isArray(v) ? v : []);\n\nconst compare = (op: string, a: unknown, b: unknown): boolean => {\n switch (op) {\n case \"==\": return a === b;\n case \"!=\": return a !== b;\n case \">\": return toNumber(a) > toNumber(b);\n case \"<\": return toNumber(a) < toNumber(b);\n case \">=\": return toNumber(a) >= toNumber(b);\n case \"<=\": return toNumber(a) <= toNumber(b);\n case \"contains\": {\n const haystack = String(a ?? \"\").toLowerCase();\n const needle = String(b ?? \"\").toLowerCase();\n return haystack.includes(needle);\n }\n default: return false;\n }\n};\n\nconst getField = (item: unknown, field: string): unknown => {\n // Empty/missing field name → compare the item itself. This makes\n // primitive arrays like `@Filter([\"a\",\"b\"], \"\", \"!=\", \"a\")` behave\n // intuitively. For objects, look up the named key (supporting dotted\n // paths so `@Filter(rows, \"user.name\", \"==\", \"Asfand\")` works without\n // pre-flattening the rows).\n if (field === \"\") return item;\n if (item && typeof item === \"object\") {\n if (field.includes(\".\")) {\n const parts = field.split(\".\");\n let cursor: unknown = item;\n for (const part of parts) {\n if (cursor && typeof cursor === \"object\") {\n cursor = (cursor as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n return cursor;\n }\n return (item as Record<string, unknown>)[field];\n }\n return undefined;\n};\n\nconst filterByField = (args: unknown[]): unknown[] => {\n const arr = toArray(args[0]);\n const field = String(args[1] ?? \"\");\n const op = String(args[2] ?? \"==\");\n const value = args[3];\n return arr.filter((item) => compare(op, getField(item, field), value));\n};\n\nconst isObject = (v: unknown): v is Record<string, unknown> =>\n Boolean(v) && typeof v === \"object\" && !Array.isArray(v);\n\n/**\n * Parse a value into a `Date` instance. Accepts ISO strings, epoch\n * milliseconds, `Date` instances themselves, and (as a graceful fallback)\n * the empty string → \"now\".\n */\nconst toDate = (v: unknown): Date => {\n if (v instanceof Date) return v;\n if (typeof v === \"number\") return new Date(v);\n if (typeof v === \"string\" && v.trim() !== \"\") {\n // Numeric strings are interpreted as epoch ms; everything else goes\n // through `Date`'s ISO/date string parser.\n if (!Number.isNaN(Number(v)) && /^-?\\d+$/.test(v.trim())) {\n return new Date(Number(v));\n }\n const d = new Date(v);\n if (!Number.isNaN(d.getTime())) return d;\n }\n return new Date();\n};\n\nconst MONTHS_SHORT = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"];\nconst MONTHS_LONG = [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"];\nconst DAYS_SHORT = [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"];\nconst DAYS_LONG = [\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"];\n\n/**\n * Tiny date formatter using a moment-like token language. Supports:\n * YYYY, YY, MMMM, MMM, MM, M, DD, D, dddd, ddd, HH, H, hh, h, mm, m, ss, s, A, a.\n * Designed for human-readable labels in cards/timelines — not a replacement\n * for `Intl.DateTimeFormat` which authors should reach for via @Format if\n * they need full locale awareness.\n */\nconst formatDateTokens = (date: Date, pattern: string): string => {\n const pad = (n: number, w = 2): string => String(n).padStart(w, \"0\");\n const hours = date.getHours();\n const hour12 = ((hours + 11) % 12) + 1;\n const tokens: Array<[RegExp, string]> = [\n [/YYYY/g, String(date.getFullYear())],\n [/YY/g, String(date.getFullYear()).slice(-2)],\n [/MMMM/g, MONTHS_LONG[date.getMonth()]!],\n [/MMM/g, MONTHS_SHORT[date.getMonth()]!],\n [/MM/g, pad(date.getMonth() + 1)],\n [/dddd/g, DAYS_LONG[date.getDay()]!],\n [/ddd/g, DAYS_SHORT[date.getDay()]!],\n [/DD/g, pad(date.getDate())],\n [/HH/g, pad(hours)],\n [/hh/g, pad(hour12)],\n [/mm/g, pad(date.getMinutes())],\n [/ss/g, pad(date.getSeconds())],\n [/\\bM\\b/g, String(date.getMonth() + 1)],\n [/\\bD\\b/g, String(date.getDate())],\n [/\\bH\\b/g, String(hours)],\n [/\\bh\\b/g, String(hour12)],\n [/\\bm\\b/g, String(date.getMinutes())],\n [/\\bs\\b/g, String(date.getSeconds())],\n [/A/g, hours >= 12 ? \"PM\" : \"AM\"],\n [/a/g, hours >= 12 ? \"pm\" : \"am\"],\n ];\n let out = pattern;\n for (const [re, value] of tokens) out = out.replace(re, value);\n return out;\n};\n\nconst formatRelative = (date: Date, now = Date.now()): string => {\n const diff = now - date.getTime();\n const abs = Math.abs(diff);\n const future = diff < 0;\n const minute = 60_000;\n const hour = 60 * minute;\n const day = 24 * hour;\n const week = 7 * day;\n const month = 30 * day;\n const year = 365 * day;\n let value: number;\n let unit: string;\n if (abs < minute) return future ? \"in a moment\" : \"just now\";\n if (abs < hour) { value = Math.round(abs / minute); unit = \"m\"; }\n else if (abs < day) { value = Math.round(abs / hour); unit = \"h\"; }\n else if (abs < week) { value = Math.round(abs / day); unit = \"d\"; }\n else if (abs < month) { value = Math.round(abs / week); unit = \"w\"; }\n else if (abs < year) { value = Math.round(abs / month); unit = \"mo\"; }\n else { value = Math.round(abs / year); unit = \"y\"; }\n return future ? `in ${value}${unit}` : `${value}${unit} ago`;\n};\n\nconst recase = (input: unknown, kind: \"camel\" | \"pascal\" | \"snake\" | \"kebab\"): string => {\n const text = String(input ?? \"\");\n // Split on any non-alphanumeric run AND at boundaries between lowercase\n // followed by uppercase (so `helloWorld` → [\"hello\",\"World\"]).\n const parts = text\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[^A-Za-z0-9]+/)\n .filter(Boolean)\n .map((p) => p.toLowerCase());\n if (parts.length === 0) return \"\";\n if (kind === \"snake\") return parts.join(\"_\");\n if (kind === \"kebab\") return parts.join(\"-\");\n const cap = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);\n if (kind === \"pascal\") return parts.map(cap).join(\"\");\n // camel\n return parts[0]! + parts.slice(1).map(cap).join(\"\");\n};\n\nexport const dataBuiltins: Record<string, BuiltinFn> = {\n Count: (args) => toArray(args[0]).length,\n Sum: (args) => toArray(args[0]).reduce<number>((acc, v) => acc + toNumber(v), 0),\n Avg: (args) => {\n const arr = toArray(args[0]);\n if (arr.length === 0) return 0;\n return arr.reduce<number>((acc, v) => acc + toNumber(v), 0) / arr.length;\n },\n Min: (args) => {\n const arr = toArray(args[0]).map(toNumber);\n return arr.length === 0 ? 0 : Math.min(...arr);\n },\n Max: (args) => {\n const arr = toArray(args[0]).map(toNumber);\n return arr.length === 0 ? 0 : Math.max(...arr);\n },\n First: (args) => toArray(args[0])[0] ?? null,\n Last: (args) => {\n const arr = toArray(args[0]);\n return arr.length === 0 ? null : arr[arr.length - 1];\n },\n Filter: filterByField,\n /** Alias for `@Filter` — identical semantics. */\n FilterBy: filterByField,\n Sort: (args) => {\n const arr = [...toArray(args[0])];\n const field = String(args[1] ?? \"\");\n const direction = String(args[2] ?? \"asc\").toLowerCase() === \"desc\" ? -1 : 1;\n arr.sort((a, b) => {\n const av = getField(a, field);\n const bv = getField(b, field);\n if (typeof av === \"number\" && typeof bv === \"number\") return (av - bv) * direction;\n return String(av ?? \"\").localeCompare(String(bv ?? \"\")) * direction;\n });\n return arr;\n },\n Round: (args) => {\n const n = toNumber(args[0]);\n const decimals = args[1] === undefined ? 0 : toNumber(args[1]);\n const factor = Math.pow(10, decimals);\n return Math.round(n * factor) / factor;\n },\n Abs: (args) => Math.abs(toNumber(args[0])),\n Floor: (args) => Math.floor(toNumber(args[0])),\n Ceil: (args) => Math.ceil(toNumber(args[0])),\n\n // ───────── Array helpers ─────────\n /** Find the first item matching a comparator (mirrors `@Filter`). */\n Find: (args) => {\n const arr = toArray(args[0]);\n const field = String(args[1] ?? \"\");\n const op = String(args[2] ?? \"==\");\n const value = args[3];\n return arr.find((item) => compare(op, getField(item, field), value)) ?? null;\n },\n /** Group items by a field — `{groupKey: [items…]}`. */\n GroupBy: (args) => {\n const arr = toArray(args[0]);\n const field = String(args[1] ?? \"\");\n const out: Record<string, unknown[]> = {};\n for (const item of arr) {\n const key = String(getField(item, field) ?? \"\");\n (out[key] ??= []).push(item);\n }\n return out;\n },\n /** Slice an array — `start`, optional `end`, both clamped. */\n Slice: (args) => {\n const arr = toArray(args[0]);\n const start = args[1] === undefined ? 0 : toNumber(args[1]);\n const end = args[2] === undefined ? arr.length : toNumber(args[2]);\n return arr.slice(start, end);\n },\n /**\n * Deduplicate. Without a field, compares values with strict equality;\n * with a field, dedupes by that field's value (first seen wins).\n */\n Unique: (args) => {\n const arr = toArray(args[0]);\n const field = args[1] === undefined ? \"\" : String(args[1] ?? \"\");\n if (!field) return Array.from(new Set(arr));\n const seen = new Set<unknown>();\n const out: unknown[] = [];\n for (const item of arr) {\n const key = getField(item, field);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(item);\n }\n return out;\n },\n /** Reverse a copy of the array (non-mutating). */\n Reverse: (args) => [...toArray(args[0])].reverse(),\n /**\n * Inclusive integer range. `@Range(0, 4)` → `[0,1,2,3,4]`. With a third\n * argument, controls the step (defaults to 1, may be negative).\n */\n Range: (args) => {\n const start = toNumber(args[0]);\n const end = toNumber(args[1]);\n const step = args[2] === undefined ? (end >= start ? 1 : -1) : toNumber(args[2]);\n if (step === 0) return [start];\n const out: number[] = [];\n if (step > 0) {\n for (let n = start; n <= end; n += step) out.push(n);\n } else {\n for (let n = start; n >= end; n += step) out.push(n);\n }\n return out;\n },\n /** Repeat a value N times — handy for skeleton placeholders. */\n Repeat: (args) => {\n const n = Math.max(0, toNumber(args[1]));\n return Array.from({ length: n }, () => args[0]);\n },\n /** Reshape an object — keep only the listed keys. */\n Pick: (args) => {\n const obj = args[0];\n if (!isObject(obj)) return {};\n const keys = toArray(args[1]).map((k) => String(k ?? \"\"));\n const out: Record<string, unknown> = {};\n for (const key of keys) {\n if (key in obj) out[key] = obj[key];\n }\n return out;\n },\n\n // ───────── Formatting ─────────\n /**\n * Locale-aware number/currency formatter. Modes:\n * - `\"currency\"` (default `USD`)\n * - `\"percent\"` — multiplies by 100; pass already-fractional values\n * - `\"number\"` / omitted — plain numeric formatting\n */\n Format: (args) => {\n const value = toNumber(args[0]);\n const mode = String(args[1] ?? \"number\");\n const opt = args[2];\n if (mode === \"currency\") {\n const currency = String(opt ?? \"USD\") || \"USD\";\n const locale = args[3] === undefined ? undefined : String(args[3] ?? \"\");\n try {\n return new Intl.NumberFormat(locale || undefined, { style: \"currency\", currency }).format(value);\n } catch {\n return value.toFixed(2);\n }\n }\n if (mode === \"percent\") {\n const locale = args[2] === undefined ? undefined : String(args[2] ?? \"\");\n return new Intl.NumberFormat(locale || undefined, { style: \"percent\", maximumFractionDigits: 2 }).format(value);\n }\n const locale = args[2] === undefined ? undefined : String(args[2] ?? \"\");\n return new Intl.NumberFormat(locale || undefined).format(value);\n },\n /**\n * Format a date. The second argument is either a moment-like pattern\n * (e.g. `\"MMM D\"`, `\"YYYY-MM-DD\"`) or one of these named modes:\n * - `\"relative\"` — \"5m ago\", \"in 2h\"\n * - `\"date\"` — locale short date\n * - `\"time\"` — locale short time\n * - `\"datetime\"` — locale short datetime\n * - `\"iso\"` — ISO 8601 string\n */\n FormatDate: (args) => {\n const date = toDate(args[0]);\n const mode = String(args[1] ?? \"MMM D\");\n switch (mode) {\n case \"relative\": return formatRelative(date);\n case \"date\": return date.toLocaleDateString();\n case \"time\": return date.toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" });\n case \"datetime\": return date.toLocaleString();\n case \"iso\": return date.toISOString();\n default: return formatDateTokens(date, mode);\n }\n },\n\n // ───────── Date / time helpers ─────────\n /** Current moment as epoch ms — feed to @FormatDate for display. */\n Now: () => Date.now(),\n /** Today's date at midnight, as an ISO string. */\n Today: () => {\n const d = new Date();\n d.setHours(0, 0, 0, 0);\n return d.toISOString();\n },\n /** Shift a date by N days (negative N moves backward). */\n AddDays: (args) => {\n const date = toDate(args[0]);\n const days = toNumber(args[1]);\n const next = new Date(date.getTime());\n next.setDate(next.getDate() + days);\n return next.toISOString();\n },\n /** Shift a date by N hours (negative N moves backward). */\n AddHours: (args) => {\n const date = toDate(args[0]);\n const hours = toNumber(args[1]);\n const next = new Date(date.getTime());\n next.setTime(next.getTime() + hours * 3_600_000);\n return next.toISOString();\n },\n /** Whole-day difference from `start` to `end` (end − start). */\n DiffDays: (args) => {\n const start = toDate(args[0]);\n const end = toDate(args[1]);\n const msPerDay = 86_400_000;\n return Math.round((end.getTime() - start.getTime()) / msPerDay);\n },\n /** UTC Sunday 00:00:00 for the week containing `date`. */\n StartOfWeek: (args) => {\n const date = toDate(args[0]);\n const next = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));\n next.setUTCDate(next.getUTCDate() - next.getUTCDay());\n return next.toISOString();\n },\n /** Last moment of the calendar month containing `date`. */\n EndOfMonth: (args) => {\n const date = toDate(args[0]);\n const next = new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59, 999);\n return next.toISOString();\n },\n\n // ───────── String helpers ─────────\n /** Pluralisation: `@Plural(n, \"order\", \"orders\")` → \"1 order\"/\"2 orders\". */\n Plural: (args) => {\n const n = toNumber(args[0]);\n const singular = String(args[1] ?? \"\");\n const plural = args[2] === undefined ? singular + \"s\" : String(args[2] ?? \"\");\n return `${n} ${n === 1 ? singular : plural}`;\n },\n Capitalize: (args) => {\n const text = String(args[0] ?? \"\");\n if (text.length === 0) return \"\";\n return text.charAt(0).toUpperCase() + text.slice(1);\n },\n Lowercase: (args) => String(args[0] ?? \"\").toLowerCase(),\n Uppercase: (args) => String(args[0] ?? \"\").toUpperCase(),\n Titlecase: (args) => String(args[0] ?? \"\")\n .split(/\\s+/)\n .filter(Boolean)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())\n .join(\" \"),\n Case: (args) => {\n const kind = String(args[1] ?? \"camel\").toLowerCase();\n if (kind === \"snake\" || kind === \"kebab\" || kind === \"pascal\" || kind === \"camel\") {\n return recase(args[0], kind);\n }\n return recase(args[0], \"camel\");\n },\n Join: (args) => {\n const arr = toArray(args[0]);\n const sep = args[1] === undefined ? \",\" : String(args[1] ?? \"\");\n return arr.map((v) => (v == null ? \"\" : String(v))).join(sep);\n },\n Split: (args) => {\n const text = String(args[0] ?? \"\");\n const sep = args[1] === undefined ? \",\" : String(args[1] ?? \"\");\n return text.split(sep);\n },\n Trim: (args) => String(args[0] ?? \"\").trim(),\n Replace: (args) => {\n const text = String(args[0] ?? \"\");\n const search = String(args[1] ?? \"\");\n const replacement = args[2] === undefined ? \"\" : String(args[2] ?? \"\");\n return text.split(search).join(replacement);\n },\n Substring: (args) => {\n const text = String(args[0] ?? \"\");\n const start = toNumber(args[1]);\n const end = args[2] === undefined ? text.length : toNumber(args[2]);\n return text.substring(start, end);\n },\n StartsWith: (args) => String(args[0] ?? \"\").startsWith(String(args[1] ?? \"\")),\n EndsWith: (args) => String(args[0] ?? \"\").endsWith(String(args[1] ?? \"\")),\n Contains: (args) => String(args[0] ?? \"\").includes(String(args[1] ?? \"\")),\n Match: (args) => {\n const text = String(args[0] ?? \"\");\n const pattern = String(args[1] ?? \"\");\n try {\n return new RegExp(pattern).test(text);\n } catch {\n return false;\n }\n },\n\n // ───────── Numeric utility ─────────\n /** Clamp a number into `[min, max]`. */\n Clamp: (args) => {\n const v = toNumber(args[0]);\n const min = toNumber(args[1]);\n const max = toNumber(args[2]);\n return Math.min(Math.max(v, min), max);\n },\n Pow: (args) => Math.pow(toNumber(args[0]), toNumber(args[1])),\n Sqrt: (args) => Math.sqrt(toNumber(args[0])),\n Random: () => Math.random(),\n Log: (args) => Math.log(toNumber(args[0])),\n};\n\n/**\n * Marker emitted by the `Theme({...})` construct. Carries an arbitrary token\n * map that the element applies on top of the base theme between render\n * cycles. Distinct from `ComponentNode` so the renderer can ignore it (it is\n * a side-effect, not a piece of UI to draw).\n *\n * Authors declare a theme like any other top-level binding:\n *\n * theme = Theme({ colors: { primary: \"#0969da\" }, radius: { button: \"6px\" } })\n * root = Stack([...])\n */\nexport interface ThemeNode {\n kind: \"Theme\";\n tokens: Record<string, string>;\n}\n\nexport const isThemeNode = (value: unknown): value is ThemeNode => {\n return Boolean(\n value && typeof value === \"object\" &&\n (value as { kind?: unknown }).kind === \"Theme\",\n );\n};\n","/**\n * Lightweight reactive state container.\n *\n * Each `$variable` is tracked here. Components and queries subscribe to a\n * specific set of state names; when any of them changes, their `notify`\n * callback fires. There are no proxies or Symbols on the user-facing API,\n * which keeps the surface small and predictable.\n */\n\nexport type StateValue = unknown;\n\nexport type Subscriber = (changedNames: ReadonlySet<string>) => void;\n\n/**\n * Pluggable persistent storage adapter for `$$variable` declarations.\n *\n * The default implementation reads/writes JSON-encoded values to the host\n * page's `localStorage`. Hosts (or tests) can swap it out via\n * `StateStore.setPersistenceAdapter(...)` — useful for SSR shims or to\n * scope storage per-element via a custom key prefix.\n */\nexport interface PersistenceAdapter {\n load(name: string): StateValue | undefined;\n save(name: string, value: StateValue): void;\n remove(name: string): void;\n}\n\nexport class StateStore {\n private values = new Map<string, StateValue>();\n private defaults = new Map<string, StateValue>();\n /** Persistent variable names — written to the adapter on every change. */\n private persistent = new Set<string>();\n private persistenceAdapter: PersistenceAdapter | null = null;\n private subscribers = new Set<Subscriber>();\n private pendingChanges = new Set<string>();\n private flushScheduled = false;\n\n setPersistenceAdapter(adapter: PersistenceAdapter | null): void {\n this.persistenceAdapter = adapter;\n }\n\n declare(name: string, defaultValue: StateValue): void {\n this.defaults.set(name, defaultValue);\n if (!this.values.has(name)) {\n this.values.set(name, defaultValue);\n }\n }\n\n /**\n * Declare a persistent `$$variable`. The adapter is queried for an\n * existing value; if one is found, it replaces the default. Otherwise\n * the default is written back so the next mount reads the seeded value.\n */\n declarePersistent(name: string, defaultValue: StateValue): void {\n this.persistent.add(name);\n this.defaults.set(name, defaultValue);\n const adapter = this.persistenceAdapter;\n let initial: StateValue = defaultValue;\n if (adapter) {\n const stored = adapter.load(name);\n if (stored !== undefined) initial = stored;\n }\n this.values.set(name, initial);\n }\n\n isPersistent(name: string): boolean {\n return this.persistent.has(name);\n }\n\n has(name: string): boolean {\n return this.values.has(name);\n }\n\n get(name: string): StateValue {\n return this.values.get(name);\n }\n\n set(name: string, value: StateValue): void {\n if (this.values.get(name) === value) return;\n this.values.set(name, value);\n this.pendingChanges.add(name);\n if (this.persistent.has(name)) {\n this.persistenceAdapter?.save(name, value);\n }\n this.scheduleFlush();\n }\n\n /** Iterate over every (name, value) pair. Order is insertion order. */\n entries(): IterableIterator<[string, StateValue]> {\n return this.values.entries();\n }\n\n /** Snapshot every (name, value) pair into a plain object. */\n snapshot(): Record<string, StateValue> {\n const out: Record<string, StateValue> = {};\n this.values.forEach((value, key) => {\n out[key] = value;\n });\n return out;\n }\n\n /**\n * Aktion 0.5 §26 — resumability primitive. Restores\n * every atom in `snapshot` *without* notifying subscribers, so the\n * host can seed values before the runtime mounts (SSR hydration,\n * URL-backed deep links, conversational continuity). Atoms that have\n * not yet been `declare`d are still written so they show up the\n * moment the program declares them.\n *\n * The persistence adapter is *not* consulted — hydration is\n * authoritative. If the caller wants persisted reads to win, they\n * should call `hydrate(snapshot)` before `declare(name, …)`.\n */\n hydrate(snapshot: Readonly<Record<string, StateValue>>): void {\n for (const [name, value] of Object.entries(snapshot)) {\n this.values.set(name, value);\n }\n }\n\n reset(...names: string[]): void {\n let dirty = false;\n for (const name of names) {\n // Reset is a no-op for names that were never declared — keeps the\n // store free of `undefined` sentinels when the LLM types\n // `@Reset($typo)` for a variable that doesn't exist.\n if (!this.defaults.has(name)) continue;\n const fallback = this.defaults.get(name);\n if (this.values.get(name) === fallback) continue;\n this.values.set(name, fallback);\n this.pendingChanges.add(name);\n if (this.persistent.has(name)) {\n this.persistenceAdapter?.save(name, fallback);\n }\n dirty = true;\n }\n if (dirty) this.scheduleFlush();\n }\n\n resetAll(): void {\n let dirty = false;\n for (const [name, value] of this.defaults.entries()) {\n if (this.values.get(name) === value) continue;\n this.values.set(name, value);\n this.pendingChanges.add(name);\n dirty = true;\n }\n if (dirty) this.scheduleFlush();\n }\n\n /**\n * Replace all state entries. Called when a fresh program is loaded.\n *\n * Also drops any pending change notifications: their names refer to the\n * previous program's bindings, which no longer exist, and forwarding them\n * to subscribers can fire queries / scripts that race against the new\n * program's planning step.\n */\n rebind(declarations: Iterable<[string, StateValue]>): void {\n this.values.clear();\n this.defaults.clear();\n this.persistent.clear();\n this.pendingChanges.clear();\n for (const [name, value] of declarations) {\n this.defaults.set(name, value);\n this.values.set(name, value);\n }\n }\n\n subscribe(subscriber: Subscriber): () => void {\n this.subscribers.add(subscriber);\n return () => this.subscribers.delete(subscriber);\n }\n\n private scheduleFlush(): void {\n if (this.flushScheduled) return;\n this.flushScheduled = true;\n queueMicrotask(() => this.flush());\n }\n\n private flush(): void {\n this.flushScheduled = false;\n if (this.pendingChanges.size === 0) return;\n const changes = new Set(this.pendingChanges);\n this.pendingChanges.clear();\n for (const subscriber of [...this.subscribers]) {\n subscriber(changes);\n }\n }\n}\n\n/**\n * Build a `PersistenceAdapter` backed by `window.localStorage` (or\n * `sessionStorage`). The returned adapter namespaces each key by\n * `keyPrefix` so two elements on the same page don't clobber one\n * another's `$$variable` values. Returns `null` when no storage is\n * available (SSR, sandboxed iframes, private mode in some browsers).\n */\nexport function createLocalStorageAdapter(\n keyPrefix: string,\n storage: Storage | null,\n): PersistenceAdapter | null {\n if (!storage) return null;\n const fullKey = (name: string): string => `${keyPrefix}::${name}`;\n return {\n load(name) {\n try {\n const raw = storage.getItem(fullKey(name));\n if (raw === null) return undefined;\n return JSON.parse(raw) as StateValue;\n } catch {\n return undefined;\n }\n },\n save(name, value) {\n try {\n storage.setItem(fullKey(name), JSON.stringify(value));\n } catch {\n // Quota errors or denied storage are swallowed — persistence is a\n // best-effort enhancement, not a correctness requirement.\n }\n },\n remove(name) {\n try {\n storage.removeItem(fullKey(name));\n } catch {/* see save() */}\n },\n };\n}\n","/**\n * HTTP runtime for the language. The language exposes a single\n * `http({...})` function that returns a reactive resource bag with\n * `data`, `error`, `status`, `loading`, `headers`, `lastUpdated`,\n * `refetch()`, and `cancel()`.\n *\n * Configuration (base URL, default headers, retry, interceptors) is\n * captured by an `HttpRuntime` singleton; the host registers it once\n * at element-construction time. Programs may opt in to per-program\n * defaults via `$http = Http({ baseUrl, headers, retry, ... })`.\n */\n\nimport type { EvaluationContext } from \"./evaluator.js\";\n\n/* -------------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------------- */\n\nexport type HttpMethod =\n | \"GET\"\n | \"HEAD\"\n | \"OPTIONS\"\n | \"POST\"\n | \"PUT\"\n | \"PATCH\"\n | \"DELETE\";\n\nexport interface HttpRequest {\n url: string;\n method: HttpMethod;\n headers: Record<string, string>;\n body?: unknown;\n signal?: AbortSignal;\n}\n\nexport interface HttpResponse {\n status: number;\n headers: Record<string, string>;\n body: unknown;\n}\n\nexport interface HttpInterceptors {\n onRequest?: (request: HttpRequest) => HttpRequest | Promise<HttpRequest>;\n onResponse?: (\n response: HttpResponse,\n retry: () => Promise<HttpResponse>,\n ) => HttpResponse | Promise<HttpResponse>;\n onError?: (error: unknown, request: HttpRequest) => void;\n}\n\nexport interface HttpDefaults {\n baseUrl?: string;\n headers?: Record<string, string>;\n timeoutMs?: number;\n retry?: { count: number; backoff?: \"linear\" | \"exponential\" };\n credentials?: RequestCredentials;\n}\n\n/** Reactive lifecycle of an `http({...})` resource. */\nexport type ResourceState = \"idle\" | \"loading\" | \"data\" | \"error\" | \"stale\";\n\n/**\n * Reactive bag returned by `http({...})`. Fields update in place as\n * the request progresses; the runtime calls `notify()` so the next\n * render observes the new values.\n */\nexport interface EndpointResource {\n state: ResourceState;\n data: unknown;\n error: unknown;\n loading: boolean;\n status?: number;\n headers?: Record<string, string>;\n lastUpdated?: number;\n refetch: () => Promise<void>;\n cancel: () => void;\n}\n\n/** Compatibility shim — subscription transports were removed in this version. */\nexport interface SubscriptionTransport {\n open(url: string, opts: { protocol?: string; headers?: Record<string, string> }): {\n onMessage(cb: (raw: unknown) => void): void;\n onError(cb: (err: unknown) => void): void;\n onClose(cb: () => void): void;\n onOpen(cb: () => void): void;\n send(payload: unknown): void;\n close(): void;\n };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Runtime */\n/* -------------------------------------------------------------------------- */\n\nexport class HttpRuntime {\n private interceptors: HttpInterceptors = {};\n private defaults: HttpDefaults = {};\n\n setDefaults(defaults: HttpDefaults): void {\n this.defaults = { ...defaults };\n }\n\n /** Merge new interceptors on top of any previously-registered ones. */\n registerInterceptors(interceptors: HttpInterceptors): void {\n this.interceptors = { ...this.interceptors, ...interceptors };\n }\n\n /** Resolve a relative URL against the configured `baseUrl`. */\n resolveUrl(url: string): string {\n const base = this.defaults.baseUrl;\n if (!base) return url;\n if (/^https?:\\/\\//i.test(url) || /^wss?:\\/\\//i.test(url)) return url;\n if (url.startsWith(\"/\")) {\n return base.replace(/\\/$/, \"\") + url;\n }\n return base.replace(/\\/$/, \"\") + \"/\" + url;\n }\n\n /**\n * Issue a single HTTP request. Runs through `onRequest`/`onResponse`\n * interceptors and surfaces a `retry()` one-shot inside `onResponse`.\n * Honours `defaults.timeoutMs` via `AbortController`.\n */\n async request(input: HttpRequest): Promise<HttpResponse> {\n let req: HttpRequest = {\n ...input,\n headers: { ...this.defaults.headers, ...input.headers },\n };\n if (this.interceptors.onRequest) {\n try {\n req = await this.interceptors.onRequest(req);\n } catch (err) {\n this.interceptors.onError?.(err, req);\n throw err;\n }\n }\n\n const exec = async (): Promise<HttpResponse> => {\n const controller = new AbortController();\n const timeoutMs = this.defaults.timeoutMs ?? 0;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n if (timeoutMs > 0) {\n timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n }\n try {\n const fetchFn = typeof fetch === \"function\" ? fetch : null;\n if (!fetchFn) {\n throw new Error(\"`fetch` is not available in this environment\");\n }\n const init: RequestInit = {\n method: req.method,\n headers: req.headers,\n signal: req.signal ?? controller.signal,\n };\n if (req.body !== undefined && req.method !== \"GET\" && req.method !== \"HEAD\") {\n init.body = encodeBody(req.body, req.headers);\n }\n if (this.defaults.credentials) {\n init.credentials = this.defaults.credentials;\n }\n const response = await fetchFn(req.url, init);\n const headers: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n headers[key] = value;\n });\n const contentType = headers[\"content-type\"] ?? \"\";\n let body: unknown;\n if (response.status === 204 || req.method === \"HEAD\") {\n body = null;\n } else if (contentType.includes(\"application/json\")) {\n body = await response.json().catch(() => null);\n } else {\n body = await response.text().catch(() => \"\");\n }\n return { status: response.status, headers, body };\n } finally {\n if (timeoutId) clearTimeout(timeoutId);\n }\n };\n\n const retryCfg = this.defaults.retry;\n const maxRetries = Math.max(0, retryCfg?.count ?? 0);\n const backoffMode = retryCfg?.backoff ?? \"exponential\";\n\n const execWithRetry = async (): Promise<HttpResponse> => {\n let lastErr: unknown = null;\n for (let attempt = 0; attempt <= maxRetries; attempt += 1) {\n try {\n const response = await exec();\n if (response.status >= 500 && response.status <= 599 && attempt < maxRetries) {\n await sleep(computeBackoff(backoffMode, attempt));\n continue;\n }\n return response;\n } catch (err) {\n lastErr = err;\n if (attempt < maxRetries) {\n await sleep(computeBackoff(backoffMode, attempt));\n continue;\n }\n throw err;\n }\n }\n throw lastErr ?? new Error(\"retry loop exhausted\");\n };\n\n try {\n let response = await execWithRetry();\n if (this.interceptors.onResponse) {\n let retried = false;\n const retry = async (): Promise<HttpResponse> => {\n if (retried) return response;\n retried = true;\n return execWithRetry();\n };\n response = await this.interceptors.onResponse(response, retry);\n }\n return response;\n } catch (err) {\n this.interceptors.onError?.(err, req);\n throw err;\n }\n }\n}\n\nfunction computeBackoff(mode: \"linear\" | \"exponential\", attempt: number): number {\n if (mode === \"linear\") return 1000 * (attempt + 1);\n return Math.min(30_000, 500 * 2 ** attempt);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction encodeBody(body: unknown, headers: Record<string, string>): BodyInit {\n if (body === null || body === undefined) return \"\";\n if (typeof body === \"string\") return body;\n if (body instanceof Blob || body instanceof ArrayBuffer) return body as BodyInit;\n if (typeof FormData !== \"undefined\" && body instanceof FormData) return body;\n if (typeof URLSearchParams !== \"undefined\" && body instanceof URLSearchParams) return body;\n if (!headers[\"content-type\"] && !headers[\"Content-Type\"]) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n try {\n return JSON.stringify(body);\n } catch {\n return String(body);\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* http({...}) — reactive resource factory */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Build an `HttpRequest` from the user-supplied configuration object\n * accepted by `http({...})`. Accepts every standard `fetch` option plus\n * a `query` shorthand whose entries are appended to the URL as a\n * querystring. Anything missing falls back to sane defaults.\n */\nfunction buildRequestFromConfig(config: unknown): HttpRequest {\n const cfg = (config && typeof config === \"object\" && !Array.isArray(config))\n ? (config as Record<string, unknown>)\n : {};\n const url = typeof cfg.url === \"string\" ? cfg.url : \"\";\n const method = (typeof cfg.method === \"string\" ? cfg.method.toUpperCase() : \"GET\") as HttpMethod;\n const headers: Record<string, string> = {};\n if (cfg.headers && typeof cfg.headers === \"object\" && !Array.isArray(cfg.headers)) {\n for (const [k, v] of Object.entries(cfg.headers as Record<string, unknown>)) {\n if (v == null) continue;\n headers[k] = String(v);\n }\n }\n let finalUrl = url;\n if (cfg.query && typeof cfg.query === \"object\" && !Array.isArray(cfg.query)) {\n const params = new URLSearchParams();\n for (const [k, v] of Object.entries(cfg.query as Record<string, unknown>)) {\n if (v == null) continue;\n params.append(k, String(v));\n }\n const qs = params.toString();\n if (qs) finalUrl += (finalUrl.includes(\"?\") ? \"&\" : \"?\") + qs;\n }\n const req: HttpRequest = {\n url: finalUrl,\n method,\n headers,\n body: cfg.body,\n };\n if (cfg.signal instanceof AbortSignal) req.signal = cfg.signal;\n return req;\n}\n\n/**\n * Run a single `http({...})` call and return the reactive resource bag.\n *\n * The bag mutates in place: `data`, `error`, `status`, `loading`,\n * `headers`, `lastUpdated` update during the request lifecycle. The\n * `refetch()` callback re-issues the original request; `cancel()`\n * aborts the in-flight request (no-op when idle).\n */\nexport function createHttpResource(\n config: unknown,\n ctx: EvaluationContext,\n): EndpointResource {\n const resource: EndpointResource = {\n state: \"loading\",\n data: undefined,\n error: undefined,\n loading: true,\n refetch: async () => { await run(); },\n cancel: () => {\n if (controller) controller.abort();\n },\n };\n\n let controller: AbortController | null = null;\n let inFlight = false;\n const notify = () => ctx.notify?.();\n\n const run = async (): Promise<void> => {\n if (inFlight && controller) controller.abort();\n inFlight = true;\n controller = new AbortController();\n resource.state = resource.data === undefined ? \"loading\" : \"stale\";\n resource.loading = true;\n notify();\n\n if (!ctx.http) {\n resource.error = { message: \"http runtime not available\" };\n resource.state = \"error\";\n resource.loading = false;\n inFlight = false;\n notify();\n return;\n }\n try {\n const req = buildRequestFromConfig(config);\n req.url = ctx.http.resolveUrl(req.url);\n req.signal = controller.signal;\n const response = await ctx.http.request(req);\n const ok = response.status >= 200 && response.status < 300;\n if (ok) {\n resource.data = response.body;\n resource.state = \"data\";\n resource.error = undefined;\n } else {\n resource.error = { status: response.status, body: response.body };\n resource.state = \"error\";\n }\n resource.status = response.status;\n resource.headers = response.headers;\n resource.lastUpdated = Date.now();\n } catch (err) {\n if ((err as { name?: string })?.name === \"AbortError\") return;\n resource.error = err;\n resource.state = \"error\";\n } finally {\n inFlight = false;\n resource.loading = false;\n notify();\n }\n };\n\n // Kick off the initial fetch on the next tick so the synchronous\n // evaluation doesn't have to await.\n void run();\n return resource;\n}\n","/**\n * Hash-based router for `<aktion-app>`.\n *\n * The router is owned by the host element and exposed to:\n * - The evaluator (which special-cases `Routes(...)` to pick the matching\n * `Route(path, content)` and inject path params as the loop variable\n * `params`).\n * - The renderer's helpers (so `NavLink(...)` can wire click handlers).\n * - The action runner (`@Navigate(\"/path\")` step).\n *\n * The wire format is hash-based — `#/page-name`. The router strips the leading\n * `#` and any trailing `?…` query string before exposing the path. Navigating\n * inside the component updates `window.location.hash`, and external hash\n * changes (browser back/forward, direct URL edits) are picked up by the\n * `hashchange` listener.\n *\n * The router is always started by the host element when it connects so that\n * navigation works out of the box. In environments without a `window`\n * (server-side rendering, tests) the router stays in \"memory\" mode:\n * `navigate(...)` records the new path internally without touching the URL.\n */\n\nexport type RouteParams = Record<string, string>;\n\nexport interface RouteMatch {\n matched: boolean;\n params: RouteParams;\n /** True when the matched route is a wildcard (`*`) catch-all. */\n wildcard?: boolean;\n}\n\nexport interface RouteChangeDetail {\n path: string;\n previousPath: string | null;\n source: \"init\" | \"hashchange\" | \"navigate\" | \"external\";\n}\n\nexport type RouteListener = (detail: RouteChangeDetail) => void;\n\nexport interface RouterOptions {\n /** Initial path when no hash is set. Defaults to `/`. */\n defaultPath?: string;\n}\n\n/**\n * Normalise an arbitrary string into a clean route path.\n *\n * readHashPath(\"\") → \"/\"\n * readHashPath(\"#\") → \"/\"\n * readHashPath(\"#/\") → \"/\"\n * readHashPath(\"#/about\") → \"/about\"\n * readHashPath(\"#about\") → \"/about\"\n * readHashPath(\"/foo/bar?x=1\") → \"/foo/bar\"\n * readHashPath(\"//foo///bar//\") → \"/foo/bar\"\n */\nexport function normalisePath(raw: string | null | undefined): string {\n if (!raw) return \"/\";\n let value = String(raw);\n if (value.startsWith(\"#\")) value = value.slice(1);\n // Strip query string and inner fragment.\n const queryAt = value.indexOf(\"?\");\n if (queryAt >= 0) value = value.slice(0, queryAt);\n // Collapse repeated slashes, then strip trailing slash (but keep \"/\").\n value = value.replace(/\\/{2,}/g, \"/\");\n if (!value || value === \"/\") return \"/\";\n if (!value.startsWith(\"/\")) value = \"/\" + value;\n if (value.length > 1 && value.endsWith(\"/\")) value = value.slice(0, -1);\n return value;\n}\n\n/**\n * Match a route pattern against a concrete path. Patterns support:\n * - literal segments: `/about`\n * - parameter segments: `/users/:id`\n * - wildcard catch-all: `*` (matches any path, params empty unless mixed)\n * - mixed wildcard: `/docs/*` (matches everything under `/docs/`)\n */\nexport function matchRoute(pattern: string, path: string): RouteMatch {\n if (!pattern) return { matched: false, params: {} };\n // Pure wildcard catches everything.\n if (pattern === \"*\") return { matched: true, params: {}, wildcard: true };\n\n const normPattern = normalisePath(pattern);\n const normPath = normalisePath(path);\n\n const patternSegments = normPattern === \"/\" ? [] : normPattern.slice(1).split(\"/\");\n const pathSegments = normPath === \"/\" ? [] : normPath.slice(1).split(\"/\");\n\n const params: RouteParams = {};\n let wildcard = false;\n\n for (let i = 0; i < patternSegments.length; i += 1) {\n const patternSegment = patternSegments[i]!;\n\n if (patternSegment === \"*\") {\n // Trailing wildcard — consumes the rest of the path.\n wildcard = true;\n const rest = pathSegments.slice(i).join(\"/\");\n params._ = rest;\n return { matched: true, params, wildcard };\n }\n\n const pathSegment = pathSegments[i];\n if (pathSegment === undefined) return { matched: false, params: {} };\n\n if (patternSegment.startsWith(\":\")) {\n const name = patternSegment.slice(1);\n if (!name) return { matched: false, params: {} };\n params[name] = decodeURIComponent(pathSegment);\n continue;\n }\n\n if (patternSegment !== pathSegment) return { matched: false, params: {} };\n }\n\n // No wildcard, and path has more segments than pattern → no match.\n if (!wildcard && pathSegments.length > patternSegments.length) {\n return { matched: false, params: {} };\n }\n\n return wildcard ? { matched: true, params, wildcard: true } : { matched: true, params };\n}\n\n/**\n * Singleton-per-element router. Owns the current path, listens for\n * `hashchange` events when enabled, and notifies subscribers when the path\n * changes for any reason.\n */\nexport class Router {\n private currentPath: string;\n private currentParams: RouteParams = {};\n private currentPattern: string | null = null;\n private enabled = false;\n private hashListener: (() => void) | null = null;\n private listeners = new Set<RouteListener>();\n private readonly defaultPath: string;\n /** True while we're updating `window.location.hash` ourselves — used to\n * filter out the resulting `hashchange` echo. */\n private settingHash = false;\n\n constructor(options: RouterOptions = {}) {\n this.defaultPath = normalisePath(options.defaultPath ?? \"/\");\n this.currentPath = this.defaultPath;\n }\n\n /**\n * Attach the `hashchange` listener and synchronise from the current URL.\n * Safe to call multiple times — it's idempotent.\n */\n start(): void {\n if (this.enabled) return;\n this.enabled = true;\n if (typeof window === \"undefined\") return;\n\n const sync = (source: RouteChangeDetail[\"source\"]): void => {\n if (this.settingHash) return;\n const hashPath = normalisePath(window.location.hash);\n this.setPath(hashPath, source);\n };\n\n const listener = (): void => sync(\"hashchange\");\n window.addEventListener(\"hashchange\", listener);\n this.hashListener = listener;\n sync(\"init\");\n }\n\n /**\n * Detach the `hashchange` listener. The current path stays as the last\n * observed value so a follow-up `start()` resumes cleanly.\n */\n stop(): void {\n if (!this.enabled) return;\n this.enabled = false;\n if (typeof window !== \"undefined\" && this.hashListener) {\n window.removeEventListener(\"hashchange\", this.hashListener);\n }\n this.hashListener = null;\n }\n\n getPath(): string {\n return this.currentPath;\n }\n\n getParams(): RouteParams {\n return this.currentParams;\n }\n\n /** Path pattern of the most recently matched `Route` (or null). */\n getActivePattern(): string | null {\n return this.currentPattern;\n }\n\n /**\n * Called by `Routes(...)` after each render so we have the canonical\n * pattern + params for the active page (used by `NavLink` to highlight the\n * active link). The state store is NOT touched here.\n */\n setActiveMatch(pattern: string | null, params: RouteParams): void {\n this.currentPattern = pattern;\n // Reference equality short-circuits work for the most common case\n // (route hasn't changed since the last render).\n if (!shallowEqual(this.currentParams, params)) {\n this.currentParams = params;\n }\n }\n\n /**\n * Navigate to the given path. When enabled, this updates the URL hash and\n * relies on `hashchange` to notify listeners (so browser history works).\n * When disabled, the navigation stays in-memory.\n */\n navigate(path: string): void {\n const next = normalisePath(path);\n if (next === this.currentPath) return;\n\n if (this.enabled && typeof window !== \"undefined\") {\n this.settingHash = true;\n try {\n window.location.hash = \"#\" + next;\n } finally {\n // The `hashchange` listener fires asynchronously, but some browsers\n // (and happy-dom) fire it synchronously. Either way we reset the\n // flag after the next microtask so the event we triggered doesn't\n // come back through.\n queueMicrotask(() => {\n this.settingHash = false;\n });\n }\n // Some test environments (happy-dom) don't always fire hashchange.\n // Update state eagerly so subscribers don't have to depend on the\n // event being delivered.\n this.setPath(next, \"navigate\");\n return;\n }\n\n this.setPath(next, \"navigate\");\n }\n\n subscribe(listener: RouteListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /** Replace the current path without going through `window.location`. */\n private setPath(path: string, source: RouteChangeDetail[\"source\"]): void {\n const next = normalisePath(path);\n if (next === this.currentPath) return;\n const previousPath = this.currentPath;\n this.currentPath = next;\n // Params and pattern are recomputed by the next render — clear them so\n // a stale match from the previous page doesn't leak into the new one.\n this.currentParams = {};\n this.currentPattern = null;\n for (const listener of [...this.listeners]) {\n try {\n listener({ path: next, previousPath, source });\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\"[aktion] router listener failed\", err);\n }\n }\n }\n}\n\nfunction shallowEqual(a: Record<string, unknown>, b: Record<string, unknown>): boolean {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (a[key] !== b[key]) return false;\n }\n return true;\n}\n","/**\n * Browser storage namespace for Aktion.\n *\n * Exposes a single `storage` global that wraps three browser storage\n * mechanisms — `localStorage`, `sessionStorage`, and document cookies —\n * behind a uniform `set` / `get` / `remove` / `clear` API. Authors can\n * reach for the default `localStorage` directly (`storage.set(\"k\", \"v\")`)\n * or namespace through `storage.local`, `storage.session`, or\n * `storage.cookies`.\n *\n * Values that aren't strings round-trip through `JSON.stringify` /\n * `JSON.parse`, so authors can persist arrays and objects without manual\n * serialisation. Failures (quota exceeded, disabled storage, malformed\n * JSON) are swallowed and reported via the return values rather than\n * thrown — keeps streaming scripts robust in privacy / SSR contexts\n * where the underlying APIs may be missing.\n */\n\n/** Options accepted by `storage.cookies.set` (mirrors the standard cookie attributes). */\nexport interface CookieOptions {\n /** Days until expiry, or a Date instance for an absolute expiry. */\n expires?: number | Date | string;\n /** `Max-Age` in seconds — overrides `expires` when both are set. */\n maxAge?: number;\n /** Restrict cookie to the given path (defaults to `/`). */\n path?: string;\n /** Restrict cookie to the given domain. */\n domain?: string;\n /** Only send over HTTPS. */\n secure?: boolean;\n /** `SameSite` policy — `\"Strict\"`, `\"Lax\"`, or `\"None\"`. */\n sameSite?: \"Strict\" | \"Lax\" | \"None\" | \"strict\" | \"lax\" | \"none\";\n}\n\nexport interface StorageNamespace {\n set: (key: string, value: unknown, options?: CookieOptions) => boolean;\n get: (key: string) => unknown;\n remove: (key: string, options?: CookieOptions) => boolean;\n clear: () => boolean;\n}\n\nexport interface StorageRoot extends StorageNamespace {\n local: StorageNamespace;\n session: StorageNamespace;\n cookies: StorageNamespace;\n}\n\n/**\n * Try / catch wrapper used by every storage operation. Returns the\n * fallback when the underlying API throws (e.g. SecurityError in private\n * browsing modes). Keeps the storage surface side-effect free in tests\n * even when `localStorage` is missing.\n */\nconst safeRun = <T>(fn: () => T, fallback: T): T => {\n try {\n return fn();\n } catch {\n return fallback;\n }\n};\n\n/** Serialise a value the same way every namespace does (strings pass through). */\nconst serialise = (value: unknown): string => {\n if (typeof value === \"string\") return value;\n if (value === null) return \"null\";\n if (value === undefined) return \"\";\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n};\n\n/** Parse a string back to its original shape (JSON when possible). */\nconst deserialise = (raw: string | null): unknown => {\n if (raw === null || raw === \"\") return raw;\n // Numbers/booleans/null/objects are JSON-encoded by `set`; plain strings\n // fail JSON.parse and fall back to the raw value (so legacy keys keep\n // working even when authors wrote raw strings via `js{}` blocks).\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n};\n\nconst createWebStorageNamespace = (\n getBackend: () => Storage | null,\n): StorageNamespace => ({\n set: (key, value) =>\n safeRun(() => {\n const backend = getBackend();\n if (!backend) return false;\n backend.setItem(String(key), serialise(value));\n return true;\n }, false),\n get: (key) =>\n safeRun(() => {\n const backend = getBackend();\n if (!backend) return null;\n return deserialise(backend.getItem(String(key)));\n }, null),\n remove: (key) =>\n safeRun(() => {\n const backend = getBackend();\n if (!backend) return false;\n backend.removeItem(String(key));\n return true;\n }, false),\n clear: () =>\n safeRun(() => {\n const backend = getBackend();\n if (!backend) return false;\n backend.clear();\n return true;\n }, false),\n});\n\nconst getLocalBackend = (): Storage | null => {\n if (typeof globalThis === \"undefined\") return null;\n const g = globalThis as { localStorage?: Storage };\n return g.localStorage ?? null;\n};\n\nconst getSessionBackend = (): Storage | null => {\n if (typeof globalThis === \"undefined\") return null;\n const g = globalThis as { sessionStorage?: Storage };\n return g.sessionStorage ?? null;\n};\n\nconst getDocument = (): Document | null => {\n if (typeof globalThis === \"undefined\") return null;\n const g = globalThis as { document?: Document };\n return g.document ?? null;\n};\n\n/** Format a cookie expiry date — accepts days, Date, or ISO string. */\nconst formatExpires = (value: CookieOptions[\"expires\"]): string | null => {\n if (value === undefined || value === null) return null;\n if (value instanceof Date) return value.toUTCString();\n if (typeof value === \"string\") {\n const parsed = new Date(value);\n return Number.isNaN(parsed.getTime()) ? null : parsed.toUTCString();\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n const date = new Date();\n date.setTime(date.getTime() + value * 86_400_000);\n return date.toUTCString();\n }\n return null;\n};\n\n/** Build the trailing attribute portion of a `Set-Cookie` string. */\nconst buildCookieAttributes = (options: CookieOptions = {}): string => {\n const parts: string[] = [];\n const expires = formatExpires(options.expires);\n if (expires) parts.push(`expires=${expires}`);\n if (typeof options.maxAge === \"number\" && Number.isFinite(options.maxAge)) {\n parts.push(`max-age=${Math.floor(options.maxAge)}`);\n }\n parts.push(`path=${options.path ?? \"/\"}`);\n if (options.domain) parts.push(`domain=${options.domain}`);\n if (options.secure) parts.push(\"secure\");\n if (options.sameSite) {\n const value = options.sameSite.charAt(0).toUpperCase() + options.sameSite.slice(1).toLowerCase();\n parts.push(`samesite=${value}`);\n }\n return parts.length === 0 ? \"\" : `; ${parts.join(\"; \")}`;\n};\n\nconst readAllCookies = (): Record<string, string> => {\n const doc = getDocument();\n if (!doc) return {};\n const out: Record<string, string> = {};\n const raw = doc.cookie ?? \"\";\n if (!raw) return out;\n for (const pair of raw.split(\";\")) {\n const trimmed = pair.trim();\n if (!trimmed) continue;\n const eq = trimmed.indexOf(\"=\");\n if (eq < 0) {\n out[decodeURIComponent(trimmed)] = \"\";\n continue;\n }\n const key = decodeURIComponent(trimmed.slice(0, eq));\n const value = decodeURIComponent(trimmed.slice(eq + 1));\n out[key] = value;\n }\n return out;\n};\n\nconst cookies: StorageNamespace = {\n set: (key, value, options) =>\n safeRun(() => {\n const doc = getDocument();\n if (!doc) return false;\n const encodedKey = encodeURIComponent(String(key));\n const encodedValue = encodeURIComponent(serialise(value));\n doc.cookie = `${encodedKey}=${encodedValue}${buildCookieAttributes(options)}`;\n return true;\n }, false),\n get: (key) =>\n safeRun(() => {\n const all = readAllCookies();\n const raw = all[String(key)];\n return raw === undefined ? null : deserialise(raw);\n }, null),\n remove: (key, options) =>\n safeRun(() => {\n const doc = getDocument();\n if (!doc) return false;\n const encodedKey = encodeURIComponent(String(key));\n const opts: CookieOptions = {\n ...options,\n expires: new Date(0),\n maxAge: 0,\n };\n doc.cookie = `${encodedKey}=${buildCookieAttributes(opts)}`;\n return true;\n }, false),\n clear: () =>\n safeRun(() => {\n const doc = getDocument();\n if (!doc) return false;\n const all = readAllCookies();\n for (const key of Object.keys(all)) {\n const encodedKey = encodeURIComponent(key);\n doc.cookie = `${encodedKey}=${buildCookieAttributes({ expires: new Date(0), maxAge: 0 })}`;\n }\n return true;\n }, false),\n};\n\nconst local = createWebStorageNamespace(getLocalBackend);\nconst session = createWebStorageNamespace(getSessionBackend);\n\n/**\n * The `storage` global exposed to Aktion programs. Default\n * methods (`storage.set` / `storage.get` / `storage.remove` /\n * `storage.clear`) delegate to `localStorage`; nested namespaces select\n * a specific backend.\n */\nexport const storage: StorageRoot = {\n set: local.set,\n get: local.get,\n remove: local.remove,\n clear: local.clear,\n local,\n session,\n cookies,\n};\n","/**\n * Console namespace for Aktion.\n *\n * Exposes a `console` global that forwards to the browser's built-in\n * `console` methods (`log`, `error`, `warn`, `info`, `debug`). The\n * forwarder gracefully no-ops when no global console is available (e.g.\n * during SSR or inside a worker without a console binding) so authors\n * can sprinkle `console.log(...)` calls without breaking partial-stream\n * renders.\n *\n * The runtime intentionally does NOT shadow JavaScript's full console\n * surface — just the five methods that LLM-authored scripts reach for.\n */\n\ntype ConsoleMethod = \"log\" | \"error\" | \"warn\" | \"info\" | \"debug\";\n\nconst METHODS: readonly ConsoleMethod[] = [\"log\", \"error\", \"warn\", \"info\", \"debug\"];\n\nexport interface ConsoleNamespace {\n log: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n debug: (...args: unknown[]) => void;\n}\n\nconst getNativeConsole = (): Partial<Record<ConsoleMethod, (...args: unknown[]) => void>> | null => {\n if (typeof globalThis === \"undefined\") return null;\n const g = globalThis as { console?: Console };\n return g.console ?? null;\n};\n\nconst forward = (method: ConsoleMethod) =>\n (...args: unknown[]): void => {\n const native = getNativeConsole();\n if (!native) return;\n const fn = native[method] ?? native.log;\n if (typeof fn !== \"function\") return;\n try {\n fn(...args);\n } catch {\n /* swallow — console failures must not crash the render */\n }\n };\n\nexport const consoleNs: ConsoleNamespace = METHODS.reduce(\n (acc, method) => {\n acc[method] = forward(method);\n return acc;\n },\n {} as ConsoleNamespace,\n);\n","/**\n * Evaluator for Aktion programs.\n *\n * The evaluator walks expressions to produce values. Component calls\n * become `ComponentNode` objects that the renderer maps to web components.\n * Expressions that reference `$variables` are wrapped in a `Computation`\n * so that their dependencies can be tracked and re-evaluated when state\n * changes.\n */\n\nimport type {\n Expression,\n Program,\n Statement,\n ComponentDeclaration,\n EffectDeclaration,\n ActionDeclaration,\n BlockExpr,\n ObjectProperty,\n} from \"../parser/types.js\";\nimport type { StateStore } from \"./state.js\";\nimport type { HttpRuntime } from \"./http.js\";\nimport { createHttpResource } from \"./http.js\";\nimport type { I18nRuntime } from \"./i18n.js\";\nimport type { ActionDeclRunner } from \"./effects.js\";\nimport { dataBuiltins, type ThemeNode } from \"./builtins.js\";\nimport { matchRoute, type Router } from \"./router.js\";\nimport { findComponent } from \"../library/registry.js\";\nimport { findPositionalIndex } from \"../library/types.js\";\nimport type { ComponentLibrary } from \"../library/types.js\";\nimport { storage as storageGlobal } from \"./storage.js\";\nimport { consoleNs as consoleGlobal } from \"./console.js\";\n\n/**\n * Built-in namespaces injected as top-level identifiers so authors can\n * reach for them without an explicit declaration. Each value is an\n * ordinary object — its public methods become `MethodCall` targets\n * (e.g. `storage.local.get(\"x\")`, `console.warn(\"…\")`).\n */\nconst GLOBAL_NAMESPACES: Record<string, unknown> = {\n storage: storageGlobal,\n console: consoleGlobal,\n};\n\nexport interface ArgMeta {\n /** Name of the `$variable` if this argument is a direct state reference. */\n stateRef?: string;\n}\n\nexport interface ComponentNode {\n __kind: \"Component\";\n /** Component name as written in Aktion. */\n name: string;\n /** Positional arguments after evaluation. */\n args: unknown[];\n /** Per-position metadata (state ref binding, etc.). */\n argMeta: ArgMeta[];\n /**\n * Explicit `key:` override for content-addressed identity (§13). When\n * present, the renderer uses this value as the suffix of the instance\n * path instead of the source location — so reordering siblings keeps\n * per-instance state attached to the right node.\n */\n explicitKey?: unknown;\n /** Original AST for debugging/introspection. */\n source?: { line: number; column: number };\n}\n\nexport const isComponentNode = (value: unknown): value is ComponentNode => {\n return Boolean(\n value && typeof value === \"object\" &&\n (value as { __kind?: unknown }).__kind === \"Component\",\n );\n};\n\n/**\n * Lazy node produced when a user-declared `component Foo(p) { ... }` is\n * called. The renderer expands these per-instance: each instance gets its\n * own state-alias scope so two `Counter()` calls hold independent `$state`\n * atoms (§7 — per-instance reactivity).\n *\n * The evaluator captures the call arguments + named slots eagerly; the\n * body itself is evaluated at render-time once the instance key is known.\n */\nexport interface UserComponentNode {\n __kind: \"UserComponent\";\n decl: ComponentDeclaration;\n /** Positional argument values (already evaluated). */\n positional: unknown[];\n /** Named argument values (already evaluated), keyed by param/slot name. */\n named: Record<string, unknown>;\n /** Optional `key:` override the caller passed for stable instance identity. */\n explicitKey?: unknown;\n source?: { line: number; column: number };\n}\n\nexport const isUserComponentNode = (value: unknown): value is UserComponentNode => {\n return Boolean(\n value && typeof value === \"object\" &&\n (value as { __kind?: unknown }).__kind === \"UserComponent\",\n );\n};\n\nexport interface EvaluationContext {\n state: StateStore;\n /** Per-program scope for non-state assignments (refs to other lines). */\n bindings: Map<string, () => unknown>;\n /** Raw AST expressions for each top-level identifier. */\n expressions: Map<string, Expression>;\n /** Set of $variable names accessed during the current evaluation. */\n trackedState: Set<string>;\n /**\n * Inline loop variables for expression `for` / `match`, router param\n * bindings, lambda parameters, and component declaration parameters.\n */\n loopVars: Map<string, unknown>;\n /**\n * Per-instance state alias scope (§7). When a user-declared component\n * body declares `$state n = 0`, the renderer pushes an alias frame so\n * that the StateRef `n` reads/writes the per-instance key (e.g.\n * `Counter@1:5#0:n`) rather than a shared global atom. The lookup walks\n * from the top of the stack down — outer frames are still visible when\n * not overridden.\n */\n stateAliases: Array<Map<string, string>>;\n /** Optional router — exposed to the runtime for `_route_.path` / `params`. */\n router?: Router;\n /** Component library used to resolve trailing named-arg object literals. */\n library?: ComponentLibrary;\n /** Component declarations from the program (`component Foo() { ... }`). */\n componentDecls: Map<string, ComponentDeclaration>;\n /** Effect declarations (`effect [ ...deps ] { ... }`), keyed by auto-generated name. */\n effectDecls: Map<string, EffectDeclaration>;\n /** Action declarations (`action Foo() { ... }`). */\n actionDecls: Map<string, ActionDeclaration>;\n /** HTTP runtime (`http({...})` calls + interceptor configuration). */\n http?: HttpRuntime;\n /** Aktion 0.5 i18n runtime (`$i18n = i18n({...})` declaration + `t()` builtin). */\n i18n?: I18nRuntime;\n /** Aktion 0.5 action runner (`action Foo() optimistic { … }` invocations). */\n actionRunner?: ActionDeclRunner;\n /** Notify the host that something changed and a re-render is needed. */\n notify?: () => void;\n /**\n * Optional executor for raw `js{ … }` blocks encountered inside an\n * inline lambda. When set, evaluating a lambda whose body resolves to\n * a `JsBlock` payload will invoke this with the captured body so\n * `Button(\"Hi\", action: () => { js{ alert(\"Hi\") } })` actually runs\n * the script instead of returning the deferred payload.\n */\n jsBlockExecutor?: (body: string, args?: Record<string, unknown>) => unknown;\n}\n\n/**\n * Optional injectables for `createContext` — the host element passes its\n * runtime singletons (HTTP, i18n, action runner) so endpoint use sites and\n * action calls can resolve against them.\n */\nexport interface CreateContextOptions {\n router?: Router;\n library?: ComponentLibrary;\n http?: HttpRuntime;\n i18n?: I18nRuntime;\n actionRunner?: ActionDeclRunner;\n notify?: () => void;\n jsBlockExecutor?: (body: string, args?: Record<string, unknown>) => unknown;\n}\n\n/**\n * Build a top-level evaluation context for a freshly parsed program.\n */\nexport function createContext(\n state: StateStore,\n options: CreateContextOptions = {},\n): EvaluationContext {\n return {\n state,\n bindings: new Map(),\n expressions: new Map(),\n trackedState: new Set(),\n loopVars: new Map(),\n stateAliases: [],\n router: options.router,\n library: options.library,\n componentDecls: new Map(),\n effectDecls: new Map(),\n actionDecls: new Map(),\n http: options.http,\n i18n: options.i18n,\n actionRunner: options.actionRunner,\n notify: options.notify,\n jsBlockExecutor: options.jsBlockExecutor,\n };\n}\n\n/**\n * Build the `args` map handed to a `js{ … }` body so authors can\n * reference lambda parameters via `ctx.args.<name>`.\n */\nfunction paramArgs(\n params: ReadonlyArray<{ name: string }>,\n callArgs: ReadonlyArray<unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (let i = 0; i < params.length; i += 1) {\n out[params[i]!.name] = callArgs[i];\n }\n return out;\n}\n\n/**\n * Resolve a `$name` reference through the active per-instance alias\n * stack. Returns the topmost binding or `name` itself when no alias is\n * present. Exported so the action / effect runners can resolve writes\n * the same way the evaluator resolves reads.\n */\nexport function resolveStateAlias(ctx: EvaluationContext, name: string): string {\n for (let i = ctx.stateAliases.length - 1; i >= 0; i -= 1) {\n const frame = ctx.stateAliases[i]!;\n const aliased = frame.get(name);\n if (aliased !== undefined) return aliased;\n }\n return name;\n}\n\n/**\n * Plan a program: declare state variables, register HTTP endpoints, and\n * build lazy bindings for every assignment so forward references resolve.\n */\nexport function planProgram(program: Program, ctx: EvaluationContext): void {\n // First pass: declare state defaults so `$vars` resolve immediately.\n // Every `$x = expr` declares a single-tier reactive atom; the initial\n // value is computed via best-effort literal evaluation so partial\n // streams don't need a full context yet.\n for (const stmt of program.statements) {\n if (stmt.kind === \"Assignment\" && stmt.isState) {\n const initial = evaluateLiteral(stmt.expression);\n ctx.state.declare(stmt.identifier, initial);\n }\n }\n // 1.25 pass: state declarations whose RHS is a `http({...})` call need\n // their resource bag created eagerly so the request fires at program\n // mount. We re-run those initializers through the full evaluator now\n // that every state slot has at least a literal default.\n for (const stmt of program.statements) {\n if (stmt.kind !== \"Assignment\" || !stmt.isState) continue;\n if (stmt.expression.kind !== \"Call\") continue;\n if (stmt.expression.callee !== \"http\") continue;\n const value = evaluate(stmt.expression, ctx);\n ctx.state.set(stmt.identifier, value);\n }\n\n // 1.5 pass: resolve `Http({...})` / `i18n({...})` setup helpers so any\n // subsequent http() calls observe the configured defaults.\n for (const stmt of program.statements) {\n if (stmt.kind !== \"Assignment\") continue;\n const expr = stmt.expression;\n if (expr.kind !== \"Call\") continue;\n if ((stmt.identifier === \"http\" || stmt.identifier === \"$http\") && expr.callee === \"Http\") {\n evaluate(expr, ctx);\n continue;\n }\n if ((stmt.identifier === \"i18n\" || stmt.identifier === \"$i18n\") && expr.callee === \"i18n\") {\n evaluate(expr, ctx);\n continue;\n }\n }\n\n // Second pass: install bindings for components, helpers, and any other\n // non-state declarations.\n for (const stmt of program.statements) {\n installStatementBinding(stmt, ctx);\n }\n}\n\nfunction installStatementBinding(stmt: Statement, ctx: EvaluationContext): void {\n switch (stmt.kind) {\n case \"ComponentDeclaration\":\n ctx.componentDecls.set(stmt.name, stmt);\n return;\n case \"EffectDeclaration\":\n ctx.effectDecls.set(stmt.name, stmt);\n return;\n case \"ActionDeclaration\":\n ctx.actionDecls.set(stmt.name, stmt);\n return;\n case \"Emit\":\n case \"Cleanup\":\n case \"Await\":\n case \"Return\":\n case \"ExpressionStatement\":\n return;\n case \"Assignment\": {\n if (stmt.isState) return;\n ctx.expressions.set(stmt.identifier, stmt.expression);\n const expr = stmt.expression;\n ctx.bindings.set(stmt.identifier, () => evaluate(expr, ctx));\n return;\n }\n }\n}\n\n/**\n * Evaluate a `_router_({ \"/\": Home(), \"/users/:id\": User(params), default: NotFound() })`\n * call. The argument MUST be an object literal whose keys are route patterns\n * (string literals) or the `default` keyword (wildcard fallback). Values are\n * arbitrary expressions, evaluated lazily — only the matching arm runs, and\n * `params` is bound as a loop variable inside that body so authors can read\n * captured path segments (`:id`, `*` → `params._`).\n *\n * The return value is the matched arm's evaluated expression, or `null` when\n * no arm matches and no `default` is provided. The host's `Router` instance\n * is informed via `setActiveMatch(...)` so `NavLink` can highlight the\n * currently-active route.\n */\nfunction evaluateRouterCall(\n args: Expression[],\n ctx: EvaluationContext,\n loc?: { line: number; column: number },\n): unknown {\n const arg = args[0];\n if (!arg || arg.kind !== \"Object\") {\n // eslint-disable-next-line no-console\n console.error(\n `[aktion] _router_ expects an object literal of route arms (e.g. \\`_router_({ \"/\": Home(), default: NotFound() })\\`).`,\n loc,\n );\n ctx.router?.setActiveMatch(null, {});\n return null;\n }\n const path = readRoutePath(ctx);\n let wildcardArm: ObjectProperty | null = null;\n for (const prop of arg.properties) {\n if (prop.spread) continue;\n const pattern = prop.key;\n if (pattern === \"default\" || pattern === \"*\") {\n // Hold the wildcard until every concrete pattern has failed.\n wildcardArm = prop;\n continue;\n }\n const result = matchRoute(pattern, path);\n if (!result.matched) continue;\n return runRouterArm(pattern, prop.value, result.params, ctx);\n }\n if (wildcardArm) {\n return runRouterArm(null, wildcardArm.value, {}, ctx);\n }\n ctx.router?.setActiveMatch(null, {});\n return null;\n}\n\nfunction runRouterArm(\n pattern: string | null,\n body: Expression,\n params: Record<string, string>,\n ctx: EvaluationContext,\n): unknown {\n const prev = ctx.loopVars.get(\"params\");\n const had = ctx.loopVars.has(\"params\");\n ctx.loopVars.set(\"params\", params);\n try {\n const value = evaluate(body, ctx);\n ctx.router?.setActiveMatch(pattern, params);\n return value;\n } finally {\n if (had) ctx.loopVars.set(\"params\", prev);\n else ctx.loopVars.delete(\"params\");\n }\n}\n\n/**\n * Best-effort evaluation of literal-only expressions used for $variable\n * defaults. Falls back to `null` for expressions that need a full context\n * — we keep the binding present so `$foo` returns a typed value (null)\n * instead of `undefined`, which would surface in concatenations as the\n * string \"undefined\".\n */\nfunction evaluateLiteral(expr: Expression): unknown {\n switch (expr.kind) {\n case \"Literal\": return expr.value;\n case \"Array\": {\n const out: unknown[] = [];\n for (const e of expr.elements) {\n if (e.kind === \"Spread\") continue;\n out.push(evaluateLiteral(e));\n }\n return out;\n }\n case \"Object\": {\n const obj: Record<string, unknown> = {};\n for (const prop of expr.properties) {\n if (prop.spread) continue;\n obj[prop.key] = evaluateLiteral(prop.value);\n }\n return obj;\n }\n case \"Template\": {\n if (expr.expressions.length === 0) return expr.quasis[0] ?? \"\";\n return null;\n }\n default: return null;\n }\n}\n\nexport function evaluate(expr: Expression, ctx: EvaluationContext): unknown {\n switch (expr.kind) {\n case \"Literal\": return expr.value;\n case \"Identifier\": {\n if (ctx.loopVars.has(expr.name)) return ctx.loopVars.get(expr.name);\n // `_route_` is the canonical handle for the router's reactive\n // surface. Reading it subscribes to the internal `route` state slot\n // so the renderer re-runs when the URL hash changes, and the\n // returned object exposes `path`, `params`, `pattern`, `query`,\n // plus an imperative `navigate(path)` method that delegates to the\n // host router.\n if (expr.name === \"_route_\") {\n ctx.trackedState.add(\"route\");\n return ctx.router ? buildRouteState(ctx.router) : { path: \"/\", params: {}, pattern: null, query: {}, navigate() {}, toString() { return \"/\"; } };\n }\n const binding = ctx.bindings.get(expr.name);\n if (binding) return binding();\n // A bare `myAction` reference (e.g. `Button(\"Save\", save)`) resolves\n // to a callable wrapping the action runner. Without this branch the\n // identifier returns null and the click silently no-ops.\n const action = ctx.actionDecls.get(expr.name);\n if (action) return makeActionCallable(action, ctx);\n // Built-in namespace globals (`storage`, `console`). Returned as\n // ordinary objects so member/method-call expressions resolve\n // against them directly via the standard `memberAccess` path.\n if (Object.prototype.hasOwnProperty.call(GLOBAL_NAMESPACES, expr.name)) {\n return GLOBAL_NAMESPACES[expr.name];\n }\n // Unknown identifier — render as null so the parser is forgiving.\n return null;\n }\n case \"StateRef\": {\n // Resolve through the per-instance alias stack so `$n` inside a\n // component body picks the right per-instance slot.\n const resolved = resolveStateAlias(ctx, expr.name);\n ctx.trackedState.add(resolved);\n return ctx.state.get(resolved);\n }\n case \"Array\": {\n const out: unknown[] = [];\n for (const element of expr.elements) {\n if (element.kind === \"Spread\") {\n const value = evaluate(element.argument, ctx);\n if (Array.isArray(value)) {\n for (const item of value) out.push(item);\n } else if (value != null) {\n // Mirror JS spread on iterables — strings spread into their\n // characters. Objects without an iterator are ignored to keep\n // LLM mistakes from blowing up the render.\n if (typeof value === \"string\") for (const ch of value) out.push(ch);\n }\n continue;\n }\n out.push(evaluate(element, ctx));\n }\n return out;\n }\n case \"Object\": {\n const obj: Record<string, unknown> = {};\n for (const prop of expr.properties) {\n if (prop.spread) {\n const value = evaluate(prop.value, ctx);\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n obj[k] = v;\n }\n }\n continue;\n }\n obj[prop.key] = evaluate(prop.value, ctx);\n }\n return obj;\n }\n case \"Member\": {\n const target = evaluate(expr.object, ctx);\n if (expr.optional && target == null) return undefined;\n if (expr.computed) {\n const key = evaluate(expr.computed, ctx);\n return computedMemberAccess(target, key);\n }\n return memberAccess(target, expr.property ?? \"\");\n }\n case \"Unary\": {\n const value = evaluate(expr.argument, ctx);\n return expr.operator === \"!\" ? !value : -toNumber(value);\n }\n case \"Binary\": return evaluateBinary(expr.operator, expr.left, expr.right, ctx);\n case \"Ternary\": {\n const test = evaluate(expr.test, ctx);\n return test ? evaluate(expr.consequent, ctx) : evaluate(expr.alternate, ctx);\n }\n case \"Call\": return evaluateComponentCall(expr.callee, expr.arguments, ctx, expr.loc);\n case \"MethodCall\": return evaluateMethodCall(expr, ctx);\n case \"BuiltinCall\": return evaluateBuiltinCall(expr.name, expr.arguments, ctx);\n case \"Template\": return evaluateTemplate(expr.quasis, expr.expressions, ctx);\n case \"Spread\": {\n // A bare spread outside of an array/object literal collapses to its\n // argument value. The array/object evaluators handle the spread\n // semantics, so we only reach here for malformed input.\n return evaluate(expr.argument, ctx);\n }\n case \"If\": return evaluateIf(expr, ctx);\n case \"Match\": return evaluateMatch(expr, ctx);\n case \"For\": return evaluateFor(expr, ctx);\n case \"Block\": return evaluateBlock(expr, ctx);\n case \"Lambda\": {\n // Lambdas evaluate to a callable JS function. We capture the current\n // context AND a snapshot of the active per-instance state-alias\n // stack so that closures created inside a `component` body still\n // resolve `$n` to the right per-instance slot when invoked later\n // (the render pass that built them already popped the alias frame).\n const lambdaParams = expr.params;\n const lambdaBody = expr.body;\n const capturedAliases: Array<Map<string, string>> = ctx.stateAliases.map(\n (frame) => new Map(frame),\n );\n // Also capture the loopVars present at lambda-creation time so a\n // handler emitted inside `for item in items { Button(item.name, () => del(item.id)) }`\n // can read `item` at click time even though the loop variable is\n // long gone by then.\n const capturedLoopVars = new Map(ctx.loopVars);\n return (...callArgs: unknown[]) => {\n const restoreLoopVars = new Map(ctx.loopVars);\n const restoreAliases = ctx.stateAliases.slice();\n // Restore the captured loop vars + alias frames for the body.\n ctx.loopVars.clear();\n for (const [k, v] of capturedLoopVars) ctx.loopVars.set(k, v);\n ctx.stateAliases.length = 0;\n for (const frame of capturedAliases) ctx.stateAliases.push(frame);\n\n const restore: Array<{ name: string; had: boolean; prev: unknown }> = [];\n for (let i = 0; i < lambdaParams.length; i += 1) {\n const param = lambdaParams[i]!;\n let value: unknown = callArgs[i];\n if (value === undefined && param.defaultValue) {\n value = evaluate(param.defaultValue, ctx);\n }\n restore.push({\n name: param.name,\n had: ctx.loopVars.has(param.name),\n prev: ctx.loopVars.get(param.name),\n });\n ctx.loopVars.set(param.name, value);\n }\n try {\n if (lambdaBody.kind === \"JsBlock\") {\n const body = (lambdaBody as { body: string }).body;\n // Execute eagerly when the host has wired a runner — this is\n // what lets `Button(\"…\", action: () => { js{ … } })` run the\n // script on click. When no runner is available we keep the\n // legacy deferred payload so the action / effect machinery\n // can still process it later.\n if (ctx.jsBlockExecutor) {\n return ctx.jsBlockExecutor(body, paramArgs(lambdaParams, callArgs));\n }\n return { __kind: \"JsBlock\", body };\n }\n const result = evaluate(lambdaBody as Expression, ctx);\n // The body might be a `Block` that ends in a `js{}` expression\n // (`() => { js{ … } }`) — when that returns a deferred payload\n // and we have an executor, run it for its side effects.\n if (\n ctx.jsBlockExecutor &&\n result && typeof result === \"object\" &&\n (result as { __kind?: unknown }).__kind === \"JsBlock\"\n ) {\n const body = (result as { body: string }).body;\n return ctx.jsBlockExecutor(body, paramArgs(lambdaParams, callArgs));\n }\n return result;\n } finally {\n for (const slot of restore) {\n if (slot.had) ctx.loopVars.set(slot.name, slot.prev);\n else ctx.loopVars.delete(slot.name);\n }\n // Fully restore the caller's scope — drop our temporary\n // captured-frame substitution and put back whatever was there.\n ctx.loopVars.clear();\n for (const [k, v] of restoreLoopVars) ctx.loopVars.set(k, v);\n ctx.stateAliases.length = 0;\n for (const frame of restoreAliases) ctx.stateAliases.push(frame);\n }\n };\n }\n case \"JsBlock\": {\n return { __kind: \"JsBlock\", body: expr.body };\n }\n case \"Bind\": {\n // `bind:prop: target` desugars to a special `BindNode` that the\n // renderer recognises and wires up two-way (read + change handler).\n return {\n __kind: \"Bind\",\n prop: expr.prop,\n target: evaluate(expr.target, ctx),\n targetExpr: expr.target,\n };\n }\n case \"NamedArg\":\n return evaluate(expr.value, ctx);\n default: return null;\n }\n}\n\nfunction evaluateIf(expr: { test: Expression; consequent: BlockExpr; alternate?: Expression | BlockExpr }, ctx: EvaluationContext): unknown {\n if (evaluate(expr.test, ctx)) {\n return evaluateBlock(expr.consequent, ctx);\n }\n if (expr.alternate) {\n if ((expr.alternate as { kind?: string }).kind === \"Block\") {\n return evaluateBlock(expr.alternate as BlockExpr, ctx);\n }\n return evaluate(expr.alternate as Expression, ctx);\n }\n return null;\n}\n\nfunction evaluateMatch(\n expr: { discriminant: Expression; arms: ReadonlyArray<{ pattern: Expression | \"_\"; body: Expression }> },\n ctx: EvaluationContext,\n): unknown {\n const value = evaluate(expr.discriminant, ctx);\n for (const arm of expr.arms) {\n if (arm.pattern === \"_\") {\n return evaluate(arm.body, ctx);\n }\n const patternValue = evaluate(arm.pattern, ctx);\n if (patternValue === value) {\n return evaluate(arm.body, ctx);\n }\n }\n return null;\n}\n\nfunction evaluateFor(\n expr: {\n item: string;\n index?: string;\n destructure?: ReadonlyArray<string>;\n iterable: Expression;\n body: BlockExpr;\n },\n ctx: EvaluationContext,\n): unknown {\n const iterableValue = evaluate(expr.iterable, ctx);\n if (!Array.isArray(iterableValue)) return [];\n const out: unknown[] = [];\n const itemHad = ctx.loopVars.has(expr.item);\n const itemPrev = ctx.loopVars.get(expr.item);\n const idxName = expr.index;\n const idxHad = idxName ? ctx.loopVars.has(idxName) : false;\n const idxPrev = idxName ? ctx.loopVars.get(idxName) : undefined;\n const destructure = expr.destructure ?? [];\n const destructurePrev: Array<{ name: string; had: boolean; value: unknown }> =\n destructure.map((name) => ({\n name,\n had: ctx.loopVars.has(name),\n value: ctx.loopVars.get(name),\n }));\n try {\n for (let i = 0; i < iterableValue.length; i += 1) {\n const row = iterableValue[i];\n ctx.loopVars.set(expr.item, row);\n if (idxName) ctx.loopVars.set(idxName, i);\n for (const field of destructure) {\n const value = row && typeof row === \"object\"\n ? (row as Record<string, unknown>)[field]\n : undefined;\n ctx.loopVars.set(field, value);\n }\n out.push(evaluateBlock(expr.body, ctx));\n }\n } finally {\n if (itemHad) ctx.loopVars.set(expr.item, itemPrev);\n else ctx.loopVars.delete(expr.item);\n if (idxName) {\n if (idxHad) ctx.loopVars.set(idxName, idxPrev);\n else ctx.loopVars.delete(idxName);\n }\n for (const entry of destructurePrev) {\n if (entry.had) ctx.loopVars.set(entry.name, entry.value);\n else ctx.loopVars.delete(entry.name);\n }\n }\n return out;\n}\n\n/**\n * Evaluate a block: run every declaration / statement sequentially and\n * return the value of the last expression statement (last-expression-wins\n * per §3.5 of the spec). Statements that don't produce a value (state\n * declarations, effect declarations, helper bindings, …) are still\n * executed for their side-effects on `ctx`.\n */\nfunction evaluateBlock(block: BlockExpr, ctx: EvaluationContext): unknown {\n let result: unknown = null;\n // Clone-restore tracking for any block-local bindings that shadow outer\n // names (component params, $state declarations, etc.). We only restore\n // names introduced by THIS block.\n const introduced: string[] = [];\n for (const stmt of block.body) {\n switch (stmt.kind) {\n case \"ExpressionStatement\":\n result = evaluate(stmt.expression, ctx);\n continue;\n case \"Assignment\": {\n const value = evaluate(stmt.expression, ctx);\n if (stmt.isState && stmt.identifier) {\n // `$x = expr` inside a block (lambda body, if/match arm, for body)\n // writes to the reactive state store, resolving through the\n // per-instance alias stack so user-component scopes hit the\n // right slot (§7). Without this branch the assignment would\n // silently fall into `loopVars` and never trigger a re-render.\n const target = resolveStateAlias(ctx, stmt.identifier);\n ctx.state.set(target, value);\n } else {\n if (!ctx.loopVars.has(stmt.identifier)) introduced.push(stmt.identifier);\n ctx.loopVars.set(stmt.identifier, value);\n }\n result = value;\n continue;\n }\n case \"Return\":\n result = stmt.argument ? evaluate(stmt.argument, ctx) : undefined;\n return result;\n case \"ComponentDeclaration\":\n case \"EffectDeclaration\":\n case \"ActionDeclaration\":\n // Top-level constructs that may legally appear inside a block;\n // register them on the context so they're discoverable from\n // sibling statements without mutating outer scope.\n installStatementBinding(stmt, ctx);\n continue;\n case \"Emit\":\n case \"Cleanup\":\n case \"Await\":\n // These are deferred to the action / effect runners; in a pure\n // expression block they are no-ops.\n continue;\n }\n }\n // Restore introduced names so block-local bindings don't leak.\n for (const name of introduced) ctx.loopVars.delete(name);\n return result;\n}\n\nfunction evaluateTemplate(\n quasis: string[],\n expressions: Expression[],\n ctx: EvaluationContext,\n): string {\n let out = quasis[0] ?? \"\";\n for (let i = 0; i < expressions.length; i += 1) {\n out += stringify(evaluate(expressions[i]!, ctx));\n out += quasis[i + 1] ?? \"\";\n }\n return out;\n}\n\nfunction evaluateBinary(\n op: string,\n leftExpr: Expression,\n rightExpr: Expression,\n ctx: EvaluationContext,\n): unknown {\n if (op === \"&&\") {\n const left = evaluate(leftExpr, ctx);\n if (!left) return left;\n return evaluate(rightExpr, ctx);\n }\n if (op === \"||\") {\n const left = evaluate(leftExpr, ctx);\n if (left) return left;\n return evaluate(rightExpr, ctx);\n }\n if (op === \"??\") {\n const left = evaluate(leftExpr, ctx);\n if (left !== null && left !== undefined) return left;\n return evaluate(rightExpr, ctx);\n }\n\n const left = evaluate(leftExpr, ctx);\n const right = evaluate(rightExpr, ctx);\n\n switch (op) {\n case \"+\":\n if (typeof left === \"string\" || typeof right === \"string\") {\n return stringify(left) + stringify(right);\n }\n return toNumber(left) + toNumber(right);\n case \"-\": return toNumber(left) - toNumber(right);\n case \"*\": return toNumber(left) * toNumber(right);\n case \"/\": {\n const r = toNumber(right);\n return r === 0 ? 0 : toNumber(left) / r;\n }\n case \"%\": {\n const r = toNumber(right);\n return r === 0 ? 0 : toNumber(left) % r;\n }\n case \"==\": return left === right;\n case \"!=\": return left !== right;\n case \">\": return toNumber(left) > toNumber(right);\n case \"<\": return toNumber(left) < toNumber(right);\n case \">=\": return toNumber(left) >= toNumber(right);\n case \"<=\": return toNumber(left) <= toNumber(right);\n default: return null;\n }\n}\n\n/**\n * Evaluate an `object.method(args)` invocation. Positional arguments\n * pass through unchanged; any `NamedArg` entries in the argument list\n * collapse into a single trailing options object so authors can write\n * `storage.cookies.set(\"k\", \"v\", expires: 1, path: \"/\")` instead of the\n * more verbose `{...}` literal. Unknown methods resolve to `null`\n * rather than throwing — keeps streaming scripts forgiving when a\n * runtime value disappears mid-render.\n */\nfunction evaluateMethodCall(\n expr: {\n object: Expression;\n method: string;\n arguments: Expression[];\n optional?: boolean;\n },\n ctx: EvaluationContext,\n): unknown {\n const target = evaluate(expr.object, ctx);\n if (target == null) {\n return expr.optional ? undefined : null;\n }\n const fn = (target as Record<string, unknown>)[expr.method];\n if (typeof fn !== \"function\") return null;\n\n const positional: unknown[] = [];\n const named: Record<string, unknown> = {};\n let hasNamed = false;\n for (const arg of expr.arguments) {\n if (arg.kind === \"NamedArg\") {\n named[arg.name] = evaluate(arg.value, ctx);\n hasNamed = true;\n continue;\n }\n if (arg.kind === \"Spread\") {\n const value = evaluate(arg.argument, ctx);\n if (Array.isArray(value)) {\n for (const item of value) positional.push(item);\n }\n continue;\n }\n positional.push(evaluate(arg, ctx));\n }\n const callArgs = hasNamed ? [...positional, named] : positional;\n try {\n return (fn as (...a: unknown[]) => unknown).apply(target, callArgs);\n } catch (err) {\n // Don't crash the render — surface the failure via the host console\n // so authors can still see what went wrong.\n // eslint-disable-next-line no-console\n console.error(`[aktion] method \"${expr.method}\" threw`, err);\n return null;\n }\n}\n\nfunction evaluateComponentCall(\n callee: string,\n args: Expression[],\n ctx: EvaluationContext,\n loc?: { line: number; column: number },\n): unknown {\n // `_router_({ \"/\": Home(), \"/users/:id\": User(params), default: NotFound() })`\n // — the routing primitive. Intercept *before* arguments are evaluated so\n // only the matching arm's body runs (and so `params` is in scope for it).\n if (callee === \"_router_\") {\n return evaluateRouterCall(args, ctx, loc);\n }\n // Aktion 0.5 component declarations win over the legacy macro form and the\n // built-in library. This lets author code override built-in components\n // by name (e.g. wrapping `Button` with telemetry).\n const componentDecl = ctx.componentDecls.get(callee);\n if (componentDecl) {\n return invokeComponentDecl(componentDecl, args, ctx, loc);\n }\n // Aktion 0.5 action declarations: when called as `myAction(arg1, arg2)`, the\n // call returns a function that the action runner will invoke. Returning\n // a function (rather than running synchronously) lets `onClick: myAction`\n // bindings work without the renderer racing the action body.\n const actionDecl = ctx.actionDecls.get(callee);\n if (actionDecl) {\n if (args.length === 0) {\n // Bare reference (`onClick: save`) — return the callable.\n return makeActionCallable(actionDecl, ctx);\n }\n // Eager invocation (`save(orderId)`) — schedule the action body.\n const evaluated = args.map((a) =>\n a.kind === \"NamedArg\" ? evaluate(a.value, ctx) : evaluate(a, ctx),\n );\n return invokeActionDecl(actionDecl, evaluated, ctx);\n }\n // `http({ url, method, body, headers, ... })` builtin — returns a\n // reactive `EndpointResource` bag with `data`, `error`, `loading`,\n // `status`, `lastUpdated`, `headers`, `refetch()`, `cancel()`.\n if (callee === \"http\") {\n const optsArg = args[0];\n const opts = optsArg\n ? (optsArg.kind === \"NamedArg\" ? evaluate(optsArg.value, ctx) : evaluate(optsArg, ctx))\n : {};\n return createHttpResource(opts, ctx);\n }\n // Local lambda registered into loopVars (e.g. an in-block helper\n // `itemRow = (item) => Card(item.title)` evaluated by `evaluateBlock`).\n const localHelper = ctx.loopVars.get(callee);\n if (typeof localHelper === \"function\") {\n const evaluated = args.map((arg) => evaluate(arg, ctx));\n return (localHelper as (...a: unknown[]) => unknown)(...evaluated);\n }\n // Top-level lambda binding: e.g. `priorityTone = (p) => match p { ... }`.\n const binding = ctx.bindings.get(callee);\n if (binding) {\n const fn = binding();\n if (typeof fn === \"function\") {\n const evaluated = args.map((arg) =>\n arg.kind === \"NamedArg\" ? evaluate(arg.value, ctx) : evaluate(arg, ctx),\n );\n return (fn as (...a: unknown[]) => unknown)(...evaluated);\n }\n }\n\n if (callee === \"Theme\") {\n // `Theme({ colors: {...}, radius: {...}, font: {...}, motion: {...},\n // elevation: {...} })` — capture the structured token map to be\n // applied on top of the base theme between render cycles. We do not\n // render anything; the element picks the value up via the `theme`\n // binding (or any other binding) and writes the tokens to its host.\n //\n // The keys inside each group are flattened into prefixed CSS tokens\n // (`colors.primary` → `colorPrimary`, `radius.md` → `radiusMd`, …).\n // The legacy flat-shape form is rejected — see `collectThemeTokens`.\n const tokensArg = args[0];\n const tokens = collectThemeTokens(tokensArg ? evaluate(tokensArg, ctx) : null);\n const node: ThemeNode = { kind: \"Theme\", tokens };\n return node;\n }\n if (callee === \"Http\") {\n // `Http({ baseUrl, headers, retry, ... })` — pushes config into the\n // host runtime and returns a marker so callers can `$http = Http({...})`\n // without crashing the evaluator. The marker has a stable shape so\n // host code introspecting `$http` sees the configured defaults.\n const configArg = args[0];\n const config = configArg ? evaluate(configArg, ctx) : null;\n if (config && typeof config === \"object\" && !Array.isArray(config) && ctx.http) {\n const cfg = config as Record<string, unknown>;\n ctx.http.setDefaults({\n baseUrl: typeof cfg.baseUrl === \"string\" ? cfg.baseUrl : undefined,\n headers: cfg.headers && typeof cfg.headers === \"object\" && !Array.isArray(cfg.headers)\n ? Object.fromEntries(\n Object.entries(cfg.headers as Record<string, unknown>).map(([k, v]) => [k, String(v ?? \"\")]),\n )\n : undefined,\n timeoutMs: typeof cfg.timeout === \"number\" ? cfg.timeout : undefined,\n retry: cfg.retry && typeof cfg.retry === \"object\" && !Array.isArray(cfg.retry)\n ? {\n count: Number((cfg.retry as Record<string, unknown>).count ?? 0) || 0,\n backoff: (cfg.retry as Record<string, unknown>).backoff === \"linear\"\n ? \"linear\"\n : \"exponential\",\n }\n : undefined,\n credentials:\n cfg.credentials === \"omit\" || cfg.credentials === \"same-origin\" || cfg.credentials === \"include\"\n ? cfg.credentials\n : undefined,\n });\n }\n return { __kind: \"Http\", config };\n }\n if (callee === \"i18n\") {\n // `i18n({ locale, messages, fallback })` — push into the host runtime.\n const configArg = args[0];\n const config = configArg ? evaluate(configArg, ctx) : null;\n if (config && typeof config === \"object\" && !Array.isArray(config) && ctx.i18n) {\n const cfg = config as Record<string, unknown>;\n ctx.i18n.configure({\n locale: typeof cfg.locale === \"string\" ? cfg.locale : \"en\",\n messages:\n cfg.messages && typeof cfg.messages === \"object\" && !Array.isArray(cfg.messages)\n ? (cfg.messages as Record<string, unknown>)\n : {},\n fallback: typeof cfg.fallback === \"string\" ? cfg.fallback : \"en\",\n fallbackMessages:\n cfg.fallbackMessages && typeof cfg.fallbackMessages === \"object\" && !Array.isArray(cfg.fallbackMessages)\n ? (cfg.fallbackMessages as Record<string, unknown>)\n : undefined,\n });\n }\n return { __kind: \"I18n\", config };\n }\n // Final fallthrough: treat the call as a built-in component invocation\n // and build a `ComponentNode` the renderer will hand to the library. If\n // the callee resolves against *neither* the library nor any user\n // declaration we return a synthetic Skeleton node (§2 — anticipatory\n // skeletons). This handles mid-stream forward references like\n // `root = App()` that arrive before the `component App() { ... }`\n // declaration has finished streaming: rather than dumping\n // `[unknown component: App]` into the DOM, the user sees a Skeleton\n // until the next render pass resolves the declaration.\n if (ctx.library && !findComponent(ctx.library, callee)) {\n if (findComponent(ctx.library, \"Skeleton\")) {\n const skeleton: ComponentNode = {\n __kind: \"Component\",\n name: \"Skeleton\",\n args: [],\n argMeta: [],\n source: loc,\n };\n return skeleton;\n }\n return null;\n }\n // Extract a `key:` named-arg up-front (§13 — content-addressed\n // identity). The renderer uses it instead of the source location so\n // reordering siblings keeps per-instance state attached to the right\n // node. We strip it from the arg list before evaluating positional /\n // named props so the library never sees it as a prop.\n let explicitKey: unknown = undefined;\n const propArgs: Expression[] = [];\n for (const arg of args) {\n if (arg.kind === \"NamedArg\" && arg.name === \"key\") {\n explicitKey = evaluate(arg.value, ctx);\n continue;\n }\n propArgs.push(arg);\n }\n const { args: evaluated, argMeta } = resolveLibraryCallArgs(ctx, callee, propArgs);\n const node: ComponentNode = {\n __kind: \"Component\",\n name: callee,\n args: evaluated,\n argMeta,\n explicitKey,\n source: loc,\n };\n return node;\n}\n\n/**\n * Aktion 0.5 §19.1 — build the slot-aligned `args` and\n * `argMeta` arrays for a library-component call. The function handles:\n *\n * - Plain positional arguments — routed to the spec's single\n * `positional: true` prop (or slot 0 by default). A direct\n * `$variable` reference also lifts to `argMeta.stateRef` so the\n * library renderer can wire two-way binding.\n * - `NamedArg`s — routed by prop name. If the named arg's value is a\n * bare `$variable` (`Input(\"title\", value: $title)`), the slot's\n * `argMeta.stateRef` is set too.\n * - `Bind` expressions (`bind:value: $title`) — same as NamedArg but\n * also marks the slot's `argMeta.stateRef` from the bind target.\n * - Extra positional args (multi-positional, §19.1 violation) — fall\n * through to the next unnamed slot in declaration order so the\n * graceful runtime path keeps rendering while the schema-validator\n * warning surfaces the migration hint.\n *\n * For user-declared components (no library spec) we fall back to the\n * simple \"evaluate each argument as-is\" path so per-instance state lookup\n * sees raw `propArgs` unchanged.\n */\nfunction resolveLibraryCallArgs(\n ctx: EvaluationContext,\n callee: string,\n propArgs: Expression[],\n): { args: unknown[]; argMeta: ArgMeta[] } {\n const spec = ctx.library ? findComponent(ctx.library, callee) : undefined;\n if (!spec) {\n const args = propArgs.map((arg) =>\n arg.kind === \"NamedArg\"\n ? evaluate(arg.value, ctx)\n : arg.kind === \"Bind\"\n ? evaluate(arg.target, ctx)\n : evaluate(arg, ctx),\n );\n const argMeta = propArgs.map<ArgMeta>((arg) =>\n arg.kind === \"StateRef\"\n ? { stateRef: arg.name }\n : arg.kind === \"Bind\" && arg.target.kind === \"StateRef\"\n ? { stateRef: arg.target.name }\n : arg.kind === \"NamedArg\" && arg.value.kind === \"StateRef\"\n ? { stateRef: arg.value.name }\n : {},\n );\n return { args, argMeta };\n }\n\n const slotByName = new Map<string, number>();\n spec.props.forEach((p, i) => {\n slotByName.set(p.name, i);\n if (p.aliases) {\n for (const alias of p.aliases) {\n if (!slotByName.has(alias)) slotByName.set(alias, i);\n }\n }\n });\n const positionalIndex = findPositionalIndex(spec);\n const slots: Array<{ value: unknown; meta: ArgMeta; filled: boolean }> = spec.props.map(() => ({\n value: undefined,\n meta: {},\n filled: false,\n }));\n\n type PositionalSource = { expr: Expression; value: unknown };\n const positionals: PositionalSource[] = [];\n\n for (const arg of propArgs) {\n if (arg.kind === \"NamedArg\") {\n const slot = slotByName.get(arg.name);\n if (slot === undefined) continue;\n const value = evaluate(arg.value, ctx);\n slots[slot]!.value = value;\n slots[slot]!.filled = true;\n if (arg.value.kind === \"StateRef\") {\n slots[slot]!.meta = { stateRef: arg.value.name };\n }\n continue;\n }\n if (arg.kind === \"Bind\") {\n const slot = slotByName.get(arg.prop);\n if (slot === undefined) continue;\n const value = evaluate(arg.target, ctx);\n slots[slot]!.value = value;\n slots[slot]!.filled = true;\n if (arg.target.kind === \"StateRef\") {\n slots[slot]!.meta = { stateRef: arg.target.name };\n }\n continue;\n }\n positionals.push({ expr: arg, value: evaluate(arg, ctx) });\n }\n\n // Aktion 0.5 §19.1 — exactly one positional argument max\n // *at the language layer* (schema validator surfaces an error for any\n // additional positional). The runtime keeps a graceful render path so\n // direct-evaluator callers without the validator hooked up still see a\n // populated node: the first positional lands in the spec's positional\n // slot; any extras fall through to the next unnamed slots in spec\n // order. This is the same \"best-effort render even on schema error\"\n // contract the rest of the runtime follows.\n if (positionals.length > 0 && positionalIndex >= 0 && !slots[positionalIndex]!.filled) {\n const { expr, value } = positionals.shift()!;\n slots[positionalIndex]!.value = value;\n slots[positionalIndex]!.filled = true;\n if (expr.kind === \"StateRef\") slots[positionalIndex]!.meta = { stateRef: expr.name };\n }\n let cursor = 0;\n for (const { expr, value } of positionals) {\n while (cursor < spec.props.length && slots[cursor]!.filled) cursor += 1;\n if (cursor >= spec.props.length) break;\n slots[cursor]!.value = value;\n slots[cursor]!.filled = true;\n if (expr.kind === \"StateRef\") slots[cursor]!.meta = { stateRef: expr.name };\n cursor += 1;\n }\n\n // Trim trailing empty slots so optional tail props stay omitted from\n // `node.args` (preserves the legacy contract every library renderer\n // assumes — undefined-tail slots are not appended).\n const args: unknown[] = slots.map((s) => s.value);\n const argMeta: ArgMeta[] = slots.map((s) => s.meta);\n while (args.length > 0 && args[args.length - 1] === undefined) {\n args.pop();\n argMeta.pop();\n }\n return { args, argMeta };\n}\n\n/**\n * Invoke a Aktion 0.5 `component Name(p) { ... }` declaration. Parameters are\n * bound to the supplied positional / named arguments and the block body\n * is evaluated; the last expression's value is returned as the rendered\n * output. State and effect declarations inside the body are *registered\n * during the block walk*; full per-instance scoping is a follow-up — see\n * the status file. The current behaviour: the first invocation registers\n * any `$state`/`effect`/`action` inside as global names, which works for\n * single-instance components but does not yet isolate multiple instances.\n */\nfunction invokeComponentDecl(\n decl: ComponentDeclaration,\n args: Expression[],\n ctx: EvaluationContext,\n loc?: { line: number; column: number },\n): unknown {\n // Split positional vs. named so we can build the slot-aware UserComponentNode\n // the renderer expands at render-time. Positional args bind to params in\n // declaration order; extras become the implicit `children` slot. Named\n // args bind by name (params first, then slots, then a special `key:`).\n const positionalExprs: Expression[] = [];\n const named: Record<string, Expression> = {};\n let explicitKeyExpr: Expression | undefined;\n for (const arg of args) {\n if (arg.kind === \"NamedArg\") {\n if (arg.name === \"key\") {\n explicitKeyExpr = arg.value;\n } else {\n named[arg.name] = arg.value;\n }\n } else {\n positionalExprs.push(arg);\n }\n }\n\n // Evaluate args in the caller's scope (params are not in scope yet, so\n // arg expressions cannot reference the component's own params — which\n // matches every other language with eager argument evaluation).\n const positional = positionalExprs.map((expr) =>\n expr.kind === \"Spread\" ? evaluate(expr.argument, ctx) : evaluate(expr, ctx),\n );\n // Flatten Spread results inline so `Counter(...defaults, key: \"a\")` works.\n const flatPositional: unknown[] = [];\n for (let i = 0; i < positionalExprs.length; i += 1) {\n const expr = positionalExprs[i]!;\n const value = positional[i];\n if (expr.kind === \"Spread\" && Array.isArray(value)) {\n for (const item of value) flatPositional.push(item);\n } else {\n flatPositional.push(value);\n }\n }\n const evaluatedNamed: Record<string, unknown> = {};\n for (const [name, expr] of Object.entries(named)) {\n evaluatedNamed[name] = evaluate(expr, ctx);\n }\n const explicitKey = explicitKeyExpr ? evaluate(explicitKeyExpr, ctx) : undefined;\n\n return {\n __kind: \"UserComponent\",\n decl,\n positional: flatPositional,\n named: evaluatedNamed,\n explicitKey,\n source: loc,\n } satisfies UserComponentNode;\n}\n\n/**\n * Evaluate a user-declared component body in a fresh per-instance scope.\n * Called by the renderer once the stable instance key is known so\n * `$state` declarations inside the body land in instance-private slots.\n *\n * `instanceKey` should be a deterministic string derived from the\n * render-tree path (and/or the `key:` override) — it becomes the prefix\n * for every per-instance state atom and effect / action declaration.\n *\n * Returns the body's last-expression value (typically a `ComponentNode`\n * the renderer can hand to the library, or another `UserComponentNode`\n * to expand recursively).\n */\nexport function evaluateUserComponent(\n node: UserComponentNode,\n ctx: EvaluationContext,\n instanceKey: string,\n): unknown {\n const { decl, positional, named } = node;\n const restoreLoopVars: Array<{ name: string; had: boolean; prev: unknown }> = [];\n // Bind component params in declaration order, with defaults for absent\n // values. Trailing positional becomes `children`.\n for (let i = 0; i < decl.params.length; i += 1) {\n const param = decl.params[i]!;\n let value: unknown;\n if (named[param.name] !== undefined) {\n value = named[param.name];\n } else if (positional[i] !== undefined) {\n value = positional[i];\n } else if (param.defaultValue) {\n // Defaults are evaluated in the component's own scope so they may\n // reference earlier params (`tone: \"info\", icon: iconFor(tone)`).\n value = evaluate(param.defaultValue, ctx);\n } else {\n value = undefined;\n }\n restoreLoopVars.push({\n name: param.name,\n had: ctx.loopVars.has(param.name),\n prev: ctx.loopVars.get(param.name),\n });\n ctx.loopVars.set(param.name, value);\n }\n // `children` slot from any extra trailing positional arguments.\n if (positional.length > decl.params.length) {\n const extras = positional.slice(decl.params.length);\n const childrenValue = extras.length === 1 ? extras[0] : extras;\n restoreLoopVars.push({\n name: \"children\",\n had: ctx.loopVars.has(\"children\"),\n prev: ctx.loopVars.get(\"children\"),\n });\n ctx.loopVars.set(\"children\", childrenValue);\n }\n // Named slots: declared as `slots: { name? }` on the component.\n if (decl.slots.length > 0) {\n const slotsValue: Record<string, unknown> = {};\n for (const slotName of decl.slots) {\n if (named[slotName] !== undefined) {\n slotsValue[slotName] = named[slotName];\n }\n }\n restoreLoopVars.push({\n name: \"slots\",\n had: ctx.loopVars.has(\"slots\"),\n prev: ctx.loopVars.get(\"slots\"),\n });\n ctx.loopVars.set(\"slots\", slotsValue);\n }\n\n // Walk the body once to discover `$x = expr` state assignments and\n // pre-allocate per-instance aliases for them. We do this *before*\n // evaluating the body so that forward references inside the body\n // resolve to the aliased name.\n const aliasFrame = new Map<string, string>();\n for (const stmt of decl.body.body) {\n if (stmt.kind === \"Assignment\" && stmt.isState) {\n const instanceName = `${instanceKey}:${stmt.identifier}`;\n aliasFrame.set(stmt.identifier, instanceName);\n ctx.state.declare(instanceName, evaluateLiteral(stmt.expression));\n }\n }\n ctx.stateAliases.push(aliasFrame);\n try {\n return evaluateBlock(decl.body, ctx);\n } finally {\n ctx.stateAliases.pop();\n for (const slot of restoreLoopVars) {\n if (slot.had) ctx.loopVars.set(slot.name, slot.prev);\n else ctx.loopVars.delete(slot.name);\n }\n }\n}\n\n/**\n * Build a callable that runs the action body when invoked. The returned\n * function signature matches a JS event handler (`(event) => Promise<unknown>`)\n * so `onClick: actionName` bindings dispatch correctly without extra\n * adapter logic.\n */\nfunction makeActionCallable(decl: ActionDeclaration, ctx: EvaluationContext) {\n // Snapshot the alias frames *at callable-creation time* so per-instance\n // `$state` slots declared in the surrounding `component` body resolve\n // correctly when the action fires later (e.g. on click). Without this,\n // the action would inherit the alias stack as it exists at *call time* —\n // which is usually empty because component rendering already returned.\n // The lambda path (§9 `Lambda` in `evaluate`) does the same.\n const capturedAliases: Array<Map<string, string>> = ctx.stateAliases.map(\n (frame) => new Map(frame),\n );\n return async (...args: unknown[]) => {\n const restoreAliases = ctx.stateAliases.slice();\n ctx.stateAliases.length = 0;\n for (const frame of capturedAliases) ctx.stateAliases.push(frame);\n try {\n return await invokeActionDecl(decl, args, ctx);\n } finally {\n ctx.stateAliases.length = 0;\n for (const frame of restoreAliases) ctx.stateAliases.push(frame);\n }\n };\n}\n\n/**\n * Run an action declaration eagerly with `args` already evaluated. The\n * call returns a Promise so authors can `await save(order.id)` and have\n * the optimistic-rollback semantics described in §10.\n */\nfunction invokeActionDecl(\n decl: ActionDeclaration,\n args: unknown[],\n ctx: EvaluationContext,\n): Promise<unknown> | unknown {\n if (!ctx.actionRunner) {\n // No host runtime — fall back to a synchronous best-effort eval that\n // still binds parameters and runs the body but ignores `await` /\n // `optimistic`. Better than silently dropping the call.\n const restore: Array<{ name: string; had: boolean; prev: unknown }> = [];\n for (let i = 0; i < decl.params.length; i += 1) {\n const param = decl.params[i]!;\n restore.push({\n name: param.name,\n had: ctx.loopVars.has(param.name),\n prev: ctx.loopVars.get(param.name),\n });\n ctx.loopVars.set(param.name, args[i]);\n }\n try {\n return evaluateBlock(decl.body, ctx);\n } finally {\n for (const slot of restore) {\n if (slot.had) ctx.loopVars.set(slot.name, slot.prev);\n else ctx.loopVars.delete(slot.name);\n }\n }\n }\n return ctx.actionRunner.run(decl, args, ctx);\n}\n\nfunction evaluateBuiltinCall(\n name: string,\n args: Expression[],\n ctx: EvaluationContext,\n): unknown {\n // Synthetic assignment-as-expression emitted by the parser for the\n // single-statement lambda form `() => $x = expr` (and `+=`, `-=`,\n // `*=`, `/=`, `??=`). Without this handler the assignment would be\n // silently dropped because no real `@__rui_assign__` builtin exists.\n if (name === \"__rui_assign__\") {\n return evaluateSyntheticAssign(args, ctx);\n }\n if (name === \"__rui_postfix__\") {\n return evaluateSyntheticPostfix(args, ctx);\n }\n // Fallback iteration builtin (the blessed surface is the expression-form\n // `for x in xs { ... }`). Kept available because some templates pre-date\n // the `for` expression and the spec (§28) explicitly preserves these\n // builtins as fallbacks for one positional-only iteration.\n if (name === \"Each\") {\n const sourceArg = args[0];\n const varNameArg = args[1];\n const templateArg = args[2];\n if (!sourceArg || !varNameArg || !templateArg) return [];\n const sourceValue = evaluate(sourceArg, ctx);\n const arr = Array.isArray(sourceValue) ? sourceValue : [];\n const varName = varNameArg.kind === \"Literal\" ? String(varNameArg.value ?? \"\") : \"\";\n // Destructuring forms: `\"{id, name, role}\"` binds those fields directly\n // in addition to the row object (also bound under its single-name\n // counterpart for backward compatibility — `\"{id, name}\"` exposes\n // `id` / `name`; `\"row,{id,name}\"` would expose `row`, `id`, `name`).\n const destructuring = parseDestructureNames(varName);\n const out: unknown[] = [];\n // Snapshot every binding we are about to overwrite so we can restore\n // the outer scope exactly — including the legitimate case where the\n // outer value is `undefined`. Using `has(...)` instead of `prev ===\n // undefined` prevents an inner @Each from accidentally deleting an\n // outer loop var.\n const snapshots = destructuring.bindings.map((name) => ({\n name,\n had: ctx.loopVars.has(name),\n prev: ctx.loopVars.get(name),\n }));\n try {\n for (const item of arr) {\n if (destructuring.scalarName) {\n ctx.loopVars.set(destructuring.scalarName, item);\n }\n for (const field of destructuring.fields) {\n if (item && typeof item === \"object\") {\n ctx.loopVars.set(field, (item as Record<string, unknown>)[field]);\n } else {\n ctx.loopVars.set(field, undefined);\n }\n }\n out.push(evaluate(templateArg, ctx));\n }\n } finally {\n for (const slot of snapshots) {\n if (slot.had) ctx.loopVars.set(slot.name, slot.prev);\n else ctx.loopVars.delete(slot.name);\n }\n }\n return out;\n }\n\n // Lazy conditional renderer: `@If(cond, trueNode, falseNode?)`. Only the\n // selected branch is evaluated — useful for forms whose alternate branch\n // would otherwise consume `params.id` / loop variables in scope.\n if (name === \"If\") {\n const condArg = args[0];\n const thenArg = args[1];\n const elseArg = args[2];\n if (!condArg) return null;\n const condition = evaluate(condArg, ctx);\n if (condition) return thenArg ? evaluate(thenArg, ctx) : null;\n return elseArg ? evaluate(elseArg, ctx) : null;\n }\n\n if (name === \"Switch\") {\n const valueArg = args[0];\n const casesArg = args[1];\n const defaultArg = args[2];\n if (!valueArg || !casesArg) return null;\n const value = evaluate(valueArg, ctx);\n const key = stringify(value);\n if (casesArg.kind === \"Object\") {\n for (const prop of casesArg.properties) {\n if (prop.spread) continue;\n if (prop.key === key) return evaluate(prop.value, ctx);\n }\n }\n return defaultArg ? evaluate(defaultArg, ctx) : null;\n }\n\n // Aktion 0.5 i18n: `t(key, vars?)` — global translation builtin.\n if (name === \"T\" || name === \"t\") {\n const keyArg = args[0];\n const varsArg = args[1];\n const key = keyArg ? String(evaluate(keyArg, ctx) ?? \"\") : \"\";\n if (!ctx.i18n) return key;\n let vars: Record<string, unknown> | undefined;\n if (varsArg) {\n const evaluated = evaluate(varsArg, ctx);\n if (evaluated && typeof evaluated === \"object\" && !Array.isArray(evaluated)) {\n vars = evaluated as Record<string, unknown>;\n }\n }\n return ctx.i18n.t(key, vars);\n }\n\n // Aktion 0.5 i18n: `Locale()` — return the active locale tag. Cheap escape\n // hatch so authors can pass it to `Format`/`FormatDate` without wiring\n // a `$session.locale` atom themselves.\n if (name === \"Locale\") {\n return ctx.i18n?.getLocale() ?? \"\";\n }\n\n const fn = dataBuiltins[name];\n if (!fn) return null;\n const evaluated = args.map((a) => evaluate(a, ctx));\n return fn(evaluated);\n}\n\n/**\n * Apply a compound-assignment operator. Used by the synthetic\n * `__rui_assign__` builtin so single-statement lambdas like\n * `() => $count += 1` update state through the same code path the\n * action runner uses.\n */\nfunction applyAssignOp(op: string, current: unknown, next: unknown): unknown {\n switch (op) {\n case \"=\": return next;\n case \"+=\": {\n if (typeof current === \"string\" || typeof next === \"string\") {\n return `${current ?? \"\"}${next ?? \"\"}`;\n }\n return toNumber(current) + toNumber(next);\n }\n case \"-=\": return toNumber(current) - toNumber(next);\n case \"*=\": return toNumber(current) * toNumber(next);\n case \"/=\": {\n const divisor = toNumber(next);\n return divisor === 0 ? 0 : toNumber(current) / divisor;\n }\n case \"??=\": return current == null ? next : current;\n default: return next;\n }\n}\n\n/**\n * Evaluate a `__rui_assign__(target, value, op)` synthetic call. The\n * target is either a `StateRef` (write to the state store, alias-aware)\n * or a plain `Identifier` (write to `loopVars` so block-local helpers\n * still observe the new value).\n */\nfunction evaluateSyntheticAssign(\n args: Expression[],\n ctx: EvaluationContext,\n): unknown {\n const [targetExpr, valueExpr, opExpr] = args;\n if (!targetExpr || !valueExpr) return null;\n const op = opExpr && opExpr.kind === \"Literal\" ? String(opExpr.value ?? \"=\") : \"=\";\n const rhs = evaluate(valueExpr, ctx);\n if (targetExpr.kind === \"StateRef\") {\n const target = resolveStateAlias(ctx, targetExpr.name);\n const current = ctx.state.get(target);\n const next = applyAssignOp(op, current, rhs);\n ctx.state.set(target, next);\n return next;\n }\n if (targetExpr.kind === \"Identifier\") {\n const current = ctx.loopVars.get(targetExpr.name);\n const next = applyAssignOp(op, current, rhs);\n ctx.loopVars.set(targetExpr.name, next);\n return next;\n }\n return rhs;\n}\n\n/**\n * Evaluate a `__rui_postfix__(target, op)` synthetic call (`++` / `--`).\n * Returns the value *after* the increment so the expression composes\n * predictably inside other expressions.\n */\nfunction evaluateSyntheticPostfix(\n args: Expression[],\n ctx: EvaluationContext,\n): unknown {\n const [targetExpr, opExpr] = args;\n if (!targetExpr) return null;\n const op = opExpr && opExpr.kind === \"Literal\" ? String(opExpr.value ?? \"++\") : \"++\";\n const delta = op === \"--\" ? -1 : 1;\n if (targetExpr.kind === \"StateRef\") {\n const target = resolveStateAlias(ctx, targetExpr.name);\n const next = toNumber(ctx.state.get(target)) + delta;\n ctx.state.set(target, next);\n return next;\n }\n if (targetExpr.kind === \"Identifier\") {\n const next = toNumber(ctx.loopVars.get(targetExpr.name)) + delta;\n ctx.loopVars.set(targetExpr.name, next);\n return next;\n }\n return null;\n}\n\n/**\n * Parse an `@Each` loop variable specifier into the set of names to bind.\n * Supports:\n * - `\"row\"` — single scalar binding\n * - `\"{id, name}\"` — destructure the row object's fields\n * - `\"row, {id, name}\"` — bind the row AND destructured fields\n * The result lists every name we will write into `ctx.loopVars` so the\n * caller can snapshot/restore them.\n */\nfunction parseDestructureNames(spec: string): {\n scalarName: string;\n fields: string[];\n bindings: string[];\n} {\n const trimmed = spec.trim();\n if (!trimmed) return { scalarName: \"\", fields: [], bindings: [] };\n\n // `{a, b, c}` — pure destructure.\n if (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n const fields = trimmed.slice(1, -1).split(\",\").map((f) => f.trim()).filter(Boolean);\n return { scalarName: \"\", fields, bindings: fields };\n }\n // `row, {a, b}` — row binding plus destructured fields.\n const braceIdx = trimmed.indexOf(\"{\");\n if (braceIdx > 0) {\n const head = trimmed.slice(0, braceIdx).trim();\n const scalar = head.replace(/,\\s*$/, \"\").trim();\n const closeIdx = trimmed.indexOf(\"}\", braceIdx);\n const fields = closeIdx > braceIdx\n ? trimmed.slice(braceIdx + 1, closeIdx).split(\",\").map((f) => f.trim()).filter(Boolean)\n : [];\n return { scalarName: scalar, fields, bindings: scalar ? [scalar, ...fields] : fields };\n }\n return { scalarName: trimmed, fields: [], bindings: [trimmed] };\n}\n\n/**\n * Resolve the current route path. Prefers the router (when present), falls\n * back to the `route` state slot, and finally to \"/\". Tracking the slot\n * here makes router bindings reactive to host pages that write the path\n * imperatively (e.g. for SSR-style hydration).\n */\nfunction readRoutePath(ctx: EvaluationContext): string {\n if (ctx.router) {\n return ctx.router.getPath();\n }\n if (ctx.state.has(\"route\")) {\n ctx.trackedState.add(\"route\");\n const value = ctx.state.get(\"route\");\n if (typeof value === \"string\" && value) return value;\n if (value && typeof value === \"object\" && \"path\" in value) {\n const path = (value as { path: unknown }).path;\n if (typeof path === \"string\" && path) return path;\n }\n }\n return \"/\";\n}\n\n/**\n * Build the reactive `_route_` payload from the host's `Router`. Returns\n * a plain object with `path`, `params`, `pattern`, `query`, a\n * `navigate(path)` method that delegates to the router, plus a\n * `toString()` so template literals like `${_route_}` still coerce to\n * the path. Computed on every read so route arm matches that update\n * params mid-render are reflected in subsequent `_route_.params` reads\n * in the same render pass.\n */\nfunction buildRouteState(router: NonNullable<EvaluationContext[\"router\"]>): Record<string, unknown> {\n const path = router.getPath();\n const params: Record<string, unknown> = { ...router.getParams() };\n const pattern = router.getActivePattern();\n const query: Record<string, string> = {};\n if (typeof globalThis !== \"undefined\" && (globalThis as { location?: { search?: string } }).location) {\n const search = (globalThis as { location?: { search?: string } }).location?.search ?? \"\";\n if (search) {\n const usp = new URLSearchParams(search.startsWith(\"?\") ? search.slice(1) : search);\n for (const [k, v] of usp) query[k] = v;\n }\n }\n return {\n path,\n params,\n pattern,\n query,\n navigate(target: unknown): void {\n if (typeof target !== \"string\" || !target) return;\n router.navigate(target);\n },\n toString() {\n return path;\n },\n };\n}\n\n/**\n * Aktion 0.5 §19.1 — see `resolveLibraryCallArgs`. The\n * legacy \"trailing object literal expands to named args\" hack was\n * removed in 0.5 — object literals are treated as opaque values like\n * any other argument, so `Stack({ gap: \"md\" })` no longer aliases\n * `Stack(gap: \"md\")`.\n */\n\nfunction computedMemberAccess(target: unknown, key: unknown): unknown {\n if (target == null) return undefined;\n\n if (Array.isArray(target)) {\n const index = toArrayIndex(key, target.length);\n if (index === null) return undefined;\n return target[index];\n }\n\n if (typeof target === \"string\") {\n const index = toArrayIndex(key, target.length);\n if (index === null) return undefined;\n return target[index];\n }\n\n if (typeof target === \"object\") {\n return (target as Record<string, unknown>)[String(key ?? \"\")];\n }\n\n return undefined;\n}\n\n/** Resolve numeric/string keys to a bounded array index (supports negatives). */\nfunction toArrayIndex(key: unknown, length: number): number | null {\n let index: number;\n if (typeof key === \"number\") {\n index = key;\n } else if (typeof key === \"string\" && key.trim() !== \"\" && !Number.isNaN(Number(key))) {\n index = Number(key);\n } else {\n return null;\n }\n if (index < 0) index = length + index;\n if (index < 0 || index >= length) return null;\n return index;\n}\n\nfunction memberAccess(target: unknown, property: string): unknown {\n if (target == null) return undefined;\n if (Array.isArray(target)) {\n // A handful of \"array-shaped\" properties LLMs reach for reflexively.\n // Resolving them here means common JS idioms (`$todos.length`,\n // `$rows.first`) just work without forcing every author to remember the\n // @Count/@First builtins.\n switch (property) {\n case \"length\": return target.length;\n case \"first\": return target[0] ?? null;\n case \"last\": return target.length === 0 ? null : target[target.length - 1];\n default: break;\n }\n // \"Array pluck\": map each item through the property. Idiomatic for\n // turning `data.rows` into a per-column array.\n return target.map((item) => {\n if (item && typeof item === \"object\") {\n return (item as Record<string, unknown>)[property];\n }\n return undefined;\n });\n }\n if (typeof target === \"string\") {\n // Strings get the same shortcut so the LLM doesn't have to switch idioms.\n if (property === \"length\") return target.length;\n }\n if (typeof target === \"object\") {\n return (target as Record<string, unknown>)[property];\n }\n return undefined;\n}\n\nfunction toNumber(v: unknown): number {\n if (typeof v === \"number\") return v;\n if (typeof v === \"string\") {\n if (v.trim() === \"\") return 0;\n const n = Number(v);\n return Number.isNaN(n) ? 0 : n;\n }\n if (typeof v === \"boolean\") return v ? 1 : 0;\n return 0;\n}\n\n/**\n * Flatten a Aktion 0.5 theme config into the flat\n * `{tokenKey: string}` shape the host element applies as CSS variables.\n *\n * Only the structured form is accepted:\n *\n * `Theme({ name, colors: {...}, radius: {...}, font: {...},\n * motion: {...}, elevation: {...}, direction })`\n *\n * Groups flatten with a stable naming convention:\n * `colors.primary` → `colorPrimary`\n * `radius.md` → `radiusMd`\n * `font.heading` → `fontHeading`\n * `motion.default` → `motionDefault`\n * `elevation.2` → `elevation2`\n *\n * Top-level metadata keys (`name`, `direction`) are accepted but never\n * emitted as CSS variables. The legacy flat-shape form\n * (`Theme({colorPrimary: \"...\", ...})`) and free-form CSS variable\n * keys (`Theme({\"--color-x\": \"...\"})`) were removed in SUIS/2: the\n * runtime ignores unknown top-level keys silently to keep streaming\n * partial themes safe, but the schema validator surfaces them as\n * advisory warnings (§15) so authors can migrate.\n */\nconst STRUCTURED_THEME_GROUPS = new Set([\n \"colors\",\n \"radius\",\n \"font\",\n \"motion\",\n \"elevation\",\n]);\nconst THEME_METADATA_KEYS = new Set([\"name\", \"direction\"]);\n\nfunction collectThemeTokens(value: unknown): Record<string, string> {\n const out: Record<string, string> = {};\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return out;\n const map = value as Record<string, unknown>;\n for (const [key, raw] of Object.entries(map)) {\n if (raw == null) continue;\n if (THEME_METADATA_KEYS.has(key)) continue;\n if (!STRUCTURED_THEME_GROUPS.has(key)) {\n // Legacy flat-shape token (e.g. `colorPrimary`, `radiusMd`) or\n // free-form CSS variable key (`--color-x`). Silently drop —\n // schema validation surfaces it as a warning at parse time so\n // the author sees the migration hint without crashing the\n // render.\n continue;\n }\n if (raw && typeof raw === \"object\" && !Array.isArray(raw)) {\n const prefix = key === \"colors\" ? \"color\" : key;\n for (const [innerKey, innerValue] of Object.entries(raw as Record<string, unknown>)) {\n if (innerValue == null) continue;\n const flatKey = prefix + capitalise(innerKey);\n out[flatKey] = stringifyTokenValue(innerValue);\n }\n }\n }\n return out;\n}\n\nfunction capitalise(value: string): string {\n if (!value) return \"\";\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction stringifyTokenValue(value: unknown): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return String(value);\n return \"\";\n}\n\nfunction stringify(v: unknown): string {\n if (v == null) return \"\";\n if (typeof v === \"string\") return v;\n if (typeof v === \"number\" || typeof v === \"boolean\") return String(v);\n // Objects with a custom `toString()` (notably the reactive `_route_`\n // payload whose `toString()` returns `path`) get their string form so\n // template literals like `${_route_}` keep coercing to the path.\n if (typeof v === \"object\" && v !== null) {\n const proto = Object.getPrototypeOf(v);\n const ownToString = (v as { toString?: () => string }).toString;\n if (typeof ownToString === \"function\" && ownToString !== Object.prototype.toString) {\n const str = ownToString.call(v);\n if (typeof str === \"string\") return str;\n }\n void proto;\n }\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n","/**\n * Aktion 0.5 i18n runtime — `$i18n` declaration + `t()` global builtin (§23).\n *\n * The runtime is intentionally tiny:\n * - Holds the active locale, fallback locale, and message map.\n * - `t(key, vars?)` looks up `key` (dot-paths supported, e.g. `\"orders.title\"`),\n * falls back to the fallback locale's bundle, then to the bare key.\n * - `vars?` are interpolated using `${name}` placeholders.\n *\n * Locale-aware formatting (`Money`, `Date`, `Number`, `Percent`,\n * `RelativeTime`) is wired through `getLocale()` so library components\n * can read the live value without each declaring it as a prop.\n */\n\nexport interface I18nConfig {\n locale: string;\n messages: Record<string, unknown>;\n fallback?: string;\n /** Optional secondary message map for the fallback locale. */\n fallbackMessages?: Record<string, unknown>;\n}\n\nexport class I18nRuntime {\n private locale = \"en\";\n private fallback = \"en\";\n private messages: Record<string, unknown> = {};\n private fallbackMessages: Record<string, unknown> = {};\n\n configure(config: I18nConfig): void {\n this.locale = config.locale || \"en\";\n this.fallback = config.fallback ?? \"en\";\n this.messages = sanitiseMessages(config.messages);\n this.fallbackMessages = sanitiseMessages(config.fallbackMessages ?? {});\n }\n\n /** Current active locale tag (e.g. `\"en-US\"`, `\"de\"`). */\n getLocale(): string {\n return this.locale;\n }\n\n /** Snapshot of the configured fallback locale. */\n getFallback(): string {\n return this.fallback;\n }\n\n /**\n * Translate a dot-pathed key, optionally interpolating `${name}` vars.\n *\n * Resolution order:\n * 1. The active locale's message map.\n * 2. The fallback locale's message map (if provided separately).\n * 3. The bare key as a literal string.\n */\n t(key: string, vars?: Record<string, unknown>): string {\n const value =\n readPath(this.messages, key) ??\n readPath(this.fallbackMessages, key) ??\n key;\n if (typeof value !== \"string\") return key;\n return interpolate(value, vars);\n }\n}\n\nfunction sanitiseMessages(input: unknown): Record<string, unknown> {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return {};\n return input as Record<string, unknown>;\n}\n\nfunction readPath(messages: Record<string, unknown>, key: string): unknown {\n if (!key) return undefined;\n // Fast path for non-nested keys.\n if (key.indexOf(\".\") === -1) return messages[key];\n let cursor: unknown = messages;\n for (const segment of key.split(\".\")) {\n if (!cursor || typeof cursor !== \"object\") return undefined;\n cursor = (cursor as Record<string, unknown>)[segment];\n }\n return cursor;\n}\n\nfunction interpolate(template: string, vars?: Record<string, unknown>): string {\n if (!vars) return template;\n return template.replace(/\\$\\{([^}]+)\\}/g, (_, expr: string) => {\n const value = vars[expr.trim()];\n if (value === null || value === undefined) return \"\";\n return String(value);\n });\n}\n","/**\n * Aktion effect runtime — mounts `effect [ ...deps ] { … }` blocks,\n * runs their triggers, and tears them down on unmount.\n *\n * Each declaration's bracketed dependency list mixes:\n * - state triggers (`$atom`) — re-run when any listed atom changes.\n * - lifecycle triggers (`on:mount`, `on:unmount`).\n * - interval triggers (`on:every(N)`) — re-run every N ms.\n * - rate-limit modifiers (`debounce(N)`, `throttle(N)`) — wrap the body\n * with a trailing-edge rate-limit.\n *\n * Empty dependency lists (`effect { ... }`) and explicit\n * `effect [on:mount] { ... }` are equivalent — both run the body once on\n * mount.\n *\n * `cleanup(fn)` registrations inside the body are collected and fired on\n * unmount, on re-run, or on program reload.\n */\n\nimport type {\n ActionDeclaration,\n EffectDeclaration,\n Statement,\n} from \"../parser/types.js\";\nimport type { EvaluationContext } from \"./evaluator.js\";\nimport { evaluate, resolveStateAlias } from \"./evaluator.js\";\nimport type { StateStore, StateValue } from \"./state.js\";\n\nexport interface EffectRunnerOptions {\n state: StateStore;\n /** Called whenever an effect mutates state or completes — schedules render. */\n notify: () => void;\n /** Called when the action body emits a CustomEvent via `emit`. */\n onEmit?: (eventName: string, detail: unknown) => void;\n /** Host element — exposed to `js{}` block bodies as `ctx.host`. */\n host?: HTMLElement;\n /**\n * Optional pluggable async tool registry — exposed to `js{}` blocks as\n * `ctx.tools.<name>(...)`. Each entry is invoked with whatever args the\n * JS body passes; the return value is awaited. Hosts can register fetch\n * shims, persistence helpers, etc.\n */\n tools?: Record<string, (...args: unknown[]) => unknown>;\n}\n\ninterface MountedEffect {\n decl: EffectDeclaration;\n cleanups: Array<() => void>;\n intervals: Array<ReturnType<typeof setInterval>>;\n unsubscribers: Array<() => void>;\n /** Snapshot of `ctx` at mount-time so re-runs reuse the same scope. */\n ctxRef: () => EvaluationContext;\n}\n\nexport class EffectRunner {\n private mounted = new Map<string, MountedEffect>();\n private errors: string[] = [];\n\n constructor(private readonly options: EffectRunnerOptions) {}\n\n /** Get any errors raised at mount-time (denied capabilities, parse issues). */\n getErrors(): ReadonlyArray<string> {\n return this.errors;\n }\n\n /**\n * Mount every effect declaration in `decls`. Idempotent: declarations\n * that are already mounted under the same name are left alone, those\n * that vanish from the new program are torn down.\n */\n syncEffects(\n decls: ReadonlyArray<EffectDeclaration>,\n getCtx: () => EvaluationContext,\n ): void {\n this.errors = [];\n const incoming = new Set(decls.map((d) => d.name));\n // Tear down effects no longer in the program.\n for (const name of [...this.mounted.keys()]) {\n if (!incoming.has(name)) {\n this.unmount(name);\n }\n }\n for (const decl of decls) {\n if (!this.mounted.has(decl.name)) {\n this.mount(decl, getCtx);\n }\n }\n }\n\n reset(): void {\n for (const name of [...this.mounted.keys()]) {\n this.unmount(name);\n }\n this.errors = [];\n }\n\n private mount(\n decl: EffectDeclaration,\n getCtx: () => EvaluationContext,\n ): void {\n const mounted: MountedEffect = {\n decl,\n cleanups: [],\n intervals: [],\n unsubscribers: [],\n ctxRef: getCtx,\n };\n this.mounted.set(decl.name, mounted);\n\n const rawRunBody = (): void => {\n // Reset cleanups before each run — prior cleanups should fire so\n // observers / listeners don't leak across re-fires.\n for (const fn of mounted.cleanups.splice(0)) {\n try { fn(); } catch (err) { logCleanupError(decl.name, err); }\n }\n try {\n runEffectBody(decl, getCtx(), mounted, this.options);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(`[aktion] effect \"${decl.name}\" failed`, err);\n } finally {\n this.options.notify();\n }\n };\n\n // Optional `debounce(N)` / `throttle(N)` modifier — rate-limit the\n // effect body. The wrapper is installed once at mount-time so\n // subsequent re-runs go through the same timer state.\n const runBody = wrapRateLimit(rawRunBody, decl.rateLimit, mounted);\n\n // Wire triggers.\n let hasMountTrigger = false;\n let hasUnmountTrigger = false;\n let hasEveryTrigger = false;\n for (const trigger of decl.triggers) {\n switch (trigger.kind) {\n case \"lifecycle\":\n if (trigger.name === \"mount\") hasMountTrigger = true;\n if (trigger.name === \"unmount\") hasUnmountTrigger = true;\n break;\n case \"every\": {\n hasEveryTrigger = true;\n const id = setInterval(runBody, trigger.intervalMs);\n mounted.intervals.push(id);\n break;\n }\n case \"state\": {\n const targetName = trigger.name;\n const unsub = this.options.state.subscribe((changed) => {\n if (changed.has(targetName)) runBody();\n });\n mounted.unsubscribers.push(unsub);\n break;\n }\n }\n }\n\n // Default trigger: if no triggers are declared at all, treat as on:mount.\n // If `on:unmount` is the only trigger, the body is run on teardown\n // instead.\n if (decl.triggers.length === 0 || hasMountTrigger) {\n runBody();\n } else if (!hasEveryTrigger && !hasUnmountTrigger && decl.triggers.every((t) => t.kind === \"state\")) {\n // Pure state-driven effects also run once on mount so the initial\n // state is observed (matches React's `useEffect` and the spec's\n // \"first quiescence\" rule for stream effects).\n runBody();\n }\n }\n\n private unmount(name: string): void {\n const mounted = this.mounted.get(name);\n if (!mounted) return;\n this.mounted.delete(name);\n\n for (const id of mounted.intervals) clearInterval(id);\n for (const unsub of mounted.unsubscribers) {\n try { unsub(); } catch { /* swallow */ }\n }\n for (const fn of mounted.cleanups) {\n try { fn(); } catch (err) { logCleanupError(name, err); }\n }\n\n // Run `on:unmount` body if declared.\n const hasUnmountTrigger = mounted.decl.triggers.some(\n (t) => t.kind === \"lifecycle\" && t.name === \"unmount\",\n );\n if (hasUnmountTrigger) {\n try {\n runEffectBody(mounted.decl, mounted.ctxRef(), mounted, this.options);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(`[aktion] effect \"${name}\" unmount body threw`, err);\n }\n }\n }\n}\n\n/**\n * Wrap `run` with a debounce / throttle gate when the declaration carries\n * a `debounce(N)` / `throttle(N)` modifier. Returns the raw `run` when no\n * modifier is present. The pending timer is registered as a cleanup so a\n * fast unmount cancels in-flight calls.\n */\nfunction wrapRateLimit(\n run: () => void,\n rateLimit: EffectDeclaration[\"rateLimit\"],\n mounted: MountedEffect,\n): () => void {\n if (!rateLimit || rateLimit.ms <= 0) return run;\n if (rateLimit.kind === \"debounce\") {\n let timer: ReturnType<typeof setTimeout> | null = null;\n const cancel = () => {\n if (timer) { clearTimeout(timer); timer = null; }\n };\n mounted.cleanups.push(cancel);\n return () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => { timer = null; run(); }, rateLimit.ms);\n };\n }\n // Throttle: fire immediately, then ignore further calls until `ms` elapsed.\n let lastFired = 0;\n let pending: ReturnType<typeof setTimeout> | null = null;\n mounted.cleanups.push(() => {\n if (pending) { clearTimeout(pending); pending = null; }\n });\n return () => {\n const now = Date.now();\n const elapsed = now - lastFired;\n if (elapsed >= rateLimit.ms) {\n lastFired = now;\n run();\n } else if (!pending) {\n // Schedule a trailing call so the latest state still propagates.\n pending = setTimeout(() => {\n pending = null;\n lastFired = Date.now();\n run();\n }, rateLimit.ms - elapsed);\n }\n };\n}\n\nfunction runEffectBody(\n decl: EffectDeclaration,\n ctx: EvaluationContext,\n mounted: MountedEffect,\n options: EffectRunnerOptions,\n): void {\n // Walk the block body executing each statement. Effect bodies allow:\n // - assignments (`$state = …`) — committed as state writes.\n // - expression statements — evaluated for side effects.\n // - `cleanup(fn)` calls — register a teardown handler.\n // - `emit \"name\" { detail }` — dispatch an outbound event.\n for (const stmt of decl.body.body) {\n runStatement(stmt, ctx, mounted, options);\n }\n}\n\nfunction runStatement(\n stmt: Statement,\n ctx: EvaluationContext,\n mounted: MountedEffect,\n options: EffectRunnerOptions,\n): unknown {\n switch (stmt.kind) {\n case \"ExpressionStatement\": {\n const expr = stmt.expression;\n // `cleanup(fn)` is a function call — recognise it and register the\n // callback rather than evaluating the call normally.\n if (expr.kind === \"Call\" && expr.callee === \"cleanup\") {\n const cb = expr.arguments[0] ? evaluate(expr.arguments[0], ctx) : null;\n if (typeof cb === \"function\") {\n mounted.cleanups.push(cb as () => void);\n }\n return undefined;\n }\n // Inline `js { ... }` block — execute the opaque body.\n if (expr.kind === \"JsBlock\") {\n return executeJsBlock(expr.body, mounted.decl.name, ctx, options, mounted);\n }\n return evaluate(expr, ctx);\n }\n case \"Assignment\": {\n const value = evaluate(stmt.expression, ctx);\n if (stmt.identifier && stmt.identifier !== \"\") {\n // Treat any assignment inside an effect body as a state write.\n // This mirrors the spec's \"$x = …\" mutation form. Route through\n // the per-instance alias stack so writes from inside a component\n // body hit the right per-instance slot (§7).\n const target = resolveStateAlias(ctx, stmt.identifier);\n ctx.state.set(target, value as StateValue);\n }\n return value;\n }\n case \"Cleanup\": {\n const cb = stmt.callback ? evaluate(stmt.callback, ctx) : null;\n if (typeof cb === \"function\") {\n mounted.cleanups.push(cb as () => void);\n }\n return undefined;\n }\n case \"Emit\": {\n const detail = evaluate(stmt.detail, ctx);\n options.onEmit?.(stmt.eventName, detail);\n return undefined;\n }\n default:\n return undefined;\n }\n}\n\nfunction logCleanupError(name: string, err: unknown): void {\n // eslint-disable-next-line no-console\n console.error(`[aktion] cleanup for effect \"${name}\" threw`, err);\n}\n\n/* -------------------------------------------------------------------------- */\n/* JS escape hatch — executes `js { ... }` blocks inside effect/action bodies */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Shape exposed to `js{}` bodies as the `ctx` parameter. Intentionally\n * narrow — `ctx.state`, `ctx.cleanup`, `ctx.host`, `ctx.tools`, and\n * `ctx.args` (for action bodies) cover the common cases without leaking\n * the entire runtime surface to opaque JS.\n */\ninterface JsBlockCtx {\n state: {\n get: (name: string) => unknown;\n set: (name: string, value: unknown) => void;\n };\n cleanup: (fn: () => void) => void;\n host?: HTMLElement;\n tools: Record<string, (...args: unknown[]) => unknown>;\n args: Record<string, unknown>;\n}\n\ninterface JsBlockExecOptions {\n state: StateStore;\n host?: HTMLElement;\n tools?: Record<string, (...args: unknown[]) => unknown>;\n}\n\n/**\n * Build a standalone `js{ … }` runner closure for the renderer / inline\n * lambdas to invoke. Identical sandbox surface as the effect/action\n * runners (host, tools, state get/set, optional cleanup hook).\n */\nexport function createInlineJsExecutor(\n options: JsBlockExecOptions,\n): (body: string, args?: Record<string, unknown>) => unknown {\n return (body, args = {}) => executeJsBlock(body, \"<inline>\", undefined as unknown as EvaluationContext, options, undefined, args);\n}\n\nfunction executeJsBlock(\n body: string,\n ownerName: string,\n ctx: EvaluationContext,\n options: JsBlockExecOptions,\n mounted?: MountedEffect,\n args: Record<string, unknown> = {},\n): unknown {\n const blockCtx: JsBlockCtx = {\n state: {\n get: (name) => options.state.get(name),\n set: (name, value) => options.state.set(name, value as StateValue),\n },\n cleanup: (fn) => {\n if (typeof fn !== \"function\") return;\n if (mounted) mounted.cleanups.push(fn);\n },\n host: options.host,\n tools: options.tools ?? {},\n args,\n };\n try {\n // Wrap the body as `(async (ctx) => { <body> })(ctx)` so authors can\n // freely use `await`. The block is opaque — we never reparse it.\n // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func\n const fn = new Function(\n \"ctx\",\n `return (async () => { ${body}\\n })()`,\n ) as (c: JsBlockCtx) => Promise<unknown>;\n const result = fn(blockCtx);\n if (result && typeof (result as Promise<unknown>).then === \"function\") {\n (result as Promise<unknown>).catch((err) => {\n // eslint-disable-next-line no-console\n console.error(`[aktion] js{} body in \"${ownerName}\" rejected`, err);\n });\n }\n return result;\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(`[aktion] js{} body in \"${ownerName}\" threw`, err);\n return undefined;\n }\n // ctx ref kept to silence \"unused\" linter on a future no-op refactor.\n void ctx;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Action runner (§10) — optimistic snapshot/rollback */\n/* -------------------------------------------------------------------------- */\n\nexport interface ActionRunnerOptions {\n state: StateStore;\n notify: () => void;\n onEmit?: (eventName: string, detail: unknown) => void;\n onAssistantMessage?: (message: string) => void;\n /** Host element exposed to `js{}` blocks as `ctx.host`. */\n host?: HTMLElement;\n /** Pluggable tool registry exposed to `js{}` blocks as `ctx.tools.<name>`. */\n tools?: Record<string, (...args: unknown[]) => unknown>;\n}\n\n/**\n * Run an `action` declaration. When the declaration is `optimistic` we\n * snapshot every state atom touched before the first `await`; if any\n * subsequent step throws, the snapshot is restored.\n */\nexport class ActionDeclRunner {\n constructor(private readonly options: ActionRunnerOptions) {}\n\n async run(\n decl: ActionDeclaration,\n callArgs: unknown[],\n ctx: EvaluationContext,\n ): Promise<unknown> {\n // Bind parameters into loop vars + collect them as a name-keyed map so\n // `js{}` bodies can read them via `ctx.args.<name>`.\n const restore: Array<{ name: string; had: boolean; prev: unknown }> = [];\n const args: Record<string, unknown> = {};\n for (let i = 0; i < decl.params.length; i += 1) {\n const param = decl.params[i]!;\n const value = callArgs[i];\n restore.push({\n name: param.name,\n had: ctx.loopVars.has(param.name),\n prev: ctx.loopVars.get(param.name),\n });\n ctx.loopVars.set(param.name, value);\n args[param.name] = value;\n }\n // Snapshot for optimistic rollback. We snapshot the entire state\n // store; the spec only requires snapshotting writes-before-first-await\n // but the simpler whole-store snapshot is always correct (the cost is\n // a single `Map` clone — negligible).\n const snapshot: Map<string, StateValue> | null = decl.optimistic\n ? snapshotState(this.options.state)\n : null;\n try {\n let lastValue: unknown;\n for (const stmt of decl.body.body) {\n lastValue = await this.runStatement(stmt, ctx, decl, args);\n }\n this.options.notify();\n return lastValue;\n } catch (err) {\n if (snapshot) {\n restoreState(this.options.state, snapshot);\n this.options.notify();\n }\n // eslint-disable-next-line no-console\n console.error(`[aktion] action \"${decl.name}\" failed`, err);\n throw err;\n } finally {\n for (const slot of restore) {\n if (slot.had) ctx.loopVars.set(slot.name, slot.prev);\n else ctx.loopVars.delete(slot.name);\n }\n }\n }\n\n private async runStatement(\n stmt: Statement,\n ctx: EvaluationContext,\n decl: ActionDeclaration,\n args: Record<string, unknown>,\n ): Promise<unknown> {\n switch (stmt.kind) {\n case \"ExpressionStatement\": {\n const expr = stmt.expression;\n if (expr.kind === \"JsBlock\") {\n const result = executeJsBlock(\n expr.body,\n decl.name,\n ctx,\n this.options,\n undefined,\n args,\n );\n return await unwrapPromise(result);\n }\n const value = evaluate(expr, ctx);\n return await unwrapPromise(value);\n }\n case \"Await\": {\n const value = evaluate(stmt.argument, ctx);\n return await unwrapPromise(value);\n }\n case \"Assignment\": {\n const value = await unwrapPromise(evaluate(stmt.expression, ctx));\n if (stmt.identifier) {\n // Resolve through the per-instance alias stack so an `action`\n // declared inside a `component` body writes the right slot (§7).\n const target = resolveStateAlias(ctx, stmt.identifier);\n this.options.state.set(target, value as StateValue);\n }\n return value;\n }\n case \"Return\": {\n if (!stmt.argument) return undefined;\n return await unwrapPromise(evaluate(stmt.argument, ctx));\n }\n case \"Emit\": {\n const detail = evaluate(stmt.detail, ctx);\n this.options.onEmit?.(stmt.eventName, detail);\n return undefined;\n }\n default:\n return undefined;\n }\n }\n}\n\nasync function unwrapPromise(value: unknown): Promise<unknown> {\n if (value && typeof (value as { then?: unknown }).then === \"function\") {\n return await (value as Promise<unknown>);\n }\n return value;\n}\n\nfunction snapshotState(state: StateStore): Map<string, StateValue> {\n const out = new Map<string, StateValue>();\n for (const [name, value] of state.entries()) {\n out.set(name, value);\n }\n return out;\n}\n\nfunction restoreState(state: StateStore, snapshot: Map<string, StateValue>): void {\n for (const [name, value] of snapshot) {\n state.set(name, value);\n }\n}\n","/**\n * Font Awesome integration for `<aktion-app>`.\n *\n * Icons across the library are referenced by Font Awesome name (without the\n * `fa-` prefix). The optional `variant:` prefix (`solid:`, `regular:`,\n * `brands:`) picks the FA style — when omitted, it defaults to `solid`.\n *\n * The custom element auto-loads the CDN stylesheet on connect (once per\n * page and once per shadow root) so host apps do not have to add anything\n * to make icons render.\n */\n\nexport const FONT_AWESOME_CDN_URL =\n \"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css\";\n\nexport const FONT_AWESOME_VERSION = \"6.7.2\";\n\nconst LINK_MARKER_ATTR = \"data-rui-font-awesome\";\n\nconst SUPPORTED_VARIANTS = new Set([\"solid\", \"regular\", \"brands\"]);\n\nconst DEFAULT_VARIANT = \"solid\";\n\n/**\n * Inject the Font Awesome stylesheet into `document.head` (once per page)\n * and into the given shadow root (once per instance) so icon classes\n * resolve both outside and inside the custom element.\n *\n * Safe to call from every `connectedCallback`.\n */\nexport function ensureFontAwesomeLoaded(shadow: ShadowRoot): void {\n if (typeof document !== \"undefined\") {\n injectLink(document.head, document);\n }\n injectLink(shadow, shadow.ownerDocument ?? document);\n}\n\nfunction injectLink(root: ParentNode, doc: Document): void {\n // happy-dom logs disallowed external stylesheet loads to stderr before\n // throwing, so a plain try/catch isn't enough to keep the test output\n // clean. Detect the test environment and skip — there is no browser to\n // render icons into anyway.\n if (isHappyDomEnvironment()) return;\n\n const existing = root.querySelector(\n `link[${LINK_MARKER_ATTR}=\"${FONT_AWESOME_VERSION}\"]`,\n );\n if (existing) return;\n const link = doc.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = FONT_AWESOME_CDN_URL;\n link.setAttribute(LINK_MARKER_ATTR, FONT_AWESOME_VERSION);\n try {\n root.appendChild(link);\n } catch {\n // Defensive: some DOM implementations may still throw when appending an\n // external stylesheet. Production browsers never throw here.\n }\n}\n\nfunction isHappyDomEnvironment(): boolean {\n const g = globalThis as { happyDOM?: unknown };\n return typeof g.happyDOM !== \"undefined\";\n}\n\n/**\n * Resolve a Aktion icon string into Font Awesome class tokens.\n *\n * - `\"house\"` → `[\"fa-solid\", \"fa-house\"]`\n * - `\"regular:star\"` → `[\"fa-regular\", \"fa-star\"]`\n * - `\"brands:github\"` → `[\"fa-brands\", \"fa-github\"]`\n *\n * Invisible Unicode glyph modifiers (variation selectors U+FE0E/U+FE0F and\n * the zero-width joiner U+200D) are stripped before validation — they often\n * sneak in when an LLM copies an FA name out of a doc that previously used\n * an emoji glyph, and would otherwise break ASCII-only validation.\n *\n * Returns an empty array for blank input or names that contain non-ASCII\n * characters (legacy emoji input — the caller renders those inline as text).\n */\nexport function resolveIconClasses(value: unknown): string[] {\n if (typeof value !== \"string\") return [];\n const sanitized = stripInvisibleModifiers(value).trim();\n if (!sanitized) return [];\n if (!isAsciiIconName(sanitized)) return [];\n\n const [variant, name] = splitVariant(sanitized);\n if (!name) return [];\n return [`fa-${variant}`, `fa-${name}`];\n}\n\nconst INVISIBLE_MODIFIER_RE = /[\\uFE0E\\uFE0F\\u200D\\u200C\\uFEFF]/g;\n\nfunction stripInvisibleModifiers(input: string): string {\n return input.replace(INVISIBLE_MODIFIER_RE, \"\");\n}\n\n/**\n * True when the value should be treated as a Font Awesome name (vs legacy\n * emoji text that the renderer should print inline).\n */\nexport function isIconName(value: unknown): value is string {\n return resolveIconClasses(value).length > 0;\n}\n\nfunction splitVariant(input: string): [string, string] {\n const idx = input.indexOf(\":\");\n if (idx === -1) return [DEFAULT_VARIANT, input];\n const variant = input.slice(0, idx).trim().toLowerCase();\n const name = input.slice(idx + 1).trim();\n if (!SUPPORTED_VARIANTS.has(variant)) return [DEFAULT_VARIANT, name || input];\n return [variant, name];\n}\n\nfunction isAsciiIconName(value: string): boolean {\n // FA names are kebab-case ASCII (letters, digits, dashes). Allow the\n // optional `variant:` prefix. Anything else (emoji, accented text)\n // falls back to inline text rendering.\n return /^[a-zA-Z0-9:_-]+$/.test(value);\n}\n\nexport const ICON_SIZES = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\"] as const;\nexport type IconSize = (typeof ICON_SIZES)[number];\n\nexport function isIconSize(value: unknown): value is IconSize {\n return typeof value === \"string\" && (ICON_SIZES as readonly string[]).includes(value);\n}\n","/**\n * DOM helpers shared by built-in components.\n */\n\nimport { resolveIconClasses, type IconSize } from \"../icons/index.js\";\n\nexport function el<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Record<string, string | number | boolean | null | undefined>,\n children?: ReadonlyArray<Node | string | null | undefined>,\n): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n if (attrs) {\n for (const [key, value] of Object.entries(attrs)) {\n if (value === null || value === undefined || value === false) continue;\n if (key === \"class\") node.setAttribute(\"class\", String(value));\n else if (key === \"html\") node.innerHTML = String(value);\n else if (value === true) node.setAttribute(key, \"\");\n else node.setAttribute(key, String(value));\n }\n }\n if (children) {\n for (const child of children) {\n if (child === null || child === undefined) continue;\n node.append(typeof child === \"string\" ? document.createTextNode(child) : child);\n }\n }\n return node;\n}\n\nexport function text(value: unknown): string {\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n return String(value);\n}\n\nexport function classNames(...parts: Array<string | false | null | undefined>): string {\n return parts.filter(Boolean).join(\" \");\n}\n\nexport function asArray<T>(value: unknown): T[] {\n if (Array.isArray(value)) return value as T[];\n if (value === null || value === undefined) return [];\n return [value as T];\n}\n\nexport function asString(value: unknown, fallback = \"\"): string {\n if (value === null || value === undefined) return fallback;\n if (typeof value === \"string\") return value;\n return String(value);\n}\n\nexport function asBoolean(value: unknown, fallback = false): boolean {\n if (typeof value === \"boolean\") return value;\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n if (value === null || value === undefined) return fallback;\n return Boolean(value);\n}\n\nexport function asNumber(value: unknown, fallback = 0): number {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\" && value.trim() !== \"\") {\n const n = Number(value);\n if (!Number.isNaN(n)) return n;\n }\n return fallback;\n}\n\n/**\n * Breakpoint keys honoured by responsive prop maps (Grid columns, Stack\n * direction, etc.). Ordered from narrow → wide so CSS only needs to chain\n * one `min-width` per breakpoint and naturally cascades.\n */\nexport const RESPONSIVE_BREAKPOINTS = [\"base\", \"sm\", \"md\", \"lg\", \"xl\"] as const;\nexport type Breakpoint = typeof RESPONSIVE_BREAKPOINTS[number];\n\n/**\n * Normalise a prop value that may be a single value or a responsive map\n * like `{sm: 1, md: 2, lg: 4}`. Returns either:\n * - `{kind: \"single\", value}` — caller should use the value directly\n * - `{kind: \"responsive\", values}` — caller should emit CSS variables /\n * data attributes for each breakpoint\n *\n * A bare key without a breakpoint prefix (e.g. `{value: 2}`) collapses to\n * a single-value result. Unknown breakpoint keys are ignored so typos\n * don't crash the page.\n */\nexport type ResponsiveProp<T> =\n | { kind: \"single\"; value: T | null }\n | { kind: \"responsive\"; values: Partial<Record<Breakpoint, T>> };\n\nexport function readResponsiveProp<T>(value: unknown): ResponsiveProp<T> {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) {\n return { kind: \"single\", value: (value ?? null) as T | null };\n }\n const entries = Object.entries(value as Record<string, unknown>);\n const values: Partial<Record<Breakpoint, T>> = {};\n let matched = false;\n for (const [key, raw] of entries) {\n if ((RESPONSIVE_BREAKPOINTS as readonly string[]).includes(key)) {\n values[key as Breakpoint] = raw as T;\n matched = true;\n }\n }\n if (!matched) {\n // Caller passed a non-responsive object — treat as a single value\n // (probably a component-config object the caller passes through).\n return { kind: \"single\", value: value as T };\n }\n return { kind: \"responsive\", values };\n}\n\n/**\n * Strip characters that would let an LLM-supplied string break out of a\n * `url(\"...\")` literal embedded in an inline `style` attribute. We keep the\n * common allowed URL characters and drop anything that could close the\n * literal, terminate the declaration, or introduce another rule. Returns an\n * empty string for non-string / blank input so callers can render a tasteful\n * fallback rather than a malformed `url(\"\")`.\n */\nconst CSS_URL_FORBIDDEN = /[\"'\\\\\\n\\r<>;{}]/g;\nexport function sanitiseCssUrl(raw: string): string {\n if (!raw) return \"\";\n return raw.replace(CSS_URL_FORBIDDEN, \"\").trim();\n}\n\n/**\n * Validate a CSS length / dimension value (`280px`, `40vh`, `clamp(...)`,\n * `calc(...)`) so an LLM-supplied string cannot inject extra declarations\n * through an inline `style` attribute. We accept a small alphabet that covers\n * every standard CSS length token; anything outside that — or values that\n * are unreasonably long — falls back to `fallback`.\n */\nconst CSS_LENGTH_ALLOWED = /^[a-zA-Z0-9.%+\\-*/\\s(),]+$/;\nexport function sanitiseCssLength(raw: unknown, fallback: string): string {\n const trimmed = (asString(raw) ?? \"\").trim();\n if (!trimmed) return fallback;\n if (trimmed.length > 64) return fallback;\n if (!CSS_LENGTH_ALLOWED.test(trimmed)) return fallback;\n return trimmed;\n}\n\n/**\n * URL schemes that are allowed in anchor `href` and `window.open` targets.\n * Anything outside this allow-list (notably `javascript:`, `vbscript:`,\n * `data:` text payloads, `file:`) is rewritten to a safe placeholder so a\n * hostile LLM/tool response cannot smuggle script execution into a click.\n */\nconst SAFE_HREF_SCHEMES = new Set([\"http\", \"https\", \"mailto\", \"tel\"]);\n\n/**\n * Sanitise an LLM-supplied `href` value before it lands on an anchor.\n *\n * - Fragments (`#anchor`), root-relative paths (`/about`), and pure query\n * strings (`?q=foo`) are kept verbatim.\n * - Absolute URLs with an allow-listed scheme (`http`, `https`, `mailto`,\n * `tel`) are kept verbatim.\n * - Anything else — `javascript:`, `vbscript:`, `data:text/html`,\n * `file:`, protocol-relative `//host/path`, control characters — collapses\n * to `fallback` (default `\"#\"`) so the click never navigates anywhere\n * dangerous.\n *\n * This is the single chokepoint every component should call before assigning\n * `href`. The Markdown renderer has its own (stricter, HTML-escaping)\n * sibling, but the validation rules match so behaviour stays consistent.\n */\nexport function sanitiseHref(raw: unknown, fallback = \"#\"): string {\n const value = asString(raw).trim();\n if (!value) return fallback;\n // Strip control characters (including TAB / LF / CR) before scheme\n // detection — `java\\tscript:` is a well-known browser-tolerated bypass.\n // eslint-disable-next-line no-control-regex\n const cleaned = value.replace(/[\\u0000-\\u001F\\u007F]/g, \"\");\n if (!cleaned) return fallback;\n // Protocol-relative URLs (`//host/path`) inherit the page scheme and can\n // navigate to a hostile origin, so they are treated as unsafe.\n if (cleaned.startsWith(\"//\")) return fallback;\n // Same-origin shapes — fragments, root-relative, query-only — are safe.\n if (\n cleaned.startsWith(\"#\") ||\n cleaned.startsWith(\"/\") ||\n cleaned.startsWith(\"?\") ||\n cleaned.startsWith(\".\")\n ) {\n return cleaned;\n }\n const schemeMatch = /^([a-zA-Z][a-zA-Z0-9+.\\-]*):/.exec(cleaned);\n if (!schemeMatch) {\n // No scheme = a relative path like `about.html` or `page#foo`.\n return cleaned;\n }\n const scheme = schemeMatch[1]!.toLowerCase();\n if (!SAFE_HREF_SCHEMES.has(scheme)) return fallback;\n return cleaned;\n}\n\n/**\n * URL schemes that are safe to render inside an `<img src>`. Browsers do not\n * execute JavaScript from `img.src`, but a hostile `data:text/html` (in\n * theory ignored by image decoders), `javascript:`, or `vbscript:` is still\n * worth rejecting to keep the surface predictable for downstream consumers\n * that may copy `src` into other attribute slots.\n */\nconst SAFE_IMAGE_SCHEMES = new Set([\"http\", \"https\", \"data\", \"blob\"]);\n\n/**\n * Sanitise an LLM-supplied image `src` before it lands on an `<img>`.\n *\n * Relative paths and same-origin shapes are kept as-is. Absolute URLs with\n * an allow-listed scheme (`http`, `https`, `data`, `blob`) are kept. Anything\n * else (`javascript:`, `vbscript:`, `file:`, …) returns the empty string so\n * callers can render their own placeholder.\n */\nexport function sanitiseImageSrc(raw: unknown): string {\n const value = asString(raw).trim();\n if (!value) return \"\";\n // eslint-disable-next-line no-control-regex\n const cleaned = value.replace(/[\\u0000-\\u001F\\u007F]/g, \"\");\n if (!cleaned) return \"\";\n // Protocol-relative is fine for images (browsers resolve to current scheme)\n // but we still bail because it leaks the host scheme into a foreign origin.\n if (cleaned.startsWith(\"//\")) return \"\";\n if (\n cleaned.startsWith(\"/\") ||\n cleaned.startsWith(\".\") ||\n cleaned.startsWith(\"?\") ||\n cleaned.startsWith(\"#\")\n ) {\n return cleaned;\n }\n const schemeMatch = /^([a-zA-Z][a-zA-Z0-9+.\\-]*):/.exec(cleaned);\n if (!schemeMatch) return cleaned;\n const scheme = schemeMatch[1]!.toLowerCase();\n if (!SAFE_IMAGE_SCHEMES.has(scheme)) return \"\";\n // For `data:` URLs, only allow `image/*` payloads — `data:text/html` would\n // render markup if a host accidentally copies the src into another sink.\n if (scheme === \"data\" && !/^data:image\\//i.test(cleaned)) return \"\";\n return cleaned;\n}\n\n/**\n * Render an icon-typed prop into an `<i class=\"rui-icon fa-...\">` element.\n *\n * Falls back to a `<span>` containing the raw string when the value is not\n * a Font Awesome name (legacy emoji input). Returns `null` when the value\n * is empty / nullish so callers can short-circuit.\n */\nexport function renderIcon(\n value: unknown,\n options: { className?: string; size?: IconSize | string } = {},\n): HTMLElement | null {\n const text = asString(value);\n if (!text) return null;\n const classes = resolveIconClasses(text);\n const wrapperClass = [\"rui-icon\", options.className].filter(Boolean).join(\" \");\n if (classes.length === 0) {\n return el(\"span\", {\n class: wrapperClass,\n \"data-icon-size\": options.size ?? null,\n }, [text]);\n }\n return el(\"i\", {\n class: `${wrapperClass} ${classes.join(\" \")}`,\n \"data-icon-size\": options.size ?? null,\n \"aria-hidden\": \"true\",\n });\n}\n","/**\n * Layout components: Stack, StackItem, Grid, GridItem, Box, Card, CardHeader,\n * CardFooter, Tabs, TabItem, Accordion, AccordionItem,\n * Modal, AspectRatio, ScrollArea.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport {\n el, asArray, asString, asBoolean, asNumber, renderIcon, sanitiseCssLength,\n readResponsiveProp, RESPONSIVE_BREAKPOINTS, type Breakpoint, type ResponsiveProp,\n} from \"../utils.js\";\n\nconst GRID_COLUMNS = 12;\n\nconst FLEX_ALIGN: Record<string, string> = {\n start: \"flex-start\",\n center: \"center\",\n end: \"flex-end\",\n stretch: \"stretch\",\n};\n\nconst FLEX_JUSTIFY: Record<string, string> = {\n start: \"flex-start\",\n center: \"center\",\n end: \"flex-end\",\n between: \"space-between\",\n around: \"space-around\",\n evenly: \"space-evenly\",\n};\n\nfunction mapFlexAlign(token: string): string {\n return FLEX_ALIGN[token] ?? \"stretch\";\n}\n\nfunction mapFlexJustify(token: string): string {\n return FLEX_JUSTIFY[token] ?? \"flex-start\";\n}\n\nfunction applyDirectionWithReverse(value: string, reverse: boolean): string {\n if (!reverse) return value;\n if (value === \"row\") return \"row-reverse\";\n if (value === \"column\") return \"column-reverse\";\n if (value.endsWith(\"-reverse\")) return value;\n return `${value}-reverse`;\n}\n\nfunction emitResponsiveSpacingVars(\n styleParts: string[],\n prop: Extract<ResponsiveProp<string>, { kind: \"responsive\" }>,\n cssPrefix: string,\n): void {\n for (const bp of RESPONSIVE_BREAKPOINTS) {\n const v = prop.values[bp];\n if (v) styleParts.push(`${cssPrefix}-${bp}:var(--rui-spacing-${v}, ${v})`);\n }\n}\n\nfunction emitResponsiveFlexVars(\n styleParts: string[],\n prop: Extract<ResponsiveProp<string>, { kind: \"responsive\" }>,\n cssPrefix: string,\n mapper: (token: string) => string,\n): void {\n for (const bp of RESPONSIVE_BREAKPOINTS) {\n const v = prop.values[bp];\n if (v) styleParts.push(`${cssPrefix}-${bp}:${mapper(String(v))}`);\n }\n}\n\nfunction applyResponsiveEnumProp(\n value: unknown,\n styleParts: string[],\n attrs: Record<string, string | null>,\n options: {\n attrName: string;\n responsiveFlag: string;\n cssVarPrefix: string;\n defaultToken: string;\n mapper: (token: string) => string;\n },\n): void {\n const parsed = readResponsiveProp<string>(value);\n if (parsed.kind === \"single\") {\n const token = parsed.value ? String(parsed.value) : options.defaultToken;\n attrs[options.attrName] = token;\n return;\n }\n attrs[options.attrName] = \"responsive\";\n attrs[options.responsiveFlag] = \"true\";\n emitResponsiveFlexVars(styleParts, parsed, options.cssVarPrefix, options.mapper);\n}\n\nfunction isComponentNamed(value: unknown, name: string): boolean {\n return Boolean(\n value\n && typeof value === \"object\"\n && (value as { __kind?: string }).__kind === \"Component\"\n && (value as { name?: string }).name === name,\n );\n}\n\nfunction stackBaseDirection(props: Record<string, unknown>): string {\n const direction = readResponsiveProp<string>(props.direction);\n if (direction.kind === \"single\") {\n return direction.value ? String(direction.value) : \"column\";\n }\n return direction.values.base ? String(direction.values.base) : \"column\";\n}\n\nexport const StackItem: ComponentSpec = {\n name: \"StackItem\",\n description:\n \"Wraps a single child in a flex item with explicit grow/shrink/basis, \" +\n \"alignment, and order. Use inside `Stack` when the default row flex \" +\n \"growth would stretch toolbars, chips, or asymmetric layouts.\",\n props: [\n { name: \"child\", type: \"Node\", description: \"Child node to wrap\" },\n { name: \"grow\", type: \"number\", optional: true, description: \"flex-grow (0 or 1 typical)\" },\n { name: \"shrink\", type: \"number\", optional: true, description: \"flex-shrink (0 or 1 typical)\" },\n { name: \"basis\", type: \"string\", optional: true, description: \"flex-basis (`auto`, `0`, or CSS length)\" },\n { name: \"alignSelf\", type: \"string\", optional: true, enum: [\"start\", \"center\", \"end\", \"stretch\"], description: \"Per-item cross-axis alignment\" },\n { name: \"order\", type: \"number\", optional: true, description: \"Visual order override\" },\n { name: \"minWidth\", type: \"string\", optional: true, description: \"CSS min-width\" },\n { name: \"maxWidth\", type: \"string\", optional: true, description: \"CSS max-width\" },\n ],\n render: (_node, props, helpers) => {\n const attrs: Record<string, string | null> = { class: \"rui-stack-item\" };\n const styleParts: string[] = [];\n if (props.grow !== undefined && props.grow !== null) {\n attrs[\"data-grow\"] = String(asNumber(props.grow, 0));\n }\n if (props.shrink !== undefined && props.shrink !== null) {\n attrs[\"data-shrink\"] = String(asNumber(props.shrink, 1));\n }\n const basis = asString(props.basis);\n if (basis === \"auto\" || basis === \"0\") {\n attrs[\"data-basis\"] = basis;\n } else if (basis) {\n styleParts.push(`flex-basis:${sanitiseCssLength(basis, basis)}`);\n }\n const alignSelf = asString(props.alignSelf);\n if (alignSelf) attrs[\"data-align-self\"] = alignSelf;\n if (props.order !== undefined && props.order !== null) {\n const order = asNumber(props.order, 0);\n attrs[\"data-order\"] = String(order);\n styleParts.push(`order:${order}`);\n }\n const minWidth = asString(props.minWidth);\n if (minWidth) styleParts.push(`min-width:${sanitiseCssLength(minWidth, minWidth)}`);\n const maxWidth = asString(props.maxWidth);\n if (maxWidth) styleParts.push(`max-width:${sanitiseCssLength(maxWidth, maxWidth)}`);\n if (styleParts.length > 0) attrs.style = styleParts.join(\";\");\n const root = el(\"div\", attrs);\n root.append(helpers.renderNode(props.child));\n return root;\n },\n};\n\nexport const Stack: ComponentSpec = {\n name: \"Stack\",\n description:\n \"Flex container that arranges children in a row or column. \" +\n \"`direction`, `gap`, `align`, `justify`, and `padding` accept either a \" +\n \"single value OR a responsive map like `{sm: \\\"column\\\", md: \\\"row\\\"}`. \" +\n \"Row stacks grow children uniformly by default (`uniform=true`); set \" +\n \"`uniform=false` or wrap children in `StackItem` for toolbars and \" +\n \"asymmetric rows. Use `reverse` for chat-style column-reverse timelines.\",\n props: [\n { name: \"children\", type: \"Node[]\", description: \"Child components to stack\" },\n { name: \"direction\", type: \"string | object\", optional: true, enum: [\"column\", \"row\"], description: \"Layout direction (default column). May be a responsive map.\" },\n { name: \"gap\", type: \"string | object\", optional: true, enum: [\"xs\", \"s\", \"m\", \"l\", \"xl\"], description: \"Spacing between children. May be a responsive map.\" },\n { name: \"align\", type: \"string | object\", optional: true, enum: [\"start\", \"center\", \"end\", \"stretch\"], description: \"Cross-axis alignment. May be a responsive map.\" },\n { name: \"justify\", type: \"string | object\", optional: true, enum: [\"start\", \"center\", \"end\", \"between\", \"around\", \"evenly\"], description: \"Main-axis alignment. May be a responsive map.\" },\n { name: \"alignContent\", type: \"string\", optional: true, enum: [\"start\", \"center\", \"end\", \"between\", \"around\", \"stretch\"], description: \"Multi-line wrap alignment\" },\n { name: \"wrap\", type: \"boolean\", optional: true, description: \"Allow wrapping\" },\n { name: \"reverse\", type: \"boolean\", optional: true, description: \"Reverse main-axis order (column-reverse / row-reverse)\" },\n { name: \"uniform\", type: \"boolean\", optional: true, description: \"Row children share space equally (default true for row stacks)\" },\n { name: \"inline\", type: \"boolean\", optional: true, description: \"Use inline-flex instead of flex\" },\n { name: \"padding\", type: \"string | object\", optional: true, enum: [\"xs\", \"s\", \"m\", \"l\", \"xl\"], description: \"Inner padding token. May be a responsive map.\" },\n ],\n render: (_node, props, helpers) => {\n const direction = readResponsiveProp<string>(props.direction);\n const gap = readResponsiveProp<string>(props.gap);\n const padding = readResponsiveProp<string>(props.padding);\n const reverse = asBoolean(props.reverse);\n const baseDir = stackBaseDirection(props);\n const uniformDefault = baseDir === \"row\";\n const uniform = props.uniform === undefined\n ? uniformDefault\n : asBoolean(props.uniform, uniformDefault);\n const attrs: Record<string, string | null> = {\n class: \"rui-stack\",\n \"data-wrap\": asBoolean(props.wrap) ? \"true\" : null,\n \"data-reverse\": reverse ? \"true\" : null,\n \"data-uniform\": uniform ? \"true\" : \"false\",\n \"data-inline\": asBoolean(props.inline) ? \"true\" : null,\n };\n const styleParts: string[] = [];\n if (direction.kind === \"single\") {\n const dir = direction.value ? String(direction.value) : \"column\";\n attrs[\"data-direction\"] = applyDirectionWithReverse(dir, reverse);\n } else {\n attrs[\"data-direction\"] = \"responsive\";\n attrs[\"data-responsive-dir\"] = \"true\";\n for (const bp of RESPONSIVE_BREAKPOINTS) {\n const v = direction.values[bp];\n if (v) styleParts.push(`--rui-stack-dir-${bp}:${applyDirectionWithReverse(String(v), reverse)}`);\n }\n }\n if (gap.kind === \"single\") {\n attrs[\"data-gap\"] = gap.value ? String(gap.value) : \"m\";\n } else {\n attrs[\"data-gap\"] = \"responsive\";\n attrs[\"data-responsive-gap\"] = \"true\";\n emitResponsiveSpacingVars(styleParts, gap, \"--rui-stack-gap\");\n }\n applyResponsiveEnumProp(props.align, styleParts, attrs, {\n attrName: \"data-align\",\n responsiveFlag: \"data-responsive-align\",\n cssVarPrefix: \"--rui-stack-align\",\n defaultToken: \"stretch\",\n mapper: mapFlexAlign,\n });\n applyResponsiveEnumProp(props.justify, styleParts, attrs, {\n attrName: \"data-justify\",\n responsiveFlag: \"data-responsive-justify\",\n cssVarPrefix: \"--rui-stack-justify\",\n defaultToken: \"start\",\n mapper: mapFlexJustify,\n });\n const alignContent = asString(props.alignContent);\n if (alignContent) attrs[\"data-align-content\"] = alignContent;\n if (padding.kind === \"single\") {\n const pad = padding.value ? String(padding.value) : null;\n if (pad) attrs[\"data-padding\"] = pad;\n } else {\n attrs[\"data-padding\"] = \"responsive\";\n attrs[\"data-responsive-padding\"] = \"true\";\n emitResponsiveSpacingVars(styleParts, padding, \"--rui-stack-padding\");\n }\n if (styleParts.length > 0) attrs.style = styleParts.join(\";\");\n const root = el(\"div\", attrs);\n for (const child of asArray(props.children)) {\n root.append(helpers.renderNode(child));\n }\n return root;\n },\n};\n\nexport const Card: ComponentSpec = {\n name: \"Card\",\n description: \"Vertical card container.\",\n props: [\n { name: \"children\", type: \"Node[]\", description: \"Card contents\" },\n { name: \"variant\", type: \"string\", optional: true, enum: [\"default\", \"outlined\", \"elevated\"] },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", {\n class: \"rui-card\",\n \"data-variant\": asString(props.variant, \"default\"),\n });\n for (const child of asArray(props.children)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nexport const CardHeader: ComponentSpec = {\n name: \"CardHeader\",\n description: \"Card header with title and optional subtitle.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"subtitle\", type: \"string\", optional: true },\n ],\n render: (_node, props) => {\n const root = el(\"header\", { class: \"rui-card-header\" });\n root.append(el(\"h3\", { class: \"rui-card-title\" }, [asString(props.title)]));\n const subtitle = asString(props.subtitle);\n if (subtitle) root.append(el(\"p\", { class: \"rui-card-subtitle\" }, [subtitle]));\n return root;\n },\n};\n\nexport const CardFooter: ComponentSpec = {\n name: \"CardFooter\",\n description: \"Card footer for actions.\",\n props: [{ name: \"children\", type: \"Node[]\" }],\n render: (_node, props, helpers) => {\n const root = el(\"footer\", { class: \"rui-card-footer\" });\n for (const child of asArray(props.children)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nexport const Separator: ComponentSpec = {\n name: \"Separator\",\n description:\n \"Visual divider between content sections. Supports horizontal or \" +\n \"vertical orientation, and an optional center `label` (lifted from \" +\n \"the legacy `Divider`). Use `decorative=false` to expose the \" +\n \"separator to assistive tech.\",\n props: [\n { name: \"orientation\", type: \"string\", optional: true, enum: [\"horizontal\", \"vertical\"] },\n { name: \"label\", type: \"string\", optional: true, description: \"Optional label rendered in the middle (horizontal only)\" },\n { name: \"decorative\", type: \"boolean\", optional: true, description: \"Hides the separator from assistive tech when true (default)\" },\n ],\n render: (_node, props) => {\n const orientation = asString(props.orientation, \"horizontal\");\n const decorative = asBoolean(props.decorative, true);\n const label = asString(props.label);\n if (label && orientation === \"horizontal\") {\n return el(\"div\", {\n class: \"rui-separator rui-separator-with-label\",\n \"data-orientation\": orientation,\n role: decorative ? \"presentation\" : \"separator\",\n \"aria-orientation\": decorative ? null : orientation,\n }, [\n el(\"span\", { class: \"rui-separator-line\" }),\n el(\"span\", { class: \"rui-separator-label\" }, [label]),\n el(\"span\", { class: \"rui-separator-line\" }),\n ]);\n }\n return el(\"div\", {\n class: \"rui-separator\",\n \"data-orientation\": orientation,\n role: decorative ? \"presentation\" : \"separator\",\n \"aria-orientation\": decorative ? null : orientation,\n });\n },\n};\n\nconst renderStepLi = (title: string, details: string, active = false): HTMLElement => {\n const root = el(\"li\", {\n class: \"rui-steps-item\",\n \"data-active\": active ? \"true\" : \"false\",\n });\n root.append(el(\"div\", { class: \"rui-steps-title\" }, [title]));\n if (details) root.append(el(\"div\", { class: \"rui-steps-details\" }, [details]));\n return root;\n};\n\nexport const Steps: ComponentSpec = {\n name: \"Steps\",\n description:\n \"Numbered step-by-step guide. Pass items as `{title, details?, active?}` \" +\n \"objects. Use `active` to mark the current step in a multi-step flow.\",\n props: [\n { name: \"items\", type: \"object[]\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"ol\", { class: \"rui-steps\" });\n for (const item of asArray<unknown>(props.items)) {\n if (item && typeof item === \"object\" && (item as { __kind?: string }).__kind === \"Component\") {\n root.append(helpers.renderNode(item));\n continue;\n }\n if (item && typeof item === \"object\") {\n const data = item as { title?: unknown; details?: unknown; active?: unknown };\n root.append(renderStepLi(\n asString(data.title),\n asString(data.details),\n asBoolean(data.active),\n ));\n continue;\n }\n // Plain string falls back to a title-only step.\n root.append(renderStepLi(asString(item), \"\"));\n }\n return root;\n },\n};\n\nexport const TabItem: ComponentSpec = {\n name: \"TabItem\",\n description:\n \"Single tab definition (used inside Tabs). Add `badge` for a count \" +\n \"chip in the tab trigger, and `icon` for a leading Font Awesome icon.\",\n props: [\n { name: \"value\", type: \"string\", description: \"Stable identifier for the tab\" },\n { name: \"label\", type: \"string\", description: \"Display label\" },\n { name: \"children\", type: \"Node[]\", description: \"Tab content\" },\n { name: \"badge\", type: \"string\", optional: true, description: \"Trailing chip rendered in the tab trigger (count / status)\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Optional Font Awesome icon name shown before the label\" },\n ],\n render: (_node, props, helpers) => {\n const wrapper = el(\"div\", {\n class: \"rui-tab-content\",\n role: \"tabpanel\",\n \"data-value\": asString(props.value),\n \"data-active\": \"false\",\n });\n for (const child of asArray(props.children)) wrapper.append(helpers.renderNode(child));\n return wrapper;\n },\n};\n\nexport const Tabs: ComponentSpec = {\n name: \"Tabs\",\n description:\n \"Tabbed container. Children must be TabItem components. Supports \" +\n \"`orientation=\\\"vertical\\\"` for sidebar-style tabs and built-in \" +\n \"keyboard navigation (←/→ or ↑/↓, Home, End).\",\n props: [\n { name: \"items\", type: \"TabItem[]\", description: \"Tab definitions\" },\n { name: \"defaultValue\", type: \"string\", optional: true, description: \"Initially active tab value\" },\n { name: \"orientation\", type: \"string\", optional: true, enum: [\"horizontal\", \"vertical\"], description: \"Layout direction (default `horizontal`)\" },\n ],\n render: (_node, props, helpers) => {\n const items = asArray<unknown>(props.items);\n const orientation = asString(props.orientation, \"horizontal\");\n const root = el(\"div\", { class: \"rui-tabs\", \"data-orientation\": orientation });\n const tablist = el(\"div\", {\n class: \"rui-tab-list\",\n role: \"tablist\",\n \"aria-orientation\": orientation,\n });\n const panels = el(\"div\", { class: \"rui-tab-panels\" });\n\n // Compute the falsy-default tab value (LLM-supplied `defaultValue` or\n // the first item) so we can seed the persistent active slot when the\n // user has never interacted with this Tabs instance.\n let fallbackValue = asString(props.defaultValue);\n if (!fallbackValue && items.length > 0) {\n const first = items[0] as { args?: unknown[] } | undefined;\n fallbackValue = asString(first?.args?.[0], \"tab-0\");\n }\n\n // Persist the active tab across re-renders. Without this slot the active\n // pane would jump back to `defaultValue` every time an unrelated state\n // change re-renders the tree (e.g. typing into an Input one panel over).\n const activeSlot = helpers.useInstanceState<string>(\"activeTab\", fallbackValue);\n\n // If `defaultValue` was changed by the LLM since last render, honour the\n // new prop. This lets host code drive the active tab via state without\n // breaking the persistence behaviour for user-initiated clicks.\n if (asString(props.defaultValue) && asString(props.defaultValue) !== fallbackValue) {\n activeSlot.set(asString(props.defaultValue));\n }\n\n // Make sure the persisted value still refers to a tab that exists —\n // the LLM may have removed the previously-active tab mid-stream.\n const validValues = new Set(\n items.map((item, idx) => asString((item as { args?: unknown[] }).args?.[0], `tab-${idx}`)),\n );\n if (!validValues.has(activeSlot.get())) {\n activeSlot.set(fallbackValue);\n }\n\n // setActive walks the LIVE DOM (via the clicked button's ancestor chain)\n // instead of the local `tablist` / `panels` closure variables. With the\n // morph reconciler in place, an unrelated re-render may produce a fresh\n // Tabs subtree whose onclick handlers get copied onto the previously\n // mounted nodes — the closures' local refs point at the discarded fresh\n // subtree, but `event.currentTarget` is always the in-DOM button.\n const setActive = (next: string, originBtn: Element): void => {\n activeSlot.set(next);\n const liveRoot = originBtn.closest(\".rui-tabs\");\n if (!liveRoot) return;\n liveRoot.querySelectorAll<HTMLButtonElement>(\".rui-tab-trigger\").forEach((b) => {\n const isActive = b.getAttribute(\"data-value\") === next;\n b.setAttribute(\"aria-selected\", isActive ? \"true\" : \"false\");\n b.tabIndex = isActive ? 0 : -1;\n });\n liveRoot.querySelectorAll<HTMLElement>(\".rui-tab-content\").forEach((p) => {\n p.setAttribute(\"data-active\", p.getAttribute(\"data-value\") === next ? \"true\" : \"false\");\n });\n };\n\n items.forEach((item, idx) => {\n const tabNode = item as { name?: string; args?: unknown[] };\n const value = asString(tabNode.args?.[0], `tab-${idx}`);\n const label = asString(tabNode.args?.[1], `Tab ${idx + 1}`);\n const badge = asString(tabNode.args?.[3]);\n const icon = asString(tabNode.args?.[4]);\n const isActive = value === activeSlot.get();\n const button = el(\n \"button\",\n {\n class: \"rui-tab-trigger\",\n role: \"tab\",\n type: \"button\",\n \"data-value\": value,\n \"aria-selected\": isActive ? \"true\" : \"false\",\n tabindex: isActive ? \"0\" : \"-1\",\n },\n );\n // We use the icon helper without falling back to inline emoji so that\n // an unset icon prop renders the trigger as label-only.\n const iconNode = icon ? renderIconForTab(icon) : null;\n if (iconNode) button.append(iconNode);\n button.append(el(\"span\", { class: \"rui-tab-trigger-label\" }, [label]));\n if (badge) button.append(el(\"span\", { class: \"rui-tab-trigger-badge\" }, [badge]));\n button.onclick = (event) => {\n const origin = (event.currentTarget ?? event.target) as Element;\n setActive(value, origin);\n };\n // Keyboard navigation between tabs (ArrowLeft/Right/Up/Down/Home/End)\n // resolves the next focusable trigger from the live DOM so it survives\n // morph reconciliation.\n button.onkeydown = (event) => {\n const e = event as KeyboardEvent;\n const horizontal = orientation !== \"vertical\";\n const isNext = horizontal ? e.key === \"ArrowRight\" : e.key === \"ArrowDown\";\n const isPrev = horizontal ? e.key === \"ArrowLeft\" : e.key === \"ArrowUp\";\n if (!isNext && !isPrev && e.key !== \"Home\" && e.key !== \"End\") return;\n e.preventDefault();\n const origin = (e.currentTarget ?? e.target) as Element;\n const liveList = origin.closest(\".rui-tab-list\");\n if (!liveList) return;\n const triggers = Array.from(liveList.querySelectorAll<HTMLButtonElement>(\".rui-tab-trigger\"));\n if (triggers.length === 0) return;\n const currentIdx = triggers.indexOf(origin as HTMLButtonElement);\n let nextIdx = currentIdx;\n if (e.key === \"Home\") nextIdx = 0;\n else if (e.key === \"End\") nextIdx = triggers.length - 1;\n else if (isNext) nextIdx = (currentIdx + 1) % triggers.length;\n else if (isPrev) nextIdx = (currentIdx - 1 + triggers.length) % triggers.length;\n const target = triggers[nextIdx];\n if (!target) return;\n target.focus();\n const nextValue = target.getAttribute(\"data-value\") ?? \"\";\n if (nextValue) setActive(nextValue, target);\n };\n tablist.append(button);\n\n const panel = helpers.renderNode(item) as HTMLElement;\n panel.setAttribute(\"data-value\", value);\n panel.setAttribute(\"data-active\", isActive ? \"true\" : \"false\");\n panels.append(panel);\n });\n\n root.append(tablist, panels);\n return root;\n },\n};\n\nfunction renderIconForTab(iconName: string): HTMLElement | null {\n // Tab triggers use the standard rui-icon helper class so consumers can\n // override icon spacing via theme tokens without touching the trigger.\n return renderIcon(iconName, { className: \"rui-tab-trigger-icon\" });\n}\n\nexport const AccordionItem: ComponentSpec = {\n name: \"AccordionItem\",\n description: \"Single accordion section.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"children\", type: \"Node[]\" },\n { name: \"open\", type: \"boolean\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const details = el(\"details\", { class: \"rui-accordion-item\" });\n if (asBoolean(props.open)) details.setAttribute(\"open\", \"\");\n const summary = el(\"summary\", { class: \"rui-accordion-trigger\" }, [asString(props.title)]);\n details.append(summary);\n const body = el(\"div\", { class: \"rui-accordion-body\" });\n for (const child of asArray(props.children)) body.append(helpers.renderNode(child));\n details.append(body);\n return details;\n },\n};\n\nexport const Accordion: ComponentSpec = {\n name: \"Accordion\",\n description: \"Accordion container. Children must be AccordionItem components.\",\n props: [{ name: \"items\", type: \"AccordionItem[]\" }],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-accordion\" });\n for (const child of asArray(props.items)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nconst clampGridColumns = (n: number): number => Math.max(1, Math.min(GRID_COLUMNS, Math.round(n)));\n\n/** Resolve a grid span from a number or fraction string (e.g. `\"1/3\"` → 4 on a 12-col grid). */\nexport function resolveSpan(span: unknown): number {\n if (span == null || span === \"\") return 12;\n const raw = String(span).trim();\n if (raw.includes(\"/\")) {\n const [numPart, denPart] = raw.split(\"/\");\n const num = Number(numPart);\n const den = Number(denPart);\n if (Number.isFinite(num) && Number.isFinite(den) && den > 0) {\n return clampGridColumns(Math.round((GRID_COLUMNS * num) / den));\n }\n }\n if (raw === \"auto\" || raw === \"fit\" || raw === \"auto-fit\" || raw === \"full\" || raw === \"100%\") return 12;\n return clampGridColumns(asNumber(span, 12));\n}\n\nfunction gridMinChildWidth(props: Record<string, unknown>): string {\n const width = asString(props.minChildWidth) || asString(props.minItemWidth);\n return sanitiseCssLength(width || \"220px\", \"220px\");\n}\n\nexport const GridItem: ComponentSpec = {\n name: \"GridItem\",\n description:\n \"Wraps a child in a 12-column grid cell with `span`, `offset`, and \" +\n \"responsive `spanAt` maps. Parent `Grid` auto-enables 12-column mode \" +\n \"when any child is a `GridItem`. Fraction spans like `\\\"1/3\\\"` resolve \" +\n \"against the 12-column track.\",\n props: [\n { name: \"child\", type: \"Node\", description: \"Child node to place in the grid\" },\n { name: \"span\", type: \"number | string\", optional: true, description: \"Columns to span (1–12) or fraction like \\\"1/2\\\", \\\"1/3\\\"\" },\n { name: \"offset\", type: \"number\", optional: true, description: \"Empty columns before this item (0–11)\" },\n { name: \"spanAt\", type: \"object\", optional: true, description: \"Responsive span map `{sm: 12, md: 6, lg: 4}`\" },\n ],\n render: (_node, props, helpers) => {\n const baseSpan = resolveSpan(props.span ?? 12);\n const spanAt = readResponsiveProp<number | string>(props.spanAt);\n const offset = props.offset === undefined || props.offset === null\n ? 0\n : Math.max(0, Math.min(GRID_COLUMNS - 1, Math.round(asNumber(props.offset, 0))));\n const attrs: Record<string, string | null> = {\n class: \"rui-grid-item\",\n \"data-span\": String(baseSpan),\n };\n const styleParts: string[] = [`--rui-grid-item-span:${baseSpan}`];\n if (offset > 0) {\n attrs[\"data-offset\"] = String(offset);\n styleParts.push(`--rui-grid-item-offset:${offset}`);\n }\n if (spanAt.kind === \"responsive\") {\n attrs[\"data-responsive-span\"] = \"true\";\n for (const bp of RESPONSIVE_BREAKPOINTS) {\n const v = spanAt.values[bp];\n if (v !== undefined) {\n const resolved = resolveSpan(v);\n styleParts.push(`--rui-grid-item-span-${bp}:${resolved}`);\n }\n }\n } else if (spanAt.kind === \"single\" && spanAt.value != null) {\n const resolved = resolveSpan(spanAt.value);\n styleParts.push(`--rui-grid-item-span:${resolved}`);\n attrs[\"data-span\"] = String(resolved);\n }\n attrs.style = styleParts.join(\";\");\n const root = el(\"div\", attrs);\n root.append(helpers.renderNode(props.child));\n return root;\n },\n};\n\nexport const Box: ComponentSpec = {\n name: \"Box\",\n description:\n \"Spacing and surface wrapper for padding, margin, borders, semantic \" +\n \"backgrounds, and max-width constraints. Use when a `Card` is too heavy \" +\n \"but the content needs a subtle surface or inset.\",\n props: [\n { name: \"children\", type: \"Node[]\" },\n { name: \"padding\", type: \"string | object\", optional: true, enum: [\"xs\", \"s\", \"m\", \"l\", \"xl\"], description: \"Inner padding. May be a responsive map.\" },\n { name: \"margin\", type: \"string | object\", optional: true, enum: [\"xs\", \"s\", \"m\", \"l\", \"xl\"], description: \"Outer margin. May be a responsive map.\" },\n { name: \"border\", type: \"string\", optional: true, enum: [\"none\", \"subtle\", \"default\"], description: \"Border preset (default none)\" },\n { name: \"background\", type: \"string\", optional: true, enum: [\"none\", \"surface\", \"muted\", \"primary\", \"success\", \"warning\", \"danger\", \"info\"], description: \"Semantic background token\" },\n { name: \"maxWidth\", type: \"string\", optional: true, description: \"CSS max-width\" },\n ],\n render: (_node, props, helpers) => {\n const padding = readResponsiveProp<string>(props.padding);\n const margin = readResponsiveProp<string>(props.margin);\n const attrs: Record<string, string | null> = {\n class: \"rui-box\",\n \"data-border\": asString(props.border, \"none\"),\n \"data-background\": asString(props.background, \"none\"),\n };\n const styleParts: string[] = [];\n const maxWidth = asString(props.maxWidth);\n if (maxWidth) styleParts.push(`max-width:${sanitiseCssLength(maxWidth, maxWidth)}`);\n if (padding.kind === \"single\") {\n const pad = padding.value ? String(padding.value) : null;\n if (pad) attrs[\"data-padding\"] = pad;\n } else {\n attrs[\"data-padding\"] = \"responsive\";\n attrs[\"data-responsive-padding\"] = \"true\";\n emitResponsiveSpacingVars(styleParts, padding, \"--rui-box-padding\");\n }\n if (margin.kind === \"single\") {\n const mar = margin.value ? String(margin.value) : null;\n if (mar) attrs[\"data-margin\"] = mar;\n } else {\n attrs[\"data-margin\"] = \"responsive\";\n attrs[\"data-responsive-margin\"] = \"true\";\n emitResponsiveSpacingVars(styleParts, margin, \"--rui-box-margin\");\n }\n if (styleParts.length > 0) attrs.style = styleParts.join(\";\");\n const root = el(\"div\", attrs);\n for (const child of asArray(props.children)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nexport const Grid: ComponentSpec = {\n name: \"Grid\",\n description:\n \"Responsive CSS grid. Use for KPI strips, feature blocks, card grids, \" +\n \"and asymmetric layouts with `GridItem` spans. Set `columns: 12` (or \" +\n \"include `GridItem` children) for a 12-column track system with \" +\n \"fractional spans like `\\\"1/3\\\"`. `columns` and `gap` accept responsive \" +\n \"maps like `{sm: 1, md: 2, lg: 4}`.\",\n props: [\n { name: \"children\", type: \"Node[]\" },\n { name: \"columns\", type: \"number | object\", optional: true, description: \"Target column count 1–12 (default auto-fit). `12` enables 12-column mode. May be a responsive map.\" },\n { name: \"gap\", type: \"string | object\", optional: true, enum: [\"xs\", \"s\", \"m\", \"l\", \"xl\"], description: \"Gap size (both axes). May be a responsive map.\" },\n { name: \"rowGap\", type: \"string | object\", optional: true, enum: [\"xs\", \"s\", \"m\", \"l\", \"xl\"], description: \"Row gap override. May be a responsive map.\" },\n { name: \"columnGap\", type: \"string | object\", optional: true, enum: [\"xs\", \"s\", \"m\", \"l\", \"xl\"], description: \"Column gap override. May be a responsive map.\" },\n { name: \"minItemWidth\", type: \"string\", optional: true, description: \"CSS min width for auto-fit fallback (alias: minChildWidth)\" },\n { name: \"minChildWidth\", type: \"string\", optional: true, description: \"CSS min child width; also applies when `columns` is set\" },\n { name: \"alignItems\", type: \"string\", optional: true, enum: [\"start\", \"center\", \"end\", \"stretch\"], description: \"Align items inside grid cells\" },\n { name: \"justifyItems\", type: \"string\", optional: true, enum: [\"start\", \"center\", \"end\", \"stretch\"], description: \"Justify items inside grid cells\" },\n { name: \"dense\", type: \"boolean\", optional: true, description: \"Use dense auto-flow packing\" },\n ],\n render: (_node, props, helpers) => {\n const children = asArray(props.children);\n const hasGridItems = children.some((child) => isComponentNamed(child, \"GridItem\"));\n const columns = readResponsiveProp<number | string>(props.columns);\n const gap = readResponsiveProp<string>(props.gap);\n const rowGap = readResponsiveProp<string>(props.rowGap);\n const columnGap = readResponsiveProp<string>(props.columnGap);\n const attrs: Record<string, string | null> = {\n class: \"rui-grid\",\n };\n const styleParts: string[] = [];\n // Twelve-column mode is enabled when (a) the author explicitly asks\n // for 12 columns or (b) GridItem children are present AND no explicit\n // non-12 column count was supplied. When the author writes\n // `Grid([...], 3)` they expect a 3-column grid regardless of whether\n // the children are GridItem wrappers; forcing 12-column mode squashes\n // each `GridItem` (default span=1) to 1/12 of the row.\n let twelveColMode = false;\n let explicitNonTwelve = false;\n\n if (columns.kind === \"single\") {\n const requested = columns.value === null ? 0 : asNumber(columns.value, 0);\n const cols = requested > 0 ? clampGridColumns(requested) : 0;\n if (cols === GRID_COLUMNS) {\n twelveColMode = true;\n } else if (cols > 0) {\n explicitNonTwelve = true;\n }\n if (cols > 0) {\n attrs[\"data-columns\"] = String(cols);\n const minChild = asString(props.minChildWidth) || asString(props.minItemWidth);\n if (minChild) {\n attrs[\"data-min-child-width\"] = \"true\";\n styleParts.push(`--rui-grid-min-child:${sanitiseCssLength(minChild, \"220px\")}`);\n }\n } else {\n styleParts.push(`--rui-grid-min-item:${gridMinChildWidth(props)}`);\n }\n } else {\n attrs[\"data-responsive-cols\"] = \"true\";\n for (const bp of RESPONSIVE_BREAKPOINTS) {\n const v = columns.values[bp as Breakpoint];\n if (v === undefined) continue;\n const cols = clampGridColumns(asNumber(v, 0));\n if (cols === GRID_COLUMNS) {\n twelveColMode = true;\n } else if (cols > 0) {\n explicitNonTwelve = true;\n }\n styleParts.push(`--rui-grid-cols-${bp}:${cols}`);\n }\n }\n\n if (hasGridItems && !explicitNonTwelve) twelveColMode = true;\n if (twelveColMode) attrs[\"data-grid-mode\"] = \"12\";\n\n if (gap.kind === \"single\") {\n attrs[\"data-gap\"] = gap.value ? String(gap.value) : \"m\";\n } else {\n attrs[\"data-gap\"] = \"responsive\";\n attrs[\"data-responsive-gap\"] = \"true\";\n emitResponsiveSpacingVars(styleParts, gap, \"--rui-grid-gap\");\n }\n\n if (rowGap.kind === \"single\" && rowGap.value) {\n attrs[\"data-row-gap\"] = String(rowGap.value);\n } else if (rowGap.kind === \"responsive\") {\n attrs[\"data-row-gap\"] = \"responsive\";\n attrs[\"data-responsive-row-gap\"] = \"true\";\n emitResponsiveSpacingVars(styleParts, rowGap, \"--rui-grid-row-gap\");\n }\n\n if (columnGap.kind === \"single\" && columnGap.value) {\n attrs[\"data-column-gap\"] = String(columnGap.value);\n } else if (columnGap.kind === \"responsive\") {\n attrs[\"data-column-gap\"] = \"responsive\";\n attrs[\"data-responsive-column-gap\"] = \"true\";\n emitResponsiveSpacingVars(styleParts, columnGap, \"--rui-grid-column-gap\");\n }\n\n const alignItems = asString(props.alignItems);\n if (alignItems) attrs[\"data-align-items\"] = alignItems;\n const justifyItems = asString(props.justifyItems);\n if (justifyItems) attrs[\"data-justify-items\"] = justifyItems;\n if (asBoolean(props.dense)) attrs[\"data-dense\"] = \"true\";\n\n if (styleParts.length > 0) attrs.style = styleParts.join(\";\");\n const root = el(\"div\", attrs);\n for (const child of children) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nexport const AspectRatio: ComponentSpec = {\n name: \"AspectRatio\",\n description:\n \"Container that constrains its child to a fixed aspect ratio (e.g. 16:9 \" +\n \"for video embeds, 1:1 for thumbnails). The child fills the box.\",\n props: [\n { name: \"ratio\", type: \"string\", description: \"`width:height` (e.g. `16:9`, `4:3`) or a decimal like `1.78`\" },\n { name: \"children\", type: \"Node[]\" },\n ],\n render: (_node, props, helpers) => {\n const ratio = parseRatio(asString(props.ratio, \"16:9\"));\n const root = el(\"div\", {\n class: \"rui-aspect-ratio\",\n style: `aspect-ratio:${ratio};`,\n });\n for (const child of asArray(props.children)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nfunction parseRatio(input: string): string {\n if (input.includes(\":\")) {\n const [w, h] = input.split(\":\");\n const num = Number(w);\n const den = Number(h);\n if (Number.isFinite(num) && Number.isFinite(den) && den !== 0) return `${num} / ${den}`;\n }\n const n = Number(input);\n return Number.isFinite(n) && n > 0 ? `${n} / 1` : \"16 / 9\";\n}\n\nexport const ScrollArea: ComponentSpec = {\n name: \"ScrollArea\",\n description:\n \"Bounded scroll container. Use to clip long lists / logs / chat panels \" +\n \"to a fixed max height with a clean scrollbar.\",\n props: [\n { name: \"children\", type: \"Node[]\" },\n { name: \"maxHeight\", type: \"string\", optional: true, aliases: [\"height\"], description: \"CSS height (default 320px)\" },\n { name: \"direction\", type: \"string\", optional: true, enum: [\"vertical\", \"horizontal\", \"both\"] },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", {\n class: \"rui-scroll-area\",\n \"data-direction\": asString(props.direction, \"vertical\"),\n style: `max-height:${sanitiseCssLength(props.maxHeight, \"320px\")};`,\n });\n for (const child of asArray(props.children)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nconst MODAL_SIZES = [\"sm\", \"md\", \"lg\", \"xl\", \"full\"] as const;\n\nexport const Modal: ComponentSpec = {\n name: \"Modal\",\n description:\n \"Dialog overlay shown when `open` is true. Pass a `$variable` as \" +\n \"`open` to control it. The header always renders a × close button \" +\n \"(disable via `closable: false`); the optional `footer` slot is the \" +\n \"canonical place for action buttons. `closeOnBackdrop=true` opts in \" +\n \"to backdrop-click dismissal.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"open\", type: \"boolean\", description: \"Open/closed state — usually a $variable\" },\n { name: \"children\", type: \"Node[]\" },\n { name: \"size\", type: \"string\", optional: true, enum: MODAL_SIZES, description: \"Width preset (default `md`)\" },\n { name: \"footer\", type: \"Node[]\", optional: true, description: \"Footer slot — typically a row of action Buttons\" },\n { name: \"closable\", type: \"boolean\", optional: true, description: \"Render the header × button (default true)\" },\n { name: \"closeOnBackdrop\", type: \"boolean\", optional: true, description: \"Close when the overlay is clicked (default false)\" },\n ],\n render: (node, props, helpers) => {\n const size = asString(props.size, \"md\");\n const closable = props.closable === undefined ? true : asBoolean(props.closable);\n const overlay = el(\"div\", {\n class: \"rui-modal-overlay\",\n \"data-open\": asBoolean(props.open) ? \"true\" : \"false\",\n });\n const dialog = el(\"div\", {\n class: \"rui-modal\",\n role: \"dialog\",\n \"aria-modal\": \"true\",\n \"data-size\": size,\n });\n const header = el(\"header\", { class: \"rui-modal-header\" });\n header.append(el(\"h3\", { class: \"rui-modal-title\" }, [asString(props.title)]));\n const stateName = node.argMeta?.[1]?.stateRef;\n const closeModal = () => {\n if (!stateName) return;\n helpers.setState(stateName, false);\n };\n if (closable) {\n const closeBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-modal-close\",\n \"aria-label\": \"Close dialog\",\n }, [\"×\"]);\n closeBtn.onclick = (event) => {\n event.stopPropagation();\n closeModal();\n };\n header.append(closeBtn);\n }\n dialog.append(header);\n const body = el(\"div\", { class: \"rui-modal-body\" });\n for (const child of asArray(props.children)) body.append(helpers.renderNode(child));\n dialog.append(body);\n const footer = asArray<unknown>(props.footer);\n if (footer.length > 0) {\n const footRow = el(\"footer\", { class: \"rui-modal-footer\" });\n for (const item of footer) footRow.append(helpers.renderNode(item));\n dialog.append(footRow);\n }\n overlay.append(dialog);\n if (asBoolean(props.closeOnBackdrop) && stateName) {\n overlay.onclick = (event) => {\n if (event.target === overlay) closeModal();\n };\n }\n return overlay;\n },\n};\n","/**\n * Content components: Text, Image, Link, Badge, BadgeList, Callout,\n * CodeBlock, Skeleton, Markdown, Icon, Quote, Container, Spacer, Spinner.\n *\n * `TextContent` is exported as a deprecated alias for `Text` so existing\n * Aktion programs keep rendering — prefer `Text` in new code.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport {\n el, asArray, asString, asBoolean, asNumber, renderIcon,\n sanitiseCssLength, sanitiseHref, sanitiseImageSrc,\n} from \"../utils.js\";\nimport { ICON_SIZES } from \"../../icons/index.js\";\n\nconst ICON_VARIANTS = [\"solid\", \"regular\", \"brands\"] as const;\n\nconst SIZE_ENUM = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\"] as const;\nconst TONE_ENUM = [\"default\", \"neutral\", \"primary\", \"success\", \"warning\", \"danger\", \"info\"] as const;\n\n/**\n * Normalise a legacy size token to the shared `xs|sm|md|lg|xl` vocabulary.\n * Keeps the catalogue self-consistent (suggestion 4.2) while letting old\n * prompts that emit `\"small\"` / `\"normal\"` / `\"large\"` still render.\n */\nexport function normaliseSize(value: unknown, fallback: string = \"md\"): string {\n const v = asString(value).trim().toLowerCase();\n if (!v) return fallback;\n if (v === \"small\") return \"sm\";\n if (v === \"normal\") return \"md\";\n if (v === \"large\") return \"lg\";\n if ((SIZE_ENUM as readonly string[]).includes(v)) return v;\n return fallback;\n}\n\nexport const Icon: ComponentSpec = {\n name: \"Icon\",\n description:\n \"Single Font Awesome icon. `name` is the FA name without the `fa-` \" +\n \"prefix (e.g. `\\\"house\\\"`, `\\\"chart-line\\\"`). Use `variant` for non-solid \" +\n \"styles (`regular`/`brands`) or prefix the name (`\\\"regular:star\\\"`).\",\n props: [\n { name: \"name\", type: \"string\", description: \"FA name without the fa- prefix\" },\n { name: \"variant\", type: \"string\", optional: true, enum: ICON_VARIANTS },\n { name: \"size\", type: \"string\", optional: true, enum: ICON_SIZES },\n ],\n render: (_node, props) => {\n const name = asString(props.name);\n const variant = asString(props.variant, \"\");\n const size = asString(props.size, \"md\");\n const composed = variant ? `${variant}:${name}` : name;\n const node = renderIcon(composed, { size });\n if (node) return node;\n return el(\"span\", { class: \"rui-icon\", \"data-icon-size\": size }, [name]);\n },\n};\n\n\nconst TEXT_VARIANTS = [\n \"small\",\n \"small-heavy\",\n \"body\",\n \"body-heavy\",\n \"large\",\n \"large-heavy\",\n \"heading\",\n \"title\",\n] as const;\n\n/**\n * Sanitise an inline CSS declaration string before it lands on a DOM\n * element's `style` attribute. The `<span>` style attribute can't host\n * `<style>` injection, but we still strip the legacy attack vectors\n * (IE-only `expression()`, `javascript:` URLs, `behavior:`, `@import`)\n * and any angle brackets defensively. Returns an empty string when the\n * input is rejected so callers can drop the attribute entirely.\n */\nfunction sanitiseInlineStyle(input: unknown): string {\n const raw = asString(input).trim();\n if (!raw) return \"\";\n if (/[<>]/.test(raw)) return \"\";\n if (/\\bexpression\\s*\\(|\\bjavascript\\s*:|\\bbehavior\\s*:|@import\\b/i.test(raw)) {\n return \"\";\n }\n return raw;\n}\n\nconst TEXT_PROPS = [\n { name: \"value\", type: \"string\" },\n { name: \"variant\", type: \"string\", optional: true, enum: TEXT_VARIANTS },\n { name: \"tone\", type: \"string\", optional: true, enum: [\"default\", \"muted\", \"primary\", \"success\", \"warning\", \"danger\"], description: \"Visual accent\" },\n {\n name: \"style\",\n type: \"string\",\n optional: true,\n description: \"Inline CSS declarations applied to the rendered element (e.g. \\\"font-size: 16px; font-weight: bold; color: #000;\\\").\",\n },\n] as const;\n\nconst renderText: ComponentSpec[\"render\"] = (_node, props) => {\n const variant = asString(props.variant, \"body\");\n const tone = asString(props.tone, \"default\");\n const style = sanitiseInlineStyle(props.style);\n return el(\"span\", {\n class: \"rui-text\",\n \"data-variant\": variant,\n \"data-color\": tone,\n style: style || null,\n }, [asString(props.value)]);\n};\n\nexport const Text: ComponentSpec = {\n name: \"Text\",\n description:\n \"Renders plain text with a typographic variant. Optional `style` prop \" +\n \"accepts a CSS declaration string (e.g. \\\"font-size: 16px; color: #000;\\\") \" +\n \"applied directly to the rendered element.\",\n props: TEXT_PROPS,\n render: renderText,\n};\n\n/**\n * Deprecated alias for `Text`. Kept registered so existing Aktion\n * programs that still emit `TextContent(...)` keep rendering. New code\n * should use `Text(...)`.\n */\nexport const TextContent: ComponentSpec = {\n name: \"TextContent\",\n description: \"Deprecated alias for `Text`. Prefer `Text(...)` — both render identically.\",\n props: TEXT_PROPS,\n render: renderText,\n};\n\nconst IMAGE_FIT = [\"cover\", \"contain\", \"fill\", \"none\", \"scale-down\"] as const;\n\nexport const Image: ComponentSpec = {\n name: \"Image\",\n description:\n \"Inline image. `ratio` constrains the box to a fixed aspect ratio (e.g. \" +\n \"`16:9`, `1:1`) so callers do not need an outer `AspectRatio`. `fit` \" +\n \"controls how the image fills that box. When `src` is missing or \" +\n \"unsafe the component renders a placeholder (or `fallback` text/icon).\",\n props: [\n { name: \"src\", type: \"string\" },\n { name: \"alt\", type: \"string\", optional: true },\n { name: \"caption\", type: \"string\", optional: true },\n { name: \"ratio\", type: \"string\", optional: true, description: \"Aspect ratio shorthand (e.g. `16:9`, `1:1`, `4:3`)\" },\n { name: \"fit\", type: \"string\", optional: true, enum: IMAGE_FIT, description: \"object-fit value (default `cover`)\" },\n { name: \"fallback\", type: \"string\", optional: true, description: \"Text label or Font Awesome icon shown when src is missing/unsafe\" },\n ],\n render: (_node, props) => {\n const wrapper = el(\"figure\", {\n class: \"rui-image\",\n \"data-fit\": asString(props.fit, \"cover\"),\n style: props.ratio ? `aspect-ratio:${parseImageRatio(asString(props.ratio))};` : null,\n });\n const safeSrc = sanitiseImageSrc(props.src);\n if (safeSrc) {\n wrapper.append(el(\"img\", {\n src: safeSrc,\n alt: asString(props.alt),\n loading: \"lazy\",\n }));\n } else {\n // Rendering a broken/hostile src is worse than rendering nothing —\n // keep the layout slot but skip the network request.\n const placeholder = el(\"div\", {\n class: \"rui-image-placeholder\",\n role: \"presentation\",\n \"aria-hidden\": \"true\",\n });\n const fallback = asString(props.fallback);\n if (fallback) {\n const iconNode = renderIcon(fallback, { className: \"rui-image-fallback-icon\" });\n if (iconNode) placeholder.append(iconNode);\n else placeholder.append(el(\"span\", { class: \"rui-image-fallback-text\" }, [fallback]));\n }\n wrapper.append(placeholder);\n }\n const cap = asString(props.caption);\n if (cap) wrapper.append(el(\"figcaption\", { class: \"rui-image-caption\" }, [cap]));\n return wrapper;\n },\n};\n\nfunction parseImageRatio(input: string): string {\n if (!input) return \"auto\";\n if (input.includes(\":\")) {\n const [w, h] = input.split(\":\");\n const num = Number(w);\n const den = Number(h);\n if (Number.isFinite(num) && Number.isFinite(den) && den > 0) return `${num} / ${den}`;\n }\n const n = Number(input);\n return Number.isFinite(n) && n > 0 ? `${n} / 1` : \"auto\";\n}\n\nexport const Link: ComponentSpec = {\n name: \"Link\",\n description: \"Anchor link.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"href\", type: \"string\" },\n { name: \"external\", type: \"boolean\", optional: true },\n ],\n render: (_node, props) => {\n const external = asBoolean(props.external);\n // Sanitise the href before it lands on the anchor so a hostile\n // `javascript:` (or `vbscript:` / control-char-bypassed) URL coming from\n // an LLM/tool response cannot execute on click.\n const safeHref = sanitiseHref(props.href, \"#\");\n return el(\"a\", {\n class: \"rui-link\",\n href: safeHref,\n target: external ? \"_blank\" : null,\n // `noreferrer` rounds out `noopener` so the destination cannot read the\n // opener's `document.referrer` either — important for external links.\n rel: external ? \"noopener noreferrer\" : null,\n }, [asString(props.label)]);\n },\n};\n\nconst BADGE_VARIANTS = [\"neutral\", \"primary\", \"success\", \"warning\", \"danger\", \"info\"] as const;\n\nexport const Badge: ComponentSpec = {\n name: \"Badge\",\n description:\n \"Small pill-style tag for status, counts, categories. Accepts an \" +\n \"optional leading `icon` and a `size`.\",\n props: [\n { name: \"label\", type: \"string\", positional: true },\n { name: \"tone\", type: \"string\", optional: true, enum: BADGE_VARIANTS, aliases: [\"variant\"], description: \"Visual tone\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Optional Font Awesome icon name (e.g. \\\"star\\\")\" },\n { name: \"size\", type: \"string\", optional: true, enum: SIZE_ENUM },\n ],\n render: (_node, props) => {\n const variant = asString(props.tone, \"neutral\");\n const size = normaliseSize(props.size, \"md\");\n const root = el(\"span\", {\n class: \"rui-badge\",\n \"data-variant\": variant,\n \"data-size\": size,\n });\n const iconNode = renderIcon(props.icon, { className: \"rui-badge-icon\" });\n if (iconNode) root.append(iconNode);\n const label = asString(props.label);\n if (label) root.append(el(\"span\", { class: \"rui-badge-label\" }, [label]));\n return root;\n },\n};\n\n/**\n * `BadgeList` renders an array of string labels as a row of Badge pills.\n * Replaces the legacy `TagBlock` component.\n */\nexport const BadgeList: ComponentSpec = {\n name: \"BadgeList\",\n description: \"Cluster of Badge pills rendered from an array of strings.\",\n props: [\n { name: \"labels\", type: \"string[]\", positional: true, description: \"Array of badge labels\" },\n { name: \"tone\", type: \"string\", optional: true, enum: BADGE_VARIANTS, aliases: [\"variant\"] },\n { name: \"size\", type: \"string\", optional: true, enum: SIZE_ENUM },\n ],\n render: (_node, props) => {\n const variant = asString(props.tone, \"neutral\");\n const size = normaliseSize(props.size, \"md\");\n const root = el(\"div\", { class: \"rui-badge-list\" });\n for (const raw of asArray(props.labels)) {\n const label = asString(raw);\n if (!label) continue;\n const pill = el(\"span\", {\n class: \"rui-badge\",\n \"data-variant\": variant,\n \"data-size\": size,\n });\n pill.append(el(\"span\", { class: \"rui-badge-label\" }, [label]));\n root.append(pill);\n }\n return root;\n },\n};\n\nconst CALLOUT_VARIANTS = [\"neutral\", \"info\", \"success\", \"warning\", \"danger\", \"error\"] as const;\n\nexport const Callout: ComponentSpec = {\n name: \"Callout\",\n description:\n \"Highlighted callout banner with variant, title, description, and \" +\n \"leading icon. Pass `compact: true` for a one-line inline-note rendering.\",\n props: [\n { name: \"tone\", type: \"string\", optional: true, enum: CALLOUT_VARIANTS, aliases: [\"variant\"] },\n { name: \"title\", type: \"string\", positional: true, required: true },\n { name: \"description\", type: \"string\", optional: true, aliases: [\"text\"], description: \"Body text\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Optional Font Awesome icon name\" },\n { name: \"compact\", type: \"boolean\", optional: true, description: \"Render with the dense, one-line note shape.\" },\n ],\n render: (_node, props) => {\n const variant = asString(props.tone, \"info\");\n const compact = asBoolean(props.compact);\n const root = el(\"div\", {\n class: \"rui-callout\",\n \"data-variant\": variant,\n \"data-compact\": compact ? \"true\" : \"false\",\n });\n const iconName = asString(props.icon) || defaultCalloutIcon(variant);\n const iconNode = renderIcon(iconName, { className: \"rui-callout-icon\" });\n if (iconNode) root.append(iconNode);\n const body = el(\"div\", { class: \"rui-callout-body\" });\n body.append(el(\"div\", { class: \"rui-callout-title\" }, [asString(props.title)]));\n const desc = asString(props.description);\n if (desc) body.append(el(\"div\", { class: \"rui-callout-description\" }, [desc]));\n root.append(body);\n return root;\n },\n};\n\nexport const CodeBlock: ComponentSpec = {\n name: \"CodeBlock\",\n description:\n \"Read-only code block with a language label and a copy-to-clipboard \" +\n \"button. Pass `showLineNumbers=true` to render a gutter; `highlightLines` \" +\n \"accepts a string like `\\\"3-5,8\\\"` to emphasise specific lines.\",\n props: [\n { name: \"language\", type: \"string\", optional: true, description: \"Display label (e.g. ts, bash)\" },\n { name: \"codeString\", type: \"string\", positional: true, required: true, aliases: [\"code\"], description: \"Raw source text\" },\n { name: \"showLineNumbers\", type: \"boolean\", optional: true, description: \"Render a left-side line-number gutter\" },\n { name: \"highlightLines\", type: \"string\", optional: true, aliases: [\"highlight\"], description: \"Highlight ranges, e.g. \\\"3-5,8\\\"\" },\n { name: \"copy\", type: \"boolean\", optional: true, description: \"Show the copy-to-clipboard button (default true)\" },\n ],\n render: (_node, props) => {\n const language = asString(props.language);\n const code = asString(props.codeString);\n const showLineNumbers = asBoolean(props.showLineNumbers);\n const highlights = parseLineRanges(asString(props.highlightLines));\n const showCopy = props.copy === undefined ? true : asBoolean(props.copy);\n const root = el(\"div\", { class: \"rui-code-block\" });\n\n if (language || showCopy) {\n const head = el(\"div\", { class: \"rui-code-block-head\" });\n if (language) head.append(el(\"span\", { class: \"rui-code-block-language\" }, [language]));\n if (showCopy) {\n const copyBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-code-block-copy\",\n \"aria-label\": \"Copy code\",\n title: \"Copy\",\n });\n const copyIcon = renderIcon(\"copy\", { className: \"rui-code-block-copy-icon\" });\n if (copyIcon) copyBtn.append(copyIcon);\n copyBtn.append(el(\"span\", { class: \"rui-code-block-copy-label\" }, [\"Copy\"]));\n copyBtn.onclick = (event) => {\n const origin = (event.currentTarget ?? event.target) as HTMLButtonElement;\n // Resolve the live code from the on-page DOM so this still works\n // after the morph reconciler keeps the previous element.\n const live = origin.closest(\".rui-code-block\")?.querySelector(\"code\");\n const text = live?.textContent ?? code;\n const nav = (typeof navigator !== \"undefined\") ? navigator as Navigator & { clipboard?: { writeText?: (t: string) => Promise<void> } } : null;\n const clipboard = nav?.clipboard;\n if (clipboard?.writeText) {\n clipboard.writeText(text).catch(() => { /* user denied / non-secure */ });\n }\n const label = origin.querySelector(\".rui-code-block-copy-label\");\n if (label) {\n const original = label.textContent ?? \"Copy\";\n label.textContent = \"Copied\";\n setTimeout(() => { label.textContent = original; }, 1500);\n }\n };\n head.append(copyBtn);\n }\n root.append(head);\n }\n\n const pre = el(\"pre\", { class: \"rui-code-block-pre\", \"data-line-numbers\": showLineNumbers ? \"true\" : \"false\" });\n if (showLineNumbers || highlights.size > 0) {\n const lines = code.split(/\\r?\\n/);\n const codeEl = el(\"code\", {});\n lines.forEach((lineText, idx) => {\n const lineNumber = idx + 1;\n const line = el(\"span\", {\n class: \"rui-code-block-line\",\n \"data-line\": String(lineNumber),\n \"data-highlight\": highlights.has(lineNumber) ? \"true\" : null,\n });\n if (showLineNumbers) {\n line.append(el(\"span\", { class: \"rui-code-block-gutter\" }, [String(lineNumber)]));\n }\n line.append(el(\"span\", { class: \"rui-code-block-code\" }, [lineText]));\n codeEl.append(line);\n });\n pre.append(codeEl);\n } else {\n pre.append(el(\"code\", {}, [code]));\n }\n root.append(pre);\n return root;\n },\n};\n\nfunction parseLineRanges(input: string): Set<number> {\n const out = new Set<number>();\n if (!input) return out;\n for (const segment of input.split(\",\")) {\n const trimmed = segment.trim();\n if (!trimmed) continue;\n if (trimmed.includes(\"-\")) {\n const parts = trimmed.split(\"-\").map((s) => Number(s.trim()));\n const a = parts[0] ?? NaN;\n const b = parts[1] ?? NaN;\n if (Number.isFinite(a) && Number.isFinite(b) && a <= b) {\n for (let i = a; i <= b; i += 1) out.add(i);\n }\n } else {\n const n = Number(trimmed);\n if (Number.isFinite(n)) out.add(n);\n }\n }\n return out;\n}\n\nfunction defaultCalloutIcon(variant: string): string {\n switch (variant) {\n case \"success\": return \"circle-check\";\n case \"warning\": return \"triangle-exclamation\";\n case \"danger\":\n case \"error\": return \"circle-xmark\";\n case \"info\": return \"circle-info\";\n default: return \"circle-info\";\n }\n}\n\nconst SKELETON_VARIANTS = [\"paragraph\", \"card\", \"table-row\", \"avatar\", \"image\"] as const;\nconst SKELETON_SHAPES = [\"rect\", \"circle\"] as const;\n\nexport const Skeleton: ComponentSpec = {\n name: \"Skeleton\",\n description:\n \"Loading placeholder. Pass a `variant` for common shapes — `paragraph` \" +\n \"(default), `card`, `table-row`, `avatar`, `image` — or use `shape` / \" +\n \"`width` / `height` to build a custom one. All variants use a shimmer \" +\n \"animation that respects `prefers-reduced-motion`.\",\n props: [\n { name: \"variant\", type: \"string\", optional: true, enum: SKELETON_VARIANTS },\n { name: \"lines\", type: \"number\", optional: true, aliases: [\"count\"], description: \"Lines for the `paragraph` variant (default 3)\" },\n { name: \"height\", type: \"number | string\", optional: true, description: \"Line height in px (paragraph) or CSS height for custom shape\" },\n { name: \"shape\", type: \"string\", optional: true, enum: SKELETON_SHAPES, description: \"Force a primitive shape (rect/circle)\" },\n { name: \"width\", type: \"string\", optional: true, description: \"CSS width for shape-only skeletons\" },\n ],\n render: (_node, props) => {\n const variant = asString(props.variant);\n const shape = asString(props.shape);\n if (shape) return renderShapeSkeleton(shape, props);\n if (variant && variant !== \"paragraph\") return renderVariantSkeleton(variant, props);\n\n const rawLines = Number(props.lines);\n const lines = Math.max(1, Math.min(50, Number.isFinite(rawLines) ? Math.floor(rawLines) : 3));\n const rawHeight = Number(props.height);\n const lineHeight = Number.isFinite(rawHeight) && rawHeight > 0 ? Math.min(200, Math.floor(rawHeight)) : 12;\n const root = el(\"div\", { class: \"rui-skeleton\", \"data-variant\": \"paragraph\" });\n for (let i = 0; i < lines; i += 1) {\n root.append(el(\"div\", { class: \"rui-skeleton-line\", style: `height:${lineHeight}px` }));\n }\n return root;\n },\n};\n\nfunction renderShapeSkeleton(shape: string, props: Record<string, unknown>): HTMLElement {\n const width = sanitiseCssLength(asString(props.width), \"100%\");\n const heightInput = asString(props.height);\n const height = heightInput\n ? sanitiseCssLength(heightInput, \"16px\")\n : (shape === \"circle\" ? width : \"16px\");\n return el(\"div\", {\n class: \"rui-skeleton\",\n \"data-variant\": \"shape\",\n \"data-shape\": shape === \"circle\" ? \"circle\" : \"rect\",\n style: `width:${width};height:${height};`,\n });\n}\n\nfunction renderVariantSkeleton(variant: string, props: Record<string, unknown>): HTMLElement {\n const root = el(\"div\", { class: \"rui-skeleton\", \"data-variant\": variant });\n switch (variant) {\n case \"avatar\": {\n const size = sanitiseCssLength(asString(props.width), \"40px\");\n root.append(el(\"div\", {\n class: \"rui-skeleton-shape\",\n \"data-shape\": \"circle\",\n style: `width:${size};height:${size};`,\n }));\n return root;\n }\n case \"image\": {\n const width = sanitiseCssLength(asString(props.width), \"100%\");\n const height = sanitiseCssLength(asString(props.height), \"160px\");\n root.append(el(\"div\", {\n class: \"rui-skeleton-shape\",\n \"data-shape\": \"rect\",\n style: `width:${width};height:${height};`,\n }));\n return root;\n }\n case \"card\": {\n root.append(el(\"div\", { class: \"rui-skeleton-shape\", \"data-shape\": \"rect\", style: \"width:100%;height:120px;\" }));\n root.append(el(\"div\", { class: \"rui-skeleton-line\", style: \"height:14px;width:70%;\" }));\n root.append(el(\"div\", { class: \"rui-skeleton-line\", style: \"height:12px;width:90%;\" }));\n root.append(el(\"div\", { class: \"rui-skeleton-line\", style: \"height:12px;width:60%;\" }));\n return root;\n }\n case \"table-row\": {\n const cells = Math.max(1, Math.min(8, Math.floor(Number(props.lines ?? 4))));\n const row = el(\"div\", { class: \"rui-skeleton-row\" });\n for (let i = 0; i < cells; i += 1) {\n row.append(el(\"div\", { class: \"rui-skeleton-line\", style: \"height:12px;flex:1;\" }));\n }\n root.append(row);\n return root;\n }\n default:\n return root;\n }\n}\n\nexport const Markdown: ComponentSpec = {\n name: \"Markdown\",\n description:\n \"Render markdown-flavoured text. Supports **bold**, *italic*, `code`, \" +\n \"headings (`#`/`##`/`###`), blockquotes (`>`), bullet (`-`/`*`) and \" +\n \"numbered (`1.`) lists, fenced code blocks (```), images \" +\n \"(`![alt](src)`), inline links, and auto-linked bare URLs. Multi-line \" +\n \"paragraphs collapse into `<p>` blocks.\",\n props: [{ name: \"content\", type: \"string\" }],\n render: (_node, props) => {\n const value = asString(props.content);\n const html = renderMarkdown(value);\n return el(\"div\", { class: \"rui-markdown\", html });\n },\n};\n\nexport const Container: ComponentSpec = {\n name: \"Container\",\n description:\n \"Centered, max-width content wrapper. Use when a page is wider than \" +\n \"comfortable reading width — landing pages, marketing sections, long \" +\n \"documents. Picks a sensible default max-width per size; pass \" +\n \"`maxWidth` to override with any CSS value.\",\n props: [\n { name: \"children\", type: \"Node[]\" },\n { name: \"size\", type: \"string\", optional: true, enum: [\"sm\", \"md\", \"lg\", \"xl\", \"full\"], description: \"sm=640 / md=820 / lg=1040 / xl=1280 / full=100% (default lg)\" },\n { name: \"maxWidth\", type: \"string\", optional: true, description: \"Custom CSS max-width (overrides `size`)\" },\n { name: \"padding\", type: \"string\", optional: true, enum: [\"none\", \"s\", \"m\", \"l\"], description: \"Horizontal padding (default m)\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", {\n class: \"rui-container\",\n \"data-size\": asString(props.size, \"lg\"),\n \"data-padding\": asString(props.padding, \"m\"),\n style: props.maxWidth ? `max-width:${sanitiseCssLength(props.maxWidth, \"auto\")};` : null,\n });\n for (const child of asArray(props.children)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nexport const Spacer: ComponentSpec = {\n name: \"Spacer\",\n description:\n \"Explicit space element for fine layout control. By default acts as a \" +\n \"flex spacer that pushes following content to the far edge (use \" +\n \"inside `Stack(direction=\\\"row\\\")`). Pass `size` to render a fixed \" +\n \"vertical/horizontal gap instead.\",\n props: [\n { name: \"size\", type: \"string\", optional: true, enum: [\"xs\", \"s\", \"m\", \"l\", \"xl\"], description: \"Fixed gap; omit to flex-grow\" },\n { name: \"flex\", type: \"boolean\", optional: true, description: \"Flex-grow even when size is set (default true when size omitted)\" },\n ],\n render: (_node, props) => {\n const size = asString(props.size);\n const flex = props.flex === undefined ? !size : asBoolean(props.flex);\n return el(\"span\", {\n class: \"rui-spacer\",\n \"data-size\": size || null,\n \"data-flex\": flex ? \"true\" : \"false\",\n \"aria-hidden\": \"true\",\n });\n },\n};\n\nexport const Spinner: ComponentSpec = {\n name: \"Spinner\",\n description:\n \"Indeterminate inline loader. Use for tiny loading states inside \" +\n \"buttons, toolbars, table cells, or chat bubbles where `Skeleton` \" +\n \"and `Progress(indeterminate=true)` are too heavy. Pass `label` to \" +\n \"render an inline caption beside the spinner (also announced via \" +\n \"`aria-label`).\",\n props: [\n { name: \"size\", type: \"string\", optional: true, enum: SIZE_ENUM, description: \"Default `md`\" },\n { name: \"label\", type: \"string\", optional: true, description: \"Caption rendered beside the spinner (also announced)\" },\n { name: \"tone\", type: \"string\", optional: true, enum: TONE_ENUM, description: \"Visual accent (default `primary`)\" },\n ],\n render: (_node, props) => {\n const size = normaliseSize(props.size, \"md\");\n const tone = asString(props.tone, \"primary\");\n const label = asString(props.label);\n const root = el(\"span\", {\n class: \"rui-spinner\",\n \"data-size\": size,\n \"data-tone\": tone,\n role: \"status\",\n \"aria-live\": \"polite\",\n \"aria-label\": label || \"Loading\",\n });\n root.append(el(\"span\", { class: \"rui-spinner-ring\", \"aria-hidden\": \"true\" }));\n if (label) root.append(el(\"span\", { class: \"rui-spinner-label\" }, [label]));\n return root;\n },\n};\n\nexport const Quote: ComponentSpec = {\n name: \"Quote\",\n description:\n \"Inline pull-quote with optional citation. Lighter than `Testimonial` \" +\n \"— use inside articles, blog posts, marketing sections, or anywhere \" +\n \"you need to highlight a sentence without the full quote/author/role \" +\n \"+ rating shape.\",\n props: [\n { name: \"text\", type: \"string\" },\n { name: \"cite\", type: \"string\", optional: true, aliases: [\"attribution\", \"author\"], description: \"Attribution text shown below the quote\" },\n { name: \"tone\", type: \"string\", optional: true, enum: [\"default\", \"primary\", \"success\", \"warning\", \"danger\", \"info\"] },\n ],\n render: (_node, props) => {\n const root = el(\"figure\", {\n class: \"rui-quote\",\n \"data-tone\": asString(props.tone, \"default\"),\n });\n root.append(el(\"blockquote\", { class: \"rui-quote-text\" }, [asString(props.text)]));\n const cite = asString(props.cite);\n if (cite) root.append(el(\"figcaption\", { class: \"rui-quote-cite\" }, [cite]));\n return root;\n },\n};\n\n/* ------------------------------------------------------------------------ *\n * Markdown renderer\n *\n * Hand-rolled because we ship inside a Shadow DOM with no peer deps. The\n * parser handles:\n *\n * - Headings (#, ##, ###)\n * - Blockquotes (>)\n * - Fenced code blocks (```lang)\n * - Bullet lists (`-` / `*`) and numbered lists (`1.`)\n * - Inline **bold**, *italic*, `code`\n * - Links `[label](href)` (sanitised) and images `![alt](src)` (sanitised)\n * - Auto-linked bare HTTP/HTTPS URLs\n *\n * All HTML output is escape-encoded so an LLM cannot smuggle raw markup\n * past the parser.\n * ------------------------------------------------------------------------ */\nfunction renderMarkdown(value: string): string {\n const escape = (s: string) =>\n s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n const lines = value.split(/\\r?\\n/);\n const out: string[] = [];\n\n // List / quote state so we can close them on a context change.\n let listMode: \"ul\" | \"ol\" | null = null;\n let inQuote = false;\n let inCode = false;\n let codeLang = \"\";\n let codeBuf: string[] = [];\n\n const closeList = () => {\n if (listMode) {\n out.push(listMode === \"ul\" ? \"</ul>\" : \"</ol>\");\n listMode = null;\n }\n };\n const closeQuote = () => {\n if (inQuote) { out.push(\"</blockquote>\"); inQuote = false; }\n };\n const flushCode = () => {\n const lang = codeLang ? ` data-language=\"${escape(codeLang)}\"` : \"\";\n out.push(`<pre class=\"rui-markdown-code\"${lang}><code>${escape(codeBuf.join(\"\\n\"))}</code></pre>`);\n codeBuf = [];\n codeLang = \"\";\n inCode = false;\n };\n\n for (const rawLine of lines) {\n // Fenced code blocks must be detected before any inline transform so\n // their content is preserved verbatim (no `**bold**` interpretation).\n const fenceMatch = /^```\\s*(.*)$/.exec(rawLine.trim());\n if (inCode) {\n if (fenceMatch) {\n flushCode();\n continue;\n }\n codeBuf.push(rawLine);\n continue;\n }\n if (fenceMatch) {\n closeList(); closeQuote();\n inCode = true;\n codeLang = fenceMatch[1] ?? \"\";\n continue;\n }\n\n const heading = /^\\s*(#{1,3})\\s+(.+)$/.exec(rawLine);\n if (heading) {\n closeList(); closeQuote();\n const level = heading[1]!.length;\n out.push(`<h${level} class=\"rui-markdown-h${level}\">${inline(escape(heading[2]!))}</h${level}>`);\n continue;\n }\n\n const quoteMatch = /^\\s*>\\s?(.*)$/.exec(rawLine);\n if (quoteMatch) {\n closeList();\n if (!inQuote) { out.push(\"<blockquote class=\\\"rui-markdown-quote\\\">\"); inQuote = true; }\n out.push(`<p>${inline(escape(quoteMatch[1] ?? \"\"))}</p>`);\n continue;\n } else if (inQuote && rawLine.trim() !== \"\") {\n // Non-empty non-quote line ends a quote block.\n closeQuote();\n }\n\n const ulMatch = /^\\s*[-*]\\s+(.*)$/.exec(rawLine);\n if (ulMatch) {\n closeQuote();\n if (listMode !== \"ul\") { closeList(); out.push(\"<ul>\"); listMode = \"ul\"; }\n out.push(`<li>${inline(escape(ulMatch[1] ?? \"\"))}</li>`);\n continue;\n }\n\n const olMatch = /^\\s*\\d+\\.\\s+(.*)$/.exec(rawLine);\n if (olMatch) {\n closeQuote();\n if (listMode !== \"ol\") { closeList(); out.push(\"<ol>\"); listMode = \"ol\"; }\n out.push(`<li>${inline(escape(olMatch[1] ?? \"\"))}</li>`);\n continue;\n }\n\n if (rawLine.trim() === \"\") {\n closeList(); closeQuote();\n continue;\n }\n\n closeList(); closeQuote();\n out.push(`<p>${inline(escape(rawLine))}</p>`);\n }\n\n if (inCode) flushCode();\n closeList();\n closeQuote();\n return out.join(\"\");\n\n function inline(s: string): string {\n let result = s\n // Images first so the ![alt](src) regex does not match inside link labels.\n .replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (_match, alt: string, rawSrc: string) => {\n const src = sanitiseImageSrc(rawSrc);\n if (!src) return `<span class=\"rui-markdown-image-fallback\">${alt}</span>`;\n return `<img class=\"rui-markdown-image\" src=\"${escapeAttr(src)}\" alt=\"${alt}\" loading=\"lazy\">`;\n })\n // Inline code — careful not to match across line boundaries.\n .replace(/`([^`]+)`/g, \"<code>$1</code>\")\n .replace(/\\*\\*([^*]+)\\*\\*/g, \"<strong>$1</strong>\")\n .replace(/\\*([^*]+)\\*/g, \"<em>$1</em>\")\n .replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_match, label: string, rawHref: string) => {\n const href = sanitizeMarkdownHref(rawHref);\n return `<a class=\"rui-link\" href=\"${href}\" target=\"_blank\" rel=\"noopener noreferrer\">${label}</a>`;\n });\n // Auto-link bare http(s) URLs. We only match URLs that are not already\n // wrapped in an anchor or attribute — heuristic check via a negative\n // lookbehind on `\"` (attribute) or `>` (already inside a tag).\n result = result.replace(\n /(?<![=\"'>])\\bhttps?:\\/\\/[a-zA-Z0-9._~:/?#@!$&'()*+,;=%\\-]+/g,\n (url) => {\n const safe = sanitizeMarkdownHref(url);\n return `<a class=\"rui-link\" href=\"${safe}\" target=\"_blank\" rel=\"noopener noreferrer\">${url}</a>`;\n },\n );\n return result;\n }\n}\n\n/**\n * Block dangerous URL schemes (`javascript:`, `data:`, `vbscript:`, …) and\n * protocol-relative URLs (`//evil.com/...`) so a tool response embedded\n * inside a Markdown link cannot smuggle script execution or cross-origin\n * navigation into the page. Allow http/https/mailto/tel absolute URLs plus\n * same-origin fragments and root-relative paths.\n */\nfunction sanitizeMarkdownHref(raw: string): string {\n const trimmed = raw.trim();\n if (!trimmed) return \"#\";\n // Protocol-relative URLs (`//host/path`) inherit the page's scheme and\n // therefore can navigate to a hostile host. Treat them as unsafe.\n if (trimmed.startsWith(\"//\")) return \"#\";\n // Same-origin fragments / root-relative paths / query-only links are safe.\n if (trimmed.startsWith(\"#\") || trimmed.startsWith(\"/\") || trimmed.startsWith(\"?\")) {\n return escapeAttr(trimmed);\n }\n const schemeMatch = /^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(trimmed);\n if (!schemeMatch) return escapeAttr(trimmed);\n const scheme = schemeMatch[1]!.toLowerCase();\n const allowed = new Set([\"http\", \"https\", \"mailto\", \"tel\"]);\n if (!allowed.has(scheme)) return \"#\";\n return escapeAttr(trimmed);\n}\n\nfunction escapeAttr(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\");\n}\n\n// `asNumber` is re-exported here so consumers that wanted it for the old\n// helper shape keep working without changing imports (kept for clarity).\nexport { asNumber };\n","/**\n * Internal DOM helpers shared by primitives (`feedback.ts`) and pattern\n * composites (`patterns.ts`). Not exported from the package barrel — these\n * are implementation details that keep avatar/initials rendering consistent\n * across every component that needs them.\n */\n\nimport { el, sanitiseImageSrc } from \"../utils.js\";\n\nexport type AvatarSize = \"sm\" | \"md\" | \"lg\" | \"xl\";\n\n/** Render an `<rui-avatar>` matching the canonical Avatar primitive. */\nexport function renderAvatar(src: string, name: string, size: AvatarSize): HTMLElement {\n const root = el(\"span\", { class: \"rui-avatar\", \"data-size\": size, role: \"img\" });\n // Defensive sanitisation — even though browsers do not execute JS from\n // `img.src`, an unsafe scheme should never land on a network-fetched\n // attribute (some hosts copy the value into other sinks).\n const safeSrc = sanitiseImageSrc(src);\n if (safeSrc) {\n const img = el(\"img\", { src: safeSrc, alt: name, loading: \"lazy\" });\n // Resolve the live image from the event so this handler still works\n // after the morph reconciler copies it onto a kept DOM node.\n // (`onerror`'s first argument is typed `Event | string` because the\n // window-level handler also fires from script errors — but for an\n // `<img>` it's always an Event.)\n img.onerror = (event) => {\n const ev = event as Event;\n const live = (ev.currentTarget ?? ev.target) as Element;\n live.replaceWith(el(\"span\", { class: \"rui-avatar-fallback\" }, [initialsFor(name)]));\n };\n root.append(img);\n } else {\n root.append(el(\"span\", { class: \"rui-avatar-fallback\" }, [initialsFor(name)]));\n }\n return root;\n}\n\n/** Two-letter initials, falling back to `?` for empty input. */\nexport function initialsFor(name: string): string {\n const trimmed = name.trim();\n if (!trimmed) return \"?\";\n const parts = trimmed.split(/\\s+/).slice(0, 2);\n return parts.map((p) => p.charAt(0).toUpperCase()).join(\"\") || trimmed.charAt(0).toUpperCase();\n}\n\n/**\n * Shared outside-click + Escape dismissal for popovers, dropdowns, comboboxes.\n *\n * Previous implementations leaked listeners in three subtle ways:\n *\n * 1. Re-opening the floater (trigger clicked while still open) installed a\n * second listener pair without removing the first.\n * 2. Closing via any code path *other than* an outside-click / Escape (e.g.\n * clicking the trigger again, selecting an item, programmatic close)\n * left the listeners attached, holding references to detached DOM.\n * 3. The host node being removed from the DOM (LLM produced a new response,\n * route changed, parent re-rendered) silently kept the listeners on the\n * shadow root forever.\n *\n * This helper installs listeners exactly once per open, exposes a single\n * `dispose()` so every close path can clean up, and observes the host so we\n * auto-dispose when the floater is unmounted.\n *\n * `key` lets the caller dedupe re-opens — if the same `key` is passed while\n * a previous registration is still live, we dispose it before installing\n * the new one.\n */\nexport interface DismissHandle {\n dispose: () => void;\n}\n\ninterface DismissOptions {\n liveRoot: HTMLElement;\n onDismiss: () => void;\n /** Stable per-instance identifier, used to deduplicate re-opens. */\n key?: string;\n}\n\nconst DISMISS_REGISTRY: WeakMap<HTMLElement, DismissHandle> = new WeakMap();\n\nexport function installDismissListeners(opts: DismissOptions): DismissHandle {\n const { liveRoot, onDismiss } = opts;\n const existing = DISMISS_REGISTRY.get(liveRoot);\n if (existing) existing.dispose();\n\n const host = liveRoot.getRootNode() as Document | ShadowRoot;\n let disposed = false;\n\n const onOutside = (event: Event): void => {\n const target = event.target as Element | null;\n if (target && liveRoot.contains(target)) return;\n handle.dispose();\n onDismiss();\n };\n const onKey = (event: Event): void => {\n if ((event as KeyboardEvent).key !== \"Escape\") return;\n handle.dispose();\n onDismiss();\n };\n\n // Auto-dispose when the floater is removed from the DOM so we never keep\n // listeners alive against a detached subtree.\n const ownerDoc = liveRoot.ownerDocument;\n let observer: MutationObserver | null = null;\n if (ownerDoc && typeof MutationObserver !== \"undefined\") {\n observer = new MutationObserver(() => {\n if (!liveRoot.isConnected) handle.dispose();\n });\n const observeRoot = liveRoot.getRootNode();\n if (observeRoot instanceof Element || observeRoot instanceof Document || observeRoot instanceof ShadowRoot) {\n observer.observe(observeRoot, { childList: true, subtree: true });\n }\n }\n\n const handle: DismissHandle = {\n dispose: () => {\n if (disposed) return;\n disposed = true;\n host.removeEventListener(\"click\", onOutside, true);\n host.removeEventListener(\"keydown\", onKey, true);\n observer?.disconnect();\n DISMISS_REGISTRY.delete(liveRoot);\n },\n };\n\n // Defer attachment so the same click that opened the floater does not\n // immediately trip the close handler.\n setTimeout(() => {\n if (disposed) return;\n host.addEventListener(\"click\", onOutside, true);\n host.addEventListener(\"keydown\", onKey, true);\n }, 0);\n\n DISMISS_REGISTRY.set(liveRoot, handle);\n return handle;\n}\n\n/** Trigger an immediate dispose for a live root if one is registered. */\nexport function disposeDismissListeners(liveRoot: HTMLElement | null | undefined): void {\n if (!liveRoot) return;\n const existing = DISMISS_REGISTRY.get(liveRoot);\n if (existing) existing.dispose();\n}\n\n/**\n * Map a free-text label to a sensible Font Awesome icon. Used by\n * \"self-decorating\" defaults — e.g. StatCard auto-pick from label,\n * EmptyState auto-pick from title, Banner auto-pick from tone.\n *\n * Returns `null` when no rule matches so callers can fall back to whatever\n * default they prefer.\n */\nconst ICON_KEYWORD_RULES: Array<{ match: RegExp; icon: string }> = [\n { match: /\\b(revenue|sales|sale|income|payment|charges?|invoices?|billing)\\b/i, icon: \"sack-dollar\" },\n { match: /\\b(profit|earnings?|margin|roi)\\b/i, icon: \"chart-line\" },\n { match: /\\b(customers?|clients?|users?|members?|people|accounts?)\\b/i, icon: \"users\" },\n { match: /\\b(visitors?|sessions?|traffic|page-?views?|impressions?)\\b/i, icon: \"chart-line\" },\n { match: /\\b(orders?|carts?|purchases?|transactions?)\\b/i, icon: \"cart-shopping\" },\n { match: /\\b(products?|inventory|sku|stock|items?)\\b/i, icon: \"box\" },\n { match: /\\b(subscriptions?|plans?|tiers?|pricing)\\b/i, icon: \"credit-card\" },\n { match: /\\b(emails?|messages?|inbox|threads?|mail)\\b/i, icon: \"envelope\" },\n { match: /\\b(notifications?|alerts?|reminders?)\\b/i, icon: \"bell\" },\n { match: /\\b(growth|trend|increase|up)\\b/i, icon: \"arrow-trend-up\" },\n { match: /\\b(decline|drop|down|decrease|loss)\\b/i, icon: \"arrow-trend-down\" },\n { match: /\\b(reports?|analytics|insights?|dashboards?|metrics?|stats?|kpis?)\\b/i, icon: \"chart-pie\" },\n { match: /\\b(charts?|graphs?)\\b/i, icon: \"chart-column\" },\n { match: /\\b(tasks?|todos?|backlog|kanban|sprint)\\b/i, icon: \"list-check\" },\n { match: /\\b(projects?|workspaces?)\\b/i, icon: \"folder-open\" },\n { match: /\\b(files?|folders?|documents?|docs?|attachments?)\\b/i, icon: \"folder-open\" },\n { match: /\\b(images?|photos?|gallery|albums?)\\b/i, icon: \"image\" },\n { match: /\\b(videos?|clips?|recordings?)\\b/i, icon: \"video\" },\n { match: /\\b(audio|music|podcasts?|sounds?)\\b/i, icon: \"music\" },\n { match: /\\b(calendars?|schedule|events?|meetings?|appointments?)\\b/i, icon: \"calendar-days\" },\n { match: /\\b(comments?|replies|feedback|reviews?|ratings?)\\b/i, icon: \"comments\" },\n { match: /\\b(settings?|preferences?|config|configuration|options?)\\b/i, icon: \"gear\" },\n { match: /\\b(security|privacy|password|locks?|secure)\\b/i, icon: \"shield-halved\" },\n { match: /\\b(api|integrations?|webhooks?|connections?)\\b/i, icon: \"plug\" },\n { match: /\\b(database|storage|backups?|servers?)\\b/i, icon: \"database\" },\n { match: /\\b(speed|performance|latency|response\\s?time)\\b/i, icon: \"gauge-high\" },\n { match: /\\b(uptime|availability|status|health)\\b/i, icon: \"heart-pulse\" },\n { match: /\\b(errors?|bugs?|failures?|exceptions?|incidents?)\\b/i, icon: \"circle-exclamation\" },\n { match: /\\b(success|complete|done|approved)\\b/i, icon: \"circle-check\" },\n { match: /\\b(warnings?|caution)\\b/i, icon: \"triangle-exclamation\" },\n { match: /\\b(search|results?|queries)\\b/i, icon: \"magnifying-glass\" },\n { match: /\\b(downloads?|exports?)\\b/i, icon: \"download\" },\n { match: /\\b(uploads?|imports?)\\b/i, icon: \"upload\" },\n { match: /\\b(time|hours?|duration|elapsed)\\b/i, icon: \"clock\" },\n { match: /\\b(locations?|maps?|addresses?|countries?|regions?)\\b/i, icon: \"location-dot\" },\n { match: /\\b(stars?|favourites?|favorites?|highlights?)\\b/i, icon: \"star\" },\n { match: /\\b(trophy|awards?|achievements?|badges?|gold)\\b/i, icon: \"trophy\" },\n { match: /\\b(targets?|goals?|objectives?|quotas?)\\b/i, icon: \"bullseye\" },\n { match: /\\b(teams?|departments?|orgs?|organisations?|organizations?)\\b/i, icon: \"people-group\" },\n { match: /\\b(tickets?|issues?|bugs?|requests?)\\b/i, icon: \"ticket\" },\n { match: /\\b(deploys?|builds?|releases?|versions?)\\b/i, icon: \"rocket\" },\n];\n\nexport function pickIconForLabel(label: string | null | undefined): string | null {\n if (!label) return null;\n for (const rule of ICON_KEYWORD_RULES) {\n if (rule.match.test(label)) return rule.icon;\n }\n return null;\n}\n\n/**\n * Map a tone keyword (`primary`, `success`, `warning`, …) to a sensible\n * default icon, used by Banner / Callout when the LLM omits `icon`.\n */\nconst TONE_ICONS: Record<string, string> = {\n default: \"circle-info\",\n info: \"circle-info\",\n primary: \"bolt\",\n success: \"circle-check\",\n warning: \"triangle-exclamation\",\n danger: \"circle-exclamation\",\n error: \"circle-exclamation\",\n neutral: \"circle-info\",\n};\n\nexport function pickIconForTone(tone: string | null | undefined): string | null {\n if (!tone) return null;\n return TONE_ICONS[tone.toLowerCase()] ?? null;\n}\n\n/**\n * Build a deterministic DiceBear avatar URL for a person name.\n *\n * Used as the fallback when the LLM passes a name but omits `src`.\n * `style` defaults to `initials` which is bulletproof (no network face-art),\n * but callers can pass `shapes`, `avataaars`, etc. for fancier looks.\n */\nexport function dicebearUrlFor(name: string, style: string = \"shapes\"): string {\n const seed = name.trim() || \"anon\";\n const safeStyle = /^[a-z0-9-]+$/i.test(style) ? style : \"shapes\";\n return `https://api.dicebear.com/9.x/${safeStyle}/svg?seed=${encodeURIComponent(seed)}`;\n}\n","/**\n * Shared form helpers used by forms.ts and new-components.ts.\n */\n\nimport { asArray, asString } from \"../utils.js\";\n\nexport function extractComboboxItems(raw: unknown): Array<{ value: string; label: string }> {\n const items = asArray<unknown>(raw);\n return items\n .map((entry) => {\n if (entry && typeof entry === \"object\") {\n const node = entry as { __kind?: string; args?: unknown[]; value?: unknown; label?: unknown };\n if (node.__kind === \"Component\" && Array.isArray(node.args)) {\n const value = asString(node.args[0]);\n return { value, label: asString(node.args[1], value) };\n }\n if (node.value !== undefined || node.label !== undefined) {\n const value = asString(node.value);\n return { value, label: asString(node.label, value) };\n }\n }\n const value = asString(entry);\n return { value, label: value };\n })\n .filter((item) => item.value !== \"\" || item.label !== \"\");\n}\n","/**\n * Form components: Form, FormControl, Input, TextArea, Select, SelectItem,\n * Checkbox, CheckBoxGroup, CheckBoxItem, Radio, Button, Buttons, SearchBar,\n * Slider, NumberInput, DatePicker, FileUpload, Combobox.\n */\n\nimport type { ComponentSpec, RenderHelpers } from \"../types.js\";\nimport type { ComponentNode } from \"../../runtime/evaluator.js\";\nimport { el, asArray, asString, asBoolean, asNumber, renderIcon } from \"../utils.js\";\nimport { installDismissListeners, disposeDismissListeners } from \"./_internal.js\";\nimport { extractComboboxItems } from \"./forms-shared.js\";\n\nconst BUTTON_VARIANTS = [\"primary\", \"secondary\", \"ghost\", \"danger\"] as const;\nconst BUTTON_SIZES = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"small\", \"normal\", \"large\"] as const;\nconst INPUT_TYPES = [\"text\", \"email\", \"password\", \"number\", \"tel\", \"url\", \"date\"] as const;\n\n/**\n * Normalise size tokens to the shared `sm|md|lg` vocabulary. The legacy\n * `small|normal|large` triple is preserved (suggestion 4.2) so prompts\n * that mix the old and new names produce consistent visual output.\n */\nfunction normaliseButtonSize(value: unknown): string {\n const v = asString(value).trim().toLowerCase();\n if (v === \"xs\" || v === \"extra-small\") return \"xs\";\n if (v === \"small\" || v === \"sm\") return \"sm\";\n if (v === \"large\" || v === \"lg\") return \"lg\";\n if (v === \"xl\" || v === \"extra-large\") return \"xl\";\n if (v === \"normal\" || v === \"md\" || v === \"\") return \"md\";\n if (v === \"xs\" || v === \"sm\" || v === \"md\" || v === \"lg\" || v === \"xl\") return v;\n return \"md\";\n}\n\nexport const Button: ComponentSpec = {\n name: \"Button\",\n description: \"Clickable button. The action argument runs when clicked.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onClick\", \"onclick\"], description: \"Callable invoked when clicked\" },\n { name: \"variant\", type: \"string\", optional: true, aliases: [\"tone\"], enum: BUTTON_VARIANTS },\n { name: \"type\", type: \"string\", optional: true, enum: [\"button\", \"submit\"], description: \"HTML button type\" },\n { name: \"size\", type: \"string\", optional: true, enum: BUTTON_SIZES, description: \"Canonical `xs|sm|md|lg|xl` (legacy `small|normal|large` still accepted)\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Optional Font Awesome icon name\" },\n { name: \"iconPosition\", type: \"string\", optional: true, enum: [\"leading\", \"trailing\"], description: \"Icon placement (default leading)\" },\n { name: \"iconOnly\", type: \"boolean\", optional: true, description: \"Hide the label visually (keeps aria-label)\" },\n { name: \"loading\", type: \"boolean\", optional: true, description: \"Show spinner and disable interaction\" },\n { name: \"fullWidth\", type: \"boolean\", optional: true },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const loading = asBoolean(props.loading);\n const iconOnly = asBoolean(props.iconOnly);\n const iconPosition = asString(props.iconPosition, \"leading\");\n const labelText = asString(props.label);\n const button = el(\"button\", {\n class: \"rui-button\",\n type: asString(props.type, \"button\"),\n \"data-variant\": asString(props.variant, \"primary\"),\n \"data-size\": normaliseButtonSize(props.size),\n \"data-icon-position\": iconPosition,\n \"data-icon-only\": iconOnly ? \"true\" : null,\n \"data-full-width\": asBoolean(props.fullWidth) ? \"true\" : null,\n \"data-loading\": loading ? \"true\" : null,\n \"aria-label\": iconOnly ? labelText : null,\n disabled: asBoolean(props.disabled) || loading ? \"\" : null,\n });\n const labelSpan = el(\"span\", { class: \"rui-button-label\" }, [labelText]);\n const iconNode = renderIcon(props.icon, { className: \"rui-button-icon\" });\n const spinNode = loading ? renderIcon(\"spinner\", { className: \"rui-button-spinner\" }) : null;\n const adornment = spinNode ?? iconNode;\n if (iconOnly) {\n if (adornment) button.append(adornment);\n } else if (iconPosition === \"trailing\") {\n button.append(labelSpan);\n if (adornment) button.append(adornment);\n } else {\n if (adornment) button.append(adornment);\n button.append(labelSpan);\n }\n button.onclick = () => {\n if (loading) return;\n helpers.invoke(props.action);\n };\n return button;\n },\n};\n\nexport const Buttons: ComponentSpec = {\n name: \"Buttons\",\n description: \"Group of buttons laid out horizontally or vertically.\",\n props: [\n { name: \"items\", type: \"Button[]\" },\n { name: \"direction\", type: \"string\", optional: true, enum: [\"row\", \"column\"] },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", {\n class: \"rui-buttons\",\n \"data-direction\": asString(props.direction, \"row\"),\n });\n for (const child of asArray(props.items)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nexport const Input: ComponentSpec = {\n name: \"Input\",\n description: \"Text input field. Pass a $variable as `value` for two-way binding.\",\n props: [\n { name: \"id\", type: \"string\", description: \"Input identifier\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"type\", type: \"string\", optional: true, enum: INPUT_TYPES },\n { name: \"validations\", type: \"any\", optional: true, description: \"Array or object of validation hints\" },\n { name: \"value\", type: \"any\", optional: true, description: \"Bound value (typically $variable)\" },\n ],\n render: (node, props, helpers) => {\n const input = el(\"input\", {\n class: \"rui-input\",\n id: asString(props.id),\n name: asString(props.id),\n type: asString(props.type, \"text\"),\n placeholder: asString(props.placeholder),\n value: asString(props.value),\n });\n bindToStateAtArg(input, node, 4, helpers);\n applyValidations(input, props.validations);\n return input;\n },\n};\n\nexport const TextArea: ComponentSpec = {\n name: \"TextArea\",\n description: \"Multi-line text input.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"rows\", type: \"number\", optional: true },\n { name: \"value\", type: \"any\", optional: true },\n ],\n render: (node, props, helpers) => {\n const textarea = el(\"textarea\", {\n class: \"rui-textarea\",\n id: asString(props.id),\n name: asString(props.id),\n placeholder: asString(props.placeholder),\n rows: String(Number(props.rows ?? 4) || 4),\n });\n textarea.value = asString(props.value);\n bindToStateAtArg(textarea, node, 3, helpers);\n return textarea;\n },\n};\n\nexport const SelectItem: ComponentSpec = {\n name: \"SelectItem\",\n description: \"Single option for a Select component.\",\n props: [\n { name: \"value\", type: \"string\" },\n { name: \"label\", type: \"string\" },\n ],\n render: (_node, props) => {\n return el(\"option\", { value: asString(props.value) }, [asString(props.label)]);\n },\n};\n\nexport const Select: ComponentSpec = {\n name: \"Select\",\n description:\n \"Dropdown select. Pass a `$variable` as `value` for two-way binding. \" +\n \"Set `searchable: true` for a combobox-style filter UI on long option lists.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"items\", type: \"SelectItem[]\" },\n { name: \"label\", type: \"string\", optional: true },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"value\", type: \"any\", optional: true },\n { name: \"searchable\", type: \"boolean\", optional: true, description: \"Render as a filterable combobox\" },\n ],\n render: (node, props, helpers) => {\n if (asBoolean(props.searchable)) {\n return renderSearchableSelect(node, props, helpers);\n }\n const select = el(\"select\", {\n class: \"rui-select\",\n id: asString(props.id),\n name: asString(props.id),\n });\n const placeholder = asString(props.placeholder);\n if (placeholder) {\n select.append(el(\"option\", { value: \"\", disabled: \"\", selected: \"\" }, [placeholder]));\n }\n for (const item of asArray(props.items)) {\n select.append(helpers.renderNode(item));\n }\n select.value = asString(props.value);\n bindToStateAtArg(select, node, 4, helpers);\n return select;\n },\n};\n\nexport const Checkbox: ComponentSpec = {\n name: \"Checkbox\",\n description: \"Boolean checkbox.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"label\", type: \"string\" },\n { name: \"value\", type: \"boolean\", optional: true, aliases: [\"checked\"] },\n ],\n render: (node, props, helpers) => {\n const wrapper = el(\"label\", { class: \"rui-checkbox\" });\n const isChecked = asBoolean(props.value);\n const input = el(\"input\", {\n type: \"checkbox\",\n id: asString(props.id),\n name: asString(props.id),\n checked: isChecked ? \"\" : null,\n }) as HTMLInputElement;\n input.checked = isChecked;\n bindToStateAtArg(input, node, 2, helpers);\n wrapper.append(input, el(\"span\", { class: \"rui-checkbox-label\" }, [asString(props.label)]));\n return wrapper;\n },\n};\n\nexport const CheckBoxItem: ComponentSpec = {\n name: \"CheckBoxItem\",\n description: \"Single option inside a CheckBoxGroup.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"name\", type: \"string\", description: \"Key inside the group's value object\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"defaultChecked\", type: \"boolean\", optional: true, aliases: [\"checked\"] },\n ],\n render: (_node, props) => {\n const itemName = asString(props.name);\n const label = asString(props.label);\n const description = asString(props.description);\n const isChecked = asBoolean(props.defaultChecked);\n const wrapper = el(\"label\", {\n class: \"rui-checkbox-item\",\n \"data-name\": itemName,\n });\n const input = el(\"input\", {\n type: \"checkbox\",\n name: itemName,\n checked: isChecked ? \"\" : null,\n }) as HTMLInputElement;\n input.checked = isChecked;\n const text = el(\"div\", { class: \"rui-checkbox-item-text\" });\n text.append(el(\"div\", { class: \"rui-checkbox-item-label\" }, [label]));\n if (description) text.append(el(\"div\", { class: \"rui-checkbox-item-description\" }, [description]));\n wrapper.append(input, text);\n return wrapper;\n },\n};\n\nexport const CheckBoxGroup: ComponentSpec = {\n name: \"CheckBoxGroup\",\n description: \"Group of checkboxes. Value is an object keyed by item name. Pass a `$variable` for two-way binding.\",\n props: [\n { name: \"name\", type: \"string\", description: \"Group identifier\" },\n { name: \"items\", type: \"CheckBoxItem[]\" },\n { name: \"value\", type: \"any\", optional: true, description: \"Bound value (typically $variable)\" },\n ],\n render: (node, props, helpers) => {\n const groupName = asString(props.name);\n const root = el(\"div\", { class: \"rui-checkbox-group\", role: \"group\", \"data-name\": groupName });\n const items = asArray<{ args?: unknown[] }>(props.items);\n const valueObject = (props.value && typeof props.value === \"object\")\n ? (props.value as Record<string, unknown>)\n : {};\n const inputs: HTMLInputElement[] = [];\n\n items.forEach((item, idx) => {\n const label = asString(item.args?.[0]);\n const itemName = asString(item.args?.[1], `${groupName}-${idx}`);\n const description = asString(item.args?.[2]);\n const defaultChecked = asBoolean(item.args?.[3]);\n const id = `${groupName}-${itemName}`;\n const wrapper = el(\"label\", { class: \"rui-checkbox-item\", for: id });\n const isChecked = itemName in valueObject\n ? Boolean(valueObject[itemName])\n : defaultChecked;\n const input = el(\"input\", {\n type: \"checkbox\",\n id,\n name: itemName,\n checked: isChecked ? \"\" : null,\n }) as HTMLInputElement;\n inputs.push(input);\n const text = el(\"div\", { class: \"rui-checkbox-item-text\" });\n text.append(el(\"div\", { class: \"rui-checkbox-item-label\" }, [label]));\n if (description) text.append(el(\"div\", { class: \"rui-checkbox-item-description\" }, [description]));\n wrapper.append(input, text);\n root.append(wrapper);\n });\n\n const stateName = node.argMeta?.[2]?.stateRef;\n if (stateName) {\n helpers.bindState(root, stateName, {\n event: \"change\",\n // Read from the *live* DOM rooted at the event target, never from\n // the closure's `inputs` array. After a morph re-render those\n // captured input elements are detached and report stale `checked`.\n getValue: (rootEl) => {\n const out: Record<string, boolean> = {};\n rootEl\n .querySelectorAll<HTMLInputElement>('input[type=\"checkbox\"]')\n .forEach((input) => {\n out[input.name] = input.checked;\n });\n return out;\n },\n });\n }\n\n return root;\n },\n};\n\nexport const Radio: ComponentSpec = {\n name: \"Radio\",\n description: \"Radio button group.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"items\", type: \"SelectItem[]\" },\n { name: \"value\", type: \"any\", optional: true },\n ],\n render: (node, props, helpers) => {\n const groupName = asString(props.id);\n const root = el(\"div\", { class: \"rui-radio-group\", role: \"radiogroup\" });\n for (const item of asArray<{ args?: unknown[] }>(props.items)) {\n const value = asString(item.args?.[0]);\n const label = asString(item.args?.[1], value);\n const id = `${groupName}-${value}`;\n const itemRoot = el(\"label\", { class: \"rui-radio\", for: id });\n const isChecked = asString(props.value) === value;\n const input = el(\"input\", {\n type: \"radio\",\n id,\n name: groupName,\n value,\n checked: isChecked ? \"\" : null,\n }) as HTMLInputElement;\n input.checked = isChecked;\n bindToStateAtArg(input, node, 2, helpers);\n itemRoot.append(input, el(\"span\", { class: \"rui-radio-label\" }, [label]));\n root.append(itemRoot);\n }\n return root;\n },\n};\n\nexport const FormControl: ComponentSpec = {\n name: \"FormControl\",\n description: \"Labeled wrapper around a single form field.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"field\", type: \"Node\", aliases: [\"control\"] },\n { name: \"hint\", type: \"string\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-form-control\" });\n root.append(el(\"label\", { class: \"rui-form-label\" }, [asString(props.label)]));\n const fieldEl = helpers.renderNode(props.field);\n root.append(fieldEl);\n const hint = asString(props.hint);\n if (hint) root.append(el(\"p\", { class: \"rui-form-hint\" }, [hint]));\n return root;\n },\n};\n\nexport const SearchBar: ComponentSpec = {\n name: \"SearchBar\",\n description:\n \"Pre-styled search input with a leading magnifying-glass icon, optional \" +\n \"trailing submit button, and optional keyboard-shortcut hint. Pass a \" +\n \"`$variable` as `value` for two-way binding. Use anywhere a user \" +\n \"needs to filter content — toolbars, command bars, lists, headers.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"value\", type: \"string\", optional: true, description: \"Bound value (typically $variable)\" },\n { name: \"shortcut\", type: \"string\", optional: true, description: \"Keyboard hint chip on the right (e.g. \\\"/\\\")\" },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onClick\", \"onSubmit\"], description: \"Optional submit callable; clicking the trailing button or pressing Enter invokes it\" },\n { name: \"submitLabel\", type: \"string\", optional: true, description: \"Label for the trailing submit button (default \\\"Search\\\"). Omitted when no action is provided.\" },\n ],\n render: (node, props, helpers) => {\n const root = el(\"form\", { class: \"rui-search-bar\", role: \"search\" });\n root.onsubmit = (event) => {\n event.preventDefault();\n helpers.invoke(props.action);\n };\n const iconWrap = renderIcon(\"magnifying-glass\", { className: \"rui-search-bar-icon\" })\n ?? el(\"span\", { class: \"rui-search-bar-icon\", \"aria-hidden\": \"true\" });\n root.append(iconWrap);\n const input = el(\"input\", {\n class: \"rui-search-bar-input\",\n id: asString(props.id),\n name: asString(props.id),\n type: \"search\",\n placeholder: asString(props.placeholder, \"Search…\"),\n value: asString(props.value),\n autocomplete: \"off\",\n });\n bindToStateAtArg(input, node, 2, helpers);\n root.append(input);\n const shortcut = asString(props.shortcut);\n if (shortcut) root.append(el(\"span\", { class: \"rui-search-bar-shortcut\" }, [shortcut]));\n if (props.action != null) {\n const btn = el(\"button\", {\n type: \"submit\",\n class: \"rui-search-bar-submit\",\n }, [asString(props.submitLabel, \"Search\")]);\n root.append(btn);\n }\n return root;\n },\n};\n\nexport const Form: ComponentSpec = {\n name: \"Form\",\n description: \"Form container. Children FormControls render in order; buttons render at the bottom.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"buttons\", type: \"Buttons | Button\" },\n { name: \"fields\", type: \"FormControl[]\" },\n ],\n render: (_node, props, helpers) => {\n const form = el(\"form\", { class: \"rui-form\", id: asString(props.id) });\n form.onsubmit = (event) => event.preventDefault();\n for (const field of asArray(props.fields)) form.append(helpers.renderNode(field));\n if (props.buttons) {\n const actions = el(\"div\", { class: \"rui-form-actions\" });\n actions.append(helpers.renderNode(props.buttons));\n form.append(actions);\n }\n return form;\n },\n};\n\nexport const Slider: ComponentSpec = {\n name: \"Slider\",\n description:\n \"Range slider for selecting a single numeric value between `min` and \" +\n \"`max`. Pass a `$variable` as `value` for two-way binding. Useful for \" +\n \"filters, settings (volume, brightness), and parameter tuning.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"min\", type: \"number\", optional: true, description: \"Default 0\" },\n { name: \"max\", type: \"number\", optional: true, description: \"Default 100\" },\n { name: \"step\", type: \"number\", optional: true, description: \"Default 1\" },\n { name: \"value\", type: \"number\", optional: true, description: \"Bound value (typically $variable)\" },\n { name: \"label\", type: \"string\", optional: true },\n { name: \"showValue\", type: \"boolean\", optional: true, description: \"Render the current numeric value beside the slider\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const min = asNumber(props.min, 0);\n const max = asNumber(props.max, 100);\n const step = asNumber(props.step, 1);\n const value = asNumber(props.value, min);\n const root = el(\"div\", { class: \"rui-slider\", \"data-disabled\": asBoolean(props.disabled) ? \"true\" : \"false\" });\n const label = asString(props.label);\n const showValue = asBoolean(props.showValue);\n if (label || showValue) {\n const head = el(\"div\", { class: \"rui-slider-head\" });\n if (label) head.append(el(\"label\", { class: \"rui-slider-label\", for: id }, [label]));\n if (showValue) head.append(el(\"span\", { class: \"rui-slider-value\" }, [String(value)]));\n root.append(head);\n }\n const input = el(\"input\", {\n type: \"range\",\n class: \"rui-slider-input\",\n id,\n name: id,\n min: String(min),\n max: String(max),\n step: String(step),\n value: String(value),\n disabled: asBoolean(props.disabled) ? \"\" : null,\n }) as HTMLInputElement;\n // Update the inline value pill while dragging so the user gets feedback\n // before the state binding propagates back through a render tick.\n // NOTE: the morph copies `oninput` onto the *live* input, so we must\n // resolve sibling nodes from the event target — capturing `root` /\n // `input` here would point at the freshly-rendered (detached) tree.\n input.oninput = (event: Event) => {\n const target = event.currentTarget as HTMLInputElement | null;\n if (!target) return;\n const sliderRoot = target.closest(\".rui-slider\");\n const valueEl = sliderRoot?.querySelector(\".rui-slider-value\");\n if (valueEl) valueEl.textContent = target.value;\n };\n const stateName = node.argMeta?.[4]?.stateRef;\n if (stateName) {\n helpers.bindState(input, stateName, {\n event: \"input\",\n getValue: (n) => Number((n as HTMLInputElement).value),\n });\n }\n root.append(input);\n return root;\n },\n};\n\nexport const NumberInput: ComponentSpec = {\n name: \"NumberInput\",\n description:\n \"Numeric input with paired increment/decrement buttons. Use for \" +\n \"quantity steppers, integer settings, and any field where a `<input \" +\n \"type=\\\"number\\\">` plus +/- controls is friendlier than the native \" +\n \"spinner. Pass a `$variable` as `value` for two-way binding.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"value\", type: \"number\", optional: true, description: \"Bound value (typically $variable)\" },\n { name: \"min\", type: \"number\", optional: true },\n { name: \"max\", type: \"number\", optional: true },\n { name: \"step\", type: \"number\", optional: true, description: \"Default 1\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const step = asNumber(props.step, 1);\n const hasMin = props.min !== undefined && props.min !== null;\n const hasMax = props.max !== undefined && props.max !== null;\n const min = hasMin ? asNumber(props.min, 0) : Number.NEGATIVE_INFINITY;\n const max = hasMax ? asNumber(props.max, 0) : Number.POSITIVE_INFINITY;\n const disabled = asBoolean(props.disabled);\n const root = el(\"div\", { class: \"rui-number-input\", \"data-disabled\": disabled ? \"true\" : \"false\" });\n const decBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-number-input-button\",\n \"data-direction\": \"down\",\n \"aria-label\": \"Decrement\",\n disabled: disabled ? \"\" : null,\n }, [\"−\"]);\n const input = el(\"input\", {\n type: \"number\",\n class: \"rui-number-input-field\",\n id,\n name: id,\n value: asString(props.value),\n placeholder: asString(props.placeholder),\n min: hasMin ? String(min) : null,\n max: hasMax ? String(max) : null,\n step: String(step),\n disabled: disabled ? \"\" : null,\n }) as HTMLInputElement;\n const incBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-number-input-button\",\n \"data-direction\": \"up\",\n \"aria-label\": \"Increment\",\n disabled: disabled ? \"\" : null,\n }, [\"+\"]);\n const stateName = node.argMeta?.[1]?.stateRef;\n if (stateName) {\n helpers.bindState(input, stateName, {\n event: \"input\",\n getValue: (n) => {\n const raw = (n as HTMLInputElement).value;\n if (raw === \"\") return null;\n const num = Number(raw);\n return Number.isFinite(num) ? num : null;\n },\n });\n }\n const adjust = (origin: Element, delta: number): void => {\n // Resolve the *live* input via the DOM. The `input` captured by this\n // closure points at the freshly-rendered node, which is detached\n // once the morph reconciler reuses the previous one.\n const liveRoot = origin.closest(\".rui-number-input\");\n const live = liveRoot?.querySelector<HTMLInputElement>(\".rui-number-input-field\");\n if (!live) return;\n const current = Number(live.value);\n const base = Number.isFinite(current) ? current : 0;\n const next = clampNumber(base + delta, min, max);\n live.value = String(next);\n live.dispatchEvent(new Event(\"input\", { bubbles: true }));\n };\n decBtn.onclick = (event) => adjust((event.currentTarget ?? event.target) as Element, -step);\n incBtn.onclick = (event) => adjust((event.currentTarget ?? event.target) as Element, step);\n root.append(decBtn, input, incBtn);\n return root;\n },\n};\n\nexport const DatePicker: ComponentSpec = {\n name: \"DatePicker\",\n description:\n \"Date picker that wraps the native `<input type=\\\"date\\\">` with \" +\n \"consistent styling. Pass a `$variable` as `value` for two-way binding. \" +\n \"Use `min`/`max` to bound the selectable range.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"value\", type: \"string\", optional: true, description: \"ISO date (YYYY-MM-DD); typically $variable\" },\n { name: \"label\", type: \"string\", optional: true },\n { name: \"min\", type: \"string\", optional: true, description: \"Earliest ISO date\" },\n { name: \"max\", type: \"string\", optional: true, description: \"Latest ISO date\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const root = el(\"div\", { class: \"rui-date-picker\" });\n const label = asString(props.label);\n if (label) root.append(el(\"label\", { class: \"rui-date-picker-label\", for: id }, [label]));\n const input = el(\"input\", {\n type: \"date\",\n class: \"rui-date-picker-input\",\n id,\n name: id,\n value: asString(props.value),\n min: asString(props.min) || null,\n max: asString(props.max) || null,\n placeholder: asString(props.placeholder),\n disabled: asBoolean(props.disabled) ? \"\" : null,\n });\n bindToStateAtArg(input, node, 1, helpers);\n root.append(input);\n return root;\n },\n};\n\nexport const FileUpload: ComponentSpec = {\n name: \"FileUpload\",\n description:\n \"Styled file picker. Renders a click/drop area with a leading icon, \" +\n \"label, and helper text. Files cannot round-trip through `$variables` \" +\n \"(they are not serialisable), so pass a callable as `action` to handle \" +\n \"the picked files via `ctx.query(\\\"#id\\\").files`.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"label\", type: \"string\", optional: true, description: \"Primary label (default \\\"Choose a file\\\")\" },\n { name: \"hint\", type: \"string\", optional: true, description: \"Secondary helper text\" },\n { name: \"accept\", type: \"string\", optional: true, description: \"Comma-separated MIME types or extensions\" },\n { name: \"multiple\", type: \"boolean\", optional: true },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onChange\", \"onSelect\"], description: \"Callable fired when files are picked\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon (default \\\"cloud-arrow-up\\\")\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const id = asString(props.id);\n const disabled = asBoolean(props.disabled);\n const root = el(\"div\", {\n class: \"rui-file-upload\",\n \"data-disabled\": disabled ? \"true\" : \"false\",\n });\n const dropZone = el(\"label\", {\n class: \"rui-file-upload-dropzone\",\n for: id,\n });\n const iconNode = renderIcon(asString(props.icon, \"cloud-arrow-up\"), { className: \"rui-file-upload-icon\" });\n if (iconNode) dropZone.append(iconNode);\n const text = el(\"div\", { class: \"rui-file-upload-text\" });\n text.append(el(\"div\", { class: \"rui-file-upload-label\" }, [asString(props.label, \"Choose a file\")]));\n const hint = asString(props.hint);\n if (hint) text.append(el(\"div\", { class: \"rui-file-upload-hint\" }, [hint]));\n dropZone.append(text);\n const input = el(\"input\", {\n type: \"file\",\n id,\n name: id,\n class: \"rui-file-upload-input\",\n accept: asString(props.accept) || null,\n multiple: asBoolean(props.multiple) ? \"\" : null,\n disabled: disabled ? \"\" : null,\n });\n dropZone.append(input);\n root.append(dropZone);\n\n const isImageFile = (file: File, accept: string): boolean =>\n accept.includes(\"image\") ||\n file.type.startsWith(\"image/\") ||\n /\\.(png|jpe?g|gif|webp|svg|avif|bmp)$/i.test(file.name);\n\n input.onchange = (event) => {\n helpers.invoke(props.action);\n const fileInput = event.currentTarget as HTMLInputElement;\n const uploadRoot = fileInput.closest(\".rui-file-upload\") as HTMLElement | null;\n if (!uploadRoot) return;\n const files = fileInput.files;\n const existing = uploadRoot.querySelector(\".rui-file-upload-preview\");\n if (existing) existing.remove();\n if (!files || files.length === 0) return;\n const accept = asString(props.accept);\n const preview = el(\"div\", { class: \"rui-file-upload-preview\" });\n Array.from(files).forEach((file) => {\n const row = el(\"div\", { class: \"rui-file-upload-preview-item\" });\n if (isImageFile(file, accept)) {\n const objectUrl = URL.createObjectURL(file);\n const img = el(\"img\", {\n src: objectUrl,\n alt: file.name,\n class: \"rui-file-upload-thumbnail\",\n }) as HTMLImageElement;\n // Revoke the object URL when the image has rendered so memory is\n // released. Browsers keep the bitmap cached after decode so the\n // src can be safely revoked once `load` fires.\n img.onload = () => URL.revokeObjectURL(objectUrl);\n row.append(img);\n }\n row.append(el(\"span\", { class: \"rui-file-upload-filename\" }, [file.name]));\n preview.append(row);\n });\n uploadRoot.append(preview);\n };\n return root;\n },\n};\n\nexport const Combobox: ComponentSpec = {\n name: \"Combobox\",\n description:\n \"Searchable single-select dropdown — type to filter, click an option \" +\n \"to choose. Use instead of `Select` when the list is long enough that \" +\n \"scanning is faster than scrolling (countries, currencies, repos, \" +\n \"users). Pass a `$variable` as `value` for two-way binding; the \" +\n \"selected option's `value` is written to state on pick.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"items\", type: \"SelectItem[]\", description: \"Options; SelectItem(value, label) or {value, label}\" },\n { name: \"value\", type: \"string\", optional: true, description: \"Bound selected value (typically $variable)\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"emptyLabel\", type: \"string\", optional: true, description: \"Text shown when no items match the filter (default \\\"No matches\\\")\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n { name: \"open\", type: \"boolean\", optional: true, description: \"Initial open state — use to demo or pre-open the dropdown\" },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const items = extractComboboxItems(props.items);\n const currentValue = asString(props.value);\n const currentLabel = items.find((item) => item.value === currentValue)?.label ?? currentValue;\n const placeholder = asString(props.placeholder, \"Select…\");\n const emptyLabel = asString(props.emptyLabel, \"No matches\");\n const disabled = asBoolean(props.disabled);\n const initialOpen = asBoolean(props.open);\n const openSlot = helpers.useInstanceState<boolean>(\"open\", initialOpen);\n const filterSlot = helpers.useInstanceState<string>(\"filter\", \"\");\n const isOpen = openSlot.get();\n\n const root = el(\"div\", {\n class: \"rui-combobox\",\n \"data-open\": isOpen ? \"true\" : \"false\",\n \"data-disabled\": disabled ? \"true\" : \"false\",\n });\n const triggerBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-combobox-trigger\",\n id,\n \"aria-haspopup\": \"listbox\",\n \"aria-expanded\": isOpen ? \"true\" : \"false\",\n disabled: disabled ? \"\" : null,\n });\n triggerBtn.append(el(\"span\", {\n class: \"rui-combobox-value\",\n \"data-placeholder\": currentLabel ? \"false\" : \"true\",\n }, [currentLabel || placeholder]));\n const chevron = renderIcon(\"chevron-down\", { className: \"rui-combobox-chevron\" });\n if (chevron) triggerBtn.append(chevron);\n root.append(triggerBtn);\n\n const panel = el(\"div\", { class: \"rui-combobox-panel\", role: \"listbox\" });\n const filterInput = el(\"input\", {\n type: \"text\",\n class: \"rui-combobox-filter\",\n placeholder: \"Filter…\",\n autocomplete: \"off\",\n value: filterSlot.get(),\n }) as HTMLInputElement;\n panel.append(filterInput);\n const list = el(\"div\", { class: \"rui-combobox-list\" });\n panel.append(list);\n\n // Re-paint the option list into the supplied container. When the\n // user types into the filter input on a re-rendered combobox the\n // closure-captured `list` reference points at the (detached)\n // freshly-rendered DOM; the live target is the only thing that\n // actually shows in the page, so we accept it as an argument and let\n // each call site resolve it from the live tree.\n const renderList = (target: HTMLElement, filter: string): void => {\n target.replaceChildren();\n const lower = filter.trim().toLowerCase();\n const matches = lower === \"\"\n ? items\n : items.filter((item) =>\n item.label.toLowerCase().includes(lower) ||\n item.value.toLowerCase().includes(lower),\n );\n if (matches.length === 0) {\n target.append(el(\"div\", { class: \"rui-combobox-empty\" }, [emptyLabel]));\n return;\n }\n for (const item of matches) {\n const option = el(\"button\", {\n type: \"button\",\n class: \"rui-combobox-option\",\n role: \"option\",\n \"data-value\": item.value,\n \"aria-selected\": item.value === currentValue ? \"true\" : \"false\",\n }, [item.label]);\n option.onclick = (event) => {\n event.stopPropagation();\n selectComboboxValue(event.currentTarget as Element, item.value);\n };\n target.append(option);\n }\n };\n\n // Apply a value as the bound state, then close the combobox UI. Also\n // disposes any pending dismissal listeners so we don't accumulate them\n // after a successful pick (the previous implementation only cleaned\n // them up on outside-click / Escape).\n const selectComboboxValue = (origin: Element, value: string): void => {\n const stateName = node.argMeta?.[2]?.stateRef;\n if (stateName) {\n helpers.setState(stateName, value);\n }\n openSlot.set(false);\n filterSlot.set(\"\");\n const live = origin.closest(\".rui-combobox\") as HTMLElement | null;\n live?.setAttribute(\"data-open\", \"false\");\n live?.querySelector(\".rui-combobox-trigger\")\n ?.setAttribute(\"aria-expanded\", \"false\");\n disposeDismissListeners(live);\n };\n\n renderList(list, filterSlot.get());\n\n filterInput.oninput = (event) => {\n const target = event.currentTarget as HTMLInputElement;\n filterSlot.set(target.value);\n const liveList = target.closest(\".rui-combobox-panel\")\n ?.querySelector(\".rui-combobox-list\") as HTMLElement | null;\n if (liveList) renderList(liveList, target.value);\n };\n\n // Enter on the filter selects the first visible option, matching the\n // type-ahead behaviour that users expect from native comboboxes. We\n // resolve the option from the live DOM so the handler survives morph.\n filterInput.onkeydown = (event) => {\n const e = event as KeyboardEvent;\n if (e.key !== \"Enter\") return;\n e.preventDefault();\n const target = e.currentTarget as HTMLInputElement;\n const live = target.closest(\".rui-combobox\");\n const firstOption = live?.querySelector<HTMLElement>(\n \".rui-combobox-option[data-value]\",\n );\n const value = firstOption?.getAttribute(\"data-value\");\n if (value !== null && value !== undefined && firstOption) {\n selectComboboxValue(firstOption, value);\n }\n };\n\n triggerBtn.onclick = (event) => {\n if (disabled) return;\n event.stopPropagation();\n const next = !openSlot.get();\n openSlot.set(next);\n const live = (event.currentTarget as Element).closest(\".rui-combobox\") as HTMLElement | null;\n live?.setAttribute(\"data-open\", next ? \"true\" : \"false\");\n live?.querySelector(\".rui-combobox-trigger\")\n ?.setAttribute(\"aria-expanded\", next ? \"true\" : \"false\");\n if (!live) return;\n if (!next) {\n // Close path: release any listeners that an earlier open() installed.\n disposeDismissListeners(live);\n return;\n }\n // Focus the filter so users can type immediately. Defer one tick so\n // the element is in the DOM after attribute updates settle.\n setTimeout(() => filterInput.focus(), 0);\n installDismissListeners({\n liveRoot: live,\n onDismiss: () => {\n openSlot.set(false);\n filterSlot.set(\"\");\n live.setAttribute(\"data-open\", \"false\");\n live.querySelector(\".rui-combobox-trigger\")\n ?.setAttribute(\"aria-expanded\", \"false\");\n },\n });\n };\n root.append(panel);\n return root;\n },\n};\n\nexport const MultiSelect: ComponentSpec = {\n name: \"MultiSelect\",\n description:\n \"Multi-option searchable dropdown. Type to filter, click an option to \" +\n \"add/remove it from the bound array. Renders the selected options as \" +\n \"removable chips inside the trigger. Pass a `$variable` (array of \" +\n \"values) as `value` for two-way binding.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"items\", type: \"SelectItem[]\", description: \"Options; SelectItem(value, label) or {value, label}\" },\n { name: \"value\", type: \"any[]\", optional: true, description: \"Bound array of selected values (typically $variable)\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"emptyLabel\", type: \"string\", optional: true, description: \"Text shown when no items match the filter\" },\n { name: \"max\", type: \"number\", optional: true, description: \"Maximum number of selections\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n { name: \"open\", type: \"boolean\", optional: true, description: \"Initial open state — use to demo or pre-open the dropdown\" },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const items = extractComboboxItems(props.items);\n const placeholder = asString(props.placeholder, \"Select…\");\n const emptyLabel = asString(props.emptyLabel, \"No matches\");\n const disabled = asBoolean(props.disabled);\n const max = Math.max(0, Math.floor(Number(props.max ?? 0)));\n const selected = Array.isArray(props.value)\n ? (props.value as unknown[]).map((v) => asString(v)).filter(Boolean)\n : [];\n const selectedSet = new Set(selected);\n const stateName = node.argMeta?.[2]?.stateRef;\n\n const initialOpen = asBoolean(props.open);\n const openSlot = helpers.useInstanceState<boolean>(\"open\", initialOpen);\n const filterSlot = helpers.useInstanceState<string>(\"filter\", \"\");\n const isOpen = openSlot.get();\n\n const root = el(\"div\", {\n class: \"rui-multiselect\",\n \"data-open\": isOpen ? \"true\" : \"false\",\n \"data-disabled\": disabled ? \"true\" : \"false\",\n });\n\n const triggerBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-multiselect-trigger\",\n id,\n \"aria-haspopup\": \"listbox\",\n \"aria-expanded\": isOpen ? \"true\" : \"false\",\n disabled: disabled ? \"\" : null,\n });\n const chipRow = el(\"span\", { class: \"rui-multiselect-chips\" });\n const writeSelection = (next: string[]): void => {\n if (!stateName) return;\n helpers.setState(stateName, next);\n };\n if (selected.length === 0) {\n chipRow.append(el(\"span\", { class: \"rui-multiselect-placeholder\" }, [placeholder]));\n } else {\n for (const value of selected) {\n const label = items.find((item) => item.value === value)?.label ?? value;\n const chip = el(\"span\", { class: \"rui-multiselect-chip\", \"data-value\": value });\n chip.append(el(\"span\", { class: \"rui-multiselect-chip-label\" }, [label]));\n const removeBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-multiselect-chip-remove\",\n \"aria-label\": `Remove ${label}`,\n }, [\"×\"]);\n removeBtn.onclick = (event) => {\n event.stopPropagation();\n const next = selected.filter((v) => v !== value);\n writeSelection(next);\n };\n chip.append(removeBtn);\n chipRow.append(chip);\n }\n }\n triggerBtn.append(chipRow);\n const chevron = renderIcon(\"chevron-down\", { className: \"rui-multiselect-chevron\" });\n if (chevron) triggerBtn.append(chevron);\n root.append(triggerBtn);\n\n const panel = el(\"div\", { class: \"rui-multiselect-panel\", role: \"listbox\", \"aria-multiselectable\": \"true\" });\n const filterInput = el(\"input\", {\n type: \"text\",\n class: \"rui-multiselect-filter\",\n placeholder: \"Filter…\",\n autocomplete: \"off\",\n value: filterSlot.get(),\n }) as HTMLInputElement;\n panel.append(filterInput);\n const list = el(\"div\", { class: \"rui-multiselect-list\" });\n panel.append(list);\n\n // Paint into the *given* container so the input handler can pass the\n // live list element it found from `event.currentTarget` (the\n // closure-captured `list` is detached after morph keeps the previous\n // multiselect DOM).\n const renderList = (target: HTMLElement, filter: string): void => {\n target.replaceChildren();\n const lower = filter.trim().toLowerCase();\n const matches = lower === \"\"\n ? items\n : items.filter((item) =>\n item.label.toLowerCase().includes(lower) ||\n item.value.toLowerCase().includes(lower),\n );\n if (matches.length === 0) {\n target.append(el(\"div\", { class: \"rui-multiselect-empty\" }, [emptyLabel]));\n return;\n }\n for (const item of matches) {\n const isSelected = selectedSet.has(item.value);\n const atCap = !isSelected && max > 0 && selected.length >= max;\n const option = el(\"button\", {\n type: \"button\",\n class: \"rui-multiselect-option\",\n role: \"option\",\n \"data-value\": item.value,\n \"data-selected\": isSelected ? \"true\" : \"false\",\n \"aria-selected\": isSelected ? \"true\" : \"false\",\n disabled: atCap ? \"\" : null,\n });\n const checkbox = el(\"span\", { class: \"rui-multiselect-option-check\" });\n const checkIcon = renderIcon(isSelected ? \"check\" : \"\", { className: \"rui-multiselect-option-check-icon\" });\n if (checkIcon) checkbox.append(checkIcon);\n option.append(checkbox);\n option.append(el(\"span\", { class: \"rui-multiselect-option-label\" }, [item.label]));\n option.onclick = (event) => {\n event.stopPropagation();\n if (atCap) return;\n const next = isSelected\n ? selected.filter((v) => v !== item.value)\n : [...selected, item.value];\n writeSelection(next);\n };\n target.append(option);\n }\n };\n\n renderList(list, filterSlot.get());\n\n filterInput.oninput = (event) => {\n const target = event.currentTarget as HTMLInputElement;\n filterSlot.set(target.value);\n const liveList = target.closest(\".rui-multiselect-panel\")\n ?.querySelector(\".rui-multiselect-list\") as HTMLElement | null;\n if (liveList) renderList(liveList, target.value);\n };\n\n triggerBtn.onclick = (event) => {\n if (disabled) return;\n event.stopPropagation();\n const next = !openSlot.get();\n openSlot.set(next);\n const live = (event.currentTarget as Element).closest(\".rui-multiselect\") as HTMLElement | null;\n live?.setAttribute(\"data-open\", next ? \"true\" : \"false\");\n live?.querySelector(\".rui-multiselect-trigger\")\n ?.setAttribute(\"aria-expanded\", next ? \"true\" : \"false\");\n if (!live) return;\n if (!next) { disposeDismissListeners(live); return; }\n setTimeout(() => filterInput.focus(), 0);\n installDismissListeners({\n liveRoot: live,\n onDismiss: () => {\n openSlot.set(false);\n filterSlot.set(\"\");\n live.setAttribute(\"data-open\", \"false\");\n live.querySelector(\".rui-multiselect-trigger\")\n ?.setAttribute(\"aria-expanded\", \"false\");\n },\n });\n };\n\n root.append(panel);\n return root;\n },\n};\n\nexport const DateRangePicker: ComponentSpec = {\n name: \"DateRangePicker\",\n description:\n \"Paired date inputs with a single label, sharing the same min/max \" +\n \"range. Pass `$variable` references for both `from` and `to` to \" +\n \"two-way-bind a date range (ISO `YYYY-MM-DD` strings).\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"from\", type: \"string\", optional: true, description: \"ISO date start; typically $variable\" },\n { name: \"to\", type: \"string\", optional: true, description: \"ISO date end; typically $variable\" },\n { name: \"label\", type: \"string\", optional: true },\n { name: \"min\", type: \"string\", optional: true, description: \"Earliest selectable ISO date\" },\n { name: \"max\", type: \"string\", optional: true, description: \"Latest selectable ISO date\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const fromId = `${id}-from`;\n const toId = `${id}-to`;\n const min = asString(props.min);\n const max = asString(props.max);\n const disabled = asBoolean(props.disabled);\n const root = el(\"div\", { class: \"rui-date-range-picker\", \"data-disabled\": disabled ? \"true\" : \"false\" });\n const label = asString(props.label);\n if (label) root.append(el(\"label\", { class: \"rui-date-range-picker-label\", for: fromId }, [label]));\n const row = el(\"div\", { class: \"rui-date-range-picker-row\" });\n const fromInput = el(\"input\", {\n type: \"date\",\n class: \"rui-date-range-picker-input\",\n id: fromId,\n name: fromId,\n value: asString(props.from),\n min: min || null,\n max: max || null,\n disabled: disabled ? \"\" : null,\n \"data-role\": \"from\",\n });\n row.append(fromInput);\n row.append(el(\"span\", { class: \"rui-date-range-picker-separator\", \"aria-hidden\": \"true\" }, [\"–\"]));\n const toInput = el(\"input\", {\n type: \"date\",\n class: \"rui-date-range-picker-input\",\n id: toId,\n name: toId,\n value: asString(props.to),\n min: min || null,\n max: max || null,\n disabled: disabled ? \"\" : null,\n \"data-role\": \"to\",\n });\n row.append(toInput);\n root.append(row);\n const fromState = node.argMeta?.[1]?.stateRef;\n const toState = node.argMeta?.[2]?.stateRef;\n if (fromState) helpers.bindState(fromInput, fromState);\n if (toState) helpers.bindState(toInput, toState);\n return root;\n },\n};\n\nfunction clampNumber(value: number, min: number, max: number): number {\n if (Number.isNaN(value)) return min === Number.NEGATIVE_INFINITY ? 0 : min;\n return Math.min(Math.max(value, min), max);\n}\n\n/** Searchable `Select` delegates to the Combobox renderer (value binds at arg index 4). */\nfunction renderSearchableSelect(\n node: ComponentNode,\n props: Record<string, unknown>,\n helpers: RenderHelpers,\n): Node {\n const meta = node.argMeta ? [...node.argMeta] : [];\n while (meta.length < 5) meta.push({});\n if (meta[4]?.stateRef) meta[2] = meta[4];\n const root = Combobox.render(\n { ...node, argMeta: meta } as ComponentNode,\n {\n id: props.id,\n items: props.items,\n value: props.value,\n placeholder: props.placeholder,\n emptyLabel: \"No matches\",\n disabled: false,\n },\n helpers,\n ) as HTMLElement;\n root.classList.add(\"rui-select-searchable\");\n return root;\n}\n\nfunction bindToStateAtArg(\n element: HTMLElement,\n node: { argMeta?: { stateRef?: string }[] },\n argIndex: number,\n helpers: {\n bindState: (\n el: HTMLElement,\n name: string,\n opts?: { event?: string; getValue?: (el: HTMLElement) => unknown },\n ) => void;\n },\n): void {\n const stateName = node.argMeta?.[argIndex]?.stateRef;\n if (!stateName) return;\n if (element instanceof HTMLInputElement && element.type === \"checkbox\") {\n helpers.bindState(element, stateName, {\n event: \"change\",\n getValue: (n) => (n as HTMLInputElement).checked,\n });\n return;\n }\n helpers.bindState(element, stateName);\n}\n\nfunction applyValidations(input: HTMLInputElement, validations: unknown): void {\n if (!validations) return;\n const list = Array.isArray(validations)\n ? validations.map((v) => String(v))\n : typeof validations === \"object\"\n ? Object.entries(validations as Record<string, unknown>).map(([k, v]) => (v ? `${k}:${v}` : k))\n : [];\n for (const v of list) {\n if (v === \"required\") input.required = true;\n else if (v.startsWith(\"minLength:\")) input.minLength = Number(v.slice(\"minLength:\".length)) || 0;\n else if (v.startsWith(\"maxLength:\")) input.maxLength = Number(v.slice(\"maxLength:\".length)) || 0;\n else if (v === \"email\") input.type = \"email\";\n }\n}\n","/**\n * Rich, opinionated layout patterns the LLM can reach for in a single line.\n *\n * Each component packs an entire UI idiom (hero, page header, empty state,\n * timeline, kanban board, …) into a small, predictable signature. The goal is\n * to let the LLM emit beautiful, dense UI without composing dozens of nested\n * primitives — the components below handle the visual hierarchy internally.\n *\n * Everything here is presentational: state binding is delegated to the\n * primitives the patterns embed (Button, Card, etc.), so the patterns stay\n * stateless and composable.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport {\n el, asArray, asString, asBoolean, asNumber, renderIcon,\n sanitiseCssLength, sanitiseCssUrl, sanitiseImageSrc,\n} from \"../utils.js\";\nimport { renderAvatar, pickIconForLabel, pickIconForTone } from \"./_internal.js\";\nimport { SearchBar } from \"./forms.js\";\nimport { Grid } from \"./layout.js\";\n\nconst SURFACE_TONES = [\"default\", \"primary\", \"success\", \"warning\", \"danger\", \"info\"] as const;\n\nconst renderActionsRow = (\n raw: unknown,\n helpers: { renderNode: (n: unknown) => Node },\n): HTMLElement | null => {\n const items = asArray<unknown>(raw);\n if (items.length === 0) return null;\n const row = el(\"div\", { class: \"rui-pattern-actions\" });\n for (const item of items) row.append(helpers.renderNode(item));\n return row;\n};\n\n/**\n * Pick a short eyebrow tag for a Hero based on intent keywords in its title\n * or subtitle. Returns the empty string when no rule matches so the caller\n * can decide whether to render the band at all.\n */\nconst HERO_EYEBROW_RULES: Array<{ match: RegExp; label: string }> = [\n { match: /\\bbeta\\b/i, label: \"Beta\" },\n { match: /\\b(early\\s?access|preview)\\b/i, label: \"Preview\" },\n { match: /\\b(introduc(?:ing|e)|launch(?:ed|ing)?|announcing)\\b/i, label: \"Introducing\" },\n { match: /\\b(welcome\\b|get(?:ting)?\\s?started)/i, label: \"Welcome\" },\n { match: /\\b(new\\b|whats\\s?new|now\\b)/i, label: \"What's new\" },\n { match: /\\bfree\\b/i, label: \"Free trial\" },\n { match: /\\bupgrade\\b/i, label: \"Upgrade\" },\n { match: /\\b(sale|discount|deal)\\b/i, label: \"Limited time\" },\n];\n\nfunction deriveHeroEyebrow(title: string, subtitle: string): string {\n const haystack = `${title} ${subtitle}`.trim();\n if (!haystack) return \"\";\n for (const rule of HERO_EYEBROW_RULES) {\n if (rule.match.test(haystack)) return rule.label;\n }\n return \"\";\n}\n\nexport const Hero: ComponentSpec = {\n name: \"Hero\",\n description:\n \"Eye-catching landing/marketing header with eyebrow tag, title, subtitle, \" +\n \"optional bullet highlights, and primary/secondary CTA buttons. Use \" +\n \"`layout=\\\"cover\\\"` with `imageSrc` for an image-backed hero band \" +\n \"(pass `height` and optional `caption`). Default layout shows an \" +\n \"optional side illustration.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"subtitle\", type: \"string\", optional: true },\n { name: \"primary\", type: \"Button\", optional: true, description: \"Primary CTA — pass a Button(...)\" },\n { name: \"secondary\", type: \"Button\", optional: true, description: \"Secondary CTA — pass a Button(...)\" },\n { name: \"eyebrow\", type: \"string\", optional: true, description: \"Short uppercase tag above the title\" },\n { name: \"highlights\", type: \"string[]\", optional: true, description: \"Bullet items rendered as tag pills\" },\n { name: \"imageSrc\", type: \"string\", optional: true, description: \"Illustration or cover background when layout=cover\" },\n { name: \"caption\", type: \"string\", optional: true, description: \"Small caption above CTAs (cover layout)\" },\n { name: \"height\", type: \"string\", optional: true, description: \"Min-height for cover layout (default 280px)\" },\n { name: \"actions\", type: \"Node[]\", optional: true, description: \"CTA row (cover layout; alternative to primary/secondary)\" },\n { name: \"layout\", type: \"string\", optional: true, enum: [\"default\", \"cover\"], description: \"default = text-first; cover = image-backed band\" },\n { name: \"tone\", type: \"string\", optional: true, enum: SURFACE_TONES, description: \"Accent tone\" },\n ],\n render: (_node, props, helpers) => {\n const layout = asString(props.layout, \"default\");\n const heroTitle = asString(props.title);\n const heroSubtitle = asString(props.subtitle);\n const explicitEyebrow = asString(props.eyebrow);\n const eyebrow = explicitEyebrow || deriveHeroEyebrow(heroTitle, heroSubtitle);\n const tone = asString(props.tone, \"primary\");\n\n if (layout === \"cover\") {\n const safeImageSrc = sanitiseCssUrl(asString(props.imageSrc));\n const safeHeight = sanitiseCssLength(asString(props.height), \"280px\");\n const root = el(\"section\", {\n class: \"rui-cover\",\n \"data-tone\": tone,\n style: `background-image:linear-gradient(180deg, rgba(15, 23, 42, 0.05) 0%, rgba(15, 23, 42, 0.62) 100%), url(\"${safeImageSrc}\");min-height:${safeHeight};`,\n });\n const body = el(\"div\", { class: \"rui-cover-body\" });\n if (eyebrow) body.append(el(\"span\", { class: \"rui-cover-eyebrow\" }, [eyebrow]));\n body.append(el(\"h1\", { class: \"rui-cover-title\" }, [heroTitle]));\n if (heroSubtitle) body.append(el(\"p\", { class: \"rui-cover-subtitle\" }, [heroSubtitle]));\n const caption = asString(props.caption);\n if (caption) body.append(el(\"p\", { class: \"rui-cover-caption\" }, [caption]));\n const actions = renderActionsRow(props.actions, helpers);\n if (actions) {\n actions.classList.add(\"rui-cover-actions\");\n body.append(actions);\n } else {\n const ctaItems = [props.primary, props.secondary].filter(Boolean);\n if (ctaItems.length > 0) {\n const ctas = el(\"div\", { class: \"rui-cover-actions rui-pattern-actions\" });\n for (const cta of ctaItems) ctas.append(helpers.renderNode(cta));\n body.append(ctas);\n }\n }\n root.append(body);\n return root;\n }\n\n const heroImageSrc = sanitiseImageSrc(props.imageSrc);\n const root = el(\"section\", {\n class: \"rui-hero\",\n \"data-tone\": tone,\n \"data-has-image\": heroImageSrc ? \"true\" : \"false\",\n });\n const body = el(\"div\", { class: \"rui-hero-body\" });\n if (eyebrow) body.append(el(\"span\", { class: \"rui-hero-eyebrow\" }, [eyebrow]));\n body.append(el(\"h1\", { class: \"rui-hero-title\" }, [heroTitle]));\n if (heroSubtitle) body.append(el(\"p\", { class: \"rui-hero-subtitle\" }, [heroSubtitle]));\n const highlights = asArray<unknown>(props.highlights);\n if (highlights.length > 0) {\n const tags = el(\"div\", { class: \"rui-hero-highlights\" });\n for (const h of highlights) {\n const label = asString(h);\n if (label) tags.append(el(\"span\", { class: \"rui-hero-highlight\" }, [label]));\n }\n body.append(tags);\n }\n const ctaItems = [props.primary, props.secondary].filter(Boolean);\n if (ctaItems.length > 0) {\n const ctas = el(\"div\", { class: \"rui-hero-ctas\" });\n for (const cta of ctaItems) ctas.append(helpers.renderNode(cta));\n body.append(ctas);\n }\n root.append(body);\n if (heroImageSrc) {\n const media = el(\"div\", { class: \"rui-hero-media\" });\n media.append(el(\"img\", { src: heroImageSrc, alt: \"\", loading: \"lazy\" }));\n root.append(media);\n }\n return root;\n },\n};\n\nexport const PageHeader: ComponentSpec = {\n name: \"PageHeader\",\n description:\n \"Page-level header with breadcrumbs, title, subtitle, status tag, and a \" +\n \"right-aligned actions row. The canonical first child for any dashboard, \" +\n \"settings, or detail page — replaces ad-hoc Stack+Header+Buttons stitching. \" +\n \"If `breadcrumbs` is omitted the component auto-derives `[\\\"Home\\\", title]` \" +\n \"so the page never lacks a trail. Pass `breadcrumbs=false` to opt out.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"subtitle\", type: \"string\", optional: true },\n { name: \"breadcrumbs\", type: \"string[] | Breadcrumb | false\", optional: true, description: \"Array of strings, a Breadcrumb(...) node, or `false` to suppress the auto-derived trail\" },\n { name: \"actions\", type: \"Node[]\", optional: true, description: \"Buttons / NavLinks shown on the right\" },\n { name: \"status\", type: \"Badge\", optional: true, aliases: [\"badge\"], description: \"Optional Badge(...) rendered next to the title\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"header\", { class: \"rui-page-header\" });\n\n const title = asString(props.title);\n // Default: auto-derive [\"Home\", title] when caller omits breadcrumbs.\n // Pass `breadcrumbs=false` to suppress (handy for sign-in screens).\n let crumbs: unknown = props.breadcrumbs;\n if (crumbs === undefined || crumbs === null) {\n if (title) crumbs = [\"Home\", title];\n } else if (crumbs === false || crumbs === \"false\") {\n crumbs = null;\n }\n\n if (crumbs) {\n const crumbWrap = el(\"div\", { class: \"rui-page-header-breadcrumbs\" });\n if (Array.isArray(crumbs)) {\n crumbs.forEach((c, i) => {\n if (i > 0) crumbWrap.append(el(\"span\", { class: \"rui-page-header-crumb-sep\" }, [\"/\"]));\n crumbWrap.append(el(\"span\", { class: \"rui-page-header-crumb\" }, [asString(c)]));\n });\n } else {\n crumbWrap.append(helpers.renderNode(crumbs));\n }\n root.append(crumbWrap);\n }\n\n const titleRow = el(\"div\", { class: \"rui-page-header-title-row\" });\n const titleBlock = el(\"div\", { class: \"rui-page-header-title-block\" });\n const titleLine = el(\"div\", { class: \"rui-page-header-title-line\" });\n titleLine.append(el(\"h1\", { class: \"rui-page-header-title\" }, [title]));\n if (props.status) titleLine.append(helpers.renderNode(props.status));\n titleBlock.append(titleLine);\n\n const subtitle = asString(props.subtitle);\n if (subtitle) titleBlock.append(el(\"p\", { class: \"rui-page-header-subtitle\" }, [subtitle]));\n titleRow.append(titleBlock);\n\n const actions = renderActionsRow(props.actions, helpers);\n if (actions) {\n actions.classList.add(\"rui-page-header-actions\");\n titleRow.append(actions);\n }\n\n root.append(titleRow);\n return root;\n },\n};\n\nexport const EmptyState: ComponentSpec = {\n name: \"EmptyState\",\n description:\n \"Zero-state placeholder for empty lists, searches, dashboards. Renders \" +\n \"a centered icon (or illustration), title, description, and either a \" +\n \"single `action` Button or an `actions` row (primary + secondary). \" +\n \"Always preferable to an empty Card with raw text.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name (defaults to \\\"inbox\\\")\" },\n { name: \"illustration\", type: \"string\", optional: true, description: \"Image URL — takes precedence over `icon` when provided\" },\n { name: \"action\", type: \"Button\", optional: true, description: \"Single CTA (legacy slot)\" },\n { name: \"actions\", type: \"Node[]\", optional: true, description: \"Row of CTA Buttons / Links — preferred over `action` for primary + secondary affordances\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-empty-state\" });\n const illustration = sanitiseImageSrc(props.illustration);\n if (illustration) {\n root.append(el(\"img\", {\n class: \"rui-empty-state-illustration\",\n src: illustration,\n alt: \"\",\n loading: \"lazy\",\n }));\n } else {\n const title = asString(props.title);\n const description = asString(props.description);\n const iconName =\n asString(props.icon) ||\n pickIconForLabel(`${title} ${description}`) ||\n \"inbox\";\n const iconNode = renderIcon(iconName, { className: \"rui-empty-state-icon\" });\n if (iconNode) root.append(iconNode);\n }\n root.append(el(\"h3\", { class: \"rui-empty-state-title\" }, [asString(props.title)]));\n const desc = asString(props.description);\n if (desc) root.append(el(\"p\", { class: \"rui-empty-state-description\" }, [desc]));\n const actions = asArray<unknown>(props.actions);\n if (actions.length > 0) {\n const row = el(\"div\", { class: \"rui-empty-state-actions\" });\n for (const item of actions) row.append(helpers.renderNode(item));\n root.append(row);\n } else if (props.action) {\n const wrap = el(\"div\", { class: \"rui-empty-state-action\" });\n wrap.append(helpers.renderNode(props.action));\n root.append(wrap);\n }\n return root;\n },\n};\n\nexport const TimelineItem: ComponentSpec = {\n name: \"TimelineItem\",\n description: \"Single event on a Timeline.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"time\", type: \"string\", optional: true, description: \"Display label (ISO, relative, etc.)\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name rendered inside the marker\" },\n { name: \"tone\", type: \"string\", optional: true, enum: SURFACE_TONES },\n ],\n render: (_node, props) => {\n const li = el(\"li\", {\n class: \"rui-timeline-item\",\n \"data-tone\": asString(props.tone, \"default\"),\n });\n const marker = el(\"span\", { class: \"rui-timeline-marker\" });\n const iconNode = renderIcon(props.icon);\n if (iconNode) marker.append(iconNode);\n li.append(marker);\n\n const body = el(\"div\", { class: \"rui-timeline-body\" });\n const head = el(\"div\", { class: \"rui-timeline-head\" });\n head.append(el(\"span\", { class: \"rui-timeline-title\" }, [asString(props.title)]));\n const time = asString(props.time);\n if (time) head.append(el(\"span\", { class: \"rui-timeline-time\" }, [time]));\n body.append(head);\n\n const desc = asString(props.description);\n if (desc) body.append(el(\"div\", { class: \"rui-timeline-description\" }, [desc]));\n\n li.append(body);\n return li;\n },\n};\n\nexport const Timeline: ComponentSpec = {\n name: \"Timeline\",\n description:\n \"Vertical event timeline. Children must be TimelineItem entries. Ideal \" +\n \"for activity feeds, changelogs, and process flows.\",\n props: [{ name: \"items\", type: \"TimelineItem[]\" }],\n render: (_node, props, helpers) => {\n const root = el(\"ol\", { class: \"rui-timeline\" });\n for (const item of asArray(props.items)) root.append(helpers.renderNode(item));\n return root;\n },\n};\n\nexport const FeatureItem: ComponentSpec = {\n name: \"FeatureItem\",\n description: \"Single tile on a FeatureGrid.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name shown in a colored disc\" },\n { name: \"tone\", type: \"string\", optional: true, enum: SURFACE_TONES },\n ],\n render: (_node, props) => {\n const root = el(\"div\", {\n class: \"rui-feature-item\",\n \"data-tone\": asString(props.tone, \"primary\"),\n });\n const iconName = asString(props.icon, \"sparkles\");\n const iconNode = renderIcon(iconName, { className: \"rui-feature-icon\" });\n if (iconNode) root.append(iconNode);\n root.append(el(\"h3\", { class: \"rui-feature-title\" }, [asString(props.title)]));\n const desc = asString(props.description);\n if (desc) root.append(el(\"p\", { class: \"rui-feature-description\" }, [desc]));\n return root;\n },\n};\n\nexport const FeatureGrid: ComponentSpec = {\n name: \"FeatureGrid\",\n description:\n \"Responsive grid of FeatureItem tiles (typically 2–3 columns). Use to \" +\n \"highlight product capabilities or page categories.\",\n props: [\n { name: \"items\", type: \"FeatureItem[]\" },\n { name: \"columns\", type: \"number\", optional: true, description: \"Preferred column count (default auto)\" },\n ],\n render: (_node, props, helpers) => {\n const columns = Math.max(1, Math.min(4, Number(props.columns ?? \"auto\")));\n const root = el(\"div\", {\n class: \"rui-feature-grid\",\n \"data-columns\": columns > 0 ? String(columns) : null,\n });\n for (const item of asArray(props.items)) root.append(helpers.renderNode(item));\n return root;\n },\n};\n\nexport const Testimonial: ComponentSpec = {\n name: \"Testimonial\",\n description: \"Quote card with author, role, and optional avatar.\",\n props: [\n { name: \"quote\", type: \"string\" },\n { name: \"author\", type: \"string\", aliases: [\"name\"] },\n { name: \"role\", type: \"string\", optional: true },\n { name: \"avatarSrc\", type: \"string\", optional: true, aliases: [\"src\"] },\n { name: \"rating\", type: \"number\", optional: true, description: \"0–5 stars\" },\n ],\n render: (_node, props) => {\n const root = el(\"figure\", { class: \"rui-testimonial\" });\n const rating = Math.max(0, Math.min(5, Math.round(Number(props.rating ?? 0))));\n if (rating > 0) {\n const stars = el(\"div\", { class: \"rui-testimonial-rating\" });\n for (let i = 0; i < 5; i += 1) {\n const filled = i < rating;\n const icon = renderIcon(filled ? \"star\" : \"regular:star\", { className: \"rui-testimonial-rating-star\" });\n if (icon) stars.append(icon);\n }\n root.append(stars);\n }\n root.append(el(\"blockquote\", { class: \"rui-testimonial-quote\" }, [\n asString(props.quote),\n ]));\n const footer = el(\"figcaption\", { class: \"rui-testimonial-author\" });\n const avatarSrc = sanitiseImageSrc(props.avatarSrc);\n if (avatarSrc) {\n footer.append(el(\"img\", { class: \"rui-testimonial-avatar\", src: avatarSrc, alt: \"\" }));\n }\n const meta = el(\"div\", { class: \"rui-testimonial-meta\" });\n meta.append(el(\"div\", { class: \"rui-testimonial-name\" }, [asString(props.author)]));\n const role = asString(props.role);\n if (role) meta.append(el(\"div\", { class: \"rui-testimonial-role\" }, [role]));\n footer.append(meta);\n root.append(footer);\n return root;\n },\n};\n\nexport const ProfileCard: ComponentSpec = {\n name: \"ProfileCard\",\n description:\n \"Compact profile/user card with avatar, name, role, optional bio, social \" +\n \"tags, and a row of action buttons. Use for team rosters, contributor \" +\n \"lists, and contact panels.\",\n props: [\n { name: \"name\", type: \"string\" },\n { name: \"role\", type: \"string\", optional: true },\n { name: \"avatarSrc\", type: \"string\", optional: true, aliases: [\"src\"], description: \"Avatar image src; falls back to initials\" },\n { name: \"bio\", type: \"string\", optional: true },\n { name: \"tags\", type: \"string[]\", optional: true },\n { name: \"actions\", type: \"Node[]\", optional: true, description: \"Buttons to render at the bottom\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-profile-card\" });\n const header = el(\"div\", { class: \"rui-profile-card-header\" });\n header.append(renderAvatar(asString(props.avatarSrc), asString(props.name), \"lg\"));\n const meta = el(\"div\", { class: \"rui-profile-card-meta\" });\n meta.append(el(\"h3\", { class: \"rui-profile-card-name\" }, [asString(props.name)]));\n const role = asString(props.role);\n if (role) meta.append(el(\"p\", { class: \"rui-profile-card-role\" }, [role]));\n header.append(meta);\n root.append(header);\n\n const bio = asString(props.bio);\n if (bio) root.append(el(\"p\", { class: \"rui-profile-card-bio\" }, [bio]));\n\n const tags = asArray<unknown>(props.tags);\n if (tags.length > 0) {\n const tagRow = el(\"div\", { class: \"rui-profile-card-tags\" });\n for (const t of tags) {\n const label = asString(t);\n if (label) tagRow.append(el(\"span\", { class: \"rui-tag\", \"data-size\": \"sm\" }, [\n el(\"span\", { class: \"rui-tag-label\" }, [label]),\n ]));\n }\n root.append(tagRow);\n }\n\n const actions = renderActionsRow(props.actions, helpers);\n if (actions) {\n actions.classList.add(\"rui-profile-card-actions\");\n root.append(actions);\n }\n return root;\n },\n};\n\nexport const Comment: ComponentSpec = {\n name: \"Comment\",\n description:\n \"Single comment / message bubble. Renders avatar, author, timestamp, \" +\n \"body, and an optional row of action buttons (reply, like, …).\",\n props: [\n { name: \"author\", type: \"string\" },\n { name: \"body\", type: \"string\", aliases: [\"text\", \"message\"] },\n { name: \"time\", type: \"string\", optional: true, description: \"Relative or absolute timestamp\" },\n { name: \"avatarSrc\", type: \"string\", optional: true, aliases: [\"src\"] },\n { name: \"actions\", type: \"Node[]\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"article\", { class: \"rui-comment\" });\n root.append(renderAvatar(asString(props.avatarSrc), asString(props.author), \"md\"));\n const body = el(\"div\", { class: \"rui-comment-body\" });\n const head = el(\"header\", { class: \"rui-comment-header\" });\n head.append(el(\"span\", { class: \"rui-comment-author\" }, [asString(props.author)]));\n const time = asString(props.time);\n if (time) head.append(el(\"span\", { class: \"rui-comment-time\" }, [time]));\n body.append(head);\n body.append(el(\"div\", { class: \"rui-comment-content\" }, [asString(props.body)]));\n const actions = renderActionsRow(props.actions, helpers);\n if (actions) {\n actions.classList.add(\"rui-comment-actions\");\n body.append(actions);\n }\n root.append(body);\n return root;\n },\n};\n\nexport const Banner: ComponentSpec = {\n name: \"Banner\",\n description:\n \"Full-width announcement banner. Use at the top of a page for promos, \" +\n \"release notes, or downtime notices. For inline notices prefer Callout \" +\n \"or Alert.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"message\", type: \"string\", optional: true, aliases: [\"description\"] },\n { name: \"action\", type: \"Button\", optional: true },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name\" },\n { name: \"tone\", type: \"string\", optional: true, enum: SURFACE_TONES },\n ],\n render: (_node, props, helpers) => {\n const tone = asString(props.tone, \"primary\");\n const root = el(\"aside\", {\n class: \"rui-banner\",\n \"data-tone\": tone,\n });\n const iconName = asString(props.icon) || pickIconForTone(tone) || \"\";\n const iconNode = renderIcon(iconName, { className: \"rui-banner-icon\" });\n if (iconNode) root.append(iconNode);\n const body = el(\"div\", { class: \"rui-banner-body\" });\n body.append(el(\"strong\", { class: \"rui-banner-title\" }, [asString(props.title)]));\n const msg = asString(props.message);\n if (msg) body.append(el(\"span\", { class: \"rui-banner-message\" }, [msg]));\n root.append(body);\n if (props.action) {\n const wrap = el(\"div\", { class: \"rui-banner-action\" });\n wrap.append(helpers.renderNode(props.action));\n root.append(wrap);\n }\n return root;\n },\n};\n\nexport const KanbanCard: ComponentSpec = {\n name: \"KanbanCard\",\n description: \"Single card on a Kanban board.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"tags\", type: \"string[]\", optional: true },\n { name: \"assignee\", type: \"string\", optional: true, description: \"Name shown next to avatar initials\" },\n { name: \"tone\", type: \"string\", optional: true, enum: SURFACE_TONES },\n { name: \"icon\", type: \"string\", optional: true, description: \"Optional Font Awesome icon name shown beside the title\" },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onClick\", \"onclick\"], description: \"Optional callable fired when the card is clicked\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", {\n class: \"rui-kanban-card\",\n \"data-tone\": asString(props.tone, \"default\"),\n });\n if (typeof props.action === \"function\") {\n root.setAttribute(\"role\", \"button\");\n root.setAttribute(\"tabindex\", \"0\");\n root.onclick = () => helpers.invoke(props.action);\n root.onkeydown = (event) => {\n const e = event as KeyboardEvent;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n helpers.invoke(props.action);\n }\n };\n }\n const titleEl = el(\"div\", { class: \"rui-kanban-card-title\" });\n const iconNode = renderIcon(props.icon, { className: \"rui-kanban-card-icon\" });\n if (iconNode) titleEl.append(iconNode);\n titleEl.append(document.createTextNode(asString(props.title)));\n root.append(titleEl);\n const desc = asString(props.description);\n if (desc) root.append(el(\"p\", { class: \"rui-kanban-card-description\" }, [desc]));\n\n const tags = asArray<unknown>(props.tags);\n if (tags.length > 0) {\n const tagRow = el(\"div\", { class: \"rui-kanban-card-tags\" });\n for (const t of tags) {\n const label = asString(t);\n if (label) tagRow.append(el(\"span\", { class: \"rui-tag\", \"data-size\": \"sm\" }, [\n el(\"span\", { class: \"rui-tag-label\" }, [label]),\n ]));\n }\n root.append(tagRow);\n }\n\n const assignee = asString(props.assignee);\n if (assignee) {\n const footer = el(\"footer\", { class: \"rui-kanban-card-footer\" });\n footer.append(renderAvatar(\"\", assignee, \"sm\"));\n footer.append(el(\"span\", { class: \"rui-kanban-card-assignee\" }, [assignee]));\n root.append(footer);\n }\n return root;\n },\n};\n\nexport const KanbanColumn: ComponentSpec = {\n name: \"KanbanColumn\",\n description: \"Single column inside a KanbanBoard. Children must be KanbanCard entries.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"items\", type: \"KanbanCard[]\", aliases: [\"cards\"] },\n { name: \"tone\", type: \"string\", optional: true, enum: SURFACE_TONES, description: \"Header accent tone\" },\n ],\n render: (_node, props, helpers) => {\n const items = asArray<unknown>(props.items);\n const root = el(\"section\", {\n class: \"rui-kanban-column\",\n \"data-tone\": asString(props.tone, \"default\"),\n });\n const header = el(\"header\", { class: \"rui-kanban-column-header\" });\n header.append(el(\"span\", { class: \"rui-kanban-column-title\" }, [asString(props.title)]));\n header.append(el(\"span\", { class: \"rui-kanban-column-count\" }, [String(items.length)]));\n root.append(header);\n const body = el(\"div\", { class: \"rui-kanban-column-body\" });\n for (const item of items) body.append(helpers.renderNode(item));\n if (items.length === 0) {\n body.append(el(\"div\", { class: \"rui-kanban-column-empty\" }, [\"No items\"]));\n }\n root.append(body);\n return root;\n },\n};\n\nexport const KanbanBoard: ComponentSpec = {\n name: \"KanbanBoard\",\n description:\n \"Horizontal Kanban board. Children must be KanbanColumn entries. The \" +\n \"board scrolls horizontally on narrow viewports so columns stay readable.\",\n props: [{ name: \"columns\", type: \"KanbanColumn[]\" }],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-kanban-board\" });\n for (const column of asArray(props.columns)) root.append(helpers.renderNode(column));\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * Rich application-shell patterns\n *\n * These composites encode the most common SaaS-style page shells in a\n * single line, so the LLM can reach for them instead of stitching nested\n * Stacks/Cards by hand. They were added specifically to bridge the gap\n * between hand-rolled component demos and polished, real-world UIs.\n * ----------------------------------------------------------------------- */\n\nexport const SectionHeader: ComponentSpec = {\n name: \"SectionHeader\",\n description:\n \"Compact section header for the top of a Card or panel. Renders a small \" +\n \"eyebrow, a title, an optional subtitle, an optional status Tag/Badge, \" +\n \"and a right-aligned actions row. Use this inside a Card to introduce \" +\n \"a section instead of a bare `CardHeader`.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"subtitle\", type: \"string\", optional: true, aliases: [\"description\"] },\n { name: \"eyebrow\", type: \"string\", optional: true, description: \"Short uppercase label above the title\" },\n { name: \"status\", type: \"Badge | Tag\", optional: true, aliases: [\"badge\"] },\n { name: \"actions\", type: \"Node[]\", optional: true, description: \"Buttons / Links shown on the right\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"header\", { class: \"rui-section-header\" });\n const left = el(\"div\", { class: \"rui-section-header-left\" });\n const eyebrow = asString(props.eyebrow);\n if (eyebrow) left.append(el(\"span\", { class: \"rui-section-header-eyebrow\" }, [eyebrow]));\n const titleLine = el(\"div\", { class: \"rui-section-header-title-line\" });\n titleLine.append(el(\"h3\", { class: \"rui-section-header-title\" }, [asString(props.title)]));\n if (props.status) titleLine.append(helpers.renderNode(props.status));\n left.append(titleLine);\n const subtitle = asString(props.subtitle);\n if (subtitle) left.append(el(\"p\", { class: \"rui-section-header-subtitle\" }, [subtitle]));\n root.append(left);\n const actions = renderActionsRow(props.actions, helpers);\n if (actions) {\n actions.classList.add(\"rui-section-header-actions\");\n root.append(actions);\n }\n return root;\n },\n};\n\nexport const Toolbar: ComponentSpec = {\n name: \"Toolbar\",\n description:\n \"Horizontal toolbar for filters, search, view modes, and primary \" +\n \"actions. Left/center/right slots wrap onto separate rows on narrow \" +\n \"viewports so the bar never overflows. Pass `searchable: true` to \" +\n \"auto-mount a SearchBar in the left slot (bind `searchValue` to a \" +\n \"`$variable`). Use ABOVE a Table, List, Grid, or Kanban view — never \" +\n \"replace `PageHeader` with it.\",\n props: [\n { name: \"left\", type: \"Node[]\", optional: true, description: \"Filters / search inputs / chips\" },\n { name: \"right\", type: \"Node[]\", optional: true, description: \"Primary action buttons\" },\n { name: \"center\", type: \"Node[]\", optional: true, description: \"Centered controls (e.g. SegmentedControl, search bar)\" },\n { name: \"searchable\", type: \"boolean\", optional: true, description: \"Auto-mount a SearchBar at the start of the left slot\" },\n { name: \"searchPlaceholder\", type: \"string\", optional: true, description: \"Placeholder for the auto-mounted SearchBar\" },\n { name: \"searchValue\", type: \"string\", optional: true, description: \"$variable bound to the auto-mounted SearchBar\" },\n ],\n render: (_node, props, helpers) => {\n const center = asArray<unknown>(props.center);\n const root = el(\"div\", {\n class: \"rui-toolbar\",\n \"data-has-center\": center.length > 0 ? \"true\" : \"false\",\n });\n const left = el(\"div\", { class: \"rui-toolbar-side rui-toolbar-left\" });\n if (asBoolean(props.searchable)) {\n left.append(SearchBar.render(\n { __kind: \"Component\", name: \"SearchBar\", args: [], argMeta: [] },\n {\n id: \"toolbar-search\",\n placeholder: asString(props.searchPlaceholder, \"Search…\"),\n value: props.searchValue,\n },\n helpers,\n ));\n }\n for (const child of asArray(props.left)) left.append(helpers.renderNode(child));\n root.append(left);\n if (center.length > 0) {\n const centerWrap = el(\"div\", { class: \"rui-toolbar-side rui-toolbar-center\" });\n for (const child of center) centerWrap.append(helpers.renderNode(child));\n root.append(centerWrap);\n }\n const right = el(\"div\", { class: \"rui-toolbar-side rui-toolbar-right\" });\n for (const child of asArray(props.right)) right.append(helpers.renderNode(child));\n root.append(right);\n return root;\n },\n};\n\nexport const SidebarItem: ComponentSpec = {\n name: \"SidebarItem\",\n description:\n \"Single navigation item inside a Sidebar. Pass `active=true` to mark \" +\n \"as the current page, an `action` Action for click handling, or an \" +\n \"optional `badge` (string/number) for a trailing chip.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name rendered before the label\" },\n { name: \"active\", type: \"boolean\", optional: true },\n { name: \"badge\", type: \"string\", optional: true, description: \"Trailing chip (count or status)\" },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onClick\", \"onclick\"] },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"button\", {\n type: \"button\",\n class: \"rui-sidebar-item\",\n \"data-active\": asBoolean(props.active) ? \"true\" : \"false\",\n });\n const iconNode = renderIcon(props.icon, { className: \"rui-sidebar-item-icon\" });\n if (iconNode) root.append(iconNode);\n root.append(el(\"span\", { class: \"rui-sidebar-item-label\" }, [asString(props.label)]));\n const badge = asString(props.badge);\n if (badge) root.append(el(\"span\", { class: \"rui-sidebar-item-badge\" }, [badge]));\n if (typeof props.action === \"function\") {\n root.onclick = () => helpers.invoke(props.action);\n }\n return root;\n },\n};\n\nexport const SidebarSection: ComponentSpec = {\n name: \"SidebarSection\",\n description:\n \"Grouping inside a Sidebar — small uppercase label followed by \" +\n \"SidebarItem entries. Use this to chunk a long sidebar into sections.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"items\", type: \"SidebarItem[]\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-sidebar-section\" });\n const label = asString(props.label);\n if (label) root.append(el(\"div\", { class: \"rui-sidebar-section-label\" }, [label]));\n for (const item of asArray(props.items)) root.append(helpers.renderNode(item));\n return root;\n },\n};\n\nexport const Sidebar: ComponentSpec = {\n name: \"Sidebar\",\n description:\n \"Vertical app navigation panel. Supports a brand header, navigation \" +\n \"items (`SidebarItem` or `SidebarSection`), an optional footer, and a \" +\n \"`collapsed` mode that hides labels to leave just an icon rail. Use \" +\n \"inside `AppShell` for SaaS-style left navigation.\",\n props: [\n { name: \"items\", type: \"(SidebarItem | SidebarSection)[]\" },\n { name: \"brand\", type: \"string\", optional: true, description: \"Product name / workspace label at the top\" },\n { name: \"tagline\", type: \"string\", optional: true },\n { name: \"footer\", type: \"Node[]\", optional: true, description: \"Footer block (Avatar + name, upgrade CTA, …)\" },\n { name: \"collapsed\", type: \"boolean\", optional: true, description: \"Render as an icon-only rail (hides labels/badges)\" },\n ],\n render: (_node, props, helpers) => {\n const collapsed = asBoolean(props.collapsed);\n const root = el(\"aside\", { class: \"rui-sidebar\" });\n if (collapsed) root.dataset.collapsed = \"true\";\n const brand = asString(props.brand);\n const tagline = asString(props.tagline);\n if (brand || tagline) {\n const header = el(\"div\", { class: \"rui-sidebar-header\" });\n if (brand) header.append(el(\"div\", { class: \"rui-sidebar-brand\" }, [brand]));\n if (tagline) header.append(el(\"div\", { class: \"rui-sidebar-tagline\" }, [tagline]));\n root.append(header);\n }\n const body = el(\"nav\", { class: \"rui-sidebar-body\" });\n for (const item of asArray(props.items)) body.append(helpers.renderNode(item));\n root.append(body);\n const footerItems = asArray<unknown>(props.footer);\n if (footerItems.length > 0) {\n const footer = el(\"div\", { class: \"rui-sidebar-footer\" });\n for (const item of footerItems) footer.append(helpers.renderNode(item));\n root.append(footer);\n }\n return root;\n },\n};\n\nexport const AppShell: ComponentSpec = {\n name: \"AppShell\",\n description:\n \"Canonical SaaS application shell: optional top bar, fixed left \" +\n \"Sidebar, and scrollable main content. Reach for this whenever a \" +\n \"response represents a full product surface (dashboard with nav, \" +\n \"settings + sections, admin panels). Pass `collapsible=true` to render \" +\n \"a hamburger that turns the sidebar into a slide-over drawer on narrow \" +\n \"viewports.\",\n props: [\n { name: \"sidebar\", type: \"Sidebar\", description: \"Pass a Sidebar(...) node\" },\n { name: \"content\", type: \"Node[]\", description: \"Main content (typically starts with a PageHeader)\" },\n { name: \"topbar\", type: \"Node[]\", optional: true, description: \"Optional thin top bar above the content\" },\n { name: \"collapsible\", type: \"boolean\", optional: true, description: \"Show a hamburger that toggles the sidebar drawer on mobile\" },\n { name: \"sidebarOpen\", type: \"boolean\", optional: true, description: \"$variable controlling whether the mobile drawer is open\" },\n ],\n render: (_node, props, helpers) => {\n const collapsible = asBoolean(props.collapsible);\n const sidebarOpen = asBoolean(props.sidebarOpen);\n const root = el(\"div\", { class: \"rui-app-shell\" });\n if (collapsible) root.dataset.collapsible = \"true\";\n if (sidebarOpen) root.dataset.sidebarOpen = \"true\";\n const sidebarHost = el(\"div\", { class: \"rui-app-shell-sidebar\" });\n sidebarHost.append(helpers.renderNode(props.sidebar));\n root.append(sidebarHost);\n if (collapsible) {\n const scrim = el(\"div\", { class: \"rui-app-shell-scrim\", \"aria-hidden\": \"true\" });\n scrim.addEventListener(\"click\", () => {\n delete root.dataset.sidebarOpen;\n });\n root.append(scrim);\n }\n const main = el(\"div\", { class: \"rui-app-shell-main\" });\n const topbar = asArray<unknown>(props.topbar);\n if (topbar.length > 0 || collapsible) {\n const bar = el(\"div\", { class: \"rui-app-shell-topbar\" });\n if (collapsible) {\n const toggle = el(\"button\", {\n class: \"rui-app-shell-toggle\",\n type: \"button\",\n \"aria-label\": \"Toggle navigation\",\n });\n toggle.append(renderIcon(\"bars\", { size: \"md\" }) ?? document.createTextNode(\"≡\"));\n toggle.addEventListener(\"click\", () => {\n if (root.dataset.sidebarOpen) delete root.dataset.sidebarOpen;\n else root.dataset.sidebarOpen = \"true\";\n });\n bar.append(toggle);\n }\n for (const item of topbar) bar.append(helpers.renderNode(item));\n main.append(bar);\n }\n const content = el(\"div\", { class: \"rui-app-shell-content\" });\n for (const child of asArray(props.content)) content.append(helpers.renderNode(child));\n main.append(content);\n root.append(main);\n return root;\n },\n};\n\nexport const SplitView: ComponentSpec = {\n name: \"SplitView\",\n description:\n \"Two-pane master/detail layout — a narrow primary pane on the left, \" +\n \"wider detail pane on the right. Collapses to a single column on \" +\n \"narrow viewports. Use for inboxes, file browsers, contact lists.\",\n props: [\n { name: \"primary\", type: \"Node[]\", description: \"Master pane content (list, filters)\" },\n { name: \"detail\", type: \"Node[]\", aliases: [\"secondary\"], description: \"Detail pane content (selected item, empty state)\" },\n { name: \"primaryWidth\", type: \"string\", optional: true, aliases: [\"splitAt\"], description: \"CSS width for the primary pane (default 320px)\" },\n ],\n render: (_node, props, helpers) => {\n const width = sanitiseCssLength(asString(props.primaryWidth), \"320px\");\n const root = el(\"div\", { class: \"rui-split-view\", style: `--rui-split-primary:${width}` });\n const primary = el(\"div\", { class: \"rui-split-view-primary\" });\n for (const child of asArray(props.primary)) primary.append(helpers.renderNode(child));\n const detail = el(\"div\", { class: \"rui-split-view-detail\" });\n for (const child of asArray(props.detail)) detail.append(helpers.renderNode(child));\n root.append(primary, detail);\n return root;\n },\n};\n\nexport const DescriptionItem: ComponentSpec = {\n name: \"DescriptionItem\",\n description:\n \"Single row inside a DescriptionList. Renders a small uppercase \" +\n \"label on the left and a value (string or arbitrary Node) on the right.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"value\", type: \"Node | string\" },\n { name: \"icon\", type: \"string\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-description-item\" });\n const labelWrap = el(\"dt\", { class: \"rui-description-label\" });\n const iconNode = renderIcon(props.icon, { className: \"rui-description-icon\" });\n if (iconNode) labelWrap.append(iconNode);\n labelWrap.append(document.createTextNode(asString(props.label)));\n const value = el(\"dd\", { class: \"rui-description-value\" });\n if (props.value && typeof props.value === \"object\" && (props.value as { __kind?: string }).__kind === \"Component\") {\n value.append(helpers.renderNode(props.value));\n } else {\n value.append(document.createTextNode(asString(props.value)));\n }\n root.append(labelWrap, value);\n return root;\n },\n};\n\nexport const DescriptionList: ComponentSpec = {\n name: \"DescriptionList\",\n description:\n \"Compact key/value summary for detail pages — replaces a row of \" +\n \"`Text`s with a properly aligned `<dl>`. Children must be \" +\n \"DescriptionItem entries. Two columns by default on wide viewports.\",\n props: [\n { name: \"items\", type: \"DescriptionItem[]\" },\n { name: \"columns\", type: \"number\", optional: true, description: \"1 or 2 (default 2)\" },\n ],\n render: (_node, props, helpers) => {\n const columns = Math.max(1, Math.min(2, Math.floor(Number(props.columns ?? 2))));\n const root = el(\"dl\", {\n class: \"rui-description-list\",\n \"data-columns\": String(columns),\n });\n for (const item of asArray(props.items)) root.append(helpers.renderNode(item));\n return root;\n },\n};\n\nexport const StatusDot: ComponentSpec = {\n name: \"StatusDot\",\n description:\n \"Inline status pip + label. Use for compact health/state indicators \" +\n \"in toolbars, sidebars, lists, and table cells.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"tone\", type: \"string\", optional: true, enum: [\"default\", \"primary\", \"success\", \"warning\", \"danger\", \"info\"] },\n { name: \"pulse\", type: \"boolean\", optional: true, description: \"Animate the dot for 'live' state\" },\n ],\n render: (_node, props) => {\n const root = el(\"span\", {\n class: \"rui-status-dot\",\n \"data-tone\": asString(props.tone, \"success\"),\n \"data-pulse\": asBoolean(props.pulse) ? \"true\" : \"false\",\n });\n root.append(el(\"span\", { class: \"rui-status-dot-marker\" }));\n root.append(el(\"span\", { class: \"rui-status-dot-label\" }, [asString(props.label)]));\n return root;\n },\n};\n\nexport const PricingCard: ComponentSpec = {\n name: \"PricingCard\",\n description:\n \"Single pricing tier card with plan name, price, billing period, \" +\n \"description, bullet features, and a CTA button. Mark one tier as \" +\n \"`featured=true` to highlight it (raises the card, adds a ribbon).\",\n props: [\n { name: \"plan\", type: \"string\", description: \"Tier name (e.g. 'Pro')\" },\n { name: \"price\", type: \"string\", description: \"Display price (e.g. '$29')\" },\n { name: \"period\", type: \"string\", optional: true, description: \"Billing period (e.g. '/mo')\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"features\", type: \"string[]\", optional: true, description: \"Bullet list of included features\" },\n { name: \"action\", type: \"Button\", optional: true, aliases: [\"cta\"], description: \"Primary CTA — pass a Button(...)\" },\n { name: \"badge\", type: \"string\", optional: true, description: \"Eyebrow / badge above the plan name\" },\n { name: \"featured\", type: \"boolean\", optional: true, aliases: [\"highlighted\"] },\n ],\n render: (_node, props, helpers) => {\n const featured = asBoolean(props.featured);\n const root = el(\"article\", {\n class: \"rui-pricing-card\",\n \"data-featured\": featured ? \"true\" : \"false\",\n });\n const badge = asString(props.badge);\n if (badge) root.append(el(\"div\", { class: \"rui-pricing-card-badge\" }, [badge]));\n root.append(el(\"h3\", { class: \"rui-pricing-card-plan\" }, [asString(props.plan)]));\n const description = asString(props.description);\n if (description) root.append(el(\"p\", { class: \"rui-pricing-card-description\" }, [description]));\n const priceRow = el(\"div\", { class: \"rui-pricing-card-price-row\" });\n priceRow.append(el(\"span\", { class: \"rui-pricing-card-price\" }, [asString(props.price)]));\n const period = asString(props.period);\n if (period) priceRow.append(el(\"span\", { class: \"rui-pricing-card-period\" }, [period]));\n root.append(priceRow);\n const features = asArray<unknown>(props.features);\n if (features.length > 0) {\n const list = el(\"ul\", { class: \"rui-pricing-card-features\" });\n for (const f of features) {\n const label = asString(f);\n if (!label) continue;\n const check = renderIcon(\"circle-check\", { className: \"rui-pricing-card-check\" })\n ?? el(\"span\", { class: \"rui-pricing-card-check\" });\n list.append(el(\"li\", { class: \"rui-pricing-card-feature\" }, [\n check,\n document.createTextNode(label),\n ]));\n }\n root.append(list);\n }\n if (props.action) {\n const wrap = el(\"div\", { class: \"rui-pricing-card-action\" });\n wrap.append(helpers.renderNode(props.action));\n root.append(wrap);\n }\n return root;\n },\n};\n\nexport const PricingTable: ComponentSpec = {\n name: \"PricingTable\",\n description:\n \"Responsive grid of PricingCard tiers. Items size uniformly across a \" +\n \"row and wrap onto multiple rows on narrow viewports. Use as the \" +\n \"centerpiece of any pricing or upgrade page.\",\n props: [\n { name: \"tiers\", type: \"PricingCard[]\" },\n { name: \"columns\", type: \"number\", optional: true, description: \"Preferred column count (default auto)\" },\n ],\n render: (_node, props, helpers) => {\n const columns = Math.max(1, Math.min(4, Math.floor(Number(props.columns ?? \"auto\"))));\n const root = el(\"div\", {\n class: \"rui-pricing-table\",\n \"data-columns\": columns > 0 ? String(columns) : null,\n });\n for (const tier of asArray(props.tiers)) root.append(helpers.renderNode(tier));\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * Richer composition primitives\n *\n * These small, named patterns close the remaining gap between hand-rolled\n * `Stack(Card([...]))` blocks and the polished, dense layouts that LLMs\n * produce with shadcn/ui or Tailwind. Each component covers a recurring\n * UI motif (cover hero, media card, compact stat strip, icon tile, person\n * chip, inline notification) so the LLM can reach for a single line.\n * ----------------------------------------------------------------------- */\n\nexport const MediaCard: ComponentSpec = {\n name: \"MediaCard\",\n description:\n \"Card with a media (image) header followed by title, body, optional \" +\n \"tags, footer meta, and an actions row. Use for article previews, \" +\n \"product cards, project highlights, gallery items — anywhere a Card \" +\n \"needs a leading image. Orient with `orientation=\\\"horizontal\\\"` for \" +\n \"side-by-side media + content on wide viewports.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"imageSrc\", type: \"string\", optional: true, aliases: [\"src\", \"image\"], description: \"Image URL (omit to render a neutral placeholder)\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"tags\", type: \"string[]\", optional: true, description: \"Tag pill labels\" },\n { name: \"meta\", type: \"string\", optional: true, description: \"Footer meta line (author · date · category)\" },\n { name: \"actions\", type: \"Node[]\", optional: true, description: \"Buttons / Links rendered at the bottom\" },\n { name: \"badge\", type: \"string | Badge\", optional: true, description: \"Eyebrow string or Badge node shown over the image\" },\n { name: \"orientation\", type: \"string\", optional: true, enum: [\"vertical\", \"horizontal\"] },\n { name: \"ratio\", type: \"string\", optional: true, description: \"Media aspect ratio (default 16:9 vertical, 4:3 horizontal)\" },\n ],\n render: (_node, props, helpers) => {\n const orientation = asString(props.orientation, \"vertical\");\n const root = el(\"article\", {\n class: \"rui-media-card\",\n \"data-orientation\": orientation,\n });\n const ratio = parseMediaRatio(asString(props.ratio, orientation === \"horizontal\" ? \"4:3\" : \"16:9\"));\n const media = el(\"div\", {\n class: \"rui-media-card-media\",\n style: `aspect-ratio:${ratio};`,\n });\n const imageSrc = sanitiseImageSrc(props.imageSrc);\n if (imageSrc) {\n media.append(el(\"img\", { src: imageSrc, alt: asString(props.title), loading: \"lazy\" }));\n } else {\n media.classList.add(\"rui-media-card-media-empty\");\n const placeholder = renderIcon(\"image\", { className: \"rui-media-card-placeholder\" })\n ?? el(\"span\", { class: \"rui-media-card-placeholder\" });\n media.append(placeholder);\n }\n if (props.badge) {\n const badgeWrap = el(\"span\", { class: \"rui-media-card-badge\" });\n if (typeof props.badge === \"string\") {\n badgeWrap.append(document.createTextNode(asString(props.badge)));\n } else {\n badgeWrap.append(helpers.renderNode(props.badge));\n }\n media.append(badgeWrap);\n }\n root.append(media);\n\n const body = el(\"div\", { class: \"rui-media-card-body\" });\n body.append(el(\"h3\", { class: \"rui-media-card-title\" }, [asString(props.title)]));\n const description = asString(props.description);\n if (description) body.append(el(\"p\", { class: \"rui-media-card-description\" }, [description]));\n const tags = asArray<unknown>(props.tags);\n if (tags.length > 0) {\n const row = el(\"div\", { class: \"rui-media-card-tags\" });\n for (const t of tags) {\n const label = asString(t);\n if (label) row.append(el(\"span\", { class: \"rui-tag\", \"data-size\": \"sm\" }, [\n el(\"span\", { class: \"rui-tag-label\" }, [label]),\n ]));\n }\n body.append(row);\n }\n const meta = asString(props.meta);\n if (meta) body.append(el(\"p\", { class: \"rui-media-card-meta\" }, [meta]));\n const actions = renderActionsRow(props.actions, helpers);\n if (actions) {\n actions.classList.add(\"rui-media-card-actions\");\n body.append(actions);\n }\n root.append(body);\n return root;\n },\n};\n\nfunction parseMediaRatio(input: string): string {\n if (input.includes(\":\")) {\n const [w, h] = input.split(\":\");\n const num = Number(w);\n const den = Number(h);\n if (Number.isFinite(num) && Number.isFinite(den) && den > 0) return `${num} / ${den}`;\n }\n const n = Number(input);\n return Number.isFinite(n) && n > 0 ? `${n} / 1` : \"16 / 9\";\n}\n\n/**\n * Render a tiny inline sparkline as an SVG. Shared by `Stats`, `StatCard`,\n * and the standalone `Sparkline` component so the visual language stays\n * consistent across surfaces. `tone` maps to a CSS variable so themes can\n * override the stroke colour.\n */\nexport function renderInlineSparkline(values: number[], tone = \"primary\"): SVGSVGElement {\n const width = 80;\n const height = 24;\n const svgNS = \"http://www.w3.org/2000/svg\";\n const svg = document.createElementNS(svgNS, \"svg\");\n svg.setAttribute(\"class\", \"rui-sparkline\");\n svg.setAttribute(\"data-tone\", tone);\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svg.setAttribute(\"width\", String(width));\n svg.setAttribute(\"height\", String(height));\n svg.setAttribute(\"aria-hidden\", \"true\");\n if (values.length < 2) return svg;\n const min = Math.min(...values);\n const max = Math.max(...values);\n const range = max - min || 1;\n const step = width / (values.length - 1);\n const points = values.map((value, i) => {\n const x = i * step;\n // Bias by 2px padding top/bottom so the stroke is fully visible.\n const y = 2 + ((max - value) / range) * (height - 4);\n return [x, y] as const;\n });\n const linePath = points.map(([x, y], i) => `${i === 0 ? \"M\" : \"L\"}${x.toFixed(1)},${y.toFixed(1)}`).join(\" \");\n const areaPath = `${linePath} L${width},${height} L0,${height} Z`;\n const area = document.createElementNS(svgNS, \"path\");\n area.setAttribute(\"d\", areaPath);\n area.setAttribute(\"class\", \"rui-sparkline-area\");\n svg.appendChild(area);\n const line = document.createElementNS(svgNS, \"path\");\n line.setAttribute(\"d\", linePath);\n line.setAttribute(\"class\", \"rui-sparkline-line\");\n line.setAttribute(\"fill\", \"none\");\n svg.appendChild(line);\n return svg;\n}\n\nexport const Stats: ComponentSpec = {\n name: \"Stats\",\n description:\n \"KPI strip or grid. Pass `items` as `{label, value, hint?, tone?, spark?}` \" +\n \"objects for strip layout, or as `StatCard(...)` nodes when `layout=\\\"grid\\\"`.\",\n props: [\n { name: \"items\", type: \"object[] | StatCard[]\", description: \"Stat objects or StatCard nodes when layout=grid\" },\n { name: \"layout\", type: \"string\", optional: true, enum: [\"strip\", \"grid\"], description: \"strip = horizontal row; grid = responsive Grid\" },\n { name: \"columns\", type: \"number\", optional: true, description: \"Preferred column count for grid layout (1–6)\" },\n { name: \"align\", type: \"string\", optional: true, enum: [\"start\", \"center\", \"end\"], description: \"Strip alignment (layout=strip only)\" },\n ],\n render: (_node, props, helpers) => {\n const items = asArray<unknown>(props.items);\n const hasComponentItems = items.some(\n (item) => item && typeof item === \"object\" && (item as { __kind?: string }).__kind === \"Component\",\n );\n const layout = asString(\n props.layout,\n hasComponentItems ? \"grid\" : \"strip\",\n );\n if (layout === \"grid\") {\n const columns = props.columns ? Math.max(1, Math.min(6, Math.floor(asNumber(props.columns)))) : 0;\n const gridNode = Grid.render(\n { __kind: \"Component\", name: \"Grid\", args: [], argMeta: [] },\n {\n children: items,\n columns: columns > 0 ? columns : \"auto\",\n gap: \"m\",\n },\n helpers,\n ) as HTMLElement;\n gridNode.classList.add(\"rui-metric-grid\");\n return gridNode;\n }\n const align = asString(props.align, \"start\");\n const root = el(\"div\", { class: \"rui-stats\", \"data-align\": align });\n for (const raw of items) {\n const item = (raw ?? {}) as {\n label?: unknown; value?: unknown; hint?: unknown; tone?: unknown; spark?: unknown;\n };\n const tone = asString(item.tone, \"default\");\n const block = el(\"div\", { class: \"rui-stats-item\", \"data-tone\": tone });\n block.append(el(\"div\", { class: \"rui-stats-label\" }, [asString(item.label)]));\n const valueRow = el(\"div\", { class: \"rui-stats-value-row\" });\n valueRow.append(el(\"div\", { class: \"rui-stats-value\" }, [asString(item.value)]));\n const sparkValues = asArray<unknown>(item.spark).map((v) => Number(v)).filter((n) => Number.isFinite(n));\n if (sparkValues.length > 1) {\n valueRow.append(renderInlineSparkline(sparkValues, tone));\n }\n block.append(valueRow);\n const hint = asString(item.hint);\n if (hint) block.append(el(\"div\", { class: \"rui-stats-hint\" }, [hint]));\n root.append(block);\n }\n return root;\n },\n};\n\nexport const Tile: ComponentSpec = {\n name: \"Tile\",\n description:\n \"Compact icon + label + optional value tile. Smaller and denser than \" +\n \"`StatCard`, ideal for menu grids, quick-action panels, category \" +\n \"directories, and category filters. Pair with `Grid` for uniform rows.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name shown in a colored disc\" },\n { name: \"value\", type: \"string\", optional: true, description: \"Secondary value rendered next to/under the label\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"tone\", type: \"string\", optional: true, enum: SURFACE_TONES },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onClick\", \"onclick\"] },\n ],\n render: (_node, props, helpers) => {\n const isClickable = typeof props.action === \"function\";\n const tag = isClickable ? \"button\" : \"div\";\n const root = el(tag as \"div\", {\n type: isClickable ? \"button\" : null,\n class: \"rui-tile\",\n \"data-tone\": asString(props.tone, \"default\"),\n });\n const iconNode = renderIcon(props.icon, { className: \"rui-tile-icon\" });\n if (iconNode) root.append(iconNode);\n const body = el(\"div\", { class: \"rui-tile-body\" });\n body.append(el(\"div\", { class: \"rui-tile-label\" }, [asString(props.label)]));\n const value = asString(props.value);\n if (value) body.append(el(\"div\", { class: \"rui-tile-value\" }, [value]));\n const description = asString(props.description);\n if (description) body.append(el(\"div\", { class: \"rui-tile-description\" }, [description]));\n root.append(body);\n if (isClickable) {\n root.onclick = () => helpers.invoke(props.action);\n }\n return root;\n },\n};\n\nexport const Notification: ComponentSpec = {\n name: \"Notification\",\n description:\n \"Inline notification card with title, message, time, optional avatar, \" +\n \"and dismiss/action buttons. Use inside notification panels, inboxes, \" +\n \"or activity drawers — for top-of-page announcements prefer `Banner`.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"message\", type: \"string\", optional: true, aliases: [\"description\"] },\n { name: \"time\", type: \"string\", optional: true, description: \"Relative or absolute timestamp\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name shown in a colored disc\" },\n { name: \"avatarSrc\", type: \"string\", optional: true, aliases: [\"src\"], description: \"Avatar URL (alternative to `icon`)\" },\n { name: \"tone\", type: \"string\", optional: true, enum: SURFACE_TONES },\n { name: \"unread\", type: \"boolean\", optional: true, description: \"Highlights the card with an accent\" },\n { name: \"actions\", type: \"Node[]\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"article\", {\n class: \"rui-notification\",\n \"data-tone\": asString(props.tone, \"default\"),\n \"data-unread\": asBoolean(props.unread) ? \"true\" : \"false\",\n });\n const avatarSrc = asString(props.avatarSrc);\n if (avatarSrc) {\n root.append(renderAvatar(avatarSrc, asString(props.title), \"md\"));\n } else {\n const iconNode = renderIcon(asString(props.icon, \"bell\"), { className: \"rui-notification-icon\" });\n if (iconNode) root.append(iconNode);\n }\n const body = el(\"div\", { class: \"rui-notification-body\" });\n const head = el(\"header\", { class: \"rui-notification-head\" });\n head.append(el(\"span\", { class: \"rui-notification-title\" }, [asString(props.title)]));\n const time = asString(props.time);\n if (time) head.append(el(\"span\", { class: \"rui-notification-time\" }, [time]));\n body.append(head);\n const message = asString(props.message);\n if (message) body.append(el(\"p\", { class: \"rui-notification-message\" }, [message]));\n const actions = renderActionsRow(props.actions, helpers);\n if (actions) {\n actions.classList.add(\"rui-notification-actions\");\n body.append(actions);\n }\n root.append(body);\n return root;\n },\n};\n\nexport const PersonChip: ComponentSpec = {\n name: \"PersonChip\",\n description:\n \"Inline avatar + name + optional role/meta pill. Use anywhere a \" +\n \"person needs to be referenced compactly: table cells, list rows, \" +\n \"comments, kanban cards, sidebar footers. Pair multiple chips with \" +\n \"`Stack(direction=\\\"row\\\", wrap=true)` for assignee lists.\",\n props: [\n { name: \"name\", type: \"string\" },\n { name: \"role\", type: \"string\", optional: true, description: \"Sub-line below the name (role, email, handle, …)\" },\n { name: \"avatarSrc\", type: \"string\", optional: true, aliases: [\"src\"] },\n { name: \"size\", type: \"string\", optional: true, enum: [\"sm\", \"md\", \"lg\"] },\n { name: \"status\", type: \"string\", optional: true, enum: [\"online\", \"offline\", \"busy\", \"away\"] },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onClick\", \"onclick\"] },\n ],\n render: (_node, props, helpers) => {\n const isClickable = typeof props.action === \"function\";\n const tag = isClickable ? \"button\" : \"div\";\n const size = asString(props.size, \"md\");\n const avatarSize = size === \"lg\" ? \"lg\" : size === \"sm\" ? \"sm\" : \"md\";\n const root = el(tag as \"div\", {\n type: isClickable ? \"button\" : null,\n class: \"rui-person-chip\",\n \"data-size\": size,\n });\n const avatarWrap = el(\"span\", { class: \"rui-person-chip-avatar\" });\n avatarWrap.append(renderAvatar(asString(props.avatarSrc), asString(props.name), avatarSize));\n const status = asString(props.status);\n if (status) avatarWrap.append(el(\"span\", { class: \"rui-person-chip-status\", \"data-status\": status }));\n root.append(avatarWrap);\n const meta = el(\"div\", { class: \"rui-person-chip-meta\" });\n meta.append(el(\"span\", { class: \"rui-person-chip-name\" }, [asString(props.name)]));\n const role = asString(props.role);\n if (role) meta.append(el(\"span\", { class: \"rui-person-chip-role\" }, [role]));\n root.append(meta);\n if (isClickable) {\n root.onclick = () => helpers.invoke(props.action);\n }\n return root;\n },\n};\n\n","/**\n * Data components: Table, Col, List, ListItem, StatCard, Tree, TreeNode,\n * Sparkline.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport { el, asArray, asString, asBoolean, asNumber, renderIcon } from \"../utils.js\";\nimport { renderInlineSparkline } from \"./patterns.js\";\nimport { pickIconForLabel } from \"./_internal.js\";\n\nconst COL_ALIGN = [\"left\", \"center\", \"right\"] as const;\n\nexport const Col: ComponentSpec = {\n name: \"Col\",\n description:\n \"Single column inside a Table or DataGrid. Use `align` for per-column \" +\n \"text alignment, `format` for cell rendering \" +\n \"(`text|number|currency|date`). `sortable` and `filterable` only \" +\n \"take effect inside `DataGrid` (Table ignores them).\",\n props: [\n { name: \"header\", type: \"string\" },\n { name: \"values\", type: \"any[]\", description: \"Column values (use array pluck like data.rows.title)\" },\n { name: \"format\", type: \"string\", optional: true, enum: [\"text\", \"number\", \"currency\", \"date\"] },\n { name: \"align\", type: \"string\", optional: true, enum: COL_ALIGN, description: \"Per-column horizontal alignment\" },\n { name: \"sortable\", type: \"boolean\", optional: true, description: \"DataGrid: enable click-to-sort on this column\" },\n { name: \"filterable\", type: \"boolean\", optional: true, description: \"DataGrid: enable a per-column filter chip\" },\n ],\n // Cols are read positionally inside Table.render — this render is a fallback.\n render: (_node, props) => {\n const wrapper = el(\"div\", { class: \"rui-col\" });\n wrapper.append(el(\"strong\", {}, [asString(props.header)]));\n return wrapper;\n },\n};\n\nconst TABLE_DENSITY = [\"comfortable\", \"compact\"] as const;\n\nexport const Table: ComponentSpec = {\n name: \"Table\",\n description:\n \"Tabular data view. Children must be Col components. `density=\\\"compact\\\"` \" +\n \"tightens row padding for dense data, `striped=true` zebra-stripes the \" +\n \"rows, and `sticky=true` pins the header row when the table scrolls. \" +\n \"The empty-state row uses `emptyLabel` when set.\",\n props: [\n { name: \"columns\", type: \"Col[]\" },\n { name: \"caption\", type: \"string\", optional: true, aliases: [\"title\"] },\n { name: \"density\", type: \"string\", optional: true, enum: TABLE_DENSITY, description: \"Row padding (default `comfortable`)\" },\n { name: \"striped\", type: \"boolean\", optional: true, description: \"Zebra-stripe alternating rows\" },\n { name: \"sticky\", type: \"boolean\", optional: true, description: \"Pin the header row when the table scrolls\" },\n { name: \"emptyLabel\", type: \"string\", optional: true, description: \"Text shown when the table has no rows (default `No data`)\" },\n ],\n render: (_node, props, helpers) => {\n const cols = asArray<{ args?: unknown[] }>(props.columns);\n const density = asString(props.density, \"comfortable\");\n const striped = asBoolean(props.striped);\n const sticky = asBoolean(props.sticky);\n const wrapper = el(\"div\", {\n class: \"rui-table-wrapper\",\n \"data-density\": density,\n \"data-striped\": striped ? \"true\" : \"false\",\n \"data-sticky\": sticky ? \"true\" : \"false\",\n });\n const table = el(\"table\", { class: \"rui-table\" });\n\n const caption = asString(props.caption);\n if (caption) table.append(el(\"caption\", { class: \"rui-table-caption\" }, [caption]));\n\n const aligns = cols.map((col) => {\n const align = asString(col.args?.[3], \"\");\n return (COL_ALIGN as readonly string[]).includes(align) ? align : \"\";\n });\n\n const thead = el(\"thead\");\n const headRow = el(\"tr\");\n for (let c = 0; c < cols.length; c += 1) {\n const col = cols[c]!;\n const th = el(\"th\", {\n \"data-align\": aligns[c] || null,\n }, [asString(col.args?.[0])]);\n headRow.append(th);\n }\n thead.append(headRow);\n table.append(thead);\n\n const tbody = el(\"tbody\");\n const columnValues = cols.map((col) => asArray(col.args?.[1]));\n const formats = cols.map((col) => asString(col.args?.[2], \"text\"));\n const rowCount = Math.max(0, ...columnValues.map((c) => c.length));\n\n for (let r = 0; r < rowCount; r += 1) {\n const tr = el(\"tr\");\n columnValues.forEach((values, c) => {\n const cell = values[r];\n const format = formats[c] ?? \"text\";\n const align = aligns[c];\n const td = el(\"td\", { \"data-format\": format, \"data-align\": align || null });\n if (cell !== null && typeof cell === \"object\" && (cell as { __kind?: string }).__kind === \"Component\") {\n td.append(helpers.renderNode(cell));\n } else {\n td.textContent = formatCell(cell, format);\n }\n tr.append(td);\n });\n tbody.append(tr);\n }\n\n if (rowCount === 0) {\n const emptyRow = el(\"tr\");\n const emptyLabel = asString(props.emptyLabel, \"No data\");\n emptyRow.append(el(\"td\", {\n colspan: String(cols.length || 1),\n class: \"rui-table-empty\",\n }, [emptyLabel]));\n tbody.append(emptyRow);\n }\n\n table.append(tbody);\n wrapper.append(table);\n return wrapper;\n },\n};\n\nexport const ListItem: ComponentSpec = {\n name: \"ListItem\",\n description: \"Single list item with optional title and description.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"description\", type: \"string\", optional: true, aliases: [\"meta\"] },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name\" },\n ],\n render: (_node, props) => {\n const li = el(\"li\", { class: \"rui-list-item\" });\n const iconNode = renderIcon(props.icon, { className: \"rui-list-icon\" });\n if (iconNode) li.append(iconNode);\n const text = el(\"div\", { class: \"rui-list-text\" });\n text.append(el(\"div\", { class: \"rui-list-title\" }, [asString(props.title)]));\n const desc = asString(props.description);\n if (desc) text.append(el(\"div\", { class: \"rui-list-description\" }, [desc]));\n li.append(text);\n return li;\n },\n};\n\nexport const List: ComponentSpec = {\n name: \"List\",\n description: \"Vertical list of ListItems.\",\n props: [\n { name: \"items\", type: \"ListItem[]\" },\n { name: \"ordered\", type: \"boolean\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const tag = asBoolean(props.ordered) ? \"ol\" : \"ul\";\n const root = el(tag as \"ul\", { class: \"rui-list\" });\n for (const item of asArray(props.items)) root.append(helpers.renderNode(item));\n return root;\n },\n};\n\nexport const StatCard: ComponentSpec = {\n name: \"StatCard\",\n description:\n \"Single KPI card with label, value, optional delta, optional icon, \" +\n \"and optional inline sparkline (`spark=[…numbers]`). Use inside \" +\n \"`Stats` for a uniform KPI strip.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"value\", type: \"string\" },\n { name: \"trend\", type: \"string\", optional: true, enum: [\"up\", \"down\", \"flat\"] },\n { name: \"delta\", type: \"string\", optional: true, description: \"Change vs previous period\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name shown in a chip beside the label\" },\n { name: \"spark\", type: \"number[]\", optional: true, description: \"Optional inline sparkline values\" },\n { name: \"tone\", type: \"string\", optional: true, enum: [\"default\", \"primary\", \"success\", \"warning\", \"danger\", \"info\"] },\n ],\n render: (_node, props) => {\n const tone = asString(props.tone, \"default\");\n const root = el(\"div\", { class: \"rui-stat-card\", \"data-tone\": tone });\n const labelRow = el(\"div\", { class: \"rui-stat-label-row\" });\n const label = asString(props.label);\n const iconName = asString(props.icon) || pickIconForLabel(label) || \"\";\n const iconNode = renderIcon(iconName, { className: \"rui-stat-icon\" });\n if (iconNode) labelRow.append(iconNode);\n labelRow.append(el(\"div\", { class: \"rui-stat-label\" }, [label]));\n root.append(labelRow);\n root.append(el(\"div\", { class: \"rui-stat-value\" }, [asString(props.value)]));\n const delta = asString(props.delta);\n const trend = asString(props.trend);\n if (delta || trend) {\n root.append(el(\"div\", { class: \"rui-stat-trend\", \"data-trend\": trend || \"flat\" }, [delta || trendArrow(trend)]));\n }\n const spark = asArray<unknown>(props.spark).map((v) => asNumber(v));\n if (spark.length > 1) {\n const sparkWrap = el(\"div\", { class: \"rui-stat-spark\" });\n sparkWrap.append(renderInlineSparkline(spark, tone === \"default\" ? \"primary\" : tone));\n root.append(sparkWrap);\n }\n return root;\n },\n};\n\nexport const Sparkline: ComponentSpec = {\n name: \"Sparkline\",\n description:\n \"Tiny inline trend chart for KPIs, table cells, and dashboards. \" +\n \"Renders an SVG line with a soft fill — use anywhere you would \" +\n \"otherwise reach for `LineChart` but a single value series should \" +\n \"stay inline with surrounding text.\",\n props: [\n { name: \"values\", type: \"number[]\" },\n { name: \"tone\", type: \"string\", optional: true, enum: [\"primary\", \"success\", \"warning\", \"danger\", \"info\"] },\n ],\n render: (_node, props) => {\n const tone = asString(props.tone, \"primary\");\n const values = asArray<unknown>(props.values).map((v) => asNumber(v));\n const wrap = el(\"span\", { class: \"rui-sparkline-wrap\" });\n wrap.append(renderInlineSparkline(values, tone));\n return wrap;\n },\n};\n\nexport const TreeNode: ComponentSpec = {\n name: \"TreeNode\",\n description:\n \"Single node in a Tree view. When `children` is provided the node \" +\n \"renders as an expandable branch with a chevron; otherwise it renders \" +\n \"as a leaf. `action` fires on click. Use `active=true` to highlight \" +\n \"the current selection.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"children\", type: \"TreeNode[]\", optional: true },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon shown before the label\" },\n { name: \"expanded\", type: \"boolean\", optional: true, description: \"Whether the branch is open by default\" },\n { name: \"active\", type: \"boolean\", optional: true, aliases: [\"selected\"], description: \"Highlights the row as the current selection\" },\n { name: \"badge\", type: \"string\", optional: true, description: \"Trailing chip (count or status)\" },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onClick\", \"onclick\"], description: \"Callable fired when the row is clicked\" },\n ],\n render: (_node, props, helpers) => {\n const children = asArray<unknown>(props.children);\n const hasChildren = children.length > 0;\n const expanded = asBoolean(props.expanded);\n const active = asBoolean(props.active);\n const isClickable = typeof props.action === \"function\";\n\n const row = el(isClickable ? \"button\" : \"div\" as \"div\", {\n type: isClickable ? \"button\" : null,\n class: \"rui-tree-node-row\",\n role: \"treeitem\",\n \"data-active\": active ? \"true\" : \"false\",\n \"aria-expanded\": hasChildren ? (expanded ? \"true\" : \"false\") : null,\n });\n\n if (hasChildren) {\n const chevron = renderIcon(\"chevron-right\", { className: \"rui-tree-node-chevron\" });\n if (chevron) row.append(chevron);\n } else {\n row.append(el(\"span\", { class: \"rui-tree-node-chevron-spacer\", \"aria-hidden\": \"true\" }));\n }\n const iconNode = renderIcon(props.icon, { className: \"rui-tree-node-icon\" });\n if (iconNode) row.append(iconNode);\n row.append(el(\"span\", { class: \"rui-tree-node-label\" }, [asString(props.label)]));\n const badge = asString(props.badge);\n if (badge) row.append(el(\"span\", { class: \"rui-tree-node-badge\" }, [badge]));\n\n if (isClickable) {\n row.onclick = () => helpers.invoke(props.action);\n }\n\n if (!hasChildren) return row;\n\n // Branch: render as a <details> so expand/collapse is browser-native\n // (no extra state slot needed) and survives morph reconciliation.\n const details = el(\"details\", { class: \"rui-tree-node\" }) as HTMLDetailsElement;\n if (expanded) details.setAttribute(\"open\", \"\");\n const summary = el(\"summary\", { class: \"rui-tree-node-summary\" });\n summary.append(row);\n // When the row is clickable, swallow the summary's default toggle so a\n // click on the label runs the action without expanding/collapsing. The\n // chevron still toggles because we wire it explicitly below.\n if (isClickable) {\n summary.onclick = (event) => {\n const target = event.target as Element | null;\n if (target?.closest(\".rui-tree-node-chevron\")) return;\n event.preventDefault();\n };\n }\n details.append(summary);\n\n const childList = el(\"div\", { class: \"rui-tree-node-children\", role: \"group\" });\n for (const child of children) childList.append(helpers.renderNode(child));\n details.append(childList);\n return details;\n },\n};\n\nexport const Tree: ComponentSpec = {\n name: \"Tree\",\n description:\n \"Hierarchical tree view. Children must be TreeNode entries. Use for \" +\n \"file browsers, nested navigation, category pickers, and any \" +\n \"parent/child structure with arbitrary depth.\",\n props: [{ name: \"items\", type: \"TreeNode[]\" }],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-tree\", role: \"tree\" });\n for (const item of asArray(props.items)) root.append(helpers.renderNode(item));\n return root;\n },\n};\n\nfunction trendArrow(trend: string): string {\n if (trend === \"up\") return \"▲\";\n if (trend === \"down\") return \"▼\";\n return \"—\";\n}\n\nfunction formatCell(value: unknown, format: string): string {\n if (value === null || value === undefined) return \"\";\n switch (format) {\n case \"number\":\n return typeof value === \"number\" ? value.toLocaleString() : asString(value);\n case \"currency\":\n return typeof value === \"number\"\n ? value.toLocaleString(undefined, { style: \"currency\", currency: \"USD\" })\n : asString(value);\n case \"date\":\n try {\n const d = new Date(asString(value));\n return Number.isNaN(d.getTime()) ? asString(value) : d.toLocaleDateString();\n } catch { return asString(value); }\n default:\n return asString(value);\n }\n}\n","/**\n * Chart components: Series (data definition), BarChart, LineChart, PieChart.\n *\n * The charts are rendered as inline SVG so they work inside the shadow root\n * without any external dependency.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport { el, asArray, asString, asNumber } from \"../utils.js\";\n\nconst PALETTE: readonly string[] = [\n \"var(--rui-chart-1, #6366f1)\",\n \"var(--rui-chart-2, #10b981)\",\n \"var(--rui-chart-3, #f59e0b)\",\n \"var(--rui-chart-4, #ef4444)\",\n \"var(--rui-chart-5, #06b6d4)\",\n \"var(--rui-chart-6, #8b5cf6)\",\n];\n\nconst colorAt = (index: number): string => PALETTE[index % PALETTE.length] ?? PALETTE[0]!;\n\nexport const Series: ComponentSpec = {\n name: \"Series\",\n description: \"Named data series for charts. Used inside BarChart, LineChart, PieChart.\",\n props: [\n { name: \"name\", type: \"string\" },\n { name: \"values\", type: \"number[]\" },\n ],\n render: (_node, props) => {\n return el(\"span\", { class: \"rui-series\", \"data-name\": asString(props.name) });\n },\n};\n\ninterface SeriesData {\n name: string;\n values: number[];\n}\n\nconst readSeries = (raw: unknown[]): SeriesData[] => {\n return raw.map((s, i) => {\n const node = s as { args?: unknown[] };\n const name = asString(node.args?.[0], `Series ${i + 1}`);\n const values = asArray<unknown>(node.args?.[1]).map((v) => asNumber(v));\n return { name, values };\n });\n};\n\nexport const BarChart: ComponentSpec = {\n name: \"BarChart\",\n description: \"Vertical bar chart. `labels` define the x-axis, `series` define grouped bars.\",\n props: [\n { name: \"labels\", type: \"string[]\" },\n { name: \"series\", type: \"Series[]\" },\n { name: \"title\", type: \"string\", optional: true },\n ],\n render: (_node, props) => {\n const labels = asArray<unknown>(props.labels).map((l) => asString(l));\n const series = readSeries(asArray<unknown>(props.series));\n const root = el(\"div\", { class: \"rui-chart rui-bar-chart\" });\n if (asString(props.title)) root.append(el(\"div\", { class: \"rui-chart-title\" }, [asString(props.title)]));\n\n const max = Math.max(1, ...series.flatMap((s) => s.values));\n const width = 640;\n const height = 240;\n const labelPlan = planLabels(labels, width - 40 - 12);\n const padding = { left: 40, right: 12, top: 12, bottom: labelPlan.bottomPadding };\n const innerWidth = width - padding.left - padding.right;\n const innerHeight = height - padding.top - padding.bottom;\n const svg = createSvg(width, height);\n\n drawAxes(svg, padding, innerWidth, innerHeight, max);\n\n const groupCount = labels.length;\n const groupWidth = innerWidth / Math.max(groupCount, 1);\n const seriesCount = series.length;\n const barWidth = (groupWidth * 0.7) / Math.max(seriesCount, 1);\n\n series.forEach((s, sIdx) => {\n s.values.forEach((value, gIdx) => {\n const barHeight = (value / max) * innerHeight;\n const x = padding.left + gIdx * groupWidth + groupWidth * 0.15 + sIdx * barWidth;\n const y = padding.top + innerHeight - barHeight;\n const rect = svgEl(\"rect\", {\n x: String(x),\n y: String(y),\n width: String(Math.max(barWidth - 2, 1)),\n height: String(barHeight),\n fill: colorAt(sIdx),\n rx: \"2\",\n });\n rect.append(svgEl(\"title\", {}, [`${s.name}: ${value}`]));\n svg.append(rect);\n });\n });\n\n drawXAxisLabels(svg, labels, padding, innerWidth, innerHeight, labelPlan, (i) => padding.left + (i + 0.5) * groupWidth);\n\n root.append(svg);\n if (series.length > 0) root.append(legend(series));\n return root;\n },\n};\n\nexport const LineChart: ComponentSpec = {\n name: \"LineChart\",\n description:\n \"Line chart. `labels` define the x-axis, each Series is a line. As a \" +\n \"shortcut you can pass `data=[{x: \\\"Jan\\\", revenue: 12, signups: 4}, …]` \" +\n \"and the labels + series will be derived automatically (one line per \" +\n \"non-`x` key). Use `data` when the dataset is already row-shaped; use \" +\n \"`series` when you have explicit Series objects.\",\n props: [\n { name: \"labels\", type: \"string[]\", optional: true },\n { name: \"series\", type: \"Series[]\", optional: true },\n { name: \"data\", type: \"{x: string, [key: string]: number}[]\", optional: true, description: \"Row-shaped data — labels and series are auto-derived\" },\n { name: \"title\", type: \"string\", optional: true },\n { name: \"filled\", type: \"boolean\", optional: true, description: \"Fill the area beneath each line (area-chart style)\" },\n { name: \"stacked\", type: \"boolean\", optional: true, description: \"Stack series when filled=true\" },\n ],\n render: (_node, props) => {\n let labels = asArray<unknown>(props.labels).map((l) => asString(l));\n let series = readSeries(asArray<unknown>(props.series));\n // Row-shaped shorthand: pull labels from `x` and one Series per other key.\n const rows = asArray<unknown>(props.data);\n if (rows.length > 0 && (labels.length === 0 || series.length === 0)) {\n const derivedLabels: string[] = [];\n const seriesByKey = new Map<string, number[]>();\n for (const raw of rows) {\n const row = raw as Record<string, unknown> | null;\n if (!row || typeof row !== \"object\") continue;\n derivedLabels.push(asString(row.x ?? row.label ?? \"\"));\n for (const [k, v] of Object.entries(row)) {\n if (k === \"x\" || k === \"label\") continue;\n const num = asNumber(v);\n if (Number.isNaN(num)) continue;\n if (!seriesByKey.has(k)) seriesByKey.set(k, []);\n seriesByKey.get(k)!.push(num);\n }\n }\n if (labels.length === 0) labels = derivedLabels;\n if (series.length === 0) {\n series = [...seriesByKey.entries()].map(([name, values]) => ({ name, values }));\n }\n }\n const filled = props.filled === true;\n const stacked = props.stacked === true;\n const pointCount = Math.max(labels.length, ...series.map((s) => s.values.length), 1);\n const stackedValues: number[][] = series.map(() => Array(pointCount).fill(0));\n if (filled && stacked) {\n for (let i = 0; i < pointCount; i += 1) {\n let acc = 0;\n series.forEach((s, sIdx) => {\n acc += s.values[i] ?? 0;\n stackedValues[sIdx]![i] = acc;\n });\n }\n }\n const root = el(\"div\", {\n class: \"rui-chart rui-line-chart\",\n \"data-filled\": filled ? \"true\" : \"false\",\n });\n if (asString(props.title)) root.append(el(\"div\", { class: \"rui-chart-title\" }, [asString(props.title)]));\n\n const all = filled && stacked\n ? stackedValues.flat()\n : series.flatMap((s) => s.values);\n const max = Math.max(1, ...all);\n const min = filled && stacked ? 0 : Math.min(0, ...all);\n const width = 640;\n const height = 240;\n const labelPlan = planLabels(labels, width - 40 - 12);\n const padding = { left: 40, right: 12, top: 12, bottom: labelPlan.bottomPadding };\n const innerWidth = width - padding.left - padding.right;\n const innerHeight = height - padding.top - padding.bottom;\n const svg = createSvg(width, height);\n\n drawAxes(svg, padding, innerWidth, innerHeight, max, min);\n\n const denominator = Math.max(labels.length - 1, 1);\n const stepX = innerWidth / denominator;\n const xForPoint = (i: number): number =>\n padding.left + i * (innerWidth / Math.max(pointCount - 1, 1));\n\n series.forEach((s, sIdx) => {\n const values = filled && stacked ? stackedValues[sIdx]! : s.values;\n const baseline = filled && stacked && sIdx > 0 ? stackedValues[sIdx - 1]! : null;\n const points = values.map((value, i) => {\n const x = xForPoint(i);\n const y = padding.top + innerHeight - ((value - min) / (max - min || 1)) * innerHeight;\n return [x, y] as const;\n });\n if (filled && points.length > 0) {\n let areaPath = points.map(([x, y], i) => `${i === 0 ? \"M\" : \"L\"}${x.toFixed(1)},${y.toFixed(1)}`).join(\" \");\n if (baseline) {\n const baselinePoints = baseline.map((value, i) => {\n const x = xForPoint(i);\n const y = padding.top + innerHeight - ((value - min) / (max - min || 1)) * innerHeight;\n return [x, y] as const;\n });\n areaPath += \" \" + baselinePoints.slice().reverse().map(([x, y]) => `L${x.toFixed(1)},${y.toFixed(1)}`).join(\" \") + \" Z\";\n } else {\n const first = points[0]!;\n const last = points[points.length - 1]!;\n areaPath += ` L${last[0].toFixed(1)},${(padding.top + innerHeight).toFixed(1)} L${first[0].toFixed(1)},${(padding.top + innerHeight).toFixed(1)} Z`;\n }\n svg.append(svgEl(\"path\", {\n d: areaPath,\n fill: colorAt(sIdx),\n \"fill-opacity\": \"0.2\",\n stroke: \"none\",\n }));\n }\n const d = points.map(([x, y], i) => `${i === 0 ? \"M\" : \"L\"}${x.toFixed(1)},${y.toFixed(1)}`).join(\" \");\n svg.append(svgEl(\"path\", {\n d,\n fill: \"none\",\n stroke: colorAt(sIdx),\n \"stroke-width\": \"2\",\n \"stroke-linejoin\": \"round\",\n \"stroke-linecap\": \"round\",\n }));\n // Hide individual data points when the line is dense — they create\n // visual noise without helping readability.\n if (s.values.length <= 30) {\n points.forEach(([x, y]) => {\n svg.append(svgEl(\"circle\", {\n cx: String(x),\n cy: String(y),\n r: \"3\",\n fill: colorAt(sIdx),\n }));\n });\n }\n });\n\n drawXAxisLabels(svg, labels, padding, innerWidth, innerHeight, labelPlan, (i) => padding.left + i * stepX);\n\n root.append(svg);\n if (series.length > 0) root.append(legend(series));\n return root;\n },\n};\n\nexport const PieChart: ComponentSpec = {\n name: \"PieChart\",\n description: \"Pie/Donut chart. Each segment maps to a label/value pair.\",\n props: [\n { name: \"labels\", type: \"string[]\" },\n { name: \"values\", type: \"number[]\" },\n { name: \"title\", type: \"string\", optional: true },\n ],\n render: (_node, props) => {\n const labels = asArray<unknown>(props.labels).map((l) => asString(l));\n const values = asArray<unknown>(props.values).map((v) => asNumber(v));\n const root = el(\"div\", { class: \"rui-chart rui-pie-chart\" });\n if (asString(props.title)) root.append(el(\"div\", { class: \"rui-chart-title\" }, [asString(props.title)]));\n\n const total = values.reduce((acc, v) => acc + v, 0) || 1;\n const svg = createSvg(240, 240);\n const cx = 120, cy = 120, r = 90;\n let angle = -Math.PI / 2;\n\n values.forEach((value, i) => {\n const slice = (value / total) * Math.PI * 2;\n const next = angle + slice;\n const large = slice > Math.PI ? 1 : 0;\n const x1 = cx + r * Math.cos(angle);\n const y1 = cy + r * Math.sin(angle);\n const x2 = cx + r * Math.cos(next);\n const y2 = cy + r * Math.sin(next);\n const path = `M${cx},${cy} L${x1},${y1} A${r},${r} 0 ${large} 1 ${x2},${y2} Z`;\n const segment = svgEl(\"path\", {\n d: path,\n fill: colorAt(i),\n stroke: \"var(--rui-color-bg, #fff)\",\n \"stroke-width\": \"2\",\n });\n segment.append(svgEl(\"title\", {}, [`${labels[i] ?? \"\"}: ${value}`]));\n svg.append(segment);\n angle = next;\n });\n\n root.append(svg);\n root.append(legend(labels.map((name, i) => ({ name, values: [values[i] ?? 0] }))));\n return root;\n },\n};\n\ninterface LabelPlan {\n /** Render every Nth label (1 = all of them). */\n step: number;\n /** Rotate labels -45° when horizontal space per label is too tight. */\n rotated: boolean;\n /** Truncate each label to this many characters; full label stays in <title>. */\n maxChars: number;\n /** Reserved height under the chart so rotated labels are not clipped. */\n bottomPadding: number;\n}\n\n// Pixel budget assumptions for label sizing. These are deliberately conservative\n// — the chart is rendered as SVG so we cannot measure text without a layout\n// pass, but treating each character as ~7px wide tracks reality for the\n// chart label font (~11px sans-serif) closely enough for layout decisions.\nconst APPROX_CHAR_PX = 7;\n// Below this per-label slot, even rotated labels are too tight; we thin them\n// by showing every Nth label and keep the rest discoverable via hover titles.\nconst MIN_ROTATED_SLOT_PX = 12;\n\nfunction planLabels(labels: ReadonlyArray<string>, innerWidth: number): LabelPlan {\n if (labels.length === 0) {\n return { step: 1, rotated: false, maxChars: 32, bottomPadding: 32 };\n }\n const slot = innerWidth / Math.max(labels.length, 1);\n const longest = labels.reduce((max, l) => Math.max(max, l.length), 0);\n // Horizontal fit: enough room to print without rotating.\n if (longest * APPROX_CHAR_PX + 4 <= slot) {\n return { step: 1, rotated: false, maxChars: longest, bottomPadding: 32 };\n }\n // Otherwise rotate. If still too tight after rotating, drop every Nth label.\n const step = slot < MIN_ROTATED_SLOT_PX ? Math.max(1, Math.ceil(MIN_ROTATED_SLOT_PX / slot)) : 1;\n // Cap label characters by the bottom padding we are willing to spend. The\n // 50px budget renders ~14 chars after the 45° rotation flattens to ~70%.\n const maxChars = Math.min(longest, 14);\n return { step, rotated: true, maxChars, bottomPadding: 60 };\n}\n\nfunction truncateLabel(label: string, maxChars: number): string {\n if (label.length <= maxChars) return label;\n return label.slice(0, Math.max(maxChars - 1, 1)) + \"…\";\n}\n\nfunction drawXAxisLabels(\n svg: SVGSVGElement,\n labels: ReadonlyArray<string>,\n padding: { left: number; right: number; top: number; bottom: number },\n _innerWidth: number,\n innerHeight: number,\n plan: LabelPlan,\n xFor: (index: number) => number,\n): void {\n const baseY = padding.top + innerHeight + (plan.rotated ? 14 : 18);\n labels.forEach((label, i) => {\n if (i % plan.step !== 0) return;\n const x = xFor(i);\n const display = truncateLabel(label, plan.maxChars);\n const attrs: Record<string, string> = {\n x: String(x),\n y: String(baseY),\n class: \"rui-chart-label\",\n \"text-anchor\": plan.rotated ? \"end\" : \"middle\",\n };\n if (plan.rotated) {\n attrs.transform = `rotate(-45, ${x}, ${baseY})`;\n }\n const text = svgEl(\"text\", attrs, [display]);\n if (display !== label) {\n // Preserve the full label as a hover tooltip when we had to truncate.\n text.append(svgEl(\"title\", {}, [label]));\n }\n svg.append(text);\n });\n}\n\nfunction createSvg(width: number, height: number): SVGSVGElement {\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svg.setAttribute(\"class\", \"rui-chart-svg\");\n svg.setAttribute(\"role\", \"img\");\n return svg;\n}\n\nfunction svgEl(\n tag: string,\n attrs: Record<string, string>,\n children?: ReadonlyArray<Node | string>,\n): SVGElement {\n const node = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n for (const [key, value] of Object.entries(attrs)) node.setAttribute(key, value);\n if (children) {\n for (const child of children) {\n node.append(typeof child === \"string\" ? document.createTextNode(child) : child);\n }\n }\n return node;\n}\n\nfunction drawAxes(\n svg: SVGSVGElement,\n padding: { left: number; right: number; top: number; bottom: number },\n innerWidth: number,\n innerHeight: number,\n max: number,\n min = 0,\n): void {\n const ticks = 4;\n for (let i = 0; i <= ticks; i += 1) {\n const ratio = i / ticks;\n const y = padding.top + innerHeight - ratio * innerHeight;\n svg.append(svgEl(\"line\", {\n x1: String(padding.left),\n x2: String(padding.left + innerWidth),\n y1: String(y),\n y2: String(y),\n stroke: \"var(--rui-color-border-subtle, rgba(0,0,0,0.08))\",\n }));\n svg.append(svgEl(\"text\", {\n x: String(padding.left - 6),\n y: String(y + 3),\n \"text-anchor\": \"end\",\n class: \"rui-chart-tick\",\n }, [String(Math.round((min + (max - min) * ratio) * 10) / 10)]));\n }\n}\n\nfunction legend(series: SeriesData[]): HTMLElement {\n const root = el(\"div\", { class: \"rui-chart-legend\" });\n series.forEach((s, i) => {\n const item = el(\"span\", { class: \"rui-chart-legend-item\" });\n item.append(el(\"span\", { class: \"rui-chart-legend-swatch\", style: `background:${colorAt(i)}` }));\n item.append(el(\"span\", {}, [s.name]));\n root.append(item);\n });\n return root;\n}\n","/**\n * Chat-friendly composite components: SectionBlock, ListBlock, FollowUpBlock.\n * These wrap content with the right typography for assistant responses.\n */\n\nimport type { ComponentSpec, RenderHelpers } from \"../types.js\";\nimport { el, asArray, asBoolean, asString } from \"../utils.js\";\n\nexport const SectionBlock: ComponentSpec = {\n name: \"SectionBlock\",\n description: \"Titled chat block with a description and child content.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"children\", type: \"Node[]\" },\n { name: \"description\", type: \"string\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"section\", { class: \"rui-section-block\" });\n root.append(el(\"h3\", { class: \"rui-section-block-title\" }, [asString(props.title)]));\n const desc = asString(props.description);\n if (desc) root.append(el(\"p\", { class: \"rui-section-block-description\" }, [desc]));\n for (const child of asArray(props.children)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nexport const ListBlock: ComponentSpec = {\n name: \"ListBlock\",\n description: \"Chat-styled list with bullets, useful for steps or summaries.\",\n props: [\n { name: \"items\", type: \"string[]\" },\n { name: \"ordered\", type: \"boolean\", optional: true },\n ],\n render: (_node, props) => {\n const tag = asBoolean(props.ordered) ? \"ol\" : \"ul\";\n const root = el(tag as \"ul\", { class: \"rui-list-block\" });\n for (const item of asArray(props.items)) {\n root.append(el(\"li\", {}, [asString(item)]));\n }\n return root;\n },\n};\n\nexport const FollowUpBlock: ComponentSpec = {\n name: \"FollowUpBlock\",\n description: \"Suggested follow-up prompts shown as buttons. Each item dispatches its label as an assistant message (equivalent to `emit \\\"assistant-message\\\" { message }`).\",\n props: [\n { name: \"items\", type: \"FollowUpItem[]\", description: \"Array of FollowUpItem(label, message?), {label, message} objects, or plain strings\" },\n { name: \"title\", type: \"string\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-follow-up\" });\n const title = asString(props.title, \"You can also ask\");\n if (title) root.append(el(\"div\", { class: \"rui-follow-up-title\" }, [title]));\n const list = el(\"div\", { class: \"rui-follow-up-list\" });\n for (const item of asArray<unknown>(props.items)) {\n list.append(buildFollowUpButton(item, helpers));\n }\n root.append(list);\n return root;\n },\n};\n\nconst buildFollowUpButton = (\n item: unknown,\n helpers: Pick<RenderHelpers, \"sendToAssistant\">,\n): HTMLButtonElement => {\n const { label, message } = extractFollowUp(item);\n const button = el(\"button\", { class: \"rui-follow-up-button\", type: \"button\" }, [label]);\n button.onclick = () => {\n helpers.sendToAssistant(message);\n };\n return button;\n};\n\nconst extractFollowUp = (item: unknown): { label: string; message: string } => {\n if (typeof item === \"string\") return { label: item, message: item };\n if (item && typeof item === \"object\") {\n const node = item as { __kind?: string; args?: unknown[]; label?: unknown; message?: unknown };\n if (node.__kind === \"Component\" && Array.isArray(node.args)) {\n const label = asString(node.args[0]);\n const message = asString(node.args[1], label);\n return { label, message };\n }\n const label = asString(node.label);\n const message = asString(node.message, label);\n return { label, message };\n }\n const fallback = asString(item);\n return { label: fallback, message: fallback };\n};\n\nexport const FollowUpItem: ComponentSpec = {\n name: \"FollowUpItem\",\n description: \"Single follow-up item.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"message\", type: \"string\", optional: true, description: \"Defaults to label\" },\n ],\n render: (_node, props, helpers) => {\n const label = asString(props.label);\n const message = asString(props.message, label);\n const button = el(\"button\", { class: \"rui-follow-up-button\", type: \"button\" }, [label]);\n button.onclick = () => {\n helpers.sendToAssistant(message);\n };\n return button;\n },\n};\n\nexport const ActionLink: ComponentSpec = {\n name: \"ActionLink\",\n description: \"Inline link that runs an Action when clicked instead of navigating.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"action\", type: \"callable\", aliases: [\"onClick\", \"onclick\"] },\n ],\n render: (_node, props, helpers) => {\n const link = el(\"a\", { class: \"rui-action-link\", href: \"#\", role: \"button\" }, [asString(props.label)]);\n link.onclick = (event) => {\n event.preventDefault();\n helpers.invoke(props.action);\n };\n return link;\n },\n};\n","/**\n * Feedback primitives modeled after shadcn/ui:\n * Avatar, AvatarGroup, Progress, Switch, Toggle, ToggleGroup, Tooltip,\n * HoverCard, Popover, Toast, Toasts, Kbd.\n *\n * These cover the most common \"small bits of UI\" that the LLM otherwise has\n * to fake with Text + emoji combinations. Every component is purely\n * declarative — state binding is done at the prop level so a `$variable`\n * passed to `Switch` two-way-binds the same way it does for `Checkbox`.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport {\n el, asArray, asString, asBoolean, asNumber, renderIcon,\n sanitiseCssLength, sanitiseImageSrc,\n} from \"../utils.js\";\nimport { initialsFor, installDismissListeners, disposeDismissListeners, dicebearUrlFor } from \"./_internal.js\";\nimport { resolveIconClasses } from \"../../icons/index.js\";\n\nconst AVATAR_SIZES = [\"sm\", \"md\", \"lg\", \"xl\"] as const;\n\nconst AVATAR_FALLBACKS = [\"initials\", \"dicebear\"] as const;\n\nexport const Avatar: ComponentSpec = {\n name: \"Avatar\",\n description:\n \"User avatar. Shows the image at `src`. When `src` is missing, falls back \" +\n \"to a deterministic DiceBear illustration seeded by `name` (pass \" +\n \"`fallback=\\\"initials\\\"` to render two-letter initials instead). If the \" +\n \"image errors at runtime the avatar gracefully degrades to initials.\",\n props: [\n { name: \"name\", type: \"string\", description: \"Used for alt text + initials fallback\" },\n { name: \"src\", type: \"string\", optional: true, description: \"Image URL\" },\n { name: \"size\", type: \"string\", optional: true, enum: AVATAR_SIZES },\n { name: \"status\", type: \"string\", optional: true, enum: [\"online\", \"offline\", \"busy\", \"away\"] },\n {\n name: \"fallback\",\n type: \"string\",\n optional: true,\n enum: AVATAR_FALLBACKS,\n description: \"How to render when `src` is missing (default: dicebear illustration; pass `initials` for the two-letter pill)\",\n },\n ],\n render: (_node, props) => {\n const size = asString(props.size, \"md\");\n const root = el(\"span\", {\n class: \"rui-avatar\",\n \"data-size\": size,\n role: \"img\",\n });\n const name = asString(props.name);\n const fallback = asString(props.fallback, \"dicebear\") as (typeof AVATAR_FALLBACKS)[number];\n const explicitSrc = sanitiseImageSrc(props.src);\n const generated = !explicitSrc && fallback === \"dicebear\" && name\n ? sanitiseImageSrc(dicebearUrlFor(name))\n : \"\";\n const src = explicitSrc || generated;\n if (src) {\n const img = el(\"img\", { src, alt: name, loading: \"lazy\" });\n img.onerror = (event) => {\n const ev = event as Event;\n const live = (ev.currentTarget ?? ev.target) as Element;\n live.replaceWith(el(\"span\", { class: \"rui-avatar-fallback\" }, [initialsFor(name)]));\n };\n root.append(img);\n } else {\n root.append(el(\"span\", { class: \"rui-avatar-fallback\" }, [initialsFor(name)]));\n }\n const status = asString(props.status);\n if (status) root.append(el(\"span\", { class: \"rui-avatar-status\", \"data-status\": status }));\n return root;\n },\n};\n\nexport const AvatarGroup: ComponentSpec = {\n name: \"AvatarGroup\",\n description:\n \"Stack of overlapping avatars with a `+N` chip when the list overflows. \" +\n \"Pass either Avatar(...) nodes or plain {name, src} objects.\",\n props: [\n { name: \"items\", type: \"Avatar[]\", description: \"Avatar(...) nodes or {name, src} objects\" },\n { name: \"max\", type: \"number\", optional: true, description: \"Maximum avatars to show (default 4)\" },\n { name: \"size\", type: \"string\", optional: true, enum: AVATAR_SIZES },\n ],\n render: (_node, props, helpers) => {\n const items = asArray<unknown>(props.items);\n const max = Math.max(1, Math.floor(Number(props.max ?? 4)));\n const size = asString(props.size, \"md\");\n const visible = items.slice(0, max);\n const overflow = items.length - visible.length;\n const root = el(\"div\", { class: \"rui-avatar-group\", \"data-size\": size });\n for (const item of visible) {\n if (item && typeof item === \"object\" && (item as { __kind?: string }).__kind === \"Component\") {\n root.append(helpers.renderNode(item));\n continue;\n }\n const data = item as { name?: unknown; src?: unknown } | string | null;\n const name = typeof data === \"string\" ? data : asString((data ?? {}).name);\n const src = typeof data === \"string\" ? \"\" : asString((data ?? {}).src);\n root.append(Avatar.render(\n { __kind: \"Component\", name: \"Avatar\", args: [], argMeta: [] },\n { name, src, size },\n helpers,\n ));\n }\n if (overflow > 0) {\n root.append(el(\"span\", {\n class: \"rui-avatar rui-avatar-overflow\",\n \"data-size\": size,\n }, [el(\"span\", { class: \"rui-avatar-fallback\" }, [`+${overflow}`])]));\n }\n return root;\n },\n};\n\nexport const Progress: ComponentSpec = {\n name: \"Progress\",\n description:\n \"Linear progress bar. `value` is clamped between 0 and `max` (default \" +\n \"100). `indeterminate=true` renders a looping animation when the total \" +\n \"is unknown. Provide `segments` to render a segmented progress strip \" +\n \"(steps in an onboarding flow), or `buffered` for a secondary \" +\n \"buffer indicator (downloads, video buffering).\",\n props: [\n { name: \"value\", type: \"number\", optional: true, description: \"Current progress; ignored when indeterminate\" },\n { name: \"max\", type: \"number\", optional: true, description: \"Upper bound (default 100)\" },\n { name: \"label\", type: \"string\", optional: true, description: \"Shown above the bar\" },\n { name: \"tone\", type: \"string\", optional: true, enum: [\"primary\", \"success\", \"warning\", \"danger\", \"info\"] },\n { name: \"indeterminate\", type: \"boolean\", optional: true },\n { name: \"showValue\", type: \"boolean\", optional: true, description: \"Show the numeric value on the right\" },\n { name: \"segments\", type: \"number\", optional: true, description: \"Render N equal segments (filled by current step)\" },\n { name: \"buffered\", type: \"number\", optional: true, description: \"Secondary value (0..max) drawn behind the bar\" },\n ],\n render: (_node, props) => {\n const max = Math.max(1, asNumber(props.max, 100));\n const indeterminate = asBoolean(props.indeterminate);\n const value = Math.max(0, Math.min(max, asNumber(props.value, 0)));\n const percent = Math.round((value / max) * 100);\n const segments = Math.max(0, Math.floor(asNumber(props.segments, 0)));\n const buffered = props.buffered != null ? Math.max(0, Math.min(max, asNumber(props.buffered, 0))) : null;\n const root = el(\"div\", { class: \"rui-progress\", \"data-tone\": asString(props.tone, \"primary\") });\n const label = asString(props.label);\n const showValue = asBoolean(props.showValue);\n if (label || showValue) {\n const head = el(\"div\", { class: \"rui-progress-head\" });\n head.append(el(\"span\", { class: \"rui-progress-label\" }, [label]));\n if (showValue && !indeterminate) {\n const display = segments > 0\n ? `${Math.min(segments, Math.round((value / max) * segments))} / ${segments}`\n : `${percent}%`;\n head.append(el(\"span\", { class: \"rui-progress-value\" }, [display]));\n }\n root.append(head);\n }\n\n if (segments > 0 && !indeterminate) {\n const trackRoot = el(\"div\", {\n class: \"rui-progress-segments\",\n role: \"progressbar\",\n \"aria-valuemin\": \"0\",\n \"aria-valuemax\": String(segments),\n \"aria-valuenow\": String(Math.min(segments, Math.round((value / max) * segments))),\n });\n const filled = Math.min(segments, Math.round((value / max) * segments));\n for (let i = 0; i < segments; i += 1) {\n trackRoot.append(el(\"span\", {\n class: \"rui-progress-segment\",\n \"data-filled\": i < filled ? \"true\" : \"false\",\n }));\n }\n root.append(trackRoot);\n return root;\n }\n\n const track = el(\"div\", {\n class: \"rui-progress-track\",\n role: \"progressbar\",\n \"aria-valuemin\": \"0\",\n \"aria-valuemax\": String(max),\n \"aria-valuenow\": indeterminate ? null : String(value),\n \"data-indeterminate\": indeterminate ? \"true\" : \"false\",\n });\n if (buffered !== null) {\n const bufferedPercent = Math.round((buffered / max) * 100);\n track.append(el(\"div\", {\n class: \"rui-progress-buffer\",\n style: `width:${bufferedPercent}%`,\n \"aria-hidden\": \"true\",\n }));\n }\n track.append(el(\"div\", {\n class: \"rui-progress-bar\",\n style: indeterminate ? \"\" : `width:${percent}%`,\n }));\n root.append(track);\n return root;\n },\n};\n\nexport const Switch: ComponentSpec = {\n name: \"Switch\",\n description:\n \"Compact on/off toggle. Pass a `$variable` as `value` for two-way binding \" +\n \"— prefer Switch over Checkbox when the control represents a setting.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"label\", type: \"string\", optional: true },\n { name: \"value\", type: \"boolean\", optional: true, aliases: [\"checked\"], description: \"Bound value (typically $variable)\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const root = el(\"label\", {\n class: \"rui-switch\",\n for: id,\n \"data-disabled\": asBoolean(props.disabled) ? \"true\" : \"false\",\n });\n const isChecked = asBoolean(props.value);\n const input = el(\"input\", {\n type: \"checkbox\",\n id,\n name: id,\n class: \"rui-switch-input\",\n role: \"switch\",\n checked: isChecked ? \"\" : null,\n disabled: asBoolean(props.disabled) ? \"\" : null,\n }) as HTMLInputElement;\n input.checked = isChecked;\n const track = el(\"span\", { class: \"rui-switch-track\" }, [\n el(\"span\", { class: \"rui-switch-thumb\" }),\n ]);\n const stateName = node.argMeta?.[2]?.stateRef;\n if (stateName) {\n helpers.bindState(input, stateName, {\n event: \"change\",\n getValue: (n) => (n as HTMLInputElement).checked,\n });\n }\n const label = asString(props.label);\n const description = asString(props.description);\n root.append(input, track);\n if (label || description) {\n const meta = el(\"span\", { class: \"rui-switch-meta\" });\n if (label) meta.append(el(\"span\", { class: \"rui-switch-label\" }, [label]));\n if (description) meta.append(el(\"span\", { class: \"rui-switch-description\" }, [description]));\n root.append(meta);\n }\n return root;\n },\n};\n\nexport const ToggleGroup: ComponentSpec = {\n name: \"ToggleGroup\",\n description:\n \"Group of mutually-exclusive Toggle-style buttons (single-select). Items \" +\n \"are `[value, label]` arrays, `{value, label, icon?}` objects, or plain \" +\n \"strings (used for both value and label). Pass a `$variable` as `value` \" +\n \"for two-way binding.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"items\", type: \"any[]\" },\n { name: \"value\", type: \"any\", optional: true },\n { name: \"variant\", type: \"string\", optional: true, enum: [\"default\", \"outline\"] },\n { name: \"size\", type: \"string\", optional: true, enum: [\"sm\", \"md\", \"lg\"] },\n ],\n render: (node, props, helpers) => {\n const current = asString(props.value);\n const variant = asString(props.variant, \"outline\");\n const size = asString(props.size, \"md\");\n const root = el(\"div\", {\n class: \"rui-toggle-group\",\n role: \"radiogroup\",\n \"data-variant\": variant,\n \"data-size\": size,\n });\n const stateName = node.argMeta?.[2]?.stateRef;\n for (const raw of asArray<unknown>(props.items)) {\n const { value, label, icon } = extractToggleItem(raw);\n const isOn = value === current;\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-toggle\",\n role: \"radio\",\n \"aria-checked\": isOn ? \"true\" : \"false\",\n \"data-variant\": variant,\n \"data-size\": size,\n \"data-state\": isOn ? \"on\" : \"off\",\n \"data-value\": value,\n });\n const itemIconNode = renderIcon(icon, { className: \"rui-toggle-icon\" });\n if (itemIconNode) btn.append(itemIconNode);\n btn.append(el(\"span\", { class: \"rui-toggle-label\" }, [label]));\n if (stateName) {\n btn.onclick = () => {\n helpers.setState(stateName, value);\n };\n }\n root.append(btn);\n }\n return root;\n },\n};\n\nfunction extractToggleItem(raw: unknown): { value: string; label: string; icon: string } {\n if (typeof raw === \"string\") return { value: raw, label: raw, icon: \"\" };\n if (Array.isArray(raw)) {\n return {\n value: asString(raw[0]),\n label: asString(raw[1], asString(raw[0])),\n icon: asString(raw[2]),\n };\n }\n if (raw && typeof raw === \"object\") {\n const r = raw as { value?: unknown; label?: unknown; icon?: unknown };\n const value = asString(r.value);\n return { value, label: asString(r.label, value), icon: asString(r.icon) };\n }\n return { value: \"\", label: \"\", icon: \"\" };\n}\n\nexport const Tooltip: ComponentSpec = {\n name: \"Tooltip\",\n description:\n \"Wraps a trigger node and shows `label` text when the user hovers or \" +\n \"focuses it. Pure CSS — no JS needed. Use for short hints (≤6 words); \" +\n \"reach for HoverCard when you need rich content.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"trigger\", type: \"Node\", aliases: [\"children\"] },\n { name: \"side\", type: \"string\", optional: true, enum: [\"top\", \"bottom\", \"left\", \"right\"], aliases: [\"placement\"] },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"span\", {\n class: \"rui-tooltip\",\n \"data-side\": asString(props.side, \"top\"),\n tabindex: \"0\",\n });\n root.append(el(\"span\", { class: \"rui-tooltip-trigger\" }, [\n helpers.renderNode(props.trigger),\n ]));\n root.append(el(\"span\", { class: \"rui-tooltip-content\", role: \"tooltip\" }, [\n asString(props.label),\n ]));\n return root;\n },\n};\n\nexport const HoverCard: ComponentSpec = {\n name: \"HoverCard\",\n description:\n \"Wraps a trigger node and reveals a card with rich content on hover/focus. \" +\n \"Use for previewing a referenced item (profile, link target, definition).\",\n props: [\n { name: \"trigger\", type: \"Node\" },\n { name: \"content\", type: \"Node[]\", aliases: [\"children\"] },\n { name: \"side\", type: \"string\", optional: true, enum: [\"top\", \"bottom\", \"left\", \"right\"], aliases: [\"placement\"] },\n { name: \"open\", type: \"boolean\", optional: true, description: \"Force the card open (otherwise reveal on hover/focus)\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"span\", {\n class: \"rui-hover-card\",\n \"data-side\": asString(props.side, \"bottom\"),\n \"data-open\": asBoolean(props.open) ? \"true\" : null,\n tabindex: \"0\",\n });\n root.append(el(\"span\", { class: \"rui-hover-card-trigger\" }, [\n helpers.renderNode(props.trigger),\n ]));\n const card = el(\"span\", { class: \"rui-hover-card-content\", role: \"dialog\" });\n for (const child of asArray(props.content)) card.append(helpers.renderNode(child));\n root.append(card);\n return root;\n },\n};\n\nconst RATING_ICONS: Record<string, { full: string; half: string; empty: string }> = {\n star: { full: \"star\", half: \"star-half-stroke\", empty: \"regular:star\" },\n heart: { full: \"heart\", half: \"heart\", empty: \"regular:heart\" },\n thumb: { full: \"thumbs-up\", half: \"thumbs-up\", empty: \"regular:thumbs-up\" },\n fire: { full: \"fire\", half: \"fire\", empty: \"regular:fire\" },\n bolt: { full: \"bolt\", half: \"bolt\", empty: \"regular:bolt\" },\n};\n\nexport const Rating: ComponentSpec = {\n name: \"Rating\",\n description:\n \"Compact 0–5 star rating with optional numeric badge and review \" +\n \"count. Use in product cards, testimonials, reviews, and KPI rows. \" +\n \"Pass `interactive=true` and a `$variable` as `value` to let users \" +\n \"rate something; with `halfStep=true` clicking the left half of a \" +\n \"star sets a fractional value. `icon` swaps the glyph family — \" +\n \"`star` (default), `heart`, `thumb`, `fire`, `bolt`, or any custom \" +\n \"Font Awesome name.\",\n props: [\n { name: \"value\", type: \"number\", description: \"0–max; can be a $variable when interactive\" },\n { name: \"max\", type: \"number\", optional: true, description: \"Maximum number of stars (default 5)\" },\n { name: \"label\", type: \"string\", optional: true, description: \"Inline text shown after the stars (e.g. \\\"4.2 of 5\\\")\" },\n { name: \"count\", type: \"number\", optional: true, description: \"Review/voter count rendered in parentheses\" },\n { name: \"size\", type: \"string\", optional: true, enum: [\"sm\", \"md\", \"lg\"] },\n { name: \"interactive\", type: \"boolean\", optional: true, description: \"Allow clicking a star to set the value\" },\n { name: \"readonly\", type: \"boolean\", optional: true, description: \"Force read-only (overrides `interactive`)\" },\n { name: \"halfStep\", type: \"boolean\", optional: true, description: \"Allow half-star resolution when interactive\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Icon family — `star` (default), `heart`, `thumb`, `fire`, `bolt`, or any FA name\" },\n ],\n render: (node, props, helpers) => {\n const max = Math.max(1, Math.floor(asNumber(props.max, 5)));\n const raw = Math.max(0, Math.min(max, asNumber(props.value, 0)));\n const size = asString(props.size, \"md\");\n const interactive = asBoolean(props.interactive) && !asBoolean(props.readonly);\n const halfStep = asBoolean(props.halfStep);\n const stateName = node.argMeta?.[0]?.stateRef;\n const iconChoice = resolveRatingIcons(asString(props.icon));\n const root = el(\"div\", {\n class: \"rui-rating\",\n \"data-size\": size,\n \"data-interactive\": interactive && stateName ? \"true\" : \"false\",\n \"data-half-step\": interactive && stateName && halfStep ? \"true\" : \"false\",\n role: \"img\",\n \"aria-label\": `${raw} of ${max}`,\n });\n const stars = el(\"span\", { class: \"rui-rating-stars\" });\n for (let i = 1; i <= max; i += 1) {\n const fill = Math.max(0, Math.min(1, raw - (i - 1)));\n const iconName =\n fill >= 1 ? iconChoice.full : fill > 0 ? iconChoice.half : iconChoice.empty;\n const iconClasses = resolveIconClasses(iconName).join(\" \");\n const star = el(interactive && stateName ? \"button\" : \"span\", {\n class: `rui-rating-star ${iconClasses}`.trim(),\n type: interactive && stateName ? \"button\" : null,\n \"data-fill\": fill >= 1 ? \"full\" : fill > 0 ? \"half\" : \"empty\",\n \"aria-label\": interactive && stateName ? `Rate ${i}` : null,\n \"aria-hidden\": interactive && stateName ? null : \"true\",\n });\n if (interactive && stateName) {\n const fullValue = i;\n const halfValue = i - 0.5;\n (star as HTMLButtonElement).onclick = (event) => {\n let next: number = fullValue;\n if (halfStep) {\n // Determine which half of the star was clicked. Resolve from\n // the live element via the event so the handler still works\n // after the morph reconciler keeps the previous DOM.\n const evt = event as MouseEvent;\n const target = (evt.currentTarget ?? evt.target) as HTMLElement;\n const rect = target.getBoundingClientRect();\n if (rect.width > 0 && evt.clientX - rect.left < rect.width / 2) {\n next = halfValue;\n }\n }\n helpers.setState(stateName, next);\n };\n }\n stars.append(star);\n }\n root.append(stars);\n const label = asString(props.label);\n if (label) root.append(el(\"span\", { class: \"rui-rating-label\" }, [label]));\n const count = props.count != null ? asNumber(props.count, 0) : null;\n if (count !== null && count > 0) {\n root.append(el(\"span\", { class: \"rui-rating-count\" }, [`(${count.toLocaleString()})`]));\n }\n return root;\n },\n};\n\nfunction resolveRatingIcons(icon: string): { full: string; half: string; empty: string } {\n const key = icon.trim().toLowerCase();\n if (!key) return RATING_ICONS.star!;\n if (RATING_ICONS[key]) return RATING_ICONS[key]!;\n // Custom icon name (e.g. \"circle\") — fill/half/empty reuse the same glyph\n // and rely on the data-fill attribute for visual differentiation in CSS.\n return { full: key, half: key, empty: `regular:${key}` };\n}\n\nexport const ProgressRing: ComponentSpec = {\n name: \"ProgressRing\",\n description:\n \"Circular progress indicator. Use for KPIs, quotas, completion rings, \" +\n \"and any metric better shown as a circle than a bar. Renders the \" +\n \"value (or a custom label) inside the ring.\",\n props: [\n { name: \"value\", type: \"number\", optional: true, description: \"Current value (ignored when indeterminate)\" },\n { name: \"max\", type: \"number\", optional: true, description: \"Upper bound (default 100)\" },\n { name: \"label\", type: \"string\", optional: true, description: \"Text shown inside the ring (default \\\"{percent}%\\\")\" },\n { name: \"caption\", type: \"string\", optional: true, aliases: [\"description\"], description: \"Small caption rendered under the ring\" },\n { name: \"tone\", type: \"string\", optional: true, enum: [\"primary\", \"success\", \"warning\", \"danger\", \"info\"] },\n { name: \"size\", type: \"string\", optional: true, enum: [\"sm\", \"md\", \"lg\"] },\n { name: \"indeterminate\", type: \"boolean\", optional: true },\n ],\n render: (_node, props) => {\n const max = Math.max(1, asNumber(props.max, 100));\n const indeterminate = asBoolean(props.indeterminate);\n const value = Math.max(0, Math.min(max, asNumber(props.value, 0)));\n const percent = Math.round((value / max) * 100);\n const size = asString(props.size, \"md\");\n const px = size === \"lg\" ? 120 : size === \"sm\" ? 72 : 96;\n const stroke = size === \"lg\" ? 10 : size === \"sm\" ? 6 : 8;\n const r = (px - stroke) / 2;\n const circumference = 2 * Math.PI * r;\n const offset = indeterminate ? circumference * 0.65 : circumference * (1 - percent / 100);\n const root = el(\"div\", {\n class: \"rui-progress-ring\",\n \"data-tone\": asString(props.tone, \"primary\"),\n \"data-size\": size,\n \"data-indeterminate\": indeterminate ? \"true\" : \"false\",\n });\n const wrap = el(\"div\", { class: \"rui-progress-ring-wrap\" });\n const svgNS = \"http://www.w3.org/2000/svg\";\n const svg = document.createElementNS(svgNS, \"svg\");\n svg.setAttribute(\"width\", String(px));\n svg.setAttribute(\"height\", String(px));\n svg.setAttribute(\"viewBox\", `0 0 ${px} ${px}`);\n svg.setAttribute(\"class\", \"rui-progress-ring-svg\");\n const track = document.createElementNS(svgNS, \"circle\");\n track.setAttribute(\"class\", \"rui-progress-ring-track\");\n track.setAttribute(\"cx\", String(px / 2));\n track.setAttribute(\"cy\", String(px / 2));\n track.setAttribute(\"r\", String(r));\n track.setAttribute(\"stroke-width\", String(stroke));\n track.setAttribute(\"fill\", \"none\");\n svg.appendChild(track);\n const bar = document.createElementNS(svgNS, \"circle\");\n bar.setAttribute(\"class\", \"rui-progress-ring-bar\");\n bar.setAttribute(\"cx\", String(px / 2));\n bar.setAttribute(\"cy\", String(px / 2));\n bar.setAttribute(\"r\", String(r));\n bar.setAttribute(\"stroke-width\", String(stroke));\n bar.setAttribute(\"fill\", \"none\");\n bar.setAttribute(\"stroke-linecap\", \"round\");\n bar.setAttribute(\"stroke-dasharray\", String(circumference));\n bar.setAttribute(\"stroke-dashoffset\", String(offset));\n svg.appendChild(bar);\n wrap.append(svg);\n const rawLabel = asString(props.label, indeterminate ? \"…\" : `${percent}%`);\n const center = el(\"span\", { class: \"rui-progress-ring-value\" });\n // Allow the inner label to be a Font Awesome icon name (e.g. \"circle-check\")\n // for completion-style rings, while still accepting plain text labels.\n const labelIcon = renderIcon(rawLabel, { className: \"rui-progress-ring-icon\" });\n if (labelIcon && resolveIconClasses(rawLabel).length > 0) {\n center.append(labelIcon);\n } else {\n center.append(document.createTextNode(rawLabel));\n }\n wrap.append(center);\n root.append(wrap);\n const caption = asString(props.caption);\n if (caption) root.append(el(\"span\", { class: \"rui-progress-ring-caption\" }, [caption]));\n return root;\n },\n};\n\nexport const ChatBubble: ComponentSpec = {\n name: \"ChatBubble\",\n description:\n \"Single chat-style message bubble with author, time, and body. Use \" +\n \"for conversation threads, agent transcripts, support chats, and any \" +\n \"message-style UI. Set `from=\\\"me\\\"` (or any non-empty author) for \" +\n \"the active speaker — the bubble aligns to the right with a primary \" +\n \"tint. `from=\\\"agent\\\"` (default) renders as the canonical incoming \" +\n \"bubble on the left.\",\n props: [\n { name: \"author\", type: \"string\" },\n { name: \"body\", type: \"string\", aliases: [\"text\", \"message\"] },\n { name: \"time\", type: \"string\", optional: true },\n { name: \"avatarSrc\", type: \"string\", optional: true, aliases: [\"src\"] },\n { name: \"from\", type: \"string\", optional: true, enum: [\"agent\", \"me\", \"system\"], aliases: [\"role\"], description: \"Lane (default agent)\" },\n { name: \"status\", type: \"string\", optional: true, enum: [\"sending\", \"sent\", \"delivered\", \"read\", \"error\"] },\n ],\n render: (_node, props) => {\n const from = asString(props.from, \"agent\");\n const root = el(\"div\", {\n class: \"rui-chat-bubble\",\n \"data-from\": from,\n });\n if (from !== \"me\") {\n root.append(renderAvatarFallback(asString(props.avatarSrc), asString(props.author)));\n }\n const bubble = el(\"div\", { class: \"rui-chat-bubble-bubble\" });\n const head = el(\"header\", { class: \"rui-chat-bubble-head\" });\n head.append(el(\"span\", { class: \"rui-chat-bubble-author\" }, [asString(props.author)]));\n const time = asString(props.time);\n if (time) head.append(el(\"span\", { class: \"rui-chat-bubble-time\" }, [time]));\n bubble.append(head);\n bubble.append(el(\"p\", { class: \"rui-chat-bubble-body\" }, [asString(props.body)]));\n const status = asString(props.status);\n if (status) bubble.append(el(\"span\", { class: \"rui-chat-bubble-status\", \"data-status\": status }, [status]));\n root.append(bubble);\n if (from === \"me\") {\n root.append(renderAvatarFallback(asString(props.avatarSrc), asString(props.author)));\n }\n return root;\n },\n};\n\nfunction renderAvatarFallback(src: string, name: string): HTMLElement {\n const wrap = el(\"span\", { class: \"rui-chat-bubble-avatar\" });\n const safeSrc = sanitiseImageSrc(src);\n if (safeSrc) {\n wrap.append(el(\"img\", { src: safeSrc, alt: name, loading: \"lazy\" }));\n } else {\n wrap.append(el(\"span\", { class: \"rui-chat-bubble-fallback\" }, [initialsFor(name)]));\n }\n return wrap;\n}\n\nexport const Kbd: ComponentSpec = {\n name: \"Kbd\",\n description:\n \"Renders a keyboard shortcut chip (e.g. `Cmd+K`). Pass a single label, or \" +\n \"multiple labels as an array to render a `key + key + …` combo.\",\n props: [\n { name: \"keys\", type: \"string | string[]\" },\n { name: \"size\", type: \"string\", optional: true, enum: [\"sm\", \"md\"] },\n ],\n render: (_node, props) => {\n const size = asString(props.size, \"md\");\n const root = el(\"span\", { class: \"rui-kbd-group\", \"data-size\": size });\n const keys = Array.isArray(props.keys) ? props.keys : [props.keys];\n keys.forEach((key, i) => {\n const label = asString(key);\n if (!label) return;\n if (i > 0) root.append(el(\"span\", { class: \"rui-kbd-sep\" }, [\"+\"]));\n root.append(el(\"kbd\", { class: \"rui-kbd\" }, [label]));\n });\n return root;\n },\n};\n\nconst POPOVER_SIDES = [\"bottom\", \"top\", \"left\", \"right\"] as const;\nconst POPOVER_ALIGNS = [\"start\", \"center\", \"end\"] as const;\n\nexport const Popover: ComponentSpec = {\n name: \"Popover\",\n description:\n \"Click-triggered popup with arbitrary rich content. Use when \" +\n \"HoverCard's hover trigger is too eager and Modal/Sheet is too heavy — \" +\n \"perfect for filter panels, color pickers, share menus, and small \" +\n \"settings flyouts. The trigger stays visible while the popover is \" +\n \"open — clicking it again, clicking outside, pressing Escape, or \" +\n \"clicking the built-in × button all close it.\",\n props: [\n { name: \"trigger\", type: \"Node\", description: \"Clickable trigger element (Button, Avatar, IconButton, …). The trigger remains visible while the popover is open.\" },\n { name: \"content\", type: \"Node[]\", aliases: [\"children\"], description: \"Body rendered inside the popover\" },\n { name: \"title\", type: \"string\", optional: true, description: \"Optional bold heading rendered above the content\" },\n { name: \"side\", type: \"string\", optional: true, enum: POPOVER_SIDES, aliases: [\"placement\"], description: \"Where the popover opens relative to the trigger (default \\\"bottom\\\")\" },\n { name: \"align\", type: \"string\", optional: true, enum: POPOVER_ALIGNS, description: \"Alignment along the trigger edge (default \\\"start\\\")\" },\n { name: \"width\", type: \"string\", optional: true, description: \"CSS width for the popover panel (default \\\"280px\\\")\" },\n { name: \"open\", type: \"boolean\", optional: true, description: \"Initial open state — use to demo or pre-open the popover\" },\n ],\n render: (_node, props, helpers) => {\n const initialOpen = asBoolean(props.open);\n const openSlot = helpers.useInstanceState<boolean>(\"open\", initialOpen);\n const isOpen = openSlot.get();\n const width = sanitiseCssLength(props.width, \"\");\n const root = el(\"div\", {\n class: \"rui-popover\",\n \"data-open\": isOpen ? \"true\" : \"false\",\n \"data-side\": asString(props.side, \"bottom\"),\n \"data-align\": asString(props.align, \"start\"),\n });\n\n // Render the user's trigger directly and wrap it in a span so we can\n // attach the toggle handler without nesting <button> inside <button>\n // (which is invalid HTML and silently swallows clicks in some browsers).\n const triggerWrap = el(\"span\", {\n class: \"rui-popover-trigger\",\n \"data-state\": isOpen ? \"open\" : \"closed\",\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": isOpen ? \"true\" : \"false\",\n });\n triggerWrap.append(helpers.renderNode(props.trigger));\n root.append(triggerWrap);\n\n const body = el(\"div\", {\n class: \"rui-popover-content\",\n role: \"dialog\",\n style: width ? `width: ${width};` : null,\n });\n // Always render a header so the close (×) button has a stable slot,\n // whether or not the user provided a title.\n const header = el(\"div\", { class: \"rui-popover-header\" });\n const titleText = asString(props.title);\n header.append(\n titleText\n ? el(\"div\", { class: \"rui-popover-title\" }, [titleText])\n : el(\"span\", { class: \"rui-popover-title-spacer\" }),\n );\n const closeBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-popover-close\",\n \"aria-label\": \"Close popover\",\n }, [\"×\"]);\n closeBtn.onclick = (event) => {\n event.stopPropagation();\n setPopoverOpen(closeBtn, false, openSlot);\n };\n header.append(closeBtn);\n body.append(header);\n for (const child of asArray(props.content)) {\n body.append(helpers.renderNode(child));\n }\n root.append(body);\n\n // Property-based handlers so the morph reconciler can copy the latest\n // closure (with up-to-date `openSlot`) onto kept DOM. `addEventListener`\n // would leak a fresh listener onto every detached re-render snapshot.\n triggerWrap.onclick = (event) => {\n event.stopPropagation();\n const origin = (event.currentTarget ?? event.target) as Element;\n const next = !openSlot.get();\n const liveRoot = setPopoverOpen(origin, next, openSlot);\n if (next && liveRoot) installPopoverDismiss(liveRoot, openSlot);\n };\n triggerWrap.onkeydown = (event) => {\n const e = event as KeyboardEvent;\n const origin = (e.currentTarget ?? e.target) as Element;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n const next = !openSlot.get();\n const liveRoot = setPopoverOpen(origin, next, openSlot);\n if (next && liveRoot) installPopoverDismiss(liveRoot, openSlot);\n } else if (e.key === \"Escape\" && openSlot.get()) {\n e.preventDefault();\n setPopoverOpen(origin, false, openSlot);\n }\n };\n\n return root;\n },\n};\n\n/**\n * Toggle a Popover's open state and reflect it in the live DOM so the\n * change feels instant. Returns the live root so callers can install the\n * outside-click / Escape dismiss handlers on `open`.\n */\nconst setPopoverOpen = (\n origin: Element,\n next: boolean,\n openSlot: { set: (value: boolean) => void },\n): HTMLElement | null => {\n openSlot.set(next);\n const liveRoot = origin.closest(\".rui-popover\") as HTMLElement | null;\n if (!liveRoot) return null;\n liveRoot.setAttribute(\"data-open\", next ? \"true\" : \"false\");\n const trigger = liveRoot.querySelector(\".rui-popover-trigger\");\n trigger?.setAttribute(\"aria-expanded\", next ? \"true\" : \"false\");\n trigger?.setAttribute(\"data-state\", next ? \"open\" : \"closed\");\n if (!next) disposeDismissListeners(liveRoot);\n return liveRoot;\n};\n\nconst installPopoverDismiss = (\n liveRoot: HTMLElement,\n openSlot: { set: (value: boolean) => void },\n): void => {\n installDismissListeners({\n liveRoot,\n onDismiss: () => {\n openSlot.set(false);\n liveRoot.setAttribute(\"data-open\", \"false\");\n const trigger = liveRoot.querySelector(\".rui-popover-trigger\");\n trigger?.setAttribute(\"aria-expanded\", \"false\");\n trigger?.setAttribute(\"data-state\", \"closed\");\n },\n });\n};\n\nconst TOAST_TONES = [\"default\", \"primary\", \"success\", \"warning\", \"danger\", \"info\"] as const;\n\nconst TOASTS_POSITIONS = [\n \"top-right\", \"top-left\", \"top-center\",\n \"bottom-right\", \"bottom-left\", \"bottom-center\",\n] as const;\n\nexport const Toast: ComponentSpec = {\n name: \"Toast\",\n description:\n \"Single transient notification card. Always shows a close (×) button \" +\n \"that removes the toast from the DOM (and fires `onClose` if set). \" +\n \"Pass `duration` (ms) to auto-dismiss, or `position` for a standalone \" +\n \"one-off toast (the renderer will pin it to the viewport corner so \" +\n \"you do not have to wrap a single notification in `Stack(...)`). \" +\n \"Use `Toasts` for grouped stacks; prefer `Banner` for top-of-page \" +\n \"announcements and `Notification` for permanent inbox entries.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"message\", type: \"string\", optional: true, aliases: [\"description\"] },\n { name: \"tone\", type: \"string\", optional: true, enum: TOAST_TONES, description: \"Visual accent (default \\\"default\\\")\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name (default picked from tone)\" },\n { name: \"duration\", type: \"number\", optional: true, description: \"Auto-dismiss after N milliseconds (e.g. 4000). Omit to keep the toast until the user closes it.\" },\n { name: \"action\", type: \"Button\", optional: true, description: \"Optional inline action Button(...) shown above the message\" },\n { name: \"onClose\", type: \"callable\", optional: true, description: \"Callable invoked when the toast is dismissed (× button, auto-dismiss, or programmatic)\" },\n { name: \"position\", type: \"string\", optional: true, enum: TOASTS_POSITIONS, description: \"Pin a standalone Toast to a viewport corner without wrapping it in `Stack(...)`\" },\n ],\n render: (_node, props, helpers) => {\n const tone = asString(props.tone, \"default\");\n const position = asString(props.position);\n const root = el(\"div\", {\n class: position ? \"rui-toast rui-toast-standalone\" : \"rui-toast\",\n role: \"status\",\n \"aria-live\": tone === \"danger\" ? \"assertive\" : \"polite\",\n \"data-tone\": tone,\n \"data-position\": position || null,\n });\n const iconName = asString(props.icon) || defaultToastIcon(tone);\n const iconNode = renderIcon(iconName, { className: \"rui-toast-icon\" });\n if (iconNode) root.append(iconNode);\n const body = el(\"div\", { class: \"rui-toast-body\" });\n body.append(el(\"div\", { class: \"rui-toast-title\" }, [asString(props.title)]));\n const message = asString(props.message);\n if (message) body.append(el(\"div\", { class: \"rui-toast-message\" }, [message]));\n if (props.action) {\n const actionWrap = el(\"div\", { class: \"rui-toast-action\" });\n actionWrap.append(helpers.renderNode(props.action));\n body.append(actionWrap);\n }\n root.append(body);\n\n // Track dismiss locally so re-renders don't restart the timer or undo\n // the manual close. `useInstanceState` keeps the slot keyed by the\n // toast's path in the tree.\n const dismissedSlot = helpers.useInstanceState<boolean>(\"dismissed\", false);\n const timerSlot = helpers.useInstanceState<ReturnType<typeof setTimeout> | null>(\"timer\", null);\n\n // Resolves whichever .rui-toast element is currently in the DOM,\n // preferring the live one over the closure-captured (potentially\n // detached) root.\n const liveToast = (origin?: Element): HTMLElement | null => {\n if (origin) {\n const live = origin.closest(\".rui-toast\") as HTMLElement | null;\n if (live) return live;\n }\n return root.isConnected ? root : null;\n };\n\n const cancelTimer = (): void => {\n const handle = timerSlot.get();\n if (handle !== null) {\n clearTimeout(handle);\n timerSlot.set(null);\n }\n };\n\n const removalTimerSlot = helpers.useInstanceState<ReturnType<typeof setTimeout> | null>(\"removal-timer\", null);\n\n const dismiss = (origin?: Element): void => {\n if (dismissedSlot.get()) return;\n dismissedSlot.set(true);\n // Clear the pending auto-dismiss timer so it doesn't fire `onClose`\n // a second time after the user has already closed the toast.\n cancelTimer();\n const target = liveToast(origin);\n if (!target) return;\n target.classList.add(\"is-dismissed\");\n // Allow the CSS exit animation to complete before unmounting.\n const handle = setTimeout(() => {\n removalTimerSlot.set(null);\n target.remove();\n }, 180);\n removalTimerSlot.set(handle);\n helpers.registerDisposer(() => {\n const h = removalTimerSlot.get();\n if (h !== null) {\n clearTimeout(h);\n removalTimerSlot.set(null);\n }\n }, \"exit-animation-timer\");\n helpers.invoke(props.onClose);\n };\n\n const closeBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-toast-close\",\n \"aria-label\": \"Dismiss notification\",\n }, [\"×\"]);\n closeBtn.onclick = (event) => {\n event.stopPropagation();\n dismiss((event.currentTarget ?? event.target) as Element);\n };\n root.append(closeBtn);\n\n const duration = asNumber(props.duration, 0);\n if (duration > 0 && timerSlot.get() === null && !dismissedSlot.get()) {\n const handle = setTimeout(() => {\n timerSlot.set(null);\n // Only auto-dismiss if the element is still in the document and\n // hasn't been manually closed.\n if (!dismissedSlot.get() && root.isConnected) dismiss();\n }, duration);\n timerSlot.set(handle);\n // If the toast is unmounted before the timer fires (parent re-rendered\n // without it, page navigated, host cleared), cancel the timer instead\n // of letting it fire a stale `onClose` action.\n helpers.registerDisposer(() => {\n const h = timerSlot.get();\n if (h !== null) {\n clearTimeout(h);\n timerSlot.set(null);\n }\n }, \"auto-dismiss-timer\");\n }\n\n if (dismissedSlot.get()) {\n // The toast was already dismissed in a previous render cycle —\n // return an empty placeholder so the reconciler doesn't resurrect it.\n const placeholder = el(\"div\", { class: \"rui-toast-placeholder\", hidden: \"\" });\n return placeholder;\n }\n return root;\n },\n};\n\nfunction defaultToastIcon(tone: string): string {\n switch (tone) {\n case \"success\": return \"circle-check\";\n case \"warning\": return \"triangle-exclamation\";\n case \"danger\": return \"circle-xmark\";\n case \"primary\": return \"bell\";\n case \"info\": return \"circle-info\";\n default: return \"circle-info\";\n }\n}\n\n","/**\n * Navigation primitives modeled after shadcn/ui:\n * Breadcrumb, BreadcrumbItem, Pagination, Navbar, NavbarItem.\n *\n * These are intentionally light — they wrap the existing Link/NavLink\n * components when an `href`/`to` is provided so routing stays consistent\n * with the rest of the library.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport {\n el, asArray, asString, asBoolean, asNumber, renderIcon, sanitiseHref,\n} from \"../utils.js\";\n\nexport const BreadcrumbItem: ComponentSpec = {\n name: \"BreadcrumbItem\",\n description:\n \"Single item inside a Breadcrumb trail. Provide `href` for a link, omit \" +\n \"it for the current/leaf page (rendered with emphasis).\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"href\", type: \"string\", optional: true },\n { name: \"icon\", type: \"string\", optional: true, description: \"Optional Font Awesome icon name\" },\n ],\n render: (_node, props) => {\n const root = el(\"li\", { class: \"rui-breadcrumb-item\" });\n const label = asString(props.label);\n // Sanitise the href so a hostile `javascript:` URL coming from an LLM\n // cannot fire on click. Empty input keeps the legacy \"current page\"\n // rendering path so leaf crumbs still render as plain text.\n const rawHref = asString(props.href);\n const safeHref = rawHref ? sanitiseHref(rawHref) : \"\";\n const inner: Array<Node | string | null> = [];\n const iconNode = renderIcon(props.icon, { className: \"rui-breadcrumb-icon\" });\n if (iconNode) inner.push(iconNode);\n inner.push(el(\"span\", { class: \"rui-breadcrumb-label\" }, [label]));\n if (safeHref) {\n root.append(el(\"a\", { class: \"rui-breadcrumb-link\", href: safeHref }, inner));\n } else {\n root.setAttribute(\"aria-current\", \"page\");\n const span = el(\"span\", { class: \"rui-breadcrumb-current\" });\n for (const node of inner) if (node) span.append(typeof node === \"string\" ? document.createTextNode(node) : node);\n root.append(span);\n }\n return root;\n },\n};\n\nexport const Breadcrumb: ComponentSpec = {\n name: \"Breadcrumb\",\n description:\n \"Trail of links showing the user's location. Children may be \" +\n \"BreadcrumbItem(label, href?) nodes OR plain strings (the last string is \" +\n \"treated as the current page).\",\n props: [\n { name: \"items\", type: \"BreadcrumbItem[] | string[]\" },\n { name: \"separator\", type: \"string\", optional: true, description: \"Default `/`\" },\n ],\n render: (_node, props, helpers) => {\n const items = asArray<unknown>(props.items);\n const separator = asString(props.separator, \"/\");\n const root = el(\"nav\", { class: \"rui-breadcrumb\", \"aria-label\": \"Breadcrumb\" });\n const list = el(\"ol\", { class: \"rui-breadcrumb-list\" });\n items.forEach((item, i) => {\n if (i > 0) {\n list.append(el(\"li\", { class: \"rui-breadcrumb-separator\", \"aria-hidden\": \"true\" }, [separator]));\n }\n if (item && typeof item === \"object\" && (item as { __kind?: string }).__kind === \"Component\") {\n list.append(helpers.renderNode(item));\n return;\n }\n const label = asString(item);\n const isLast = i === items.length - 1;\n list.append(BreadcrumbItem.render(\n { __kind: \"Component\", name: \"BreadcrumbItem\", args: [], argMeta: [] },\n { label, href: isLast ? \"\" : \"#\" },\n helpers,\n ));\n });\n root.append(list);\n return root;\n },\n};\n\nconst PER_PAGE_OPTIONS = [10, 20, 50, 100] as const;\n\nexport const Pagination: ComponentSpec = {\n name: \"Pagination\",\n description:\n \"Page navigator with Prev/Next, page numbers, and ellipses. Pass a \" +\n \"`$variable` as `page` for two-way binding — clicking a page button \" +\n \"sets that state to the new (1-indexed) value. Add `total` to render \" +\n \"a \\\"Showing N–M of T\\\" summary, pass `$variable` as `perPage` to \" +\n \"expose a per-page selector, or set `compact: true` to drop the \" +\n \"page-number row for tight toolbars.\",\n props: [\n { name: \"page\", type: \"number\", description: \"Current page (1-indexed); typically a $variable\" },\n { name: \"totalPages\", type: \"number\", aliases: [\"pages\"] },\n { name: \"siblings\", type: \"number\", optional: true, description: \"Number of page links shown around the current page (default 1)\" },\n { name: \"total\", type: \"number\", optional: true, description: \"Total record count — enables the \\\"Showing N–M of T\\\" summary\" },\n { name: \"perPage\", type: \"number\", optional: true, description: \"Bind a `$variable` to expose a per-page selector\" },\n { name: \"perPageOptions\", type: \"number[]\", optional: true, description: \"Override the per-page choices (default 10/20/50/100)\" },\n { name: \"compact\", type: \"boolean\", optional: true, description: \"Hide page numbers — keep Prev / Next only\" },\n ],\n render: (node, props, helpers) => {\n const total = Math.max(1, Math.floor(asNumber(props.totalPages, 1)));\n const current = Math.max(1, Math.min(total, Math.floor(asNumber(props.page, 1))));\n const siblings = Math.max(0, Math.floor(asNumber(props.siblings, 1)));\n const compact = asBoolean(props.compact);\n const stateName = node.argMeta?.[0]?.stateRef;\n\n const root = el(\"nav\", { class: \"rui-pagination\", \"aria-label\": \"Pagination\", \"data-compact\": compact ? \"true\" : \"false\" });\n\n const setPage = (next: number) => {\n if (!stateName) return;\n const clamped = Math.max(1, Math.min(total, next));\n if (clamped === current) return;\n helpers.setState(stateName, clamped);\n };\n\n // Optional record-count summary (\"Showing 21–30 of 123\").\n const totalRecords = props.total != null ? Math.max(0, Math.floor(asNumber(props.total, 0))) : null;\n const perPageValue = props.perPage != null ? Math.max(1, Math.floor(asNumber(props.perPage, 0))) : null;\n if (totalRecords !== null && perPageValue && perPageValue > 0) {\n const start = totalRecords === 0 ? 0 : (current - 1) * perPageValue + 1;\n const end = Math.min(totalRecords, current * perPageValue);\n root.append(el(\"span\", { class: \"rui-pagination-summary\" }, [\n totalRecords === 0\n ? \"No results\"\n : `Showing ${start.toLocaleString()}–${end.toLocaleString()} of ${totalRecords.toLocaleString()}`,\n ]));\n } else if (totalRecords !== null) {\n root.append(el(\"span\", { class: \"rui-pagination-summary\" }, [\n `${totalRecords.toLocaleString()} result${totalRecords === 1 ? \"\" : \"s\"}`,\n ]));\n }\n\n const buttonsWrap = el(\"div\", { class: \"rui-pagination-buttons\" });\n\n const button = (label: string, target: number, opts: { active?: boolean; disabled?: boolean; ellipsis?: boolean; ariaLabel?: string } = {}) => {\n if (opts.ellipsis) {\n return el(\"span\", { class: \"rui-pagination-ellipsis\", \"aria-hidden\": \"true\" }, [label]);\n }\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-pagination-button\",\n \"data-active\": opts.active ? \"true\" : \"false\",\n \"aria-current\": opts.active ? \"page\" : null,\n \"aria-label\": opts.ariaLabel ?? null,\n disabled: opts.disabled ? \"\" : null,\n }, [label]);\n if (!opts.disabled && !opts.active) {\n btn.onclick = () => setPage(target);\n }\n return btn;\n };\n\n buttonsWrap.append(button(\"‹\", current - 1, { disabled: current <= 1, ariaLabel: \"Previous page\" }));\n\n if (!compact) {\n const pageNumbers = computePageNumbers(current, total, siblings);\n for (const entry of pageNumbers) {\n if (entry === \"…\") {\n buttonsWrap.append(button(\"…\", 0, { ellipsis: true }));\n } else {\n buttonsWrap.append(button(String(entry), entry, { active: entry === current }));\n }\n }\n } else {\n // Compact variant still shows the current page label so callers\n // know where they are when the numbered row is hidden.\n buttonsWrap.append(el(\"span\", { class: \"rui-pagination-current\" }, [`${current} / ${total}`]));\n }\n\n buttonsWrap.append(button(\"›\", current + 1, { disabled: current >= total, ariaLabel: \"Next page\" }));\n root.append(buttonsWrap);\n\n // Per-page selector — only renders when `perPage` is a $variable so the\n // bound state can absorb the change. Falls back to a passive label when\n // perPage is a plain number.\n const perPageState = node.argMeta?.[4]?.stateRef;\n if (perPageValue && (perPageState || asArray(props.perPageOptions).length > 0)) {\n const options = asArray<unknown>(props.perPageOptions).length > 0\n ? asArray<unknown>(props.perPageOptions).map((v) => Math.max(1, Math.floor(Number(v) || 0))).filter((n) => n > 0)\n : Array.from(PER_PAGE_OPTIONS);\n const perPageWrap = el(\"label\", { class: \"rui-pagination-per-page\" }, [\n document.createTextNode(\"Show \"),\n ]);\n const select = el(\"select\", { class: \"rui-pagination-per-page-select\" }) as HTMLSelectElement;\n for (const opt of options) {\n const optEl = el(\"option\", {\n value: String(opt),\n selected: opt === perPageValue ? \"\" : null,\n }, [String(opt)]);\n select.append(optEl);\n }\n if (perPageState) {\n helpers.bindState(select, perPageState, {\n event: \"change\",\n getValue: (n) => Number((n as HTMLSelectElement).value),\n });\n }\n perPageWrap.append(select);\n perPageWrap.append(document.createTextNode(\" per page\"));\n root.append(perPageWrap);\n }\n\n return root;\n },\n};\n\nfunction computePageNumbers(current: number, total: number, siblings: number): Array<number | \"…\"> {\n const pages: Array<number | \"…\"> = [];\n const range = (from: number, to: number) => {\n for (let i = from; i <= to; i += 1) pages.push(i);\n };\n const totalNumbers = siblings * 2 + 5; // first, last, current, 2 ellipses, siblings on both sides\n if (total <= totalNumbers) {\n range(1, total);\n return pages;\n }\n const leftSibling = Math.max(2, current - siblings);\n const rightSibling = Math.min(total - 1, current + siblings);\n pages.push(1);\n if (leftSibling > 2) pages.push(\"…\");\n range(leftSibling, rightSibling);\n if (rightSibling < total - 1) pages.push(\"…\");\n pages.push(total);\n return pages;\n}\n\nexport const NavbarItem: ComponentSpec = {\n name: \"NavbarItem\",\n description:\n \"Single link inside a Navbar's main item slot. Renders as an inline \" +\n \"anchor / button — pass `to` for a router-aware link, `href` for an \" +\n \"external link, or `action` for a click handler. `active=true` \" +\n \"highlights the current page.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"to\", type: \"string\", optional: true, description: \"Internal route (consumes the built-in router)\" },\n { name: \"href\", type: \"string\", optional: true, description: \"External href; opens in a new tab when set with `external=true`\" },\n { name: \"icon\", type: \"string\", optional: true },\n { name: \"active\", type: \"boolean\", optional: true },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onClick\", \"onclick\"], description: \"Callable fired on click (alternative to `to`/`href`)\" },\n { name: \"external\", type: \"boolean\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const label = asString(props.label);\n const icon = props.icon;\n const active = asBoolean(props.active);\n const to = asString(props.to);\n // Sanitise the external href so a hostile `javascript:` cannot fire on\n // click. The internal `to` value is always rendered through the hash\n // router (`#/...`) which is inherently safe.\n const safeHref = sanitiseHref(props.href, \"\");\n const external = asBoolean(props.external);\n const tagName: \"a\" | \"button\" = (to || safeHref) ? \"a\" : \"button\";\n const root = el(tagName, {\n class: \"rui-navbar-item\",\n type: tagName === \"button\" ? \"button\" : null,\n href: safeHref || (to ? `#${to.startsWith(\"/\") ? to : `/${to}`}` : null),\n target: external && safeHref ? \"_blank\" : null,\n rel: external && safeHref ? \"noopener noreferrer\" : null,\n \"data-active\": active ? \"true\" : \"false\",\n });\n const iconNode = renderIcon(icon, { className: \"rui-navbar-item-icon\" });\n if (iconNode) root.append(iconNode);\n root.append(el(\"span\", { class: \"rui-navbar-item-label\" }, [label]));\n if (to && !safeHref) {\n root.onclick = (event) => {\n if (event.defaultPrevented) return;\n const evt = event as MouseEvent;\n if (evt.button !== 0 || evt.metaKey || evt.ctrlKey || evt.shiftKey || evt.altKey) return;\n event.preventDefault();\n helpers.router.navigate(to);\n };\n } else if (typeof props.action === \"function\") {\n root.onclick = (event) => {\n event.preventDefault();\n helpers.invoke(props.action);\n };\n }\n return root;\n },\n};\n\nexport const Navbar: ComponentSpec = {\n name: \"Navbar\",\n description:\n \"Top navigation bar with a brand on the left, primary nav items in \" +\n \"the middle, and a right-aligned actions slot (user avatar, \" +\n \"DropdownMenu, CTA buttons, …). Use `sticky=true` to pin it to the \" +\n \"top of the page. The canonical companion of `Sidebar` for product \" +\n \"surfaces; prefer Navbar for marketing/docs pages without a sidebar.\",\n props: [\n { name: \"brand\", type: \"string | Node\", optional: true, description: \"Workspace/product name (string) or a node (e.g. logo Image)\" },\n { name: \"items\", type: \"NavbarItem[]\", optional: true, description: \"Center navigation items\" },\n { name: \"actions\", type: \"Node[]\", optional: true, description: \"Right-side controls (Buttons, Avatar, DropdownMenu, …)\" },\n { name: \"sticky\", type: \"boolean\", optional: true, description: \"Pin the bar to the top of the viewport\" },\n { name: \"variant\", type: \"string\", optional: true, enum: [\"default\", \"transparent\"], description: \"Visual variant\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"nav\", {\n class: \"rui-navbar\",\n \"data-sticky\": asBoolean(props.sticky) ? \"true\" : \"false\",\n \"data-variant\": asString(props.variant, \"default\"),\n \"aria-label\": \"Primary\",\n });\n const brand = props.brand;\n if (brand !== undefined && brand !== null && brand !== \"\") {\n const brandWrap = el(\"div\", { class: \"rui-navbar-brand\" });\n if (typeof brand === \"string\") {\n brandWrap.append(document.createTextNode(brand));\n } else {\n brandWrap.append(helpers.renderNode(brand));\n }\n root.append(brandWrap);\n }\n const items = asArray<unknown>(props.items);\n if (items.length > 0) {\n const list = el(\"div\", { class: \"rui-navbar-items\" });\n for (const item of items) list.append(helpers.renderNode(item));\n root.append(list);\n }\n const actions = asArray<unknown>(props.actions);\n if (actions.length > 0) {\n const right = el(\"div\", { class: \"rui-navbar-actions\" });\n for (const item of actions) right.append(helpers.renderNode(item));\n root.append(right);\n }\n return root;\n },\n};\n","/**\n * Dropdown menu primitives modeled after shadcn/ui.\n *\n * DropdownMenu(trigger, items, side?, align?, label?)\n * MenuItem(label, action?, icon?, shortcut?, variant?, disabled?)\n * MenuSeparator()\n * MenuLabel(label)\n *\n * `DropdownMenu` keeps its open/closed state persistent across re-renders via\n * `helpers.useInstanceState`, so unrelated state changes (typing into an\n * input, ticking a checkbox, …) do not collapse the menu mid-interaction.\n * Clicking the trigger toggles it; clicking a `MenuItem` runs its action and\n * closes; clicking anywhere outside the menu also closes (handled by an\n * outside-click listener attached lazily to the host shadow root on open).\n *\n * The trigger is rendered inside a `<span>` wrapper (not a nested `<button>`)\n * so that user-provided triggers like `Button(\"Open\")` or `Avatar(...)`\n * remain valid HTML and receive clicks reliably.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport { el, asArray, asString, asBoolean, renderIcon } from \"../utils.js\";\nimport { installDismissListeners, disposeDismissListeners } from \"./_internal.js\";\n\nconst MENU_SIDES = [\"bottom\", \"top\", \"left\", \"right\"] as const;\nconst MENU_ALIGNS = [\"start\", \"center\", \"end\"] as const;\nconst MENU_VARIANTS = [\"default\", \"danger\"] as const;\n\n/**\n * Walk up the live DOM and toggle the dropdown's open state, keeping the\n * persisted instance-state slot in sync. Modifies the DOM directly so the\n * interaction feels instant without waiting for a render tick.\n */\nconst setDropdownOpen = (\n origin: Element,\n next: boolean,\n openSlot: { set: (value: boolean) => void },\n): HTMLElement | null => {\n openSlot.set(next);\n const liveRoot = origin.closest(\".rui-dropdown-menu\") as HTMLElement | null;\n if (!liveRoot) return null;\n liveRoot.setAttribute(\"data-open\", next ? \"true\" : \"false\");\n const trigger = liveRoot.querySelector(\".rui-dropdown-menu-trigger\");\n trigger?.setAttribute(\"aria-expanded\", next ? \"true\" : \"false\");\n // Any path that closes the menu also releases the dismissal listeners so\n // we don't accumulate stale listener pairs on the host shadow root.\n if (!next) disposeDismissListeners(liveRoot);\n return liveRoot;\n};\n\nconst installOutsideClickClose = (\n liveRoot: HTMLElement,\n openSlot: { set: (value: boolean) => void },\n): void => {\n installDismissListeners({\n liveRoot,\n onDismiss: () => {\n openSlot.set(false);\n liveRoot.setAttribute(\"data-open\", \"false\");\n liveRoot.querySelector(\".rui-dropdown-menu-trigger\")\n ?.setAttribute(\"aria-expanded\", \"false\");\n },\n });\n};\n\ninterface MenuItemNode {\n __kind?: string;\n name?: string;\n args?: unknown[];\n argMeta?: unknown[];\n}\n\nconst isMenuChild = (item: unknown, name: string): item is MenuItemNode => {\n if (!item || typeof item !== \"object\") return false;\n const node = item as MenuItemNode;\n return node.__kind === \"Component\" && node.name === name;\n};\n\nexport const DropdownMenu: ComponentSpec = {\n name: \"DropdownMenu\",\n description:\n \"Click-triggered dropdown menu. Click the trigger to toggle, click a \" +\n \"MenuItem to run its action and close, click outside or press Escape \" +\n \"to close without acting. Children must be MenuItem, MenuSeparator, \" +\n \"or MenuLabel entries.\",\n props: [\n { name: \"trigger\", type: \"Node\", description: \"Clickable trigger element (typically a Button or Avatar)\" },\n { name: \"items\", type: \"(MenuItem | MenuSeparator | MenuLabel)[]\" },\n { name: \"side\", type: \"string\", optional: true, enum: MENU_SIDES, description: \"Where the menu opens relative to the trigger (default \\\"bottom\\\")\" },\n { name: \"align\", type: \"string\", optional: true, enum: MENU_ALIGNS, description: \"How the menu aligns along the trigger edge (default \\\"start\\\")\" },\n { name: \"label\", type: \"string\", optional: true, description: \"Optional ARIA label for the menu\" },\n { name: \"open\", type: \"boolean\", optional: true, description: \"Initial open state — use to demo or pre-open the menu\" },\n ],\n render: (_node, props, helpers) => {\n const initialOpen = asBoolean(props.open);\n const openSlot = helpers.useInstanceState<boolean>(\"open\", initialOpen);\n const isOpen = openSlot.get();\n\n const root = el(\"div\", {\n class: \"rui-dropdown-menu\",\n \"data-open\": isOpen ? \"true\" : \"false\",\n \"data-side\": asString(props.side, \"bottom\"),\n \"data-align\": asString(props.align, \"start\"),\n });\n\n // Render the user's trigger directly (Button, Avatar, IconButton, …)\n // and wrap it in a span so we don't nest <button> inside <button>\n // (which is invalid HTML and silently swallows clicks in some browsers).\n const triggerWrap = el(\"span\", {\n class: \"rui-dropdown-menu-trigger\",\n \"data-state\": isOpen ? \"open\" : \"closed\",\n \"aria-haspopup\": \"menu\",\n \"aria-expanded\": isOpen ? \"true\" : \"false\",\n tabindex: \"0\",\n });\n triggerWrap.append(helpers.renderNode(props.trigger));\n // Property-based handlers so the morph reconciler can copy the latest\n // closure (with up-to-date `openSlot`) onto kept DOM. `addEventListener`\n // would leak fresh listeners onto every detached re-render snapshot.\n triggerWrap.onclick = (event) => {\n event.stopPropagation();\n const origin = (event.currentTarget ?? event.target) as Element;\n const next = !openSlot.get();\n const liveRoot = setDropdownOpen(origin, next, openSlot);\n if (next && liveRoot) installOutsideClickClose(liveRoot, openSlot);\n };\n triggerWrap.onkeydown = (event) => {\n const e = event as KeyboardEvent;\n const origin = (e.currentTarget ?? e.target) as Element;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n const next = !openSlot.get();\n const liveRoot = setDropdownOpen(origin, next, openSlot);\n if (next && liveRoot) installOutsideClickClose(liveRoot, openSlot);\n return;\n }\n if (e.key === \"Escape\" && openSlot.get()) {\n e.preventDefault();\n setDropdownOpen(origin, false, openSlot);\n }\n };\n root.append(triggerWrap);\n\n const content = el(\"div\", {\n class: \"rui-dropdown-menu-content\",\n role: \"menu\",\n \"aria-label\": asString(props.label) || null,\n });\n\n for (const raw of asArray<unknown>(props.items)) {\n if (isMenuChild(raw, \"MenuItem\")) {\n const args = raw.args ?? [];\n const label = asString(args[0]);\n const action = args[1];\n const icon = args[2];\n const shortcut = asString(args[3]);\n const variant = asString(args[4], \"default\");\n const disabled = asBoolean(args[5]);\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-menu-item\",\n role: \"menuitem\",\n \"data-variant\": variant,\n disabled: disabled ? \"\" : null,\n });\n const iconNode = renderIcon(icon, { className: \"rui-menu-item-icon\" });\n if (iconNode) btn.append(iconNode);\n btn.append(el(\"span\", { class: \"rui-menu-item-label\" }, [label]));\n if (shortcut) btn.append(el(\"span\", { class: \"rui-menu-item-shortcut\" }, [shortcut]));\n if (!disabled) {\n btn.onclick = (event) => {\n const origin = (event.currentTarget ?? event.target) as Element;\n setDropdownOpen(origin, false, openSlot);\n helpers.invoke(action);\n };\n }\n content.append(btn);\n continue;\n }\n if (isMenuChild(raw, \"MenuSeparator\")) {\n content.append(el(\"div\", { class: \"rui-menu-separator\", role: \"separator\" }));\n continue;\n }\n if (isMenuChild(raw, \"MenuLabel\")) {\n const label = asString((raw.args ?? [])[0]);\n content.append(el(\"div\", { class: \"rui-menu-label\" }, [label]));\n continue;\n }\n // Fallback: render arbitrary child nodes (Link, Switch, …) so the LLM\n // can nest controls inside a menu when it needs to.\n content.append(helpers.renderNode(raw));\n }\n root.append(content);\n return root;\n },\n};\n\nexport const MenuItem: ComponentSpec = {\n name: \"MenuItem\",\n description:\n \"Single item inside a DropdownMenu. Renders a button-style row with an \" +\n \"optional leading icon and trailing keyboard-shortcut hint. The action \" +\n \"argument runs when clicked; the menu closes automatically afterwards.\",\n props: [\n { name: \"label\", type: \"string\" },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onClick\", \"onclick\"], description: \"Callable to execute on click\" },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon name shown before the label\" },\n { name: \"shortcut\", type: \"string\", optional: true, description: \"Trailing keyboard-shortcut hint (e.g. \\\"⌘ K\\\")\" },\n { name: \"variant\", type: \"string\", optional: true, enum: MENU_VARIANTS, description: \"Use \\\"danger\\\" for destructive actions\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n // Standalone render (when used outside a DropdownMenu): an inert button so\n // the structure still appears, but without the parent's open/close wiring.\n render: (_node, props, helpers) => {\n const disabled = asBoolean(props.disabled);\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-menu-item\",\n role: \"menuitem\",\n \"data-variant\": asString(props.variant, \"default\"),\n disabled: disabled ? \"\" : null,\n });\n const iconNode = renderIcon(props.icon, { className: \"rui-menu-item-icon\" });\n if (iconNode) btn.append(iconNode);\n btn.append(el(\"span\", { class: \"rui-menu-item-label\" }, [asString(props.label)]));\n const shortcut = asString(props.shortcut);\n if (shortcut) btn.append(el(\"span\", { class: \"rui-menu-item-shortcut\" }, [shortcut]));\n if (!disabled) {\n btn.onclick = () => {\n helpers.invoke(props.action);\n };\n }\n return btn;\n },\n};\n\nexport const MenuSeparator: ComponentSpec = {\n name: \"MenuSeparator\",\n description: \"Thin horizontal rule used inside a DropdownMenu to group items.\",\n props: [],\n render: () => el(\"div\", { class: \"rui-menu-separator\", role: \"separator\" }),\n};\n\nexport const MenuLabel: ComponentSpec = {\n name: \"MenuLabel\",\n description:\n \"Small uppercase section header inside a DropdownMenu. Use to group \" +\n \"related MenuItems (e.g. \\\"Account\\\", \\\"Workspace\\\", \\\"Danger zone\\\").\",\n props: [{ name: \"label\", type: \"string\" }],\n render: (_node, props) =>\n el(\"div\", { class: \"rui-menu-label\" }, [asString(props.label)]),\n};\n","/**\n * Advanced data components:\n *\n * - DataGrid — Table with built-in sort, filter, row selection, pagination.\n * - CalendarView — Month/week calendar grid distinct from DatePicker.\n * - ActivityLog — Timeline-like specialised feeds.\n * - ComparisonTable — Generic feature/spec comparison table.\n * - InfiniteList — Scroll-to-load list container.\n *\n * These are presentational + lightly stateful (using `useInstanceState` for\n * local UI state). State that should round-trip through the host is bound\n * via `$variables` exactly like every other component in the library.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport { el, asArray, asString, asBoolean, asNumber, renderIcon } from \"../utils.js\";\n\nconst COL_ALIGN = [\"left\", \"center\", \"right\"] as const;\n\ninterface ColDef {\n header: string;\n values: unknown[];\n format: string;\n align: string;\n sortable: boolean;\n filterable: boolean;\n key: string;\n}\n\nfunction readDataGridCols(raw: unknown): ColDef[] {\n return asArray<{ args?: unknown[] }>(raw).map((node, idx) => {\n const args = node.args ?? [];\n const header = asString(args[0]);\n return {\n header,\n values: asArray<unknown>(args[1]),\n format: asString(args[2], \"text\"),\n align: (COL_ALIGN as readonly string[]).includes(asString(args[3])) ? asString(args[3]) : \"\",\n sortable: asBoolean(args[4]),\n filterable: asBoolean(args[5]),\n key: header || `col-${idx}`,\n };\n });\n}\n\nfunction compareCells(a: unknown, b: unknown, format: string): number {\n if (a === null || a === undefined) return b === null || b === undefined ? 0 : 1;\n if (b === null || b === undefined) return -1;\n if (format === \"number\" || format === \"currency\") {\n return asNumber(a, 0) - asNumber(b, 0);\n }\n if (format === \"date\") {\n const ta = new Date(asString(a)).getTime();\n const tb = new Date(asString(b)).getTime();\n if (Number.isFinite(ta) && Number.isFinite(tb)) return ta - tb;\n }\n return asString(a).localeCompare(asString(b));\n}\n\nfunction formatCellValue(value: unknown, format: string): string {\n if (value === null || value === undefined) return \"\";\n switch (format) {\n case \"number\":\n return typeof value === \"number\" ? value.toLocaleString() : asString(value);\n case \"currency\":\n return typeof value === \"number\"\n ? value.toLocaleString(undefined, { style: \"currency\", currency: \"USD\" })\n : asString(value);\n case \"date\":\n try {\n const d = new Date(asString(value));\n return Number.isNaN(d.getTime()) ? asString(value) : d.toLocaleDateString();\n } catch { return asString(value); }\n default:\n return asString(value);\n }\n}\n\nexport const DataGrid: ComponentSpec = {\n name: \"DataGrid\",\n description:\n \"Advanced data table with sortable headers, per-column filter chips, \" +\n \"row selection (checkboxes), sticky header / first column, optional \" +\n \"pagination, an optional bulk-action toolbar slot, and click-to-act \" +\n \"rows. Columns are Col(header, values, format?, align?, sortable?, \" +\n \"filterable?) entries. Bind `$sort` (`{key, direction}` object), \" +\n \"`$selectedIds` (string[]), and `$page` (number) for full reactivity. \" +\n \"Use INSTEAD of `Table` when you need any of those interactions.\",\n props: [\n { name: \"columns\", type: \"Col[]\", description: \"Columns; pass sortable=true / filterable=true on each Col.\" },\n { name: \"rowIds\", type: \"any[]\", optional: true, description: \"Stable id per row (used by `selectedIds`); defaults to row index.\" },\n { name: \"caption\", type: \"string\", optional: true },\n { name: \"sort\", type: \"object\", optional: true, description: \"`{key, direction}` — pass a $variable for two-way binding\" },\n { name: \"selectedIds\", type: \"any[]\", optional: true, description: \"Array of selected row ids — bind a $variable\" },\n { name: \"selectable\", type: \"boolean\", optional: true, description: \"Render leading selection checkboxes\" },\n { name: \"page\", type: \"number\", optional: true, description: \"1-indexed current page — bind a $variable\" },\n { name: \"perPage\", type: \"number\", optional: true, description: \"Page size (default 20)\" },\n { name: \"emptyLabel\", type: \"string\", optional: true, description: \"Text shown when no rows match (default `No results`)\" },\n { name: \"rowAction\", type: \"callable\", optional: true, description: \"Callable fired when a row is clicked\" },\n { name: \"toolbar\", type: \"Node[]\", optional: true, description: \"Bulk-action toolbar shown above the table when any rows are selected\" },\n { name: \"density\", type: \"string\", optional: true, enum: [\"comfortable\", \"compact\"] },\n { name: \"striped\", type: \"boolean\", optional: true },\n { name: \"stickyHeader\", type: \"boolean\", optional: true, description: \"Pin the header row (default true)\" },\n { name: \"stickyFirstColumn\", type: \"boolean\", optional: true, description: \"Pin the first column horizontally\" },\n ],\n render: (node, props, helpers) => {\n const cols = readDataGridCols(props.columns);\n const rowCount = Math.max(0, ...cols.map((c) => c.values.length));\n const rowIds = asArray<unknown>(props.rowIds);\n const idFor = (rowIdx: number): string => asString(rowIds[rowIdx] ?? rowIdx);\n const sortState = (props.sort && typeof props.sort === \"object\")\n ? (props.sort as { key?: unknown; direction?: unknown })\n : null;\n const sortKey = asString(sortState?.key);\n const sortDir = asString(sortState?.direction, \"asc\") === \"desc\" ? \"desc\" : \"asc\";\n const selectedIds = asArray<unknown>(props.selectedIds).map((v) => asString(v));\n const selectedSet = new Set(selectedIds);\n const selectable = asBoolean(props.selectable) || node.argMeta?.[4]?.stateRef !== undefined;\n const stickyHeader = props.stickyHeader === undefined ? true : asBoolean(props.stickyHeader);\n const stickyFirst = asBoolean(props.stickyFirstColumn);\n const density = asString(props.density, \"comfortable\");\n const striped = asBoolean(props.striped);\n\n // Filter chip state (per-column) — stored locally because filtering\n // happens client-side and we don't want each chip to allocate its own\n // $variable.\n const filterSlot = helpers.useInstanceState<Record<string, string>>(\"filters\", {});\n const filters = filterSlot.get();\n\n // Compute a row-index ordering after applying filters + sort.\n const indices: number[] = [];\n for (let r = 0; r < rowCount; r += 1) {\n let keep = true;\n for (const c of cols) {\n if (!c.filterable) continue;\n const term = (filters[c.key] ?? \"\").trim().toLowerCase();\n if (!term) continue;\n const cell = c.values[r];\n if (!formatCellValue(cell, c.format).toLowerCase().includes(term)) {\n keep = false;\n break;\n }\n }\n if (keep) indices.push(r);\n }\n if (sortKey) {\n const sortCol = cols.find((c) => c.key === sortKey);\n if (sortCol && sortCol.sortable) {\n indices.sort((a, b) => {\n const cmp = compareCells(sortCol.values[a], sortCol.values[b], sortCol.format);\n return sortDir === \"desc\" ? -cmp : cmp;\n });\n }\n }\n\n const totalAfterFilter = indices.length;\n const perPage = Math.max(1, Math.floor(asNumber(props.perPage, 20)));\n const totalPages = Math.max(1, Math.ceil(totalAfterFilter / perPage));\n const rawPage = Math.max(1, Math.floor(asNumber(props.page, 1)));\n const page = Math.min(rawPage, totalPages);\n const visible = indices.slice((page - 1) * perPage, page * perPage);\n\n const wrapper = el(\"div\", {\n class: \"rui-data-grid\",\n \"data-density\": density,\n \"data-striped\": striped ? \"true\" : \"false\",\n \"data-sticky-header\": stickyHeader ? \"true\" : \"false\",\n \"data-sticky-first\": stickyFirst ? \"true\" : \"false\",\n });\n\n const sortStateName = node.argMeta?.[3]?.stateRef;\n const selectedStateName = node.argMeta?.[4]?.stateRef;\n const pageStateName = node.argMeta?.[6]?.stateRef;\n\n // Bulk-action toolbar (shows when at least one row is selected).\n const toolbarChildren = asArray<unknown>(props.toolbar);\n if (selectedIds.length > 0 && toolbarChildren.length > 0) {\n const bar = el(\"div\", { class: \"rui-data-grid-bulk\" });\n bar.append(el(\"span\", { class: \"rui-data-grid-bulk-count\" }, [\n `${selectedIds.length} selected`,\n ]));\n const tools = el(\"div\", { class: \"rui-data-grid-bulk-tools\" });\n for (const child of toolbarChildren) tools.append(helpers.renderNode(child));\n bar.append(tools);\n wrapper.append(bar);\n }\n\n const tableWrap = el(\"div\", { class: \"rui-data-grid-scroll\" });\n const table = el(\"table\", { class: \"rui-data-grid-table\" });\n const caption = asString(props.caption);\n if (caption) table.append(el(\"caption\", { class: \"rui-data-grid-caption\" }, [caption]));\n\n const thead = el(\"thead\");\n const headRow = el(\"tr\");\n if (selectable) {\n const th = el(\"th\", { class: \"rui-data-grid-cell-select\", scope: \"col\" });\n const allSelected = visible.length > 0 && visible.every((r) => selectedSet.has(idFor(r)));\n const cb = el(\"input\", {\n type: \"checkbox\",\n class: \"rui-data-grid-checkbox\",\n \"aria-label\": \"Select all rows on this page\",\n checked: allSelected ? \"\" : null,\n }) as HTMLInputElement;\n if (selectedStateName) {\n cb.onclick = (event) => {\n const target = event.currentTarget as HTMLInputElement;\n const next = new Set(selectedIds);\n for (const r of visible) {\n const id = idFor(r);\n if (target.checked) next.add(id); else next.delete(id);\n }\n helpers.setState(selectedStateName, Array.from(next));\n };\n }\n th.append(cb);\n headRow.append(th);\n }\n cols.forEach((col, c) => {\n const th = el(\"th\", {\n scope: \"col\",\n \"data-align\": col.align || null,\n \"data-sortable\": col.sortable ? \"true\" : null,\n \"data-active\": col.sortable && col.key === sortKey ? \"true\" : null,\n \"data-first\": c === 0 ? \"true\" : null,\n });\n if (col.sortable && sortStateName) {\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-data-grid-sort\",\n });\n btn.append(el(\"span\", {}, [col.header]));\n const dirIcon = col.key === sortKey\n ? (sortDir === \"asc\" ? \"arrow-up-short-wide\" : \"arrow-down-wide-short\")\n : \"sort\";\n const dirNode = renderIcon(dirIcon, { className: \"rui-data-grid-sort-icon\" });\n if (dirNode) btn.append(dirNode);\n btn.onclick = () => {\n const nextDir = col.key === sortKey && sortDir === \"asc\" ? \"desc\" : \"asc\";\n helpers.setState(sortStateName, { key: col.key, direction: nextDir });\n };\n th.append(btn);\n } else {\n th.append(document.createTextNode(col.header));\n }\n headRow.append(th);\n });\n thead.append(headRow);\n\n // Filter row (only if any column is filterable)\n if (cols.some((c) => c.filterable)) {\n const filterRow = el(\"tr\", { class: \"rui-data-grid-filter-row\" });\n if (selectable) filterRow.append(el(\"td\", { class: \"rui-data-grid-cell-select\" }));\n cols.forEach((col) => {\n const td = el(\"td\");\n if (col.filterable) {\n const input = el(\"input\", {\n type: \"search\",\n class: \"rui-data-grid-filter\",\n placeholder: `Filter ${col.header}`,\n value: filters[col.key] ?? \"\",\n }) as HTMLInputElement;\n input.oninput = (event) => {\n const target = event.currentTarget as HTMLInputElement;\n const next = { ...filterSlot.get(), [col.key]: target.value };\n filterSlot.set(next);\n // Resolve the *live* tbody from the input target — the\n // closure-captured `wrapper`/`tbody` references are detached\n // once morph keeps the previously mounted grid in place.\n const liveTbody = target.closest(\"table\")?.querySelector(\"tbody\") as HTMLElement | null;\n requestRebody(liveTbody);\n };\n td.append(input);\n }\n filterRow.append(td);\n });\n thead.append(filterRow);\n }\n table.append(thead);\n\n const tbody = el(\"tbody\");\n table.append(tbody);\n\n const renderBody = (rows: number[]): void => {\n tbody.replaceChildren();\n if (rows.length === 0) {\n const emptyRow = el(\"tr\");\n const span = (selectable ? 1 : 0) + Math.max(cols.length, 1);\n emptyRow.append(el(\"td\", {\n colspan: String(span),\n class: \"rui-data-grid-empty\",\n }, [asString(props.emptyLabel, \"No results\")]));\n tbody.append(emptyRow);\n return;\n }\n for (const r of rows) {\n const id = idFor(r);\n const isSelected = selectedSet.has(id);\n const tr = el(\"tr\", {\n \"data-selected\": isSelected ? \"true\" : null,\n });\n if (selectable) {\n const cellTd = el(\"td\", { class: \"rui-data-grid-cell-select\" });\n const cb = el(\"input\", {\n type: \"checkbox\",\n class: \"rui-data-grid-checkbox\",\n \"aria-label\": \"Select row\",\n checked: isSelected ? \"\" : null,\n }) as HTMLInputElement;\n if (selectedStateName) {\n cb.onclick = (event) => {\n event.stopPropagation();\n const target = event.currentTarget as HTMLInputElement;\n const next = new Set(selectedIds);\n if (target.checked) next.add(id); else next.delete(id);\n helpers.setState(selectedStateName, Array.from(next));\n };\n }\n cellTd.append(cb);\n tr.append(cellTd);\n }\n cols.forEach((col, c) => {\n const cellValue = col.values[r];\n const td = el(\"td\", {\n \"data-format\": col.format,\n \"data-align\": col.align || null,\n \"data-first\": c === 0 ? \"true\" : null,\n });\n if (cellValue !== null && typeof cellValue === \"object\"\n && (cellValue as { __kind?: string }).__kind === \"Component\") {\n td.append(helpers.renderNode(cellValue));\n } else {\n td.textContent = formatCellValue(cellValue, col.format);\n }\n tr.append(td);\n });\n if (typeof props.rowAction === \"function\") {\n tr.setAttribute(\"data-clickable\", \"true\");\n tr.onclick = (event) => {\n const target = event.target as Element | null;\n if (target?.closest(\"input,button,a,label,select,textarea\")) return;\n helpers.invoke(props.rowAction);\n };\n }\n tbody.append(tr);\n }\n };\n\n const requestRebody = (liveOverride?: HTMLElement | null): void => {\n const liveTbody = liveOverride ?? tbody;\n const localFilters = filterSlot.get();\n const filtered: number[] = [];\n for (let r = 0; r < rowCount; r += 1) {\n let keep = true;\n for (const c of cols) {\n if (!c.filterable) continue;\n const term = (localFilters[c.key] ?? \"\").trim().toLowerCase();\n if (!term) continue;\n const cell = c.values[r];\n if (!formatCellValue(cell, c.format).toLowerCase().includes(term)) {\n keep = false; break;\n }\n }\n if (keep) filtered.push(r);\n }\n if (sortKey) {\n const sortCol = cols.find((c) => c.key === sortKey);\n if (sortCol && sortCol.sortable) {\n filtered.sort((a, b) => {\n const cmp = compareCells(sortCol.values[a], sortCol.values[b], sortCol.format);\n return sortDir === \"desc\" ? -cmp : cmp;\n });\n }\n }\n const pageRows = filtered.slice((page - 1) * perPage, page * perPage);\n // Re-render against the (possibly live) tbody so user input keeps focus.\n const swap = (target: HTMLElement) => {\n target.replaceChildren();\n for (const row of pageRows) {\n // Lightweight re-render — same logic as the initial render path.\n const id = idFor(row);\n const isSelected = selectedSet.has(id);\n const tr = el(\"tr\", { \"data-selected\": isSelected ? \"true\" : null });\n if (selectable) {\n const cellTd = el(\"td\", { class: \"rui-data-grid-cell-select\" });\n const cb = el(\"input\", {\n type: \"checkbox\",\n class: \"rui-data-grid-checkbox\",\n checked: isSelected ? \"\" : null,\n }) as HTMLInputElement;\n cellTd.append(cb);\n tr.append(cellTd);\n }\n cols.forEach((col, c) => {\n const cellValue = col.values[row];\n const td = el(\"td\", {\n \"data-format\": col.format,\n \"data-align\": col.align || null,\n \"data-first\": c === 0 ? \"true\" : null,\n });\n if (cellValue !== null && typeof cellValue === \"object\"\n && (cellValue as { __kind?: string }).__kind === \"Component\") {\n td.append(helpers.renderNode(cellValue));\n } else {\n td.textContent = formatCellValue(cellValue, col.format);\n }\n tr.append(td);\n });\n target.append(tr);\n }\n if (pageRows.length === 0) {\n const emptyRow = el(\"tr\");\n const span = (selectable ? 1 : 0) + Math.max(cols.length, 1);\n emptyRow.append(el(\"td\", {\n colspan: String(span),\n class: \"rui-data-grid-empty\",\n }, [asString(props.emptyLabel, \"No results\")]));\n target.append(emptyRow);\n }\n };\n swap(liveTbody as HTMLElement);\n };\n\n renderBody(visible);\n\n tableWrap.append(table);\n wrapper.append(tableWrap);\n\n // Footer pagination summary\n if (totalAfterFilter > perPage) {\n const footer = el(\"div\", { class: \"rui-data-grid-footer\" });\n const startIdx = totalAfterFilter === 0 ? 0 : (page - 1) * perPage + 1;\n const endIdx = Math.min(totalAfterFilter, page * perPage);\n footer.append(el(\"span\", { class: \"rui-data-grid-footer-summary\" }, [\n totalAfterFilter === 0 ? \"No results\" : `Showing ${startIdx}–${endIdx} of ${totalAfterFilter}`,\n ]));\n const buttons = el(\"div\", { class: \"rui-data-grid-footer-buttons\" });\n const prev = el(\"button\", {\n type: \"button\",\n class: \"rui-data-grid-page-button\",\n disabled: page <= 1 ? \"\" : null,\n }, [\"‹ Prev\"]);\n const next = el(\"button\", {\n type: \"button\",\n class: \"rui-data-grid-page-button\",\n disabled: page >= totalPages ? \"\" : null,\n }, [\"Next ›\"]);\n if (pageStateName) {\n prev.onclick = () => {\n if (page <= 1) return;\n helpers.setState(pageStateName, page - 1);\n };\n next.onclick = () => {\n if (page >= totalPages) return;\n helpers.setState(pageStateName, page + 1);\n };\n }\n buttons.append(prev);\n buttons.append(el(\"span\", { class: \"rui-data-grid-page-current\" }, [`${page} / ${totalPages}`]));\n buttons.append(next);\n footer.append(buttons);\n wrapper.append(footer);\n }\n return wrapper;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * CalendarView — month/week calendar grid\n * ----------------------------------------------------------------------- */\n\ninterface CalendarEvent {\n date: string;\n title: string;\n tone?: string;\n time?: string;\n}\n\nfunction readCalendarEvents(raw: unknown): CalendarEvent[] {\n const out: CalendarEvent[] = [];\n for (const entry of asArray<unknown>(raw)) {\n if (!entry || typeof entry !== \"object\") continue;\n const e = entry as { date?: unknown; title?: unknown; tone?: unknown; time?: unknown };\n const date = asString(e.date);\n if (!date) continue;\n out.push({\n date,\n title: asString(e.title),\n tone: asString(e.tone, \"primary\"),\n time: asString(e.time),\n });\n }\n return out;\n}\n\nfunction startOfWeek(date: Date, weekStartsOn: number): Date {\n const out = new Date(date.getFullYear(), date.getMonth(), date.getDate());\n const day = out.getDay();\n const diff = (day - weekStartsOn + 7) % 7;\n out.setDate(out.getDate() - diff);\n return out;\n}\n\nfunction formatIsoDate(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${d}`;\n}\n\nexport const CalendarView: ComponentSpec = {\n name: \"CalendarView\",\n description:\n \"Full-month or week calendar grid for scheduling apps — distinct from \" +\n \"the form-input `DatePicker`. Pass events as an array of \" +\n \"`{date: 'YYYY-MM-DD', title, tone?, time?}` objects. Bind `value` \" +\n \"to a `$variable` for the selected date (ISO string). Use \" +\n \"`view=\\\"week\\\"` for a single-week strip. `firstDay=1` (Monday) \" +\n \"matches most business apps.\",\n props: [\n { name: \"value\", type: \"string\", optional: true, description: \"Selected ISO date (YYYY-MM-DD); bind a $variable\" },\n { name: \"month\", type: \"string\", optional: true, description: \"Reference month — ISO date or YYYY-MM (defaults to today)\" },\n { name: \"events\", type: \"object[]\", optional: true, description: \"Array of {date, title, tone?, time?} objects\" },\n { name: \"view\", type: \"string\", optional: true, enum: [\"month\", \"week\"] },\n { name: \"firstDay\", type: \"number\", optional: true, description: \"0=Sunday, 1=Monday (default 1)\" },\n { name: \"onSelect\", type: \"callable\", optional: true, description: \"Callable fired when a day is clicked; receives the ISO date string\" },\n ],\n render: (node, props, helpers) => {\n const view = asString(props.view, \"month\");\n const events = readCalendarEvents(props.events);\n const valueRaw = asString(props.value);\n const monthRaw = asString(props.month, valueRaw);\n const today = new Date();\n let refDate = new Date(NaN);\n if (monthRaw) {\n const m = /^(\\d{4})-(\\d{2})(?:-(\\d{2}))?$/.exec(monthRaw);\n if (m) {\n refDate = new Date(Number(m[1]), Number(m[2]) - 1, m[3] ? Number(m[3]) : 1);\n } else {\n const d = new Date(monthRaw);\n if (!Number.isNaN(d.getTime())) refDate = d;\n }\n }\n if (Number.isNaN(refDate.getTime())) refDate = today;\n const weekStartsOn = ((asNumber(props.firstDay, 1) % 7) + 7) % 7;\n const valueIso = valueRaw && /^\\d{4}-\\d{2}-\\d{2}$/.test(valueRaw) ? valueRaw : \"\";\n const eventsByDate = new Map<string, CalendarEvent[]>();\n for (const evt of events) {\n const key = evt.date.slice(0, 10);\n const list = eventsByDate.get(key) ?? [];\n list.push(evt);\n eventsByDate.set(key, list);\n }\n const onSelectState = node.argMeta?.[0]?.stateRef;\n const root = el(\"div\", { class: \"rui-calendar\", \"data-view\": view });\n const header = el(\"div\", { class: \"rui-calendar-header\" });\n const monthLabel = refDate.toLocaleDateString(undefined, { month: \"long\", year: \"numeric\" });\n header.append(el(\"div\", { class: \"rui-calendar-title\" }, [monthLabel]));\n root.append(header);\n\n const weekRow = el(\"div\", { class: \"rui-calendar-weekrow\" });\n const dayLabels = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n for (let i = 0; i < 7; i += 1) {\n const label = dayLabels[(weekStartsOn + i) % 7] ?? \"\";\n weekRow.append(el(\"div\", { class: \"rui-calendar-weekday\" }, [label]));\n }\n root.append(weekRow);\n\n const cells: { date: Date; inMonth: boolean }[] = [];\n if (view === \"week\") {\n const anchor = valueIso ? new Date(valueIso) : refDate;\n const start = startOfWeek(anchor, weekStartsOn);\n for (let i = 0; i < 7; i += 1) {\n const d = new Date(start);\n d.setDate(start.getDate() + i);\n cells.push({ date: d, inMonth: d.getMonth() === refDate.getMonth() });\n }\n } else {\n const firstOfMonth = new Date(refDate.getFullYear(), refDate.getMonth(), 1);\n const lastOfMonth = new Date(refDate.getFullYear(), refDate.getMonth() + 1, 0);\n const gridStart = startOfWeek(firstOfMonth, weekStartsOn);\n const totalDays = Math.ceil((lastOfMonth.getDate() + ((firstOfMonth.getDay() - weekStartsOn + 7) % 7)) / 7) * 7;\n for (let i = 0; i < totalDays; i += 1) {\n const d = new Date(gridStart);\n d.setDate(gridStart.getDate() + i);\n cells.push({ date: d, inMonth: d.getMonth() === refDate.getMonth() });\n }\n }\n\n const grid = el(\"div\", { class: \"rui-calendar-grid\", \"data-view\": view });\n const todayIso = formatIsoDate(today);\n for (const cell of cells) {\n const iso = formatIsoDate(cell.date);\n const isToday = iso === todayIso;\n const isSelected = iso === valueIso;\n const cellEvents = eventsByDate.get(iso) ?? [];\n const dayBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-calendar-day\",\n \"data-in-month\": cell.inMonth ? \"true\" : \"false\",\n \"data-today\": isToday ? \"true\" : \"false\",\n \"data-selected\": isSelected ? \"true\" : \"false\",\n \"aria-label\": cell.date.toDateString(),\n });\n dayBtn.append(el(\"span\", { class: \"rui-calendar-daynumber\" }, [String(cell.date.getDate())]));\n if (cellEvents.length > 0) {\n const evts = el(\"div\", { class: \"rui-calendar-day-events\" });\n const visibleEvents = cellEvents.slice(0, 3);\n for (const evt of visibleEvents) {\n const chip = el(\"span\", {\n class: \"rui-calendar-event\",\n \"data-tone\": evt.tone ?? \"primary\",\n title: evt.time ? `${evt.time} — ${evt.title}` : evt.title,\n }, [evt.title]);\n evts.append(chip);\n }\n if (cellEvents.length > 3) {\n evts.append(el(\"span\", { class: \"rui-calendar-event-more\" }, [\n `+${cellEvents.length - 3} more`,\n ]));\n }\n dayBtn.append(evts);\n }\n dayBtn.onclick = () => {\n if (onSelectState) helpers.setState(onSelectState, iso);\n helpers.invoke(props.onSelect, iso);\n };\n grid.append(dayBtn);\n }\n root.append(grid);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * ActivityLog — activity / audit feeds\n * ----------------------------------------------------------------------- */\n\ninterface FeedEntry {\n title: string;\n description: string;\n actor: string;\n avatarSrc: string;\n time: string;\n icon: string;\n tone: string;\n meta: string;\n}\n\nfunction readFeedEntries(raw: unknown): FeedEntry[] {\n const out: FeedEntry[] = [];\n for (const entry of asArray<unknown>(raw)) {\n if (!entry || typeof entry !== \"object\") continue;\n const e = entry as Record<string, unknown>;\n out.push({\n title: asString(e.title),\n description: asString(e.description),\n actor: asString(e.actor),\n avatarSrc: asString(e.avatarSrc),\n time: asString(e.time),\n icon: asString(e.icon),\n tone: asString(e.tone, \"default\"),\n meta: asString(e.meta),\n });\n }\n return out;\n}\n\nfunction renderFeed(klass: string, items: FeedEntry[], variant: string): HTMLElement {\n const root = el(\"ol\", { class: klass, \"data-variant\": variant });\n for (const entry of items) {\n const li = el(\"li\", { class: `${klass}-item`, \"data-tone\": entry.tone });\n const marker = el(\"span\", { class: `${klass}-marker` });\n const iconNode = renderIcon(entry.icon, { className: `${klass}-icon` });\n if (iconNode) marker.append(iconNode);\n li.append(marker);\n const body = el(\"div\", { class: `${klass}-body` });\n const head = el(\"div\", { class: `${klass}-head` });\n if (entry.actor) head.append(el(\"span\", { class: `${klass}-actor` }, [entry.actor]));\n head.append(el(\"span\", { class: `${klass}-title` }, [entry.title]));\n if (entry.time) head.append(el(\"span\", { class: `${klass}-time` }, [entry.time]));\n body.append(head);\n if (entry.description) {\n body.append(el(\"p\", { class: `${klass}-description` }, [entry.description]));\n }\n if (entry.meta) {\n body.append(el(\"span\", { class: `${klass}-meta` }, [entry.meta]));\n }\n li.append(body);\n root.append(li);\n }\n return root;\n}\n\nexport const ActivityLog: ComponentSpec = {\n name: \"ActivityLog\",\n description:\n \"Purpose-built feed of user/system activity. Each entry has `actor`, \" +\n \"`title`, `description?`, `time?`, `icon?`, `tone?`, and optional `meta` \" +\n \"(IP, browser, request id). Use `variant=\\\"audit\\\"` for monospace \" +\n \"security/admin trails. Pass items as `{actor, title, description, time, \" +\n \"icon, tone, avatarSrc, meta}` objects.\",\n props: [\n { name: \"items\", type: \"object[]\" },\n { name: \"variant\", type: \"string\", optional: true, enum: [\"default\", \"audit\"], description: \"audit = monospace voice with meta column\" },\n ],\n render: (_node, props) => {\n const variant = asString(props.variant, \"default\");\n const klass = variant === \"audit\" ? \"rui-audit-trail\" : \"rui-activity-log\";\n return renderFeed(klass, readFeedEntries(props.items), variant);\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * ComparisonTable — generic counterpart of PricingTable\n * ----------------------------------------------------------------------- */\n\nexport const ComparisonTable: ComponentSpec = {\n name: \"ComparisonTable\",\n description:\n \"Feature/spec comparison table — generic counterpart of `PricingTable`. \" +\n \"Pass `columns` (e.g. plan/product names) and `rows` of \" +\n \"`{label, values}` where `values` aligns 1-to-1 with `columns`. \" +\n \"Each value can be a boolean (✓/—), a string, or a node.\",\n props: [\n { name: \"columns\", type: \"string[]\", description: \"Column headers\" },\n { name: \"rows\", type: \"object[]\", description: \"Array of {label, values, hint?, group?} entries\" },\n { name: \"highlightColumn\", type: \"number\", optional: true, description: \"0-indexed column to visually emphasise\" },\n ],\n render: (_node, props, helpers) => {\n const columns = asArray<unknown>(props.columns).map((c) => asString(c));\n const rows = asArray<unknown>(props.rows).map((entry) => {\n const r = (entry ?? {}) as { label?: unknown; values?: unknown; hint?: unknown; group?: unknown };\n return {\n label: asString(r.label),\n values: asArray<unknown>(r.values),\n hint: asString(r.hint),\n group: asString(r.group),\n };\n });\n const highlightIdx = Math.floor(asNumber(props.highlightColumn, -1));\n const root = el(\"div\", { class: \"rui-comparison-table\" });\n const table = el(\"table\");\n const thead = el(\"thead\");\n const headRow = el(\"tr\");\n headRow.append(el(\"th\", { scope: \"col\", class: \"rui-comparison-table-feature\" }, [\"Feature\"]));\n columns.forEach((col, c) => {\n headRow.append(el(\"th\", {\n scope: \"col\",\n \"data-highlight\": c === highlightIdx ? \"true\" : null,\n }, [col]));\n });\n thead.append(headRow);\n table.append(thead);\n\n const tbody = el(\"tbody\");\n let currentGroup = \"\";\n for (const row of rows) {\n if (row.group && row.group !== currentGroup) {\n currentGroup = row.group;\n const groupRow = el(\"tr\", { class: \"rui-comparison-table-group\" });\n groupRow.append(el(\"td\", { colspan: String(columns.length + 1) }, [row.group]));\n tbody.append(groupRow);\n }\n const tr = el(\"tr\");\n const labelCell = el(\"td\", { class: \"rui-comparison-table-feature\" });\n labelCell.append(el(\"div\", { class: \"rui-comparison-table-feature-label\" }, [row.label]));\n if (row.hint) labelCell.append(el(\"div\", { class: \"rui-comparison-table-feature-hint\" }, [row.hint]));\n tr.append(labelCell);\n for (let c = 0; c < columns.length; c += 1) {\n const value = row.values[c];\n const td = el(\"td\", { \"data-highlight\": c === highlightIdx ? \"true\" : null });\n if (value === true) {\n const icon = renderIcon(\"circle-check\", { className: \"rui-comparison-yes\" });\n if (icon) td.append(icon);\n else td.textContent = \"✓\";\n } else if (value === false || value === null || value === undefined) {\n td.append(el(\"span\", { class: \"rui-comparison-no\" }, [\"—\"]));\n } else if (value && typeof value === \"object\" && (value as { __kind?: string }).__kind === \"Component\") {\n td.append(helpers.renderNode(value));\n } else {\n td.textContent = asString(value);\n }\n tr.append(td);\n }\n tbody.append(tr);\n }\n table.append(tbody);\n root.append(table);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * InfiniteList — scroll-to-load list\n * ----------------------------------------------------------------------- */\n\nexport const InfiniteList: ComponentSpec = {\n name: \"InfiniteList\",\n description:\n \"Vertical list that fires `onLoadMore` when the user scrolls near the \" +\n \"bottom. Pass already-rendered child nodes as `items`; wire `onLoadMore` \" +\n \"to an `action` that awaits a `$mutation` or `$query` (e.g. \" +\n \"`await loadMore.invoke()`) and appends to the bound state. Use \" +\n \"`loading=true` to show the spinner row, `hasMore=false` to suppress further loads.\",\n props: [\n { name: \"items\", type: \"Node[]\", description: \"Already-rendered child nodes\" },\n { name: \"onLoadMore\", type: \"callable\", optional: true, description: \"Callable fired when the sentinel scrolls into view\" },\n { name: \"loading\", type: \"boolean\", optional: true },\n { name: \"hasMore\", type: \"boolean\", optional: true, description: \"Default true — set false to hide the sentinel\" },\n { name: \"loaderLabel\", type: \"string\", optional: true, description: \"Label rendered while loading (default `Loading…`)\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-infinite-list\" });\n const list = el(\"div\", { class: \"rui-infinite-list-body\" });\n for (const child of asArray(props.items)) list.append(helpers.renderNode(child));\n root.append(list);\n const hasMore = props.hasMore === undefined ? true : asBoolean(props.hasMore);\n const loading = asBoolean(props.loading);\n if (hasMore) {\n const sentinel = el(\"div\", { class: \"rui-infinite-list-sentinel\" });\n if (loading) {\n const spin = renderIcon(\"spinner\", { className: \"rui-infinite-list-spin\" });\n if (spin) sentinel.append(spin);\n sentinel.append(el(\"span\", {}, [asString(props.loaderLabel, \"Loading…\")]));\n } else if (typeof props.onLoadMore === \"function\") {\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-infinite-list-load-more\",\n }, [\"Load more\"]);\n btn.onclick = () => helpers.invoke(props.onLoadMore);\n sentinel.append(btn);\n }\n root.append(sentinel);\n // Lightweight IntersectionObserver fallback — fires the load callback\n // when the sentinel enters the viewport. Cleaned up automatically\n // when the list is unmounted.\n if (!loading && typeof props.onLoadMore === \"function\" && typeof IntersectionObserver !== \"undefined\") {\n const callback = props.onLoadMore;\n const observer = new IntersectionObserver((entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n helpers.invoke(callback);\n break;\n }\n }\n });\n observer.observe(sentinel);\n helpers.registerDisposer(() => observer.disconnect(), \"infinite-observer\");\n }\n }\n return root;\n },\n};\n","/**\n * Media components:\n *\n * - VideoPlayer / AudioPlayer — Native media wrappers with consistent styling.\n * - Carousel — Horizontal scrolling slider with prev/next + dot navigation.\n * - Gallery — Responsive image grid with optional click-to-open Lightbox.\n * - Lightbox — Full-viewport image viewer (controlled via $variable).\n * - Map — Static map (OpenStreetMap tiles) given lat/lng coordinates.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport {\n el, asArray, asString, asBoolean, asNumber, renderIcon,\n sanitiseCssLength, sanitiseImageSrc,\n} from \"../utils.js\";\n\nconst SAFE_MEDIA_SCHEMES = /^(https?:|blob:|data:(audio|video)\\/)/i;\n\nfunction sanitiseMediaSrc(raw: unknown): string {\n const value = asString(raw).trim();\n if (!value) return \"\";\n if (value.startsWith(\"/\") || value.startsWith(\".\")) return value;\n if (value.startsWith(\"//\")) return \"\";\n return SAFE_MEDIA_SCHEMES.test(value) ? value : \"\";\n}\n\nexport const VideoPlayer: ComponentSpec = {\n name: \"VideoPlayer\",\n description:\n \"Themed native `<video>` wrapper. Pass a `src` URL (or `sources` array \" +\n \"for multi-codec fallback) and optional `poster`. Standard controls \" +\n \"are visible by default; pass `autoplay`, `loop`, `muted`, or \" +\n \"`controls=false` to override. Use for product demos, tutorials, \" +\n \"and any inline video.\",\n props: [\n { name: \"src\", type: \"string\", optional: true, description: \"Video URL (mp4 / webm / etc.)\" },\n { name: \"sources\", type: \"object[]\", optional: true, description: \"Array of {src, type} entries for multi-codec fallback\" },\n { name: \"poster\", type: \"string\", optional: true, description: \"Thumbnail image URL shown before playback\" },\n { name: \"caption\", type: \"string\", optional: true },\n { name: \"controls\", type: \"boolean\", optional: true, description: \"Show native controls (default true)\" },\n { name: \"autoplay\", type: \"boolean\", optional: true },\n { name: \"loop\", type: \"boolean\", optional: true },\n { name: \"muted\", type: \"boolean\", optional: true },\n { name: \"ratio\", type: \"string\", optional: true, description: \"Aspect ratio (default 16:9)\" },\n ],\n render: (_node, props) => {\n const root = el(\"figure\", { class: \"rui-video-player\" });\n const ratio = parseRatio(asString(props.ratio, \"16:9\"));\n const playerWrap = el(\"div\", {\n class: \"rui-video-player-frame\",\n style: `aspect-ratio:${ratio};`,\n });\n const showControls = props.controls === undefined ? true : asBoolean(props.controls);\n const video = el(\"video\", {\n class: \"rui-video-player-video\",\n controls: showControls ? \"\" : null,\n autoplay: asBoolean(props.autoplay) ? \"\" : null,\n loop: asBoolean(props.loop) ? \"\" : null,\n muted: asBoolean(props.muted) ? \"\" : null,\n poster: sanitiseImageSrc(props.poster) || null,\n playsinline: \"\",\n preload: \"metadata\",\n });\n const sources = asArray<unknown>(props.sources);\n if (sources.length > 0) {\n for (const raw of sources) {\n if (!raw || typeof raw !== \"object\") continue;\n const s = raw as { src?: unknown; type?: unknown };\n const safeSrc = sanitiseMediaSrc(s.src);\n if (!safeSrc) continue;\n video.append(el(\"source\", { src: safeSrc, type: asString(s.type) || null }));\n }\n } else {\n const safeSrc = sanitiseMediaSrc(props.src);\n if (safeSrc) video.setAttribute(\"src\", safeSrc);\n }\n playerWrap.append(video);\n root.append(playerWrap);\n const caption = asString(props.caption);\n if (caption) root.append(el(\"figcaption\", { class: \"rui-video-player-caption\" }, [caption]));\n return root;\n },\n};\n\nexport const AudioPlayer: ComponentSpec = {\n name: \"AudioPlayer\",\n description:\n \"Themed native `<audio>` wrapper with a title, optional artist, and \" +\n \"standard transport controls. Pass `src` (or `sources`) plus a \" +\n \"`title` so the bar still looks like a player when the controls bar \" +\n \"is hidden. Use for podcasts, voice notes, and demo audio.\",\n props: [\n { name: \"src\", type: \"string\", optional: true, description: \"Audio URL (mp3 / ogg / wav / etc.)\" },\n { name: \"sources\", type: \"object[]\", optional: true, description: \"Array of {src, type} entries for multi-codec fallback\" },\n { name: \"title\", type: \"string\", optional: true },\n { name: \"artist\", type: \"string\", optional: true },\n { name: \"controls\", type: \"boolean\", optional: true, description: \"Show native controls (default true)\" },\n { name: \"autoplay\", type: \"boolean\", optional: true },\n { name: \"loop\", type: \"boolean\", optional: true },\n { name: \"icon\", type: \"string\", optional: true, description: \"Leading icon (default `music`)\" },\n ],\n render: (_node, props) => {\n const root = el(\"div\", { class: \"rui-audio-player\" });\n const meta = el(\"div\", { class: \"rui-audio-player-meta\" });\n const iconNode = renderIcon(asString(props.icon, \"music\"), { className: \"rui-audio-player-icon\" });\n if (iconNode) meta.append(iconNode);\n const text = el(\"div\", { class: \"rui-audio-player-text\" });\n const title = asString(props.title);\n if (title) text.append(el(\"div\", { class: \"rui-audio-player-title\" }, [title]));\n const artist = asString(props.artist);\n if (artist) text.append(el(\"div\", { class: \"rui-audio-player-artist\" }, [artist]));\n meta.append(text);\n root.append(meta);\n const showControls = props.controls === undefined ? true : asBoolean(props.controls);\n const audio = el(\"audio\", {\n class: \"rui-audio-player-audio\",\n controls: showControls ? \"\" : null,\n autoplay: asBoolean(props.autoplay) ? \"\" : null,\n loop: asBoolean(props.loop) ? \"\" : null,\n preload: \"metadata\",\n });\n const sources = asArray<unknown>(props.sources);\n if (sources.length > 0) {\n for (const raw of sources) {\n if (!raw || typeof raw !== \"object\") continue;\n const s = raw as { src?: unknown; type?: unknown };\n const safeSrc = sanitiseMediaSrc(s.src);\n if (!safeSrc) continue;\n audio.append(el(\"source\", { src: safeSrc, type: asString(s.type) || null }));\n }\n } else {\n const safeSrc = sanitiseMediaSrc(props.src);\n if (safeSrc) audio.setAttribute(\"src\", safeSrc);\n }\n root.append(audio);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * Carousel — horizontal slider with prev/next + dot navigation\n * ----------------------------------------------------------------------- */\n\ninterface SlideHelpers {\n renderNode: (node: unknown) => Node;\n}\n\nfunction renderCarouselSlide(item: unknown, helpers: SlideHelpers): Node | null {\n if (item === null || item === undefined) return null;\n if (typeof item === \"object\" && (item as { __kind?: string }).__kind === \"Component\") {\n return helpers.renderNode(item);\n }\n if (typeof item === \"string\") {\n const safeSrc = sanitiseImageSrc(item);\n if (!safeSrc) return null;\n return el(\"img\", { src: safeSrc, alt: \"\", loading: \"lazy\", class: \"rui-carousel-image\" });\n }\n if (typeof item === \"object\") {\n const obj = item as { src?: unknown; alt?: unknown; caption?: unknown; title?: unknown };\n const safeSrc = sanitiseImageSrc(obj.src);\n if (safeSrc) {\n const wrap = el(\"figure\", { class: \"rui-carousel-figure\" });\n wrap.append(el(\"img\", {\n src: safeSrc,\n alt: asString(obj.alt ?? obj.caption ?? obj.title),\n loading: \"lazy\",\n class: \"rui-carousel-image\",\n }));\n const captionText = asString(obj.caption ?? obj.title);\n if (captionText) {\n wrap.append(el(\"figcaption\", { class: \"rui-carousel-caption\" }, [captionText]));\n }\n return wrap;\n }\n }\n return helpers.renderNode(item);\n}\n\nexport const Carousel: ComponentSpec = {\n name: \"Carousel\",\n description:\n \"Horizontal slider with prev/next buttons and dot navigation. Each \" +\n \"child slide takes full width. Slides may be Component nodes \" +\n \"(Image, Card, MediaCard, …), URL strings, or plain \" +\n \"`{src, alt, caption?}` image objects — bare image objects are \" +\n \"auto-wrapped into a captioned figure. Use for image galleries, \" +\n \"onboarding carousels, hero banners, and product image strips. The \" +\n \"active slide is preserved across re-renders via instance state.\",\n props: [\n { name: \"items\", type: \"Node[]\", description: \"Slide nodes, image URLs, or {src, alt, caption?} objects\" },\n { name: \"activeIndex\", type: \"number\", optional: true, description: \"0-indexed initial slide (default 0)\" },\n { name: \"ratio\", type: \"string\", optional: true, description: \"Aspect ratio of the frame (default `16:9`)\" },\n { name: \"showDots\", type: \"boolean\", optional: true, description: \"Show indicator dots (default true)\" },\n { name: \"showArrows\", type: \"boolean\", optional: true, description: \"Show prev/next arrows (default true)\" },\n ],\n render: (_node, props, helpers) => {\n const items = asArray<unknown>(props.items);\n const count = items.length;\n const defaultIdx = Math.max(0, Math.min(Math.max(count - 1, 0), Math.floor(asNumber(props.activeIndex, 0))));\n const slot = helpers.useInstanceState<number>(\"active\", defaultIdx);\n let active = slot.get();\n if (active >= count) { active = 0; slot.set(active); }\n const showDots = props.showDots === undefined ? true : asBoolean(props.showDots);\n const showArrows = props.showArrows === undefined ? true : asBoolean(props.showArrows);\n const ratio = parseRatio(asString(props.ratio, \"16:9\"));\n const root = el(\"div\", { class: \"rui-carousel\" });\n const frame = el(\"div\", {\n class: \"rui-carousel-frame\",\n style: `aspect-ratio:${ratio};`,\n });\n const track = el(\"div\", {\n class: \"rui-carousel-track\",\n style: `transform:translateX(${active * -100}%);`,\n });\n items.forEach((item) => {\n const slide = el(\"div\", { class: \"rui-carousel-slide\" });\n const rendered = renderCarouselSlide(item, helpers);\n if (rendered) slide.append(rendered);\n track.append(slide);\n });\n frame.append(track);\n\n const move = (origin: Element, next: number): void => {\n const clamped = ((next % count) + count) % count;\n slot.set(clamped);\n const liveRoot = origin.closest(\".rui-carousel\");\n const liveTrack = liveRoot?.querySelector(\".rui-carousel-track\") as HTMLElement | null;\n if (liveTrack) liveTrack.style.transform = `translateX(${clamped * -100}%)`;\n liveRoot?.querySelectorAll<HTMLElement>(\".rui-carousel-dot\").forEach((dot, i) => {\n dot.setAttribute(\"data-active\", i === clamped ? \"true\" : \"false\");\n });\n };\n\n if (showArrows && count > 1) {\n const prev = el(\"button\", {\n type: \"button\",\n class: \"rui-carousel-arrow\",\n \"data-direction\": \"prev\",\n \"aria-label\": \"Previous slide\",\n });\n const prevIcon = renderIcon(\"chevron-left\");\n if (prevIcon) prev.append(prevIcon);\n const next = el(\"button\", {\n type: \"button\",\n class: \"rui-carousel-arrow\",\n \"data-direction\": \"next\",\n \"aria-label\": \"Next slide\",\n });\n const nextIcon = renderIcon(\"chevron-right\");\n if (nextIcon) next.append(nextIcon);\n prev.onclick = (event) => move(event.currentTarget as Element, slot.get() - 1);\n next.onclick = (event) => move(event.currentTarget as Element, slot.get() + 1);\n frame.append(prev, next);\n }\n root.append(frame);\n\n if (showDots && count > 1) {\n const dots = el(\"div\", { class: \"rui-carousel-dots\" });\n items.forEach((_item, i) => {\n const dot = el(\"button\", {\n type: \"button\",\n class: \"rui-carousel-dot\",\n \"data-active\": i === active ? \"true\" : \"false\",\n \"aria-label\": `Go to slide ${i + 1}`,\n });\n dot.onclick = (event) => move(event.currentTarget as Element, i);\n dots.append(dot);\n });\n root.append(dots);\n }\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * Gallery + Lightbox\n * ----------------------------------------------------------------------- */\n\nexport const Gallery: ComponentSpec = {\n name: \"Gallery\",\n description:\n \"Responsive image grid. Pass items as plain URL strings, \" +\n \"`{src, alt, caption?}` objects, or `Image(...)` nodes. When \" +\n \"`onSelect` is provided each tile becomes a button; bind it through \" +\n \"an Action that opens a `Lightbox`.\",\n props: [\n { name: \"items\", type: \"any[]\" },\n { name: \"columns\", type: \"number\", optional: true, description: \"Preferred column count (default auto)\" },\n { name: \"ratio\", type: \"string\", optional: true, description: \"Per-tile aspect ratio (default `1:1`)\" },\n { name: \"onSelect\", type: \"callable\", optional: true, description: \"Callable fired when a tile is clicked\" },\n ],\n render: (_node, props, helpers) => {\n const items = asArray<unknown>(props.items);\n const columns = Math.max(1, Math.min(6, Number(props.columns ?? \"auto\")));\n const ratio = parseRatio(asString(props.ratio, \"1:1\"));\n const root = el(\"div\", {\n class: \"rui-gallery\",\n \"data-columns\": columns > 0 ? String(columns) : null,\n });\n items.forEach((raw, i) => {\n const { src, alt, caption } = extractGalleryItem(raw);\n const safeSrc = sanitiseImageSrc(src);\n const clickable = typeof props.onSelect === \"function\";\n const tile = el(clickable ? \"button\" : \"figure\" as \"figure\", {\n type: clickable ? \"button\" : null,\n class: \"rui-gallery-tile\",\n style: `aspect-ratio:${ratio};`,\n \"data-index\": String(i),\n });\n if (safeSrc) {\n tile.append(el(\"img\", { src: safeSrc, alt, loading: \"lazy\" }));\n } else {\n const placeholder = renderIcon(\"image\", { className: \"rui-gallery-placeholder\" });\n if (placeholder) tile.append(placeholder);\n }\n if (caption) {\n tile.append(el(\"span\", { class: \"rui-gallery-caption\" }, [caption]));\n }\n if (clickable) {\n tile.onclick = () => helpers.invoke(props.onSelect, i, raw);\n }\n root.append(tile);\n });\n return root;\n },\n};\n\nfunction extractGalleryItem(raw: unknown): { src: string; alt: string; caption: string } {\n if (typeof raw === \"string\") return { src: raw, alt: \"\", caption: \"\" };\n if (raw && typeof raw === \"object\") {\n const r = raw as Record<string, unknown>;\n if ((r as { __kind?: string }).__kind === \"Component\" && Array.isArray(r.args)) {\n return {\n src: asString(r.args[0]),\n alt: asString(r.args[1]),\n caption: asString(r.args[2]),\n };\n }\n return {\n src: asString(r.src),\n alt: asString(r.alt),\n caption: asString(r.caption),\n };\n }\n return { src: \"\", alt: \"\", caption: \"\" };\n}\n\nexport const Lightbox: ComponentSpec = {\n name: \"Lightbox\",\n description:\n \"Image overlay. When you bind a `$variable` to `open` you control it \" +\n \"explicitly; without one, Lightbox renders a clickable thumbnail of \" +\n \"the current image that opens the overlay on click (and uses internal \" +\n \"state for next/prev). Pass `items` (string URLs or \" +\n \"`{src, alt, caption?}` objects). Clicking the backdrop or × closes; \" +\n \"arrows step through the array.\",\n props: [\n { name: \"items\", type: \"any[]\" },\n { name: \"open\", type: \"boolean\", optional: true, description: \"Open/closed; bind a $variable to control externally\" },\n { name: \"index\", type: \"number\", optional: true, description: \"0-indexed current image; typically a $variable\" },\n ],\n render: (node, props, helpers) => {\n const items = asArray<unknown>(props.items)\n .map((raw) => extractGalleryItem(raw))\n .filter((entry) => sanitiseImageSrc(entry.src) !== \"\");\n const total = items.length;\n const indexStateName = node.argMeta?.[2]?.stateRef;\n const openStateName = node.argMeta?.[1]?.stateRef;\n // Self-managed open/index when no $variable is bound — clicking the\n // thumbnail toggles the overlay, prev/next step through `items`.\n const internalOpen = helpers.useInstanceState<boolean>(\"open\", false);\n const internalIndex = helpers.useInstanceState<number>(\"index\", 0);\n const isOpen = openStateName\n ? asBoolean(props.open)\n : internalOpen.get();\n const rawIndex = indexStateName\n ? Math.floor(asNumber(props.index, 0))\n : internalIndex.get();\n const idx = total === 0 ? 0 : ((rawIndex % total) + total) % total;\n\n const setOpen = (next: boolean): void => {\n if (openStateName) helpers.setState(openStateName, next);\n else internalOpen.set(next);\n };\n const setIndex = (next: number): void => {\n if (indexStateName) helpers.setState(indexStateName, next);\n else internalIndex.set(next);\n };\n const close = () => setOpen(false);\n const move = (delta: number) => {\n if (total === 0) return;\n setIndex(((idx + delta) % total + total) % total);\n };\n\n const root = el(\"div\", { class: \"rui-lightbox-root\" });\n // Render a clickable thumbnail when the lightbox is self-managed and\n // no externally bound `open` state is in play. Authors who explicitly\n // bind `open: $var` keep the legacy headless behaviour.\n if (!openStateName && total > 0) {\n const current = items[idx];\n const thumb = el(\"button\", {\n type: \"button\",\n class: \"rui-lightbox-thumb\",\n \"aria-label\": current?.alt || \"Open image\",\n });\n if (current) {\n const safeThumb = sanitiseImageSrc(current.src);\n if (safeThumb) thumb.append(el(\"img\", { src: safeThumb, alt: current.alt, loading: \"lazy\" }));\n }\n thumb.onclick = (event) => {\n event.stopPropagation();\n setOpen(true);\n };\n root.append(thumb);\n }\n\n const overlay = el(\"div\", {\n class: \"rui-lightbox-overlay\",\n \"data-open\": isOpen ? \"true\" : \"false\",\n });\n root.append(overlay);\n if (!isOpen || total === 0) return root;\n const current = items[idx];\n if (!current) return root;\n const safeSrc = sanitiseImageSrc(current.src);\n overlay.onclick = (event) => {\n if (event.target === overlay) close();\n };\n const dialog = el(\"div\", { class: \"rui-lightbox\", role: \"dialog\", \"aria-modal\": \"true\" });\n const closeBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-lightbox-close\",\n \"aria-label\": \"Close lightbox\",\n }, [\"×\"]);\n closeBtn.onclick = close;\n dialog.append(closeBtn);\n if (total > 1) {\n const prev = el(\"button\", {\n type: \"button\",\n class: \"rui-lightbox-arrow\",\n \"data-direction\": \"prev\",\n \"aria-label\": \"Previous image\",\n });\n const prevIcon = renderIcon(\"chevron-left\");\n if (prevIcon) prev.append(prevIcon);\n prev.onclick = () => move(-1);\n const next = el(\"button\", {\n type: \"button\",\n class: \"rui-lightbox-arrow\",\n \"data-direction\": \"next\",\n \"aria-label\": \"Next image\",\n });\n const nextIcon = renderIcon(\"chevron-right\");\n if (nextIcon) next.append(nextIcon);\n next.onclick = () => move(1);\n dialog.append(prev, next);\n }\n const imageWrap = el(\"div\", { class: \"rui-lightbox-image-wrap\" });\n if (safeSrc) {\n imageWrap.append(el(\"img\", { src: safeSrc, alt: current.alt }));\n }\n dialog.append(imageWrap);\n if (current.caption) {\n dialog.append(el(\"div\", { class: \"rui-lightbox-caption\" }, [current.caption]));\n }\n if (total > 1) {\n dialog.append(el(\"div\", { class: \"rui-lightbox-counter\" }, [`${idx + 1} / ${total}`]));\n }\n overlay.append(dialog);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * Map — static OpenStreetMap embed\n * ----------------------------------------------------------------------- */\n\nfunction parseLatLng(raw: unknown): { lat: number; lng: number } | null {\n if (!raw) return null;\n if (typeof raw === \"object\" && !Array.isArray(raw)) {\n const r = raw as { lat?: unknown; lng?: unknown; latitude?: unknown; longitude?: unknown };\n const lat = asNumber(r.lat ?? r.latitude, NaN);\n const lng = asNumber(r.lng ?? r.longitude, NaN);\n if (Number.isFinite(lat) && Number.isFinite(lng)) return { lat, lng };\n }\n if (Array.isArray(raw) && raw.length >= 2) {\n const lat = asNumber(raw[0], NaN);\n const lng = asNumber(raw[1], NaN);\n if (Number.isFinite(lat) && Number.isFinite(lng)) return { lat, lng };\n }\n if (typeof raw === \"string\") {\n const parts = raw.split(\",\").map((s) => Number(s.trim()));\n if (parts.length >= 2 && Number.isFinite(parts[0]) && Number.isFinite(parts[1])) {\n return { lat: parts[0]!, lng: parts[1]! };\n }\n }\n return null;\n}\n\nexport const Map: ComponentSpec = {\n name: \"Map\",\n description:\n \"Static map view centered on a lat/lng coordinate. Renders an \" +\n \"OpenStreetMap embed inside an `<iframe>` (no external JS, no API \" +\n \"key). Pass `lat` and `lng` as bare numbers; `zoom` controls the \" +\n \"level (1–18, default 13). Optional `markers` array adds map pins \" +\n \"(rendered as a labelled list alongside the map). Use for store \" +\n \"locators, address cards, itinerary previews.\",\n props: [\n { name: \"lat\", type: \"number\", description: \"Latitude of the map center\" },\n { name: \"lng\", type: \"number\", description: \"Longitude of the map center\" },\n { name: \"zoom\", type: \"number\", optional: true, description: \"1–18 (default 13)\" },\n { name: \"markers\", type: \"object[]\", optional: true, description: \"Array of {lat, lng, label?} markers (informational; rendered alongside the map)\" },\n { name: \"height\", type: \"string\", optional: true, description: \"CSS height (default 320px)\" },\n { name: \"caption\", type: \"string\", optional: true },\n ],\n render: (_node, props) => {\n const root = el(\"figure\", { class: \"rui-map\" });\n const height = sanitiseCssLength(props.height, \"320px\");\n const frameWrap = el(\"div\", { class: \"rui-map-frame\", style: `height:${height};` });\n const lat = asNumber(props.lat, NaN);\n const lng = asNumber(props.lng, NaN);\n const center = Number.isFinite(lat) && Number.isFinite(lng) ? { lat, lng } : null;\n if (!center) {\n frameWrap.append(el(\"div\", { class: \"rui-map-empty\" }, [\n \"Pass lat & lng (numbers) to render the map.\",\n ]));\n root.append(frameWrap);\n const caption = asString(props.caption);\n if (caption) root.append(el(\"figcaption\", { class: \"rui-map-caption\" }, [caption]));\n return root;\n }\n const zoom = Math.max(1, Math.min(18, Math.floor(asNumber(props.zoom, 13))));\n // Approximate bounding box from a span that scales with zoom — small\n // enough that the requested center stays prominent in the embed.\n const span = 1 / Math.pow(2, zoom - 8);\n const bbox = [\n center.lng - span,\n center.lat - span / 2,\n center.lng + span,\n center.lat + span / 2,\n ].join(\",\");\n const url = `https://www.openstreetmap.org/export/embed.html?bbox=${bbox}&layer=mapnik&marker=${center.lat},${center.lng}`;\n const iframe = el(\"iframe\", {\n class: \"rui-map-iframe\",\n src: url,\n loading: \"lazy\",\n title: \"Map view\",\n referrerpolicy: \"no-referrer\",\n });\n frameWrap.append(iframe);\n root.append(frameWrap);\n const markers = asArray<unknown>(props.markers)\n .map((raw) => {\n const pin = parseLatLng(raw);\n const label = raw && typeof raw === \"object\" ? asString((raw as { label?: unknown }).label) : \"\";\n return pin ? { ...pin, label } : null;\n })\n .filter((p): p is { lat: number; lng: number; label: string } => p !== null);\n if (markers.length > 0) {\n const list = el(\"ul\", { class: \"rui-map-markers\" });\n for (const m of markers) {\n const li = el(\"li\", { class: \"rui-map-marker\" });\n const pinIcon = renderIcon(\"location-dot\", { className: \"rui-map-marker-icon\" });\n if (pinIcon) li.append(pinIcon);\n li.append(el(\"span\", { class: \"rui-map-marker-label\" }, [\n m.label || `${m.lat.toFixed(4)}, ${m.lng.toFixed(4)}`,\n ]));\n list.append(li);\n }\n root.append(list);\n }\n const caption = asString(props.caption);\n if (caption) root.append(el(\"figcaption\", { class: \"rui-map-caption\" }, [caption]));\n return root;\n },\n};\n\nfunction parseRatio(input: string): string {\n if (input.includes(\":\")) {\n const [w, h] = input.split(\":\");\n const num = Number(w);\n const den = Number(h);\n if (Number.isFinite(num) && Number.isFinite(den) && den > 0) return `${num} / ${den}`;\n }\n const n = Number(input);\n return Number.isFinite(n) && n > 0 ? `${n} / 1` : \"16 / 9\";\n}\n","/**\n * Editor components:\n *\n * - RichTextEditor — `contenteditable`-based WYSIWYG editor for CMS / email.\n * - CodeEditor — Lightweight, dependency-free code editor (textarea + gutter).\n * - ContextMenu — Right-click menu attachable to any wrapped node.\n * - ColorPicker — Hex / RGB form control with preset swatches.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport { el, asArray, asString, asBoolean, asNumber, renderIcon } from \"../utils.js\";\n\n/* ----------------------------------------------------------------------- *\n * RichTextEditor\n * ----------------------------------------------------------------------- */\n\ninterface RteCommand {\n command: string;\n icon: string;\n label: string;\n block?: string;\n}\n\nconst DEFAULT_RTE_TOOLS: RteCommand[] = [\n { command: \"bold\", icon: \"bold\", label: \"Bold\" },\n { command: \"italic\", icon: \"italic\", label: \"Italic\" },\n { command: \"underline\", icon: \"underline\", label: \"Underline\" },\n { command: \"strikeThrough\", icon: \"strikethrough\", label: \"Strikethrough\" },\n { command: \"formatBlock\", icon: \"heading\", label: \"Heading\", block: \"h2\" },\n { command: \"formatBlock\", icon: \"quote-left\", label: \"Quote\", block: \"blockquote\" },\n { command: \"insertUnorderedList\", icon: \"list-ul\", label: \"Bullet list\" },\n { command: \"insertOrderedList\", icon: \"list-ol\", label: \"Numbered list\" },\n { command: \"createLink\", icon: \"link\", label: \"Link\" },\n];\n\nexport const RichTextEditor: ComponentSpec = {\n name: \"RichTextEditor\",\n description:\n \"Rich-text WYSIWYG editor for CMS, email, and comment surfaces. \" +\n \"Renders a small toolbar (bold / italic / underline / strikethrough / \" +\n \"headings / lists / quote / link) above a `contenteditable` region. \" +\n \"Pass `$variable` as `value` for two-way binding — the HTML body is \" +\n \"written back to state on every edit. Provide `placeholder` for the \" +\n \"empty-state prompt.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"value\", type: \"string\", optional: true, description: \"Bound HTML body (typically $variable)\" },\n { name: \"placeholder\", type: \"string\", optional: true, description: \"Empty-state prompt\" },\n { name: \"minHeight\", type: \"string\", optional: true, description: \"CSS min-height for the editor area (default 160px)\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const placeholder = asString(props.placeholder, \"Start writing…\");\n const disabled = asBoolean(props.disabled);\n const root = el(\"div\", {\n class: \"rui-rich-text\",\n \"data-disabled\": disabled ? \"true\" : \"false\",\n });\n const toolbar = el(\"div\", { class: \"rui-rich-text-toolbar\", role: \"toolbar\" });\n for (const tool of DEFAULT_RTE_TOOLS) {\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-rich-text-tool\",\n \"data-command\": tool.command,\n \"data-block\": tool.block ?? null,\n \"aria-label\": tool.label,\n title: tool.label,\n disabled: disabled ? \"\" : null,\n });\n const iconNode = renderIcon(tool.icon);\n if (iconNode) btn.append(iconNode);\n btn.onmousedown = (event) => event.preventDefault();\n btn.onclick = (event) => {\n const live = (event.currentTarget as Element).closest(\".rui-rich-text\");\n const editor = live?.querySelector<HTMLElement>(\".rui-rich-text-content\");\n if (!editor) return;\n editor.focus();\n try {\n if (tool.command === \"createLink\") {\n const url = window.prompt(\"URL\");\n if (url) document.execCommand(\"createLink\", false, url);\n } else if (tool.command === \"formatBlock\" && tool.block) {\n document.execCommand(\"formatBlock\", false, tool.block);\n } else {\n document.execCommand(tool.command, false);\n }\n } catch {\n // execCommand can throw in some sandboxed contexts; swallow.\n }\n // Dispatch an input event so the state binding picks up the change.\n editor.dispatchEvent(new Event(\"input\", { bubbles: true }));\n };\n toolbar.append(btn);\n }\n root.append(toolbar);\n\n const initial = asString(props.value) || \"\";\n const isEmpty = (html: string): boolean => {\n const text = html.replace(/<br\\s*\\/?>(?=\\s*$)/gi, \"\").replace(/<[^>]+>/g, \"\").replace(/&nbsp;/g, \" \").trim();\n return text.length === 0;\n };\n const editor = el(\"div\", {\n class: \"rui-rich-text-content\",\n id,\n contenteditable: disabled ? \"false\" : \"true\",\n role: \"textbox\",\n \"aria-multiline\": \"true\",\n \"aria-placeholder\": placeholder,\n \"data-placeholder\": placeholder,\n \"data-empty\": isEmpty(initial) ? \"true\" : \"false\",\n style: `min-height:${asString(props.minHeight, \"160px\")};`,\n html: initial,\n });\n const refreshEmpty = (target: HTMLElement): void => {\n target.setAttribute(\"data-empty\", isEmpty(target.innerHTML) ? \"true\" : \"false\");\n };\n const stateName = node.argMeta?.[1]?.stateRef;\n if (stateName && !disabled) {\n helpers.bindState(editor, stateName, {\n event: \"input\",\n // Sync the placeholder state on every keystroke, alongside the\n // state write — keeps both behaviours in the single property-based\n // `oninput` slot so the morph reconciler transfers them as a unit.\n getValue: (n) => {\n const target = n as HTMLElement;\n refreshEmpty(target);\n return target.innerHTML;\n },\n });\n } else {\n editor.oninput = (event) => {\n const target = (event.currentTarget ?? event.target) as HTMLElement;\n refreshEmpty(target);\n };\n }\n editor.onblur = (event) => {\n const target = (event.currentTarget ?? event.target) as HTMLElement;\n refreshEmpty(target);\n };\n root.append(editor);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * CodeEditor — lightweight textarea-based editor with gutter\n * ----------------------------------------------------------------------- */\n\nconst CODE_LANGUAGES = [\"text\", \"javascript\", \"typescript\", \"json\", \"html\", \"css\", \"bash\", \"python\", \"sql\", \"markdown\"] as const;\n\nexport const CodeEditor: ComponentSpec = {\n name: \"CodeEditor\",\n description:\n \"Lightweight, dependency-free code editor. Pairs a styled textarea \" +\n \"with a synchronised line-number gutter — no syntax highlighting, but \" +\n \"the editor stays a single rendered node so it works inside Shadow \" +\n \"DOM. Use for dev tooling, snippet editing, prompt playgrounds. Pass \" +\n \"a `$variable` as `value` for two-way binding. For read-only \" +\n \"rendering with highlights prefer `CodeBlock`.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"value\", type: \"string\", optional: true, description: \"Bound source text (typically $variable)\" },\n { name: \"language\", type: \"string\", optional: true, enum: CODE_LANGUAGES, description: \"Language label shown on the header (default `text`)\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"minHeight\", type: \"string\", optional: true, description: \"CSS min-height for the editor area (default 200px)\" },\n { name: \"tabSize\", type: \"number\", optional: true, description: \"Spaces per Tab (default 2)\" },\n { name: \"showGutter\", type: \"boolean\", optional: true, description: \"Show line-number gutter (default true)\" },\n { name: \"readonly\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const value = asString(props.value);\n const language = asString(props.language, \"text\");\n const showGutter = props.showGutter === undefined ? true : asBoolean(props.showGutter);\n const tabSize = Math.max(1, Math.min(8, Math.floor(asNumber(props.tabSize, 2))));\n const readonly = asBoolean(props.readonly);\n const minHeight = asString(props.minHeight, \"200px\");\n const root = el(\"div\", {\n class: \"rui-code-editor\",\n \"data-language\": language,\n \"data-gutter\": showGutter ? \"true\" : \"false\",\n });\n const head = el(\"div\", { class: \"rui-code-editor-head\" });\n head.append(el(\"span\", { class: \"rui-code-editor-language\" }, [language]));\n root.append(head);\n const body = el(\"div\", {\n class: \"rui-code-editor-body\",\n style: `min-height:${minHeight};`,\n });\n const gutter = el(\"div\", { class: \"rui-code-editor-gutter\", \"aria-hidden\": \"true\" });\n const renderGutter = (text: string) => {\n gutter.replaceChildren();\n const lines = text.split(/\\r?\\n/);\n const total = Math.max(1, lines.length);\n for (let i = 1; i <= total; i += 1) {\n gutter.append(el(\"span\", { class: \"rui-code-editor-line\" }, [String(i)]));\n }\n };\n if (showGutter) {\n renderGutter(value);\n body.append(gutter);\n }\n const textarea = el(\"textarea\", {\n class: \"rui-code-editor-textarea\",\n id,\n name: id,\n spellcheck: \"false\",\n autocorrect: \"off\",\n autocapitalize: \"off\",\n placeholder: asString(props.placeholder),\n readonly: readonly ? \"\" : null,\n style: `tab-size:${tabSize};-moz-tab-size:${tabSize};`,\n }) as HTMLTextAreaElement;\n textarea.value = value;\n textarea.oninput = (event) => {\n const target = event.currentTarget as HTMLTextAreaElement;\n if (!showGutter) return;\n const liveRoot = target.closest(\".rui-code-editor\");\n const liveGutter = liveRoot?.querySelector<HTMLElement>(\".rui-code-editor-gutter\");\n if (!liveGutter) return;\n liveGutter.replaceChildren();\n const lines = target.value.split(/\\r?\\n/);\n const total = Math.max(1, lines.length);\n for (let i = 1; i <= total; i += 1) {\n liveGutter.append(el(\"span\", { class: \"rui-code-editor-line\" }, [String(i)]));\n }\n };\n // Honour Tab as indentation rather than focus-change.\n textarea.onkeydown = (event) => {\n const e = event as KeyboardEvent;\n if (e.key !== \"Tab\") return;\n e.preventDefault();\n const target = e.currentTarget as HTMLTextAreaElement;\n const start = target.selectionStart;\n const end = target.selectionEnd;\n const indent = \" \".repeat(tabSize);\n target.value = target.value.slice(0, start) + indent + target.value.slice(end);\n target.selectionStart = target.selectionEnd = start + indent.length;\n target.dispatchEvent(new Event(\"input\", { bubbles: true }));\n };\n const stateName = node.argMeta?.[1]?.stateRef;\n if (stateName && !readonly) {\n helpers.bindState(textarea, stateName, {\n event: \"input\",\n getValue: (n) => (n as HTMLTextAreaElement).value,\n });\n }\n body.append(textarea);\n root.append(body);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * ContextMenu — right-click menu attachable to a child node\n * ----------------------------------------------------------------------- */\n\ninterface ContextMenuItem {\n label: string;\n action: unknown;\n icon: string;\n shortcut: string;\n variant: string;\n disabled: boolean;\n separator: boolean;\n}\n\nfunction extractContextItem(raw: unknown): ContextMenuItem | null {\n if (!raw) return null;\n if (typeof raw === \"object\") {\n const node = raw as { __kind?: string; name?: string; args?: unknown[] };\n if (node.__kind === \"Component\" && node.name === \"MenuItem\" && Array.isArray(node.args)) {\n const args = node.args;\n return {\n label: asString(args[0]),\n action: args[1],\n icon: asString(args[2]),\n shortcut: asString(args[3]),\n variant: asString(args[4], \"default\"),\n disabled: asBoolean(args[5]),\n separator: false,\n };\n }\n if (node.__kind === \"Component\" && node.name === \"MenuSeparator\") {\n return { label: \"\", action: null, icon: \"\", shortcut: \"\", variant: \"default\", disabled: false, separator: true };\n }\n const r = raw as Record<string, unknown>;\n if (r.separator) {\n return { label: \"\", action: null, icon: \"\", shortcut: \"\", variant: \"default\", disabled: false, separator: true };\n }\n return {\n label: asString(r.label),\n action: r.action,\n icon: asString(r.icon),\n shortcut: asString(r.shortcut),\n variant: asString(r.variant, \"default\"),\n disabled: asBoolean(r.disabled),\n separator: false,\n };\n }\n return null;\n}\n\nexport const ContextMenu: ComponentSpec = {\n name: \"ContextMenu\",\n description:\n \"Right-click (or long-press) menu that attaches to a child node. \" +\n \"Wraps `target` and shows the menu at the pointer when the user \" +\n \"right-clicks anywhere inside it. Items are `MenuItem(...)` nodes, \" +\n \"`MenuSeparator()` entries, or `{label, action, icon?, shortcut?, \" +\n \"variant?, disabled?, separator?}` objects. Use on table rows, tree \" +\n \"nodes, kanban cards, file browser entries.\",\n props: [\n { name: \"target\", type: \"Node\", description: \"Child node the menu is bound to\" },\n { name: \"items\", type: \"any[]\", description: \"MenuItem nodes or {label, action} objects\" },\n { name: \"label\", type: \"string\", optional: true, description: \"ARIA label for the menu\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"div\", { class: \"rui-context-menu\" });\n const wrap = el(\"div\", { class: \"rui-context-menu-target\" });\n wrap.append(helpers.renderNode(props.target));\n root.append(wrap);\n const menu = el(\"div\", {\n class: \"rui-context-menu-pop\",\n role: \"menu\",\n \"aria-label\": asString(props.label) || null,\n \"data-open\": \"false\",\n });\n const items = asArray<unknown>(props.items)\n .map(extractContextItem)\n .filter((i): i is ContextMenuItem => i !== null);\n for (const item of items) {\n if (item.separator) {\n menu.append(el(\"div\", { class: \"rui-menu-separator\", role: \"separator\" }));\n continue;\n }\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-menu-item\",\n role: \"menuitem\",\n \"data-variant\": item.variant,\n disabled: item.disabled ? \"\" : null,\n });\n const iconNode = renderIcon(item.icon, { className: \"rui-menu-item-icon\" });\n if (iconNode) btn.append(iconNode);\n btn.append(el(\"span\", { class: \"rui-menu-item-label\" }, [item.label]));\n if (item.shortcut) btn.append(el(\"span\", { class: \"rui-menu-item-shortcut\" }, [item.shortcut]));\n if (!item.disabled) {\n btn.onclick = () => {\n helpers.invoke(item.action);\n menu.setAttribute(\"data-open\", \"false\");\n };\n }\n menu.append(btn);\n }\n root.append(menu);\n\n const closeAll = () => menu.setAttribute(\"data-open\", \"false\");\n const open = (clientX: number, clientY: number) => {\n const liveRoot = wrap.isConnected ? wrap.closest(\".rui-context-menu\") as HTMLElement | null : null;\n const liveMenu = liveRoot?.querySelector<HTMLElement>(\".rui-context-menu-pop\") ?? menu;\n const rect = liveRoot?.getBoundingClientRect();\n const x = rect ? clientX - rect.left : clientX;\n const y = rect ? clientY - rect.top : clientY;\n liveMenu.style.left = `${x}px`;\n liveMenu.style.top = `${y}px`;\n liveMenu.setAttribute(\"data-open\", \"true\");\n const dismiss = (event: Event) => {\n if (event.target && liveMenu.contains(event.target as Node)) return;\n liveMenu.setAttribute(\"data-open\", \"false\");\n document.removeEventListener(\"click\", dismiss, true);\n document.removeEventListener(\"contextmenu\", dismiss, true);\n };\n setTimeout(() => {\n document.addEventListener(\"click\", dismiss, true);\n document.addEventListener(\"contextmenu\", dismiss, true);\n }, 0);\n };\n\n wrap.oncontextmenu = (event) => {\n event.preventDefault();\n open(event.clientX, event.clientY);\n };\n wrap.onkeydown = (event) => {\n const e = event as KeyboardEvent;\n if (e.key === \"ContextMenu\" || (e.shiftKey && e.key === \"F10\")) {\n e.preventDefault();\n const target = e.currentTarget as HTMLElement;\n const rect = target.getBoundingClientRect();\n open(rect.left, rect.top + rect.height);\n }\n if (e.key === \"Escape\") closeAll();\n };\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * ColorPicker\n * ----------------------------------------------------------------------- */\n\nconst DEFAULT_SWATCHES = [\n \"#0f172a\", \"#334155\", \"#64748b\", \"#94a3b8\",\n \"#ef4444\", \"#f59e0b\", \"#facc15\", \"#10b981\",\n \"#06b6d4\", \"#3b82f6\", \"#6366f1\", \"#8b5cf6\",\n];\n\nfunction normaliseHex(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return \"\";\n let hex = trimmed.startsWith(\"#\") ? trimmed.slice(1) : trimmed;\n if (hex.length === 3) hex = hex.split(\"\").map((c) => c + c).join(\"\");\n if (!/^[0-9a-fA-F]{6,8}$/.test(hex)) return \"\";\n return `#${hex.toLowerCase().slice(0, 6)}`;\n}\n\nexport const ColorPicker: ComponentSpec = {\n name: \"ColorPicker\",\n description:\n \"Hex / RGB color form control with preset swatches. Pairs a native \" +\n \"`<input type=\\\"color\\\">` chip with a hex text input and a row of \" +\n \"preset swatches. Pass a `$variable` as `value` (hex string, e.g. \" +\n \"`\\\"#6366f1\\\"`) for two-way binding. Use for theme builders, label \" +\n \"color pickers, and any \\\"pick a color\\\" surface.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"value\", type: \"string\", optional: true, description: \"Bound hex value (typically $variable)\" },\n { name: \"label\", type: \"string\", optional: true },\n { name: \"swatches\", type: \"string[]\", optional: true, description: \"Preset hex colors (default to a 12-color palette)\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const value = normaliseHex(asString(props.value)) || asString(props.value, \"#000000\");\n const disabled = asBoolean(props.disabled);\n const root = el(\"div\", { class: \"rui-color-picker\", \"data-disabled\": disabled ? \"true\" : \"false\" });\n const label = asString(props.label);\n if (label) root.append(el(\"label\", { class: \"rui-color-picker-label\", for: id }, [label]));\n const row = el(\"div\", { class: \"rui-color-picker-row\" });\n const colorInput = el(\"input\", {\n type: \"color\",\n class: \"rui-color-picker-color\",\n id,\n name: id,\n value: normaliseHex(value) || \"#000000\",\n disabled: disabled ? \"\" : null,\n }) as HTMLInputElement;\n const textInput = el(\"input\", {\n type: \"text\",\n class: \"rui-color-picker-hex\",\n value,\n placeholder: \"#000000\",\n disabled: disabled ? \"\" : null,\n autocomplete: \"off\",\n }) as HTMLInputElement;\n const swatchRow = el(\"div\", { class: \"rui-color-picker-swatches\" });\n const swatches = asArray<unknown>(props.swatches).map((c) => asString(c)).filter(Boolean);\n const palette = swatches.length > 0 ? swatches : DEFAULT_SWATCHES;\n for (const swatch of palette) {\n const safeHex = normaliseHex(swatch) || swatch;\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-color-picker-swatch\",\n style: `background:${safeHex}`,\n \"aria-label\": safeHex,\n title: safeHex,\n \"data-active\": safeHex.toLowerCase() === value.toLowerCase() ? \"true\" : \"false\",\n });\n btn.onclick = () => {\n colorInput.value = normaliseHex(safeHex) || colorInput.value;\n textInput.value = safeHex;\n colorInput.dispatchEvent(new Event(\"input\", { bubbles: true }));\n };\n swatchRow.append(btn);\n }\n const stateName = node.argMeta?.[1]?.stateRef;\n if (stateName && !disabled) {\n helpers.bindState(colorInput, stateName, {\n event: \"input\",\n getValue: (n) => (n as HTMLInputElement).value,\n });\n // Keep the hex text input in sync with the color picker.\n colorInput.addEventListener(\"input\", () => {\n textInput.value = colorInput.value;\n });\n textInput.oninput = () => {\n const next = normaliseHex(textInput.value);\n if (!next) return;\n colorInput.value = next;\n colorInput.dispatchEvent(new Event(\"input\", { bubbles: true }));\n };\n }\n row.append(colorInput, textInput);\n root.append(row, swatchRow);\n return root;\n },\n};\n","/**\n * Advanced chart components built on the same SVG primitives as `charts.ts`:\n *\n * - Gauge — half-doughnut indicator for KPIs and thresholds.\n * - Heatmap — color-intensity grid (calendar / matrix style).\n * - RadarChart — multi-axis polygon for skills, comparisons, scorecards.\n * - ScatterChart — XY scatter for correlations and distributions.\n * - Histogram — frequency distribution from raw numbers.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport { el, asArray, asString, asNumber } from \"../utils.js\";\n\nconst PALETTE: readonly string[] = [\n \"var(--rui-chart-1, #6366f1)\",\n \"var(--rui-chart-2, #10b981)\",\n \"var(--rui-chart-3, #f59e0b)\",\n \"var(--rui-chart-4, #ef4444)\",\n \"var(--rui-chart-5, #06b6d4)\",\n \"var(--rui-chart-6, #8b5cf6)\",\n];\n\nconst colorAt = (index: number): string => PALETTE[index % PALETTE.length] ?? PALETTE[0]!;\n\ninterface SeriesData {\n name: string;\n values: number[];\n}\n\nfunction readSeries(raw: unknown[]): SeriesData[] {\n return raw.map((s, i) => {\n const node = s as { args?: unknown[] };\n const name = asString(node.args?.[0], `Series ${i + 1}`);\n const values = asArray<unknown>(node.args?.[1]).map((v) => asNumber(v));\n return { name, values };\n });\n}\n\nfunction createSvg(width: number, height: number): SVGSVGElement {\n const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\n svg.setAttribute(\"class\", \"rui-chart-svg\");\n svg.setAttribute(\"role\", \"img\");\n return svg;\n}\n\nfunction svgEl(\n tag: string,\n attrs: Record<string, string>,\n children?: ReadonlyArray<Node | string>,\n): SVGElement {\n const node = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n for (const [key, value] of Object.entries(attrs)) node.setAttribute(key, value);\n if (children) {\n for (const child of children) {\n node.append(typeof child === \"string\" ? document.createTextNode(child) : child);\n }\n }\n return node;\n}\n\nfunction legend(series: SeriesData[]): HTMLElement {\n const root = el(\"div\", { class: \"rui-chart-legend\" });\n series.forEach((s, i) => {\n const item = el(\"span\", { class: \"rui-chart-legend-item\" });\n item.append(el(\"span\", { class: \"rui-chart-legend-swatch\", style: `background:${colorAt(i)}` }));\n item.append(el(\"span\", {}, [s.name]));\n root.append(item);\n });\n return root;\n}\n\n/* ----------------------------------------------------------------------- *\n * Gauge\n * ----------------------------------------------------------------------- */\n\nexport const Gauge: ComponentSpec = {\n name: \"Gauge\",\n description:\n \"Half-doughnut gauge indicator for a single value between `min` and \" +\n \"`max`. The inner value is auto-formatted from the value (override \" +\n \"via `label`). Pass `caption`, `tone`, and `size` for visual \" +\n \"treatment. Use for KPI thresholds (uptime %, score, capacity, NPS, \" +\n \"page-speed).\",\n props: [\n { name: \"value\", type: \"number\" },\n { name: \"min\", type: \"number\", optional: true, description: \"Lower bound (default 0)\" },\n { name: \"max\", type: \"number\", optional: true, description: \"Upper bound (default 100)\" },\n { name: \"caption\", type: \"string\", optional: true, description: \"Small caption below the gauge\" },\n { name: \"tone\", type: \"string\", optional: true, enum: [\"primary\", \"success\", \"warning\", \"danger\", \"info\"] },\n { name: \"size\", type: \"string\", optional: true, enum: [\"sm\", \"md\", \"lg\"] },\n { name: \"label\", type: \"string\", optional: true, description: \"Inner label override (defaults to auto-formatted value)\" },\n ],\n render: (_node, props) => {\n const min = asNumber(props.min, 0);\n const max = Math.max(min + 1, asNumber(props.max, 100));\n const value = Math.max(min, Math.min(max, asNumber(props.value, min)));\n const pct = (value - min) / (max - min);\n const tone = asString(props.tone, \"primary\");\n const size = asString(props.size, \"md\");\n const px = size === \"lg\" ? 220 : size === \"sm\" ? 140 : 180;\n const half = px / 2;\n const stroke = size === \"lg\" ? 18 : size === \"sm\" ? 10 : 14;\n const r = half - stroke;\n const root = el(\"div\", {\n class: \"rui-gauge\",\n \"data-tone\": tone,\n \"data-size\": size,\n });\n const svg = createSvg(px, half + stroke + 4);\n const cx = half;\n const cy = half;\n const startX = cx - r;\n const startY = cy;\n const endX = cx + r;\n const endY = cy;\n svg.append(svgEl(\"path\", {\n d: `M${startX},${startY} A${r},${r} 0 0 1 ${endX},${endY}`,\n fill: \"none\",\n stroke: \"var(--rui-color-border, #e2e8f0)\",\n \"stroke-width\": String(stroke),\n \"stroke-linecap\": \"round\",\n }));\n if (pct > 0) {\n const angle = Math.PI * pct;\n const x = cx - r * Math.cos(angle);\n const y = cy - r * Math.sin(angle);\n // The gauge is only the upper half of a circle, so the foreground\n // arc never exceeds 180°. `large-arc-flag` is therefore always 0 —\n // setting it to 1 makes the SVG renderer take the long way round\n // and draw the missing portion instead of the filled portion.\n svg.append(svgEl(\"path\", {\n d: `M${startX},${startY} A${r},${r} 0 0 1 ${x.toFixed(2)},${y.toFixed(2)}`,\n fill: \"none\",\n stroke: `var(--rui-color-${tone}, ${colorAt(0)})`,\n \"stroke-width\": String(stroke),\n \"stroke-linecap\": \"round\",\n class: \"rui-gauge-arc\",\n }));\n }\n root.append(svg);\n const autoLabel = formatGaugeValue(value, min, max);\n const label = asString(props.label) || autoLabel;\n root.append(el(\"div\", { class: \"rui-gauge-value\" }, [label]));\n const caption = asString(props.caption);\n if (caption) root.append(el(\"div\", { class: \"rui-gauge-caption\" }, [caption]));\n return root;\n },\n};\n\nfunction formatGaugeValue(value: number, min: number, max: number): string {\n const isPercentLike = min === 0 && max === 100;\n if (isPercentLike) {\n return value % 1 === 0 ? `${value}%` : `${value.toFixed(1)}%`;\n }\n if (Math.abs(value) >= 1000) return Math.round(value).toLocaleString();\n if (value % 1 === 0) return String(value);\n return value.toFixed(value < 10 ? 2 : 1);\n}\n\n/* ----------------------------------------------------------------------- *\n * Heatmap\n * ----------------------------------------------------------------------- */\n\nexport const Heatmap: ComponentSpec = {\n name: \"Heatmap\",\n description:\n \"Color-intensity matrix grid (calendar-style or correlation-style). \" +\n \"Pass `xLabels`, `yLabels`, and a `values` array of arrays (rows × \" +\n \"columns). Each cell's color intensity scales with the value relative \" +\n \"to the global max. Use for activity heatmaps, schedule density, \" +\n \"correlation matrices.\",\n props: [\n { name: \"xLabels\", type: \"string[]\" },\n { name: \"yLabels\", type: \"string[]\" },\n { name: \"values\", type: \"number[][]\", description: \"Matrix indexed by row (y), then column (x)\" },\n { name: \"title\", type: \"string\", optional: true },\n { name: \"tone\", type: \"string\", optional: true, enum: [\"primary\", \"success\", \"warning\", \"danger\", \"info\"] },\n ],\n render: (_node, props) => {\n const xLabels = asArray<unknown>(props.xLabels).map((l) => asString(l));\n const yLabels = asArray<unknown>(props.yLabels).map((l) => asString(l));\n const valueRows: number[][] = asArray<unknown>(props.values).map((row) =>\n asArray<unknown>(row).map((v) => asNumber(v, 0)));\n const tone = asString(props.tone, \"primary\");\n const max = Math.max(1, ...valueRows.flat());\n const root = el(\"div\", { class: \"rui-heatmap\", \"data-tone\": tone });\n if (asString(props.title)) root.append(el(\"div\", { class: \"rui-chart-title\" }, [asString(props.title)]));\n const tableWrap = el(\"div\", { class: \"rui-heatmap-table\" });\n const headerRow = el(\"div\", { class: \"rui-heatmap-row rui-heatmap-row-header\" });\n headerRow.append(el(\"div\", { class: \"rui-heatmap-cell rui-heatmap-corner\" }));\n for (const x of xLabels) {\n headerRow.append(el(\"div\", { class: \"rui-heatmap-cell rui-heatmap-xlabel\" }, [x]));\n }\n tableWrap.append(headerRow);\n valueRows.forEach((row, rIdx) => {\n const rowEl = el(\"div\", { class: \"rui-heatmap-row\" });\n rowEl.append(el(\"div\", { class: \"rui-heatmap-cell rui-heatmap-ylabel\" }, [yLabels[rIdx] ?? String(rIdx + 1)]));\n row.forEach((value, cIdx) => {\n const intensity = max > 0 ? value / max : 0;\n const cell = el(\"div\", {\n class: \"rui-heatmap-cell rui-heatmap-value\",\n style: `background:color-mix(in srgb, var(--rui-color-${tone}, ${colorAt(0)}) ${Math.round(intensity * 90 + 5)}%, transparent);`,\n title: `${xLabels[cIdx] ?? cIdx + 1} · ${yLabels[rIdx] ?? rIdx + 1}: ${value}`,\n });\n cell.append(el(\"span\", {}, [String(value)]));\n rowEl.append(cell);\n });\n tableWrap.append(rowEl);\n });\n root.append(tableWrap);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * RadarChart\n * ----------------------------------------------------------------------- */\n\nexport const RadarChart: ComponentSpec = {\n name: \"RadarChart\",\n description:\n \"Polygon chart with one axis per category. Use for skill maps, \" +\n \"scorecards, capability comparisons, and any multi-dimensional \" +\n \"snapshot. Each Series renders as a filled polygon — overlapping is \" +\n \"expected for comparisons.\",\n props: [\n { name: \"axes\", type: \"string[]\", description: \"Category labels — one per radial axis\" },\n { name: \"series\", type: \"Series[]\" },\n { name: \"max\", type: \"number\", optional: true, description: \"Outer ring value (default = max across series)\" },\n { name: \"title\", type: \"string\", optional: true },\n ],\n render: (_node, props) => {\n const axes = asArray<unknown>(props.axes).map((a) => asString(a));\n const series = readSeries(asArray<unknown>(props.series));\n const n = Math.max(axes.length, 3);\n const root = el(\"div\", { class: \"rui-chart rui-radar-chart\" });\n if (asString(props.title)) root.append(el(\"div\", { class: \"rui-chart-title\" }, [asString(props.title)]));\n const max = Math.max(1, asNumber(props.max, series.flatMap((s) => s.values).reduce((m, v) => Math.max(m, v), 1)));\n const size = 280;\n const cx = size / 2;\n const cy = size / 2;\n const r = size / 2 - 24;\n const svg = createSvg(size, size);\n const rings = 4;\n for (let i = 1; i <= rings; i += 1) {\n const radius = (r / rings) * i;\n const points: string[] = [];\n for (let j = 0; j < n; j += 1) {\n const angle = (Math.PI * 2 * j) / n - Math.PI / 2;\n points.push(`${(cx + radius * Math.cos(angle)).toFixed(1)},${(cy + radius * Math.sin(angle)).toFixed(1)}`);\n }\n svg.append(svgEl(\"polygon\", {\n points: points.join(\" \"),\n fill: \"none\",\n stroke: \"var(--rui-color-border-subtle, rgba(0,0,0,0.08))\",\n \"stroke-width\": \"1\",\n }));\n }\n for (let j = 0; j < n; j += 1) {\n const angle = (Math.PI * 2 * j) / n - Math.PI / 2;\n const x = cx + r * Math.cos(angle);\n const y = cy + r * Math.sin(angle);\n svg.append(svgEl(\"line\", {\n x1: String(cx),\n y1: String(cy),\n x2: x.toFixed(1),\n y2: y.toFixed(1),\n stroke: \"var(--rui-color-border-subtle, rgba(0,0,0,0.08))\",\n \"stroke-width\": \"1\",\n }));\n const labelX = cx + (r + 16) * Math.cos(angle);\n const labelY = cy + (r + 16) * Math.sin(angle);\n svg.append(svgEl(\"text\", {\n x: labelX.toFixed(1),\n y: labelY.toFixed(1),\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"middle\",\n class: \"rui-chart-label\",\n \"font-size\": \"13\",\n \"font-weight\": \"500\",\n }, [axes[j] ?? \"\"]));\n }\n series.forEach((s, sIdx) => {\n const points: string[] = [];\n for (let j = 0; j < n; j += 1) {\n const value = s.values[j] ?? 0;\n const ratio = Math.max(0, Math.min(1, value / max));\n const angle = (Math.PI * 2 * j) / n - Math.PI / 2;\n const x = cx + r * ratio * Math.cos(angle);\n const y = cy + r * ratio * Math.sin(angle);\n points.push(`${x.toFixed(1)},${y.toFixed(1)}`);\n }\n svg.append(svgEl(\"polygon\", {\n points: points.join(\" \"),\n fill: colorAt(sIdx),\n \"fill-opacity\": \"0.2\",\n stroke: colorAt(sIdx),\n \"stroke-width\": \"2\",\n \"stroke-linejoin\": \"round\",\n }));\n });\n root.append(svg);\n if (series.length > 0) root.append(legend(series));\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * ScatterChart\n * ----------------------------------------------------------------------- */\n\ninterface ScatterPoint {\n x: number;\n y: number;\n label: string;\n}\n\nfunction readScatterSeries(raw: unknown[]): { name: string; points: ScatterPoint[] }[] {\n return raw.map((entry, i) => {\n const node = entry as { args?: unknown[] };\n const name = asString(node.args?.[0], `Series ${i + 1}`);\n const points = asArray<unknown>(node.args?.[1]).map((p) => {\n if (Array.isArray(p)) {\n return { x: asNumber(p[0], 0), y: asNumber(p[1], 0), label: asString(p[2]) };\n }\n if (p && typeof p === \"object\") {\n const r = p as Record<string, unknown>;\n return { x: asNumber(r.x, 0), y: asNumber(r.y, 0), label: asString(r.label) };\n }\n return { x: 0, y: 0, label: \"\" };\n });\n return { name, points };\n });\n}\n\nexport const ScatterChart: ComponentSpec = {\n name: \"ScatterChart\",\n description:\n \"XY scatter plot — one dot per data point, optionally grouped by \" +\n \"series. Pass each `Series(name, points)` with points as \" +\n \"`{x, y, label?}` objects or `[x, y, label?]` tuples. Use for \" +\n \"correlations, distributions, and \\\"price vs. rating\\\" style charts.\",\n props: [\n { name: \"series\", type: \"Series[]\" },\n { name: \"xLabel\", type: \"string\", optional: true },\n { name: \"yLabel\", type: \"string\", optional: true },\n { name: \"title\", type: \"string\", optional: true },\n ],\n render: (_node, props) => {\n const series = readScatterSeries(asArray<unknown>(props.series));\n const root = el(\"div\", { class: \"rui-chart rui-scatter-chart\" });\n if (asString(props.title)) root.append(el(\"div\", { class: \"rui-chart-title\" }, [asString(props.title)]));\n const width = 640;\n const height = 280;\n const padding = { left: 50, right: 16, top: 16, bottom: 40 };\n const innerWidth = width - padding.left - padding.right;\n const innerHeight = height - padding.top - padding.bottom;\n const points = series.flatMap((s) => s.points);\n if (points.length === 0) {\n root.append(el(\"div\", { class: \"rui-chart-empty\" }, [\"No points\"]));\n return root;\n }\n const xs = points.map((p) => p.x);\n const ys = points.map((p) => p.y);\n const minX = Math.min(...xs), maxX = Math.max(...xs);\n const minY = Math.min(...ys), maxY = Math.max(...ys);\n const xRange = maxX - minX || 1;\n const yRange = maxY - minY || 1;\n const svg = createSvg(width, height);\n drawHorizontalGrid(svg, padding, innerWidth, innerHeight, maxY, minY);\n // x-axis\n svg.append(svgEl(\"line\", {\n x1: String(padding.left),\n y1: String(padding.top + innerHeight),\n x2: String(padding.left + innerWidth),\n y2: String(padding.top + innerHeight),\n stroke: \"var(--rui-color-border, #e2e8f0)\",\n }));\n series.forEach((s, sIdx) => {\n s.points.forEach((pt) => {\n const cx = padding.left + ((pt.x - minX) / xRange) * innerWidth;\n const cy = padding.top + innerHeight - ((pt.y - minY) / yRange) * innerHeight;\n const circle = svgEl(\"circle\", {\n cx: cx.toFixed(1),\n cy: cy.toFixed(1),\n r: \"7\",\n fill: colorAt(sIdx),\n \"fill-opacity\": \"0.8\",\n stroke: \"#fff\",\n \"stroke-width\": \"1.5\",\n });\n circle.append(svgEl(\"title\", {}, [pt.label || `${pt.x}, ${pt.y}`]));\n svg.append(circle);\n });\n });\n if (asString(props.xLabel)) {\n svg.append(svgEl(\"text\", {\n x: String(padding.left + innerWidth / 2),\n y: String(height - 6),\n \"text-anchor\": \"middle\",\n class: \"rui-chart-label\",\n \"font-size\": \"14\",\n \"font-weight\": \"500\",\n }, [asString(props.xLabel)]));\n }\n if (asString(props.yLabel)) {\n const labelX = 14;\n const labelY = padding.top + innerHeight / 2;\n svg.append(svgEl(\"text\", {\n x: String(labelX),\n y: String(labelY),\n \"text-anchor\": \"middle\",\n transform: `rotate(-90, ${labelX}, ${labelY})`,\n class: \"rui-chart-label\",\n \"font-size\": \"14\",\n \"font-weight\": \"500\",\n }, [asString(props.yLabel)]));\n }\n root.append(svg);\n const seriesData: SeriesData[] = series.map((s) => ({ name: s.name, values: s.points.map((p) => p.y) }));\n if (seriesData.length > 0) root.append(legend(seriesData));\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * Histogram\n * ----------------------------------------------------------------------- */\n\nexport const Histogram: ComponentSpec = {\n name: \"Histogram\",\n description:\n \"Frequency distribution from raw numeric values. Pass `values` \" +\n \"directly (the component bins them automatically) or pre-computed \" +\n \"`bins` of `{label, count}` objects. Use for response-time histograms, \" +\n \"score distributions, age buckets.\",\n props: [\n { name: \"values\", type: \"number[]\", optional: true, description: \"Raw observations (binned automatically)\" },\n { name: \"bins\", type: \"object[]\", optional: true, description: \"Pre-computed {label, count} entries (overrides `values`)\" },\n { name: \"binCount\", type: \"number\", optional: true, description: \"Number of bins when computing from `values` (default 10)\" },\n { name: \"title\", type: \"string\", optional: true },\n ],\n render: (_node, props) => {\n let bins: { label: string; count: number }[] = [];\n if (Array.isArray(props.bins) && (props.bins as unknown[]).length > 0) {\n bins = (props.bins as unknown[]).map((entry) => {\n const r = (entry ?? {}) as { label?: unknown; count?: unknown };\n return { label: asString(r.label), count: asNumber(r.count, 0) };\n });\n } else {\n const values = asArray<unknown>(props.values).map((v) => asNumber(v, NaN)).filter((n) => Number.isFinite(n));\n if (values.length > 0) {\n const binCount = Math.max(2, Math.min(50, Math.floor(asNumber(props.binCount, 10))));\n const min = Math.min(...values);\n const max = Math.max(...values);\n const span = max - min || 1;\n const step = span / binCount;\n const counts = new Array(binCount).fill(0);\n for (const v of values) {\n let idx = Math.floor((v - min) / step);\n if (idx >= binCount) idx = binCount - 1;\n if (idx < 0) idx = 0;\n counts[idx] += 1;\n }\n bins = counts.map((count, i) => {\n const a = min + i * step;\n const b = a + step;\n return { label: `${formatBinLabel(a)}–${formatBinLabel(b)}`, count };\n });\n }\n }\n const root = el(\"div\", { class: \"rui-chart rui-histogram\" });\n if (asString(props.title)) root.append(el(\"div\", { class: \"rui-chart-title\" }, [asString(props.title)]));\n if (bins.length === 0) {\n root.append(el(\"div\", { class: \"rui-chart-empty\" }, [\"No data\"]));\n return root;\n }\n const width = 640;\n const height = 240;\n const padding = { left: 40, right: 12, top: 16, bottom: 50 };\n const innerWidth = width - padding.left - padding.right;\n const innerHeight = height - padding.top - padding.bottom;\n const max = Math.max(1, ...bins.map((b) => b.count));\n const slot = innerWidth / bins.length;\n const svg = createSvg(width, height);\n drawHorizontalGrid(svg, padding, innerWidth, innerHeight, max);\n bins.forEach((bin, i) => {\n const x = padding.left + i * slot + slot * 0.1;\n const barWidth = slot * 0.8;\n const barHeight = (bin.count / max) * innerHeight;\n const y = padding.top + innerHeight - barHeight;\n const rect = svgEl(\"rect\", {\n x: x.toFixed(1),\n y: y.toFixed(1),\n width: barWidth.toFixed(1),\n height: barHeight.toFixed(1),\n fill: colorAt(0),\n rx: \"2\",\n });\n rect.append(svgEl(\"title\", {}, [`${bin.label}: ${bin.count}`]));\n svg.append(rect);\n svg.append(svgEl(\"text\", {\n x: (x + barWidth / 2).toFixed(1),\n y: String(padding.top + innerHeight + 22),\n \"text-anchor\": \"middle\",\n class: \"rui-chart-label\",\n \"font-size\": \"12\",\n }, [bin.label]));\n });\n root.append(svg);\n return root;\n },\n};\n\nfunction formatBinLabel(value: number): string {\n if (!Number.isFinite(value)) return \"?\";\n if (Math.abs(value) >= 1000) return Math.round(value).toLocaleString();\n if (Math.abs(value) >= 10) return value.toFixed(0);\n return value.toFixed(1);\n}\n\n/* ----------------------------------------------------------------------- *\n * Shared chart helpers\n * ----------------------------------------------------------------------- */\n\nfunction drawHorizontalGrid(\n svg: SVGSVGElement,\n padding: { left: number; right: number; top: number; bottom: number },\n innerWidth: number,\n innerHeight: number,\n max: number,\n min = 0,\n): void {\n const ticks = 4;\n for (let i = 0; i <= ticks; i += 1) {\n const ratio = i / ticks;\n const y = padding.top + innerHeight - ratio * innerHeight;\n svg.append(svgEl(\"line\", {\n x1: String(padding.left),\n x2: String(padding.left + innerWidth),\n y1: String(y),\n y2: String(y),\n stroke: \"var(--rui-color-border-subtle, rgba(0,0,0,0.08))\",\n }));\n svg.append(svgEl(\"text\", {\n x: String(padding.left - 8),\n y: String(y + 5),\n \"text-anchor\": \"end\",\n class: \"rui-chart-tick\",\n \"font-size\": \"14\",\n }, [String(Math.round((min + (max - min) * ratio) * 10) / 10)]));\n }\n}\n","/**\n * Advanced form components:\n *\n * - PinInput / OtpInput — Per-digit code entry for 2FA, SMS verification.\n * - PasswordInput — Text input with visibility toggle and strength meter.\n * - TagInput — Comma/Enter-separated chip input bound to a `$variable` array.\n * - MentionInput — TextArea-like input that suggests @-mentions from a list.\n * - TimePicker — `<input type=\"time\">` wrapper.\n * - DateTimePicker — `<input type=\"datetime-local\">` wrapper.\n * - MaskedInput — Text input with a simple mask (e.g. `(999) 999-9999`).\n * - FormSection / FieldSet — Semantic grouping for form fields.\n * - ValidationSummary — Aggregate errors list for the top of a form.\n * - MultiStepForm — Steps + content + prev/next composite.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport { el, asArray, asString, asBoolean, asNumber, renderIcon } from \"../utils.js\";\n\nconst PIN_TYPES = [\"numeric\", \"alphanumeric\"] as const;\n\n/* ----------------------------------------------------------------------- *\n * PinInput / OtpInput\n * ----------------------------------------------------------------------- */\n\nfunction renderPin(\n id: string,\n length: number,\n type: string,\n value: string,\n disabled: boolean,\n mask: boolean,\n onChange?: (next: string) => void,\n): HTMLElement {\n const root = el(\"div\", {\n class: \"rui-pin-input\",\n \"data-disabled\": disabled ? \"true\" : \"false\",\n });\n const inputs: HTMLInputElement[] = [];\n for (let i = 0; i < length; i += 1) {\n const input = el(\"input\", {\n class: \"rui-pin-input-slot\",\n id: i === 0 ? id : null,\n maxlength: \"1\",\n autocomplete: \"one-time-code\",\n inputmode: type === \"numeric\" ? \"numeric\" : \"text\",\n type: mask ? \"password\" : \"text\",\n \"aria-label\": `Digit ${i + 1}`,\n value: value.charAt(i) || \"\",\n disabled: disabled ? \"\" : null,\n }) as HTMLInputElement;\n inputs.push(input);\n root.append(input);\n }\n const getLiveSlots = (origin: Element): HTMLInputElement[] => {\n const pinRoot = origin.closest(\".rui-pin-input\");\n if (!pinRoot) return inputs;\n return Array.from(pinRoot.querySelectorAll<HTMLInputElement>(\".rui-pin-input-slot\"));\n };\n const collectLive = (origin: Element): string => {\n return getLiveSlots(origin).map((i) => i.value).join(\"\").slice(0, length);\n };\n inputs.forEach((input, idx) => {\n input.oninput = (event) => {\n const target = event.currentTarget as HTMLInputElement;\n const liveSlots = getLiveSlots(target);\n let v = target.value;\n if (type === \"numeric\") v = v.replace(/\\D/g, \"\");\n else v = v.replace(/[^A-Za-z0-9]/g, \"\");\n if (v.length > 1) {\n const chars = v.split(\"\");\n chars.slice(0, length - idx).forEach((c, k) => {\n const next = liveSlots[idx + k];\n if (next) next.value = c;\n });\n const lastFilled = Math.min(idx + chars.length, length - 1);\n liveSlots[lastFilled]?.focus();\n } else {\n target.value = v;\n if (v && idx < length - 1) liveSlots[idx + 1]?.focus();\n }\n onChange?.(collectLive(target));\n };\n input.onkeydown = (event) => {\n const e = event as KeyboardEvent;\n const target = e.currentTarget as HTMLInputElement;\n const liveSlots = getLiveSlots(target);\n if (e.key === \"Backspace\" && !target.value && idx > 0) {\n e.preventDefault();\n liveSlots[idx - 1]?.focus();\n const prev = liveSlots[idx - 1];\n if (prev) prev.value = \"\";\n onChange?.(collectLive(target));\n } else if (e.key === \"ArrowLeft\" && idx > 0) {\n e.preventDefault();\n liveSlots[idx - 1]?.focus();\n } else if (e.key === \"ArrowRight\" && idx < length - 1) {\n e.preventDefault();\n liveSlots[idx + 1]?.focus();\n }\n };\n });\n return root;\n}\n\nexport const PinInput: ComponentSpec = {\n name: \"PinInput\",\n description:\n \"Per-digit PIN entry. Auto-advances focus as the user types and \" +\n \"supports paste. Pass a `$variable` as `value` for two-way binding \" +\n \"(the bound value is the joined string). Use `type=\\\"numeric\\\"` for \" +\n \"PINs / 2FA codes, `\\\"alphanumeric\\\"` for invite codes.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"length\", type: \"number\", optional: true, description: \"Number of slots (default 4)\" },\n { name: \"value\", type: \"string\", optional: true, description: \"Bound value (typically $variable)\" },\n { name: \"type\", type: \"string\", optional: true, enum: PIN_TYPES },\n { name: \"mask\", type: \"boolean\", optional: true, description: \"Render slots as `<input type=password>`\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const length = Math.max(1, Math.min(12, Math.floor(asNumber(props.length, 4))));\n const type = asString(props.type, \"numeric\");\n const value = asString(props.value);\n const disabled = asBoolean(props.disabled);\n const mask = asBoolean(props.mask);\n const stateName = node.argMeta?.[2]?.stateRef;\n return renderPin(id, length, type, value, disabled, mask, (next) => {\n if (stateName) helpers.setState(stateName, next);\n });\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * PasswordInput\n * ----------------------------------------------------------------------- */\n\nfunction passwordStrength(value: string): { score: number; label: string } {\n if (!value) return { score: 0, label: \"\" };\n let score = 0;\n if (value.length >= 8) score += 1;\n if (value.length >= 12) score += 1;\n if (/[A-Z]/.test(value) && /[a-z]/.test(value)) score += 1;\n if (/[0-9]/.test(value)) score += 1;\n if (/[^A-Za-z0-9]/.test(value)) score += 1;\n score = Math.min(4, score);\n const labels = [\"Too short\", \"Weak\", \"Fair\", \"Good\", \"Strong\"];\n return { score, label: labels[score] ?? \"\" };\n}\n\nexport const PasswordInput: ComponentSpec = {\n name: \"PasswordInput\",\n description:\n \"Password input with a show/hide toggle and an optional strength \" +\n \"meter. Pass a `$variable` as `value` for two-way binding. Set \" +\n \"`strengthMeter=true` to render a 4-step indicator and label.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"value\", type: \"string\", optional: true, description: \"Bound value (typically $variable)\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"label\", type: \"string\", optional: true, description: \"Inline label above the field\" },\n { name: \"strengthMeter\", type: \"boolean\", optional: true, aliases: [\"showStrength\"] },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const visibleSlot = helpers.useInstanceState<boolean>(\"visible\", false);\n const visible = visibleSlot.get();\n const disabled = asBoolean(props.disabled);\n const root = el(\"div\", { class: \"rui-password-input\", \"data-disabled\": disabled ? \"true\" : \"false\" });\n const labelText = asString(props.label);\n if (labelText) {\n root.append(el(\"label\", { class: \"rui-password-input-label\", for: id }, [labelText]));\n }\n const row = el(\"div\", { class: \"rui-password-input-row\" });\n const input = el(\"input\", {\n type: visible ? \"text\" : \"password\",\n class: \"rui-password-input-field\",\n id,\n name: id,\n autocomplete: \"current-password\",\n placeholder: asString(props.placeholder),\n value: asString(props.value),\n disabled: disabled ? \"\" : null,\n }) as HTMLInputElement;\n const toggleBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-password-input-toggle\",\n \"aria-label\": visible ? \"Hide password\" : \"Show password\",\n });\n const toggleIcon = renderIcon(visible ? \"eye-slash\" : \"eye\");\n if (toggleIcon) toggleBtn.append(toggleIcon);\n toggleBtn.onclick = (event) => {\n event.preventDefault();\n const next = !visibleSlot.get();\n visibleSlot.set(next);\n const target = event.currentTarget as Element;\n const live = target.closest(\".rui-password-input\");\n const liveInput = live?.querySelector<HTMLInputElement>(\".rui-password-input-field\");\n if (liveInput) liveInput.type = next ? \"text\" : \"password\";\n };\n const stateName = node.argMeta?.[1]?.stateRef;\n if (stateName) {\n helpers.bindState(input, stateName, {\n event: \"input\",\n getValue: (n) => (n as HTMLInputElement).value,\n });\n }\n row.append(input);\n row.append(toggleBtn);\n root.append(row);\n if (asBoolean(props.strengthMeter)) {\n const strength = passwordStrength(asString(props.value));\n const meter = el(\"div\", { class: \"rui-password-input-strength\", \"data-score\": String(strength.score) });\n for (let i = 0; i < 4; i += 1) {\n meter.append(el(\"span\", {\n class: \"rui-password-input-strength-bar\",\n \"data-filled\": i < strength.score ? \"true\" : \"false\",\n }));\n }\n const labelRow = el(\"div\", { class: \"rui-password-input-strength-row\" });\n labelRow.append(meter);\n if (strength.label) labelRow.append(el(\"span\", { class: \"rui-password-input-strength-label\" }, [strength.label]));\n root.append(labelRow);\n }\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * TagInput\n * ----------------------------------------------------------------------- */\n\nexport const TagInput: ComponentSpec = {\n name: \"TagInput\",\n description:\n \"Tag/chip input — type a value, press Enter (or comma) to commit, \" +\n \"click × on a chip to remove. Pass a `$variable` (array of strings) \" +\n \"as `value` for two-way binding. Use for keywords, recipients, \" +\n \"labels, skills, allowlists.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"value\", type: \"string[]\", optional: true, description: \"Bound array of tag values\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"label\", type: \"string\", optional: true, description: \"Inline label above the field\" },\n { name: \"max\", type: \"number\", optional: true, description: \"Maximum number of tags\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const tags = asArray<unknown>(props.value).map((v) => asString(v)).filter(Boolean);\n const max = Math.max(0, Math.floor(asNumber(props.max, 0)));\n const disabled = asBoolean(props.disabled);\n const stateName = node.argMeta?.[1]?.stateRef;\n const setTags = (next: string[]) => {\n if (!stateName) return;\n helpers.setState(stateName, next);\n };\n const labelText = asString(props.label);\n const root = el(\"div\", {\n class: \"rui-tag-input\",\n \"data-disabled\": disabled ? \"true\" : \"false\",\n });\n for (const tag of tags) {\n const chip = el(\"span\", { class: \"rui-tag-input-chip\" });\n chip.append(el(\"span\", {}, [tag]));\n const remove = el(\"button\", {\n type: \"button\",\n class: \"rui-tag-input-remove\",\n \"aria-label\": `Remove ${tag}`,\n }, [\"×\"]);\n remove.onclick = () => setTags(tags.filter((t) => t !== tag));\n chip.append(remove);\n root.append(chip);\n }\n const input = el(\"input\", {\n type: \"text\",\n class: \"rui-tag-input-field\",\n id,\n name: id,\n placeholder: asString(props.placeholder, tags.length === 0 ? \"Add tags…\" : \"\"),\n disabled: disabled ? \"\" : null,\n autocomplete: \"off\",\n }) as HTMLInputElement;\n input.onkeydown = (event) => {\n const e = event as KeyboardEvent;\n // Read the value from the *live* input — morph keeps the previously\n // mounted DOM node, so the closure-captured `input` reference points\n // at the freshly rendered (detached) field and its `.value` is empty.\n const liveInput = e.currentTarget as HTMLInputElement;\n if (e.key === \"Enter\" || e.key === \",\") {\n e.preventDefault();\n const value = liveInput.value.trim();\n if (!value) return;\n if (max > 0 && tags.length >= max) return;\n if (tags.includes(value)) {\n liveInput.value = \"\";\n return;\n }\n setTags([...tags, value]);\n liveInput.value = \"\";\n } else if (e.key === \"Backspace\" && liveInput.value === \"\" && tags.length > 0) {\n e.preventDefault();\n setTags(tags.slice(0, -1));\n }\n };\n root.append(input);\n if (labelText) {\n const wrapper = el(\"div\", { class: \"rui-tag-input-wrapper\" });\n wrapper.append(el(\"label\", { class: \"rui-tag-input-label\", for: id }, [labelText]));\n wrapper.append(root);\n return wrapper;\n }\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * MentionInput\n * ----------------------------------------------------------------------- */\n\ninterface MentionItem {\n value: string;\n label: string;\n}\n\nfunction readMentionItems(raw: unknown): MentionItem[] {\n return asArray<unknown>(raw).map((entry) => {\n if (typeof entry === \"string\") return { value: entry, label: entry };\n if (entry && typeof entry === \"object\") {\n const r = entry as Record<string, unknown>;\n const value = asString(r.value ?? r.id ?? r.name);\n const label = asString(r.label, value);\n return { value, label };\n }\n return { value: \"\", label: \"\" };\n }).filter((i) => i.value);\n}\n\nexport const MentionInput: ComponentSpec = {\n name: \"MentionInput\",\n description:\n \"Multi-line input with inline @-mention suggestions. Typing `@` \" +\n \"opens a popover listing the provided `people` (filtered by what \" +\n \"follows). Selecting an option inserts `@label` into the text. Pass \" +\n \"a `$variable` as `value` for two-way binding. Use for comments, \" +\n \"task notes, chat composers.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"people\", type: \"any[]\", description: \"Available mentions: strings or {value, label} objects\" },\n { name: \"value\", type: \"string\", optional: true, description: \"Bound text (typically $variable)\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"rows\", type: \"number\", optional: true, description: \"TextArea rows (default 3)\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const people = readMentionItems(props.people);\n const disabled = asBoolean(props.disabled);\n const root = el(\"div\", { class: \"rui-mention-input\", \"data-disabled\": disabled ? \"true\" : \"false\" });\n const textarea = el(\"textarea\", {\n class: \"rui-mention-input-field\",\n id,\n name: id,\n rows: String(Math.max(2, Math.floor(asNumber(props.rows, 3)))),\n placeholder: asString(props.placeholder, \"Type @ to mention someone\"),\n disabled: disabled ? \"\" : null,\n }) as HTMLTextAreaElement;\n textarea.value = asString(props.value);\n const stateName = node.argMeta?.[2]?.stateRef;\n if (stateName) {\n helpers.bindState(textarea, stateName, {\n event: \"input\",\n getValue: (n) => (n as HTMLTextAreaElement).value,\n });\n }\n const suggestions = el(\"div\", { class: \"rui-mention-input-suggestions\", \"data-open\": \"false\" });\n const renderSuggestions = (query: string) => {\n suggestions.replaceChildren();\n const filtered = people.filter((p) => p.label.toLowerCase().includes(query.toLowerCase()));\n const slice = filtered.slice(0, 6);\n if (slice.length === 0) {\n suggestions.setAttribute(\"data-open\", \"false\");\n return;\n }\n suggestions.setAttribute(\"data-open\", \"true\");\n for (const item of slice) {\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-mention-input-option\",\n \"data-value\": item.value,\n }, [item.label]);\n btn.onmousedown = (event) => event.preventDefault();\n btn.onclick = () => {\n insertMention(item);\n suggestions.setAttribute(\"data-open\", \"false\");\n };\n suggestions.append(btn);\n }\n };\n const insertMention = (item: MentionItem) => {\n const text = textarea.value;\n const caret = textarea.selectionStart;\n const before = text.slice(0, caret);\n const triggerIdx = before.lastIndexOf(\"@\");\n if (triggerIdx === -1) return;\n const after = text.slice(caret);\n const insert = `@${item.label} `;\n const next = before.slice(0, triggerIdx) + insert + after;\n textarea.value = next;\n const cursor = triggerIdx + insert.length;\n textarea.selectionStart = textarea.selectionEnd = cursor;\n textarea.dispatchEvent(new Event(\"input\", { bubbles: true }));\n textarea.focus();\n };\n textarea.oninput = () => {\n const caret = textarea.selectionStart;\n const before = textarea.value.slice(0, caret);\n const match = /@([\\w-]*)$/.exec(before);\n if (match) renderSuggestions(match[1] ?? \"\");\n else suggestions.setAttribute(\"data-open\", \"false\");\n };\n textarea.onblur = () => setTimeout(() => suggestions.setAttribute(\"data-open\", \"false\"), 80);\n root.append(textarea);\n root.append(suggestions);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * TimePicker / DateTimePicker / MaskedInput\n * ----------------------------------------------------------------------- */\n\nexport const TimePicker: ComponentSpec = {\n name: \"TimePicker\",\n description:\n \"Time-of-day picker that wraps `<input type=\\\"time\\\">`. Pass a \" +\n \"`$variable` as `value` for two-way binding (HH:MM 24-hour). Set \" +\n \"`step` to constrain to specific increments (e.g. 900 for 15-minute \" +\n \"buckets).\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"value\", type: \"string\", optional: true, description: \"HH:MM value; typically $variable\" },\n { name: \"label\", type: \"string\", optional: true },\n { name: \"min\", type: \"string\", optional: true },\n { name: \"max\", type: \"string\", optional: true },\n { name: \"step\", type: \"number\", optional: true, description: \"Seconds between selectable times\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const root = el(\"div\", { class: \"rui-time-picker\" });\n const label = asString(props.label);\n if (label) root.append(el(\"label\", { class: \"rui-time-picker-label\", for: id }, [label]));\n const input = el(\"input\", {\n type: \"time\",\n class: \"rui-time-picker-input\",\n id,\n name: id,\n value: asString(props.value),\n min: asString(props.min) || null,\n max: asString(props.max) || null,\n step: props.step != null ? String(asNumber(props.step, 60)) : null,\n disabled: asBoolean(props.disabled) ? \"\" : null,\n });\n const stateName = node.argMeta?.[1]?.stateRef;\n if (stateName) helpers.bindState(input, stateName);\n root.append(input);\n return root;\n },\n};\n\nexport const DateTimePicker: ComponentSpec = {\n name: \"DateTimePicker\",\n description:\n \"Combined date + time picker — wraps `<input \" +\n \"type=\\\"datetime-local\\\">`. Pass a `$variable` as `value` for two-way \" +\n \"binding (ISO `YYYY-MM-DDTHH:MM`).\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"value\", type: \"string\", optional: true, description: \"ISO date-time value; typically $variable\" },\n { name: \"label\", type: \"string\", optional: true },\n { name: \"min\", type: \"string\", optional: true },\n { name: \"max\", type: \"string\", optional: true },\n { name: \"step\", type: \"number\", optional: true, description: \"Seconds between selectable times\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const root = el(\"div\", { class: \"rui-datetime-picker\" });\n const label = asString(props.label);\n if (label) root.append(el(\"label\", { class: \"rui-datetime-picker-label\", for: id }, [label]));\n const input = el(\"input\", {\n type: \"datetime-local\",\n class: \"rui-datetime-picker-input\",\n id,\n name: id,\n value: asString(props.value),\n min: asString(props.min) || null,\n max: asString(props.max) || null,\n step: props.step != null ? String(asNumber(props.step, 60)) : null,\n disabled: asBoolean(props.disabled) ? \"\" : null,\n });\n const stateName = node.argMeta?.[1]?.stateRef;\n if (stateName) helpers.bindState(input, stateName);\n root.append(input);\n return root;\n },\n};\n\nfunction applyMask(value: string, mask: string): string {\n let out = \"\";\n let v = value;\n for (const ch of mask) {\n if (!v) break;\n if (ch === \"9\") {\n const m = /\\d/.exec(v);\n if (!m) break;\n out += m[0];\n v = v.slice(v.indexOf(m[0]) + 1);\n } else if (ch === \"A\") {\n const m = /[a-zA-Z]/.exec(v);\n if (!m) break;\n out += m[0];\n v = v.slice(v.indexOf(m[0]) + 1);\n } else if (ch === \"*\") {\n out += v.charAt(0);\n v = v.slice(1);\n } else {\n out += ch;\n if (v.startsWith(ch)) v = v.slice(1);\n }\n }\n return out;\n}\n\nexport const MaskedInput: ComponentSpec = {\n name: \"MaskedInput\",\n description:\n \"Text input with an inline mask — `9` matches a digit, `A` matches a \" +\n \"letter, `*` matches any character, every other character is a \" +\n \"fixed delimiter. Useful for phone numbers, postal codes, credit \" +\n \"cards. Pass `mask` (e.g. `\\\"(999) 999-9999\\\"`) and a `$variable` \" +\n \"as `value`.\",\n props: [\n { name: \"id\", type: \"string\" },\n { name: \"mask\", type: \"string\", description: \"Mask pattern\" },\n { name: \"value\", type: \"string\", optional: true, description: \"Bound value (typically $variable)\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"label\", type: \"string\", optional: true, description: \"Inline label above the field\" },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (node, props, helpers) => {\n const id = asString(props.id);\n const mask = asString(props.mask);\n const disabled = asBoolean(props.disabled);\n const initial = applyMask(asString(props.value), mask);\n const labelText = asString(props.label);\n const input = el(\"input\", {\n type: \"text\",\n class: \"rui-masked-input\",\n id,\n name: id,\n value: initial,\n placeholder: asString(props.placeholder, mask),\n disabled: disabled ? \"\" : null,\n autocomplete: \"off\",\n }) as HTMLInputElement;\n const stateName = node.argMeta?.[2]?.stateRef;\n input.oninput = () => {\n input.value = applyMask(input.value, mask);\n };\n if (stateName) {\n helpers.bindState(input, stateName, {\n event: \"input\",\n getValue: (n) => (n as HTMLInputElement).value,\n });\n }\n if (labelText) {\n const wrapper = el(\"div\", { class: \"rui-masked-input-wrapper\" });\n wrapper.append(el(\"label\", { class: \"rui-masked-input-label\", for: id }, [labelText]));\n wrapper.append(input);\n return wrapper;\n }\n return input;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * FormSection / FieldSet / ValidationSummary\n * ----------------------------------------------------------------------- */\n\nexport const FormSection: ComponentSpec = {\n name: \"FormSection\",\n description:\n \"Semantic grouping for related form fields — renders a small heading \" +\n \"(`label`), optional helper paragraph, and stacks the children with \" +\n \"consistent spacing. Use INSTEAD of wrapping fields in `Card` + \" +\n \"`SectionHeader` by hand. Pair with `FieldSet` when the group is a \" +\n \"true `<fieldset>` (radio sets, checkbox groups).\",\n props: [\n { name: \"label\", type: \"string\", aliases: [\"title\"] },\n { name: \"children\", type: \"Node[]\", aliases: [\"fields\"] },\n { name: \"helper\", type: \"string\", optional: true, aliases: [\"description\"], description: \"Description rendered below the label\" },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"section\", { class: \"rui-form-section\" });\n const header = el(\"header\", { class: \"rui-form-section-header\" });\n header.append(el(\"h3\", { class: \"rui-form-section-label\" }, [asString(props.label)]));\n const helper = asString(props.helper);\n if (helper) header.append(el(\"p\", { class: \"rui-form-section-helper\" }, [helper]));\n root.append(header);\n const body = el(\"div\", { class: \"rui-form-section-body\" });\n for (const child of asArray(props.children)) body.append(helpers.renderNode(child));\n root.append(body);\n return root;\n },\n};\n\nexport const FieldSet: ComponentSpec = {\n name: \"FieldSet\",\n description:\n \"Native `<fieldset>`/`<legend>` wrapper for accessible grouping of \" +\n \"related controls. Use when assistive tech should announce the \" +\n \"wrapper (radio sets, checkbox groups). For purely visual grouping \" +\n \"prefer `FormSection`.\",\n props: [\n { name: \"legend\", type: \"string\", aliases: [\"title\", \"label\"] },\n { name: \"children\", type: \"Node[]\", aliases: [\"fields\"] },\n { name: \"helper\", type: \"string\", optional: true, aliases: [\"hint\", \"description\"] },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"fieldset\", {\n class: \"rui-fieldset\",\n disabled: asBoolean(props.disabled) ? \"\" : null,\n });\n root.append(el(\"legend\", { class: \"rui-fieldset-legend\" }, [asString(props.legend)]));\n const helper = asString(props.helper);\n if (helper) root.append(el(\"p\", { class: \"rui-fieldset-helper\" }, [helper]));\n for (const child of asArray(props.children)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nexport const ValidationSummary: ComponentSpec = {\n name: \"ValidationSummary\",\n description:\n \"Aggregate error list rendered at the top of a form. Pass `errors` \" +\n \"as `{label?, message, field?}` objects or plain strings. Pair with \" +\n \"individual field hints via `FormControl(hint=...)`.\",\n props: [\n { name: \"errors\", type: \"any[]\" },\n { name: \"title\", type: \"string\", optional: true, description: \"Heading (default \\\"Please fix the following:\\\")\" },\n { name: \"tone\", type: \"string\", optional: true, enum: [\"danger\", \"warning\"] },\n ],\n render: (_node, props) => {\n const errors = asArray<unknown>(props.errors)\n .map((entry) => {\n if (!entry) return null;\n if (typeof entry === \"string\") return { label: \"\", message: entry, field: \"\" };\n if (typeof entry === \"object\") {\n const r = entry as Record<string, unknown>;\n return {\n label: asString(r.label),\n message: asString(r.message ?? r.error),\n field: asString(r.field),\n };\n }\n return null;\n })\n .filter((e): e is { label: string; message: string; field: string } => e !== null && e.message !== \"\");\n if (errors.length === 0) {\n return el(\"div\", { class: \"rui-validation-summary\", \"data-empty\": \"true\", hidden: \"\" });\n }\n const tone = asString(props.tone, \"danger\");\n const root = el(\"aside\", {\n class: \"rui-validation-summary\",\n \"data-tone\": tone,\n role: \"alert\",\n });\n const titleNode = el(\"div\", { class: \"rui-validation-summary-title\" });\n const iconNode = renderIcon(tone === \"warning\" ? \"triangle-exclamation\" : \"circle-xmark\", { className: \"rui-validation-summary-icon\" });\n if (iconNode) titleNode.append(iconNode);\n titleNode.append(document.createTextNode(asString(props.title, \"Please fix the following:\")));\n root.append(titleNode);\n const list = el(\"ul\", { class: \"rui-validation-summary-list\" });\n for (const err of errors) {\n const li = el(\"li\", { class: \"rui-validation-summary-item\" });\n if (err.label) li.append(el(\"strong\", {}, [`${err.label}: `]));\n li.append(document.createTextNode(err.message));\n list.append(li);\n }\n root.append(list);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * MultiStepForm\n * ----------------------------------------------------------------------- */\n\ninterface MultiStepFormStep {\n title: string;\n details: string;\n content: unknown;\n}\n\nfunction readSteps(raw: unknown): MultiStepFormStep[] {\n return asArray<unknown>(raw).map((entry) => {\n if (!entry || typeof entry !== \"object\") {\n return { title: asString(entry), details: \"\", content: null };\n }\n const r = entry as Record<string, unknown>;\n return {\n title: asString(r.title),\n details: asString(r.details),\n content: r.content ?? null,\n };\n });\n}\n\nexport const MultiStepForm: ComponentSpec = {\n name: \"MultiStepForm\",\n description:\n \"Multi-step / wizard form composite. Renders a `Steps` indicator, \" +\n \"the active step's `content`, and Prev/Next buttons that drive a \" +\n \"`$variable` for the current 0-indexed step. Use INSTEAD of \" +\n \"hand-rolling `Steps` + content + manual prev/next wiring. The \" +\n \"submit button is rendered on the final step (override via \" +\n \"`submitLabel`).\",\n props: [\n { name: \"steps\", type: \"object[]\", description: \"Array of {title, details?, content} step objects\" },\n { name: \"current\", type: \"number\", description: \"0-indexed active step — bind a $variable\" },\n { name: \"onSubmit\", type: \"callable\", optional: true, description: \"Callable fired when the user clicks Submit on the final step\" },\n { name: \"prevLabel\", type: \"string\", optional: true, description: \"Default \\\"Back\\\"\" },\n { name: \"nextLabel\", type: \"string\", optional: true, description: \"Default \\\"Continue\\\"\" },\n { name: \"submitLabel\", type: \"string\", optional: true, description: \"Default \\\"Submit\\\" (final step)\" },\n ],\n render: (node, props, helpers) => {\n const steps = readSteps(props.steps);\n const total = steps.length;\n const current = Math.max(0, Math.min(total - 1, Math.floor(asNumber(props.current, 0))));\n const stateName = node.argMeta?.[1]?.stateRef;\n const root = el(\"div\", { class: \"rui-multi-step-form\" });\n const stepsEl = el(\"ol\", { class: \"rui-steps rui-multi-step-form-steps\" });\n steps.forEach((step, idx) => {\n const li = el(\"li\", {\n class: \"rui-steps-item\",\n \"data-active\": idx === current ? \"true\" : \"false\",\n \"data-complete\": idx < current ? \"true\" : \"false\",\n });\n li.append(el(\"div\", { class: \"rui-steps-title\" }, [step.title || `Step ${idx + 1}`]));\n if (step.details) li.append(el(\"div\", { class: \"rui-steps-details\" }, [step.details]));\n stepsEl.append(li);\n });\n root.append(stepsEl);\n const body = el(\"div\", { class: \"rui-multi-step-form-body\" });\n const active = steps[current];\n if (active && active.content) {\n body.append(helpers.renderNode(active.content));\n }\n root.append(body);\n const footer = el(\"div\", { class: \"rui-multi-step-form-footer\" });\n const prevBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-button\",\n \"data-variant\": \"ghost\",\n disabled: current <= 0 ? \"\" : null,\n }, [asString(props.prevLabel, \"Back\")]);\n if (stateName && current > 0) {\n prevBtn.onclick = () => helpers.setState(stateName, current - 1);\n }\n const isFinal = current >= total - 1;\n const nextLabel = isFinal ? asString(props.submitLabel, \"Submit\") : asString(props.nextLabel, \"Continue\");\n const nextBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-button\",\n \"data-variant\": \"primary\",\n }, [nextLabel]);\n nextBtn.onclick = () => {\n if (isFinal) {\n helpers.invoke(props.onSubmit);\n } else if (stateName) {\n helpers.setState(stateName, current + 1);\n }\n };\n footer.append(prevBtn);\n footer.append(el(\"span\", { class: \"rui-multi-step-form-progress\" }, [`${current + 1} / ${total}`]));\n footer.append(nextBtn);\n root.append(footer);\n return root;\n },\n};\n","/**\n * Advanced pattern composites that round out the catalogue:\n *\n * - InboxPanel — Grouped notification card list (read / unread).\n * - OnboardingChecklist — Step-by-step product checklist.\n * - LoadingState / ErrorState / SuccessState — Full-card status panels.\n * - Tour / Spotlight — Light-weight product-tour primitives.\n * - Sticky / Affix — Pin a child to the top while scrolling.\n * - ResizablePanels — Two-pane drag-to-resize split.\n * - MasonryGrid — Pinterest-style column grid.\n * - TopBar — Convenience composite.\n * - Drawer — Side-panel overlay (detail views, filters, previews).\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport {\n el, asArray, asString, asBoolean, asNumber, renderIcon,\n sanitiseCssLength,\n} from \"../utils.js\";\nimport { Notification } from \"./patterns.js\";\n\n/* ----------------------------------------------------------------------- *\n * InboxPanel\n * ----------------------------------------------------------------------- */\n\ninterface InboxEntry {\n title: string;\n message: string;\n time: string;\n icon: string;\n tone: string;\n unread: boolean;\n avatarSrc: string;\n action: unknown;\n}\n\nfunction readInboxEntries(raw: unknown): InboxEntry[] {\n return asArray<unknown>(raw)\n .map((entry) => {\n if (!entry || typeof entry !== \"object\") return null;\n const r = entry as Record<string, unknown>;\n return {\n title: asString(r.title),\n message: asString(r.message),\n time: asString(r.time),\n icon: asString(r.icon),\n tone: asString(r.tone, \"default\"),\n unread: asBoolean(r.unread),\n avatarSrc: asString(r.avatarSrc),\n action: r.action,\n };\n })\n .filter((e): e is InboxEntry => e !== null);\n}\n\nexport const InboxPanel: ComponentSpec = {\n name: \"InboxPanel\",\n description:\n \"Grouped notification list — entries are grouped into Unread/Earlier \" +\n \"sections, with a count chip on each group header. Pass `items` as \" +\n \"`{title, message, time, icon?, tone?, unread?, avatarSrc?, action?}` \" +\n \"objects. Pair with a `SectionHeader` for the panel title (the \" +\n \"component does not render its own title to avoid duplication). Use \" +\n \"for top-bar notification trays, activity drawers, and alert center \" +\n \"pages.\",\n props: [\n { name: \"items\", type: \"object[]\" },\n { name: \"emptyLabel\", type: \"string\", optional: true, description: \"Text shown when there are no notifications\" },\n { name: \"onMarkAllRead\", type: \"callable\", optional: true, description: \"Callable fired by the \\\"Mark all as read\\\" button\" },\n ],\n render: (_node, props, helpers) => {\n const entries = readInboxEntries(props.items);\n const unread = entries.filter((e) => e.unread);\n const read = entries.filter((e) => !e.unread);\n const root = el(\"div\", { class: \"rui-inbox-panel\" });\n if (typeof props.onMarkAllRead === \"function\" && unread.length > 0) {\n const toolbar = el(\"div\", { class: \"rui-inbox-panel-toolbar\" });\n const btn = el(\"button\", { type: \"button\", class: \"rui-inbox-panel-mark-all\" }, [\"Mark all as read\"]);\n btn.onclick = () => helpers.invoke(props.onMarkAllRead);\n toolbar.append(btn);\n root.append(toolbar);\n }\n if (entries.length === 0) {\n root.append(el(\"div\", { class: \"rui-inbox-panel-empty\" }, [asString(props.emptyLabel, \"You're all caught up.\")]));\n return root;\n }\n const renderGroup = (label: string, items: InboxEntry[]) => {\n if (items.length === 0) return;\n const group = el(\"section\", { class: \"rui-inbox-panel-group\" });\n const groupHead = el(\"header\", { class: \"rui-inbox-panel-group-head\" });\n groupHead.append(el(\"span\", { class: \"rui-inbox-panel-group-label\" }, [label]));\n groupHead.append(el(\"span\", { class: \"rui-inbox-panel-group-count\" }, [String(items.length)]));\n group.append(groupHead);\n for (const entry of items) {\n const card = Notification.render(\n { __kind: \"Component\", name: \"Notification\", args: [], argMeta: [] },\n {\n title: entry.title,\n message: entry.message,\n time: entry.time,\n icon: entry.icon,\n tone: entry.tone,\n avatarSrc: entry.avatarSrc,\n unread: entry.unread,\n },\n helpers,\n ) as HTMLElement;\n if (typeof entry.action === \"function\") {\n card.setAttribute(\"data-clickable\", \"true\");\n card.onclick = () => helpers.invoke(entry.action);\n }\n group.append(card);\n }\n root.append(group);\n };\n renderGroup(`Unread (${unread.length})`, unread);\n renderGroup(\"Earlier\", read);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * OnboardingChecklist\n * ----------------------------------------------------------------------- */\n\ninterface ChecklistItem {\n title: string;\n description: string;\n done: boolean;\n action: unknown;\n cta: string;\n}\n\nfunction readChecklistItems(raw: unknown): ChecklistItem[] {\n return asArray<unknown>(raw)\n .map((entry) => {\n if (!entry || typeof entry !== \"object\") return null;\n const r = entry as Record<string, unknown>;\n return {\n title: asString(r.title),\n description: asString(r.description),\n done: asBoolean(r.done),\n action: r.action,\n cta: asString(r.cta, \"Start\"),\n };\n })\n .filter((c): c is ChecklistItem => c !== null);\n}\n\nexport const OnboardingChecklist: ComponentSpec = {\n name: \"OnboardingChecklist\",\n description:\n \"Step-by-step product checklist with completion progress at the top. \" +\n \"Pass `items` as `{title, description?, done?, action?, cta?}` \" +\n \"objects. The progress percentage is computed automatically from \" +\n \"`done`. Use on first-run dashboards, empty workspaces, and \" +\n \"\\\"complete your profile\\\" surfaces.\",\n props: [\n { name: \"items\", type: \"object[]\" },\n { name: \"title\", type: \"string\", optional: true, description: \"Heading (default \\\"Getting started\\\")\" },\n { name: \"subtitle\", type: \"string\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const items = readChecklistItems(props.items);\n const completed = items.filter((i) => i.done).length;\n const total = Math.max(1, items.length);\n const pct = Math.round((completed / total) * 100);\n const root = el(\"div\", { class: \"rui-onboarding-checklist\" });\n const head = el(\"header\", { class: \"rui-onboarding-checklist-header\" });\n head.append(el(\"h3\", { class: \"rui-onboarding-checklist-title\" }, [\n asString(props.title, \"Getting started\"),\n ]));\n const subtitle = asString(props.subtitle);\n if (subtitle) head.append(el(\"p\", { class: \"rui-onboarding-checklist-subtitle\" }, [subtitle]));\n head.append(el(\"div\", { class: \"rui-onboarding-checklist-progress\" }, [\n el(\"div\", { class: \"rui-onboarding-checklist-bar\" }, [\n el(\"div\", {\n class: \"rui-onboarding-checklist-fill\",\n style: `width:${pct}%`,\n }),\n ]),\n el(\"span\", { class: \"rui-onboarding-checklist-meta\" }, [`${completed}/${items.length} complete`]),\n ]));\n root.append(head);\n const list = el(\"ol\", { class: \"rui-onboarding-checklist-list\" });\n for (const item of items) {\n const li = el(\"li\", {\n class: \"rui-onboarding-checklist-item\",\n \"data-done\": item.done ? \"true\" : \"false\",\n });\n const marker = el(\"span\", { class: \"rui-onboarding-checklist-marker\" });\n const iconNode = renderIcon(item.done ? \"circle-check\" : \"circle\", { className: \"rui-onboarding-checklist-marker-icon\" });\n if (iconNode) marker.append(iconNode);\n li.append(marker);\n const body = el(\"div\", { class: \"rui-onboarding-checklist-body\" });\n body.append(el(\"div\", { class: \"rui-onboarding-checklist-item-title\" }, [item.title]));\n if (item.description) body.append(el(\"p\", { class: \"rui-onboarding-checklist-item-description\" }, [item.description]));\n li.append(body);\n if (!item.done && typeof item.action === \"function\") {\n const btn = el(\"button\", {\n type: \"button\",\n class: \"rui-button\",\n \"data-variant\": \"secondary\",\n \"data-size\": \"sm\",\n }, [item.cta]);\n btn.onclick = () => helpers.invoke(item.action);\n li.append(btn);\n }\n list.append(li);\n }\n root.append(list);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * LoadingState / ErrorState / SuccessState\n * ----------------------------------------------------------------------- */\n\nfunction renderStateCard(opts: {\n klass: string;\n iconName: string;\n iconClass: string;\n title: string;\n description: string;\n actions: unknown;\n helpers: { renderNode: (n: unknown) => Node };\n}): HTMLElement {\n const root = el(\"div\", { class: `rui-${opts.klass}` });\n if (opts.iconName) {\n const icon = renderIcon(opts.iconName, { className: opts.iconClass });\n if (icon) root.append(icon);\n }\n if (opts.title) root.append(el(\"h3\", { class: `rui-${opts.klass}-title` }, [opts.title]));\n if (opts.description) root.append(el(\"p\", { class: `rui-${opts.klass}-description` }, [opts.description]));\n const items = asArray<unknown>(opts.actions);\n if (items.length > 0) {\n const row = el(\"div\", { class: `rui-${opts.klass}-actions` });\n for (const item of items) row.append(opts.helpers.renderNode(item));\n root.append(row);\n }\n return root;\n}\n\nexport const LoadingState: ComponentSpec = {\n name: \"LoadingState\",\n description:\n \"Full-card loading state — large spinner + title + description. Use \" +\n \"while a query is in flight or while a long-running tool runs. For \" +\n \"tiny inline loaders prefer `Spinner`; for skeleton placeholders \" +\n \"prefer `Skeleton`.\",\n props: [\n { name: \"title\", type: \"string\", optional: true, description: \"Default \\\"Loading…\\\"\" },\n { name: \"description\", type: \"string\", optional: true },\n ],\n render: (_node, props) => {\n const root = el(\"div\", { class: \"rui-loading-state\" });\n const spinner = el(\"span\", { class: \"rui-spinner\", \"data-size\": \"lg\", \"data-tone\": \"primary\" });\n spinner.append(el(\"span\", { class: \"rui-spinner-ring\", \"aria-hidden\": \"true\" }));\n root.append(spinner);\n root.append(el(\"h3\", { class: \"rui-loading-state-title\" }, [asString(props.title, \"Loading…\")]));\n const description = asString(props.description);\n if (description) root.append(el(\"p\", { class: \"rui-loading-state-description\" }, [description]));\n return root;\n },\n};\n\nexport const ErrorState: ComponentSpec = {\n name: \"ErrorState\",\n description:\n \"Full-card error placeholder. Pairs a danger icon with title, \" +\n \"description, and a row of recovery actions (Retry / Contact \" +\n \"support / Go home). Pass `actions` as Button(...) entries.\",\n props: [\n { name: \"title\", type: \"string\", optional: true, description: \"Default \\\"Something went wrong\\\"\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"actions\", type: \"Node[]\", optional: true },\n { name: \"icon\", type: \"string\", optional: true, description: \"Font Awesome icon (default `circle-exclamation`)\" },\n ],\n render: (_node, props, helpers) => renderStateCard({\n klass: \"error-state\",\n iconName: asString(props.icon, \"circle-exclamation\"),\n iconClass: \"rui-error-state-icon\",\n title: asString(props.title, \"Something went wrong\"),\n description: asString(props.description),\n actions: props.actions,\n helpers,\n }),\n};\n\nexport const SuccessState: ComponentSpec = {\n name: \"SuccessState\",\n description:\n \"Full-card success placeholder. Use for confirmation screens \" +\n \"(\\\"Order placed\\\", \\\"Payment succeeded\\\", \\\"Account verified\\\") at \" +\n \"the end of a flow. Pass `actions` for follow-up CTAs.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"actions\", type: \"Node[]\", optional: true },\n { name: \"icon\", type: \"string\", optional: true, description: \"Default `circle-check`\" },\n ],\n render: (_node, props, helpers) => renderStateCard({\n klass: \"success-state\",\n iconName: asString(props.icon, \"circle-check\"),\n iconClass: \"rui-success-state-icon\",\n title: asString(props.title),\n description: asString(props.description),\n actions: props.actions,\n helpers,\n }),\n};\n\n/* ----------------------------------------------------------------------- *\n * Tour / Spotlight\n * ----------------------------------------------------------------------- */\n\ninterface TourStep {\n title: string;\n description: string;\n target: string;\n}\n\nexport const Tour: ComponentSpec = {\n name: \"Tour\",\n description:\n \"Product-tour controller — renders the current step's title, \" +\n \"description, and a Prev/Next/Skip row. Bind `current` to a \" +\n \"`$variable` (0-indexed). Pass `steps` as `{title, description, \" +\n \"target?}` objects; the optional `target` is a CSS selector that \" +\n \"renders alongside the step for designers to reference.\",\n props: [\n { name: \"steps\", type: \"object[]\" },\n { name: \"current\", type: \"number\", description: \"0-indexed active step — bind a $variable\" },\n { name: \"open\", type: \"boolean\", optional: true, description: \"Whether the tour is visible\" },\n { name: \"onComplete\", type: \"callable\", optional: true },\n ],\n render: (node, props, helpers) => {\n const steps: TourStep[] = asArray<unknown>(props.steps).map((entry) => {\n if (!entry || typeof entry !== \"object\") return { title: asString(entry), description: \"\", target: \"\" };\n const r = entry as Record<string, unknown>;\n return { title: asString(r.title), description: asString(r.description), target: asString(r.target) };\n });\n const isOpen = props.open === undefined ? true : asBoolean(props.open);\n const total = steps.length;\n const current = Math.max(0, Math.min(total - 1, Math.floor(asNumber(props.current, 0))));\n const stateName = node.argMeta?.[1]?.stateRef;\n const overlay = el(\"div\", { class: \"rui-tour\", \"data-open\": isOpen ? \"true\" : \"false\" });\n if (!isOpen || total === 0) return overlay;\n const step = steps[current];\n if (!step) return overlay;\n const card = el(\"div\", { class: \"rui-tour-card\", role: \"dialog\", \"aria-modal\": \"false\" });\n card.append(el(\"div\", { class: \"rui-tour-step\" }, [`Step ${current + 1} of ${total}`]));\n card.append(el(\"h3\", { class: \"rui-tour-title\" }, [step.title]));\n if (step.description) card.append(el(\"p\", { class: \"rui-tour-description\" }, [step.description]));\n if (step.target) card.append(el(\"div\", { class: \"rui-tour-target\" }, [`Target: ${step.target}`]));\n const footer = el(\"div\", { class: \"rui-tour-footer\" });\n const skip = el(\"button\", { type: \"button\", class: \"rui-button\", \"data-variant\": \"ghost\" }, [\"Skip\"]);\n skip.onclick = () => helpers.invoke(props.onComplete);\n const prev = el(\"button\", {\n type: \"button\",\n class: \"rui-button\",\n \"data-variant\": \"secondary\",\n disabled: current <= 0 ? \"\" : null,\n }, [\"Back\"]);\n if (stateName && current > 0) {\n prev.onclick = () => helpers.setState(stateName, current - 1);\n }\n const isLast = current >= total - 1;\n const next = el(\"button\", { type: \"button\", class: \"rui-button\", \"data-variant\": \"primary\" }, [isLast ? \"Finish\" : \"Next\"]);\n next.onclick = () => {\n if (isLast) {\n helpers.invoke(props.onComplete);\n } else if (stateName) {\n helpers.setState(stateName, current + 1);\n }\n };\n footer.append(skip, prev, next);\n card.append(footer);\n overlay.append(card);\n return overlay;\n },\n};\n\nexport const Spotlight: ComponentSpec = {\n name: \"Spotlight\",\n description:\n \"Single-step product highlight — a dimmed full-page overlay with a \" +\n \"ring around the focused area and a small explainer card. Use for \" +\n \"one-off feature reveals (\\\"Try the new commands menu\\\"). Bind \" +\n \"`open` to a `$variable` to dismiss.\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"open\", type: \"boolean\", optional: true, description: \"Whether the spotlight is visible — typically a $variable (default true)\" },\n { name: \"description\", type: \"string\", optional: true },\n { name: \"actions\", type: \"Node[]\", optional: true, aliases: [\"action\"] },\n ],\n render: (node, props, helpers) => {\n const isOpen = props.open === undefined ? true : asBoolean(props.open);\n const overlay = el(\"div\", { class: \"rui-spotlight\", \"data-open\": isOpen ? \"true\" : \"false\" });\n if (!isOpen) return overlay;\n const card = el(\"div\", { class: \"rui-spotlight-card\" });\n card.append(el(\"h3\", { class: \"rui-spotlight-title\" }, [asString(props.title)]));\n const description = asString(props.description);\n if (description) card.append(el(\"p\", { class: \"rui-spotlight-description\" }, [description]));\n const actions = asArray<unknown>(props.actions);\n if (actions.length > 0) {\n const row = el(\"div\", { class: \"rui-spotlight-actions\" });\n for (const item of actions) row.append(helpers.renderNode(item));\n card.append(row);\n }\n const stateName = node.argMeta?.[1]?.stateRef;\n if (stateName) {\n overlay.onclick = (event) => {\n if (event.target !== overlay) return;\n helpers.setState(stateName, false);\n };\n }\n overlay.append(card);\n return overlay;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * Sticky / ResizablePanels / MasonryGrid / Drawer / TopBar\n * ----------------------------------------------------------------------- */\n\nexport const Sticky: ComponentSpec = {\n name: \"Sticky\",\n description:\n \"Wraps content in a `position: sticky` container so it pins to the \" +\n \"top (or bottom) of the nearest scrollable ancestor. Use for \" +\n \"toolbar action rows above tables, in-page navs, status banners.\",\n props: [\n { name: \"children\", type: \"Node[]\" },\n { name: \"side\", type: \"string\", optional: true, enum: [\"top\", \"bottom\"] },\n { name: \"offset\", type: \"string\", optional: true, description: \"CSS offset (default 0)\" },\n { name: \"zIndex\", type: \"number\", optional: true, description: \"Z-index (default 10)\" },\n ],\n render: (_node, props, helpers) => {\n const side = asString(props.side, \"top\");\n const offset = sanitiseCssLength(props.offset, \"0\");\n const z = Math.max(0, Math.floor(asNumber(props.zIndex, 10)));\n const styles = `position:sticky;${side}:${offset};z-index:${z};`;\n const root = el(\"div\", { class: \"rui-sticky\", style: styles });\n for (const child of asArray(props.children)) root.append(helpers.renderNode(child));\n return root;\n },\n};\n\nexport const ResizablePanels: ComponentSpec = {\n name: \"ResizablePanels\",\n description:\n \"Two-pane horizontal split with a draggable divider. The user can \" +\n \"drag the divider to resize the primary pane; defaults respect the \" +\n \"starting width. Use for code editors, file browsers, master/detail \" +\n \"layouts that need user-controllable proportions.\",\n props: [\n { name: \"primary\", type: \"Node[]\" },\n { name: \"secondary\", type: \"Node[]\" },\n { name: \"initialPrimaryWidth\", type: \"string\", optional: true, description: \"CSS width for the primary pane (default 40%)\" },\n { name: \"minPrimaryWidth\", type: \"string\", optional: true, description: \"Min width (default 240px)\" },\n ],\n render: (_node, props, helpers) => {\n const initial = sanitiseCssLength(props.initialPrimaryWidth, \"40%\");\n const minWidth = sanitiseCssLength(props.minPrimaryWidth, \"240px\");\n const root = el(\"div\", {\n class: \"rui-resizable-panels\",\n style: `--rui-resizable-primary:${initial};--rui-resizable-min:${minWidth};`,\n });\n const primary = el(\"div\", { class: \"rui-resizable-panel rui-resizable-panel-primary\" });\n for (const child of asArray(props.primary)) primary.append(helpers.renderNode(child));\n const divider = el(\"div\", {\n class: \"rui-resizable-divider\",\n role: \"separator\",\n \"aria-orientation\": \"vertical\",\n tabindex: \"0\",\n });\n const secondary = el(\"div\", { class: \"rui-resizable-panel rui-resizable-panel-secondary\" });\n for (const child of asArray(props.secondary)) secondary.append(helpers.renderNode(child));\n root.append(primary, divider, secondary);\n\n divider.onpointerdown = (event) => {\n const e = event as PointerEvent;\n const target = e.currentTarget as HTMLElement;\n target.setPointerCapture(e.pointerId);\n const live = target.closest(\".rui-resizable-panels\") as HTMLElement | null;\n if (!live) return;\n const rect = live.getBoundingClientRect();\n const onMove = (moveEvent: PointerEvent) => {\n const ratio = ((moveEvent.clientX - rect.left) / rect.width) * 100;\n const clamped = Math.max(15, Math.min(85, ratio));\n live.style.setProperty(\"--rui-resizable-primary\", `${clamped}%`);\n };\n const onUp = (upEvent: PointerEvent) => {\n target.releasePointerCapture(upEvent.pointerId);\n target.removeEventListener(\"pointermove\", onMove);\n target.removeEventListener(\"pointerup\", onUp);\n };\n target.addEventListener(\"pointermove\", onMove);\n target.addEventListener(\"pointerup\", onUp);\n };\n\n return root;\n },\n};\n\nexport const MasonryGrid: ComponentSpec = {\n name: \"MasonryGrid\",\n description:\n \"Pinterest-style column grid. Children flow into columns that reflow \" +\n \"on viewport changes. Use for galleries, social-style feeds, and \" +\n \"mixed-height card walls. Prefer `Grid` when children should share \" +\n \"the same height per row.\",\n props: [\n { name: \"items\", type: \"Node[]\" },\n { name: \"columns\", type: \"number\", optional: true, description: \"Preferred column count (default 3)\" },\n { name: \"gap\", type: \"string\", optional: true, enum: [\"xs\", \"s\", \"m\", \"l\", \"xl\"] },\n ],\n render: (_node, props, helpers) => {\n const columns = Math.max(1, Math.min(6, Math.floor(asNumber(props.columns, 3))));\n const gap = asString(props.gap, \"m\");\n const root = el(\"div\", {\n class: \"rui-masonry-grid\",\n \"data-columns\": String(columns),\n \"data-gap\": gap,\n });\n for (const item of asArray(props.items)) root.append(helpers.renderNode(item));\n return root;\n },\n};\n\nexport const Drawer: ComponentSpec = {\n name: \"Drawer\",\n description:\n \"Side drawer overlay shown when `open` is true. Pass a `$variable` as \" +\n \"`open` to control it. Choose `side` for slide direction (default right).\",\n props: [\n { name: \"title\", type: \"string\" },\n { name: \"open\", type: \"boolean\", description: \"Open/closed state — usually a $variable\" },\n { name: \"children\", type: \"Node[]\" },\n { name: \"side\", type: \"string\", optional: true, enum: [\"right\", \"left\", \"top\", \"bottom\"] },\n { name: \"footer\", type: \"Node[]\", optional: true, description: \"Optional footer actions row\" },\n ],\n render: (node, props, helpers) => {\n const isOpen = asBoolean(props.open);\n const side = asString(props.side, \"right\");\n const overlay = el(\"div\", {\n class: \"rui-sheet-overlay\",\n \"data-open\": isOpen ? \"true\" : \"false\",\n \"data-side\": side,\n });\n const panel = el(\"aside\", {\n class: \"rui-sheet\",\n role: \"dialog\",\n \"aria-modal\": \"true\",\n \"data-side\": side,\n });\n const header = el(\"header\", { class: \"rui-sheet-header\" });\n header.append(el(\"h3\", { class: \"rui-sheet-title\" }, [asString(props.title)]));\n const closeBtn = el(\"button\", {\n type: \"button\",\n class: \"rui-sheet-close\",\n \"aria-label\": \"Close\",\n }, [\"×\"]);\n const stateName = node.argMeta?.[1]?.stateRef;\n if (stateName) {\n closeBtn.onclick = () => helpers.setState(stateName, false);\n overlay.onclick = (event) => {\n if (event.target === overlay) helpers.setState(stateName, false);\n };\n }\n header.append(closeBtn);\n panel.append(header);\n const body = el(\"div\", { class: \"rui-sheet-body\" });\n for (const child of asArray(props.children)) body.append(helpers.renderNode(child));\n panel.append(body);\n const footer = asArray<unknown>(props.footer);\n if (footer.length > 0) {\n const footerRow = el(\"footer\", { class: \"rui-sheet-footer\" });\n for (const child of footer) footerRow.append(helpers.renderNode(child));\n panel.append(footerRow);\n }\n overlay.append(panel);\n return overlay;\n },\n};\n\nexport const TopBar: ComponentSpec = {\n name: \"TopBar\",\n description:\n \"Compact header strip that pairs a title (or breadcrumb) with \" +\n \"search and action slots. Use INSTEAD of hand-rolling a \" +\n \"`Stack(direction=\\\"row\\\")` above a page. For full SaaS shells use \" +\n \"`Navbar` (links) or `AppShell` (sidebar + topbar + content).\",\n props: [\n { name: \"title\", type: \"string\", optional: true },\n { name: \"subtitle\", type: \"string\", optional: true },\n { name: \"left\", type: \"Node[]\", optional: true, aliases: [\"badges\"], description: \"Leading slot (breadcrumbs, brand, status, badges)\" },\n { name: \"center\", type: \"Node[]\", optional: true, aliases: [\"search\"], description: \"Centered slot (search bar, segmented control)\" },\n { name: \"right\", type: \"Node[]\", optional: true, aliases: [\"actions\"], description: \"Trailing slot (actions, avatar)\" },\n { name: \"sticky\", type: \"boolean\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const root = el(\"header\", {\n class: \"rui-topbar\",\n \"data-sticky\": asBoolean(props.sticky) ? \"true\" : \"false\",\n });\n const left = el(\"div\", { class: \"rui-topbar-side rui-topbar-left\" });\n const title = asString(props.title);\n if (title) {\n const titleBlock = el(\"div\", { class: \"rui-topbar-title-block\" });\n titleBlock.append(el(\"h2\", { class: \"rui-topbar-title\" }, [title]));\n const subtitle = asString(props.subtitle);\n if (subtitle) titleBlock.append(el(\"p\", { class: \"rui-topbar-subtitle\" }, [subtitle]));\n left.append(titleBlock);\n }\n for (const child of asArray(props.left)) left.append(helpers.renderNode(child));\n root.append(left);\n const center = asArray<unknown>(props.center);\n if (center.length > 0) {\n const centerWrap = el(\"div\", { class: \"rui-topbar-side rui-topbar-center\" });\n for (const child of center) centerWrap.append(helpers.renderNode(child));\n root.append(centerWrap);\n }\n const right = el(\"div\", { class: \"rui-topbar-side rui-topbar-right\" });\n for (const child of asArray(props.right)) right.append(helpers.renderNode(child));\n root.append(right);\n return root;\n },\n};\n\n","/**\n * In-script theming component.\n *\n * `Theme({...})` is a meta-construct: the evaluator intercepts the call and\n * emits a `ThemeNode` instead of a regular `ComponentNode`. The element picks\n * the value up between render cycles and applies the tokens as CSS custom\n * properties on the host. This file exists so the prompt generator,\n * playground autocomplete, and the language server all know the signature.\n *\n * Authors write:\n *\n * theme = Theme({\n * colorPrimary: \"#0969da\",\n * fontFamily: \"'Inter', system-ui, sans-serif\",\n * radiusButton: \"6px\",\n * })\n * root = Stack([...])\n */\n\nimport type { ComponentSpec } from \"../types.js\";\n\nexport const Theme: ComponentSpec = {\n name: \"Theme\",\n description:\n \"Apply a partial theme on top of the base theme. Pass an object of token → value pairs (colors, fonts, radii, spacing, button styling). Assigning the result to a top-level binding (conventionally `theme`) lets the runtime detect it and write the tokens to the host as CSS custom properties — the rest of the rendered UI picks them up instantly.\",\n props: [\n {\n name: \"tokens\",\n type: \"any\",\n description:\n \"Object literal of theme tokens. Keys must match `ThemeTokens` (e.g. colorPrimary, colorBg, fontFamily, fontFamilyHeading, fontSizeBase, radiusMd, radiusButton, borderWidth, shadowMd, buttonFontWeight, …). Unknown keys are ignored.\",\n },\n ],\n // Theme(...) never produces UI — the evaluator captures it and short-\n // circuits before reaching this render fn. The no-op renderer is here so\n // the spec satisfies `ComponentSpec` for prompt / catalog generation.\n render: () => document.createDocumentFragment(),\n};\n","/**\n * Routing-related library components.\n *\n * In Aktion 0.5 routing is expressed with the\n * `_router_({...})` call (see `src/runtime/router.ts` and the\n * `evaluateRouterCall` intercept in `runtime/evaluator.ts`). The legacy\n * `Routes(...)` outlet and `Route(...)` row components, and the\n * `$router = router { … }` block syntax, were removed in the 0.5\n * cleanup pass. The only routing-related component that still ships is\n * `NavLink`, which navigates via `helpers.router.navigate(to)`.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport { asBoolean, asString, el, renderIcon } from \"../utils.js\";\n\nexport const NavLink: ComponentSpec = {\n name: \"NavLink\",\n description:\n \"Anchor that navigates to a route on click and stays in sync with the URL hash. \" +\n \"Reflects `data-active=\\\"true\\\"` when the current path matches `to` (set `exact=true` \" +\n \"to require exact equality instead of prefix matching).\",\n props: [\n { name: \"label\", type: \"string\", description: \"Visible link text.\" },\n { name: \"to\", type: \"string\", description: \"Target route path, e.g. \\\"/about\\\".\" },\n {\n name: \"variant\",\n type: \"string\",\n optional: true,\n enum: [\"default\", \"primary\", \"ghost\", \"pill\"],\n description: \"Visual variant.\",\n },\n {\n name: \"exact\",\n type: \"boolean\",\n optional: true,\n description: \"Match the current path exactly (default: prefix match).\",\n },\n {\n name: \"icon\",\n type: \"string\",\n optional: true,\n description: \"Optional Font Awesome icon name shown before the label.\",\n },\n ],\n render: (_node, props, helpers) => {\n const label = asString(props.label, \"\");\n const to = asString(props.to, \"/\");\n const variant = asString(props.variant, \"default\");\n const exact = asBoolean(props.exact, false);\n const router = helpers.router;\n const currentPath = router.getPath();\n\n const isActive = (() => {\n if (!currentPath) return false;\n if (exact) return currentPath === to;\n if (to === \"/\") return currentPath === \"/\";\n if (currentPath === to) return true;\n return currentPath.startsWith(to + \"/\");\n })();\n\n const anchor = el(\"a\", {\n class: \"rui-nav-link\",\n \"data-variant\": variant,\n \"data-active\": isActive ? \"true\" : \"false\",\n href: \"#\" + (to.startsWith(\"/\") ? to : \"/\" + to),\n });\n\n const iconNode = renderIcon(props.icon, { className: \"rui-nav-link-icon\" });\n if (iconNode) anchor.append(iconNode);\n anchor.append(el(\"span\", { class: \"rui-nav-link-label\" }, [label]));\n\n anchor.onclick = (event) => {\n if (event.defaultPrevented) return;\n if (event.button !== 0) return;\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n event.preventDefault();\n router.navigate(to);\n };\n\n return anchor;\n },\n};\n","/**\n * Tier 1–3 components: IconButton, CommandPalette, FilterChips, FieldRepeater,\n * VirtualList, QueryBuilder, DiffViewer, JsonTree, Gantt, Truncate, InlineEdit,\n * NotificationBell.\n */\n\nimport type { ComponentSpec } from \"../types.js\";\nimport {\n el, asArray, asString, asBoolean, asNumber, renderIcon,\n} from \"../utils.js\";\nimport { installDismissListeners, disposeDismissListeners } from \"./_internal.js\";\n\nconst BUTTON_VARIANTS = [\"primary\", \"secondary\", \"ghost\", \"danger\"] as const;\nconst BUTTON_SIZES = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"small\", \"normal\", \"large\"] as const;\n\nfunction normaliseButtonSize(value: unknown): string {\n const v = asString(value).trim().toLowerCase();\n if (v === \"xs\" || v === \"extra-small\") return \"xs\";\n if (v === \"small\" || v === \"sm\") return \"sm\";\n if (v === \"large\" || v === \"lg\") return \"lg\";\n if (v === \"xl\" || v === \"extra-large\") return \"xl\";\n if (v === \"normal\" || v === \"md\" || v === \"\") return \"md\";\n if (v === \"xs\" || v === \"sm\" || v === \"md\" || v === \"lg\" || v === \"xl\") return v;\n return \"md\";\n}\n\nfunction readChipList(raw: unknown): Array<{ label: string; value: string }> {\n return asArray<unknown>(raw).map((entry) => {\n if (entry && typeof entry === \"object\") {\n const obj = entry as { label?: unknown; value?: unknown };\n const value = asString(obj.value ?? obj.label);\n return { value, label: asString(obj.label, value) };\n }\n const value = asString(entry);\n return { value, label: value };\n }).filter((c) => c.label !== \"\");\n}\n\nfunction readPlainObjects(raw: unknown): Record<string, unknown>[] {\n return asArray<unknown>(raw).filter(\n (e): e is Record<string, unknown> => !!e && typeof e === \"object\" && !Array.isArray(e),\n ) as Record<string, unknown>[];\n}\n\ntype CommandItem = { label: string; value: string; group?: string; shortcut?: string; action?: unknown };\n\nfunction readCommandItems(raw: unknown): CommandItem[] {\n return asArray<unknown>(raw).map((entry) => {\n if (entry && typeof entry === \"object\") {\n const obj = entry as CommandItem;\n const value = asString(obj.value ?? obj.label);\n return {\n value,\n label: asString(obj.label, value),\n group: asString(obj.group) || undefined,\n shortcut: asString(obj.shortcut) || undefined,\n action: obj.action,\n };\n }\n const value = asString(entry);\n return { value, label: value };\n }).filter((i) => i.label !== \"\");\n}\n\nfunction readFields(raw: unknown): Array<{ name: string; label: string; type?: string }> {\n return asArray<unknown>(raw).map((entry) => {\n if (entry && typeof entry === \"object\") {\n const obj = entry as { name?: unknown; label?: unknown; type?: unknown };\n const name = asString(obj.name ?? obj.label);\n return { name, label: asString(obj.label, name), type: asString(obj.type, \"text\") || \"text\" };\n }\n const name = asString(entry);\n return { name, label: name, type: \"text\" };\n }).filter((f) => f.name !== \"\");\n}\n\nfunction readGanttTasks(raw: unknown): Array<{\n id: string; label: string; start: string; end: string; progress?: number;\n}> {\n return readPlainObjects(raw).map((t, i) => ({\n id: asString(t.id, `task-${i}`),\n label: asString(t.label ?? t.name, `Task ${i + 1}`),\n start: asString(t.start),\n end: asString(t.end),\n progress: t.progress != null ? asNumber(t.progress, 0) : undefined,\n }));\n}\n\nfunction parseIsoDate(value: string): number {\n const t = Date.parse(value);\n return Number.isNaN(t) ? Date.now() : t;\n}\n\nfunction diffLines(left: string, right: string): Array<{ type: \"same\" | \"add\" | \"remove\"; text: string }> {\n const a = left.split(\"\\n\");\n const b = right.split(\"\\n\");\n const max = Math.max(a.length, b.length);\n const out: Array<{ type: \"same\" | \"add\" | \"remove\"; text: string }> = [];\n for (let i = 0; i < max; i++) {\n const la = a[i];\n const lb = b[i];\n if (la === lb) {\n if (la !== undefined) out.push({ type: \"same\", text: la });\n } else {\n if (la !== undefined) out.push({ type: \"remove\", text: la });\n if (lb !== undefined) out.push({ type: \"add\", text: lb });\n }\n }\n return out;\n}\n\nfunction jsonPreview(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\nfunction appendJsonChildren(\n container: HTMLElement,\n entries: ReadonlyArray<readonly [string, unknown]>,\n expanded: boolean,\n depth: number,\n): void {\n for (const [key, val] of entries) {\n const row = el(\"div\", { class: \"rui-json-tree-row\" });\n row.append(el(\"span\", { class: \"rui-json-tree-key\" }, [`${key}: `]));\n if (val !== null && typeof val === \"object\") {\n row.append(buildJsonTree(val, expanded, depth + 1));\n } else {\n row.append(el(\"span\", { class: \"rui-json-tree-leaf\" }, [jsonPreview(val)]));\n }\n container.append(row);\n }\n}\n\nfunction buildJsonTree(data: unknown, expanded: boolean, depth = 0): HTMLElement {\n const root = el(\"div\", { class: \"rui-json-tree-node\", \"data-depth\": String(depth) });\n if (data === null || typeof data !== \"object\") {\n root.append(el(\"span\", { class: \"rui-json-tree-leaf\" }, [jsonPreview(data)]));\n return root;\n }\n const isArray = Array.isArray(data);\n const entries = isArray\n ? (data as unknown[]).map((v, i) => [String(i), v] as const)\n : (Object.entries(data as Record<string, unknown>) as ReadonlyArray<readonly [string, unknown]>);\n const open = expanded || depth < 1;\n const toggle = el(\"button\", {\n type: \"button\",\n class: \"rui-json-tree-toggle\",\n \"aria-expanded\": open ? \"true\" : \"false\",\n }, [open ? \"▼\" : \"▶\", isArray ? ` Array(${entries.length})` : ` Object`]);\n const children = el(\"div\", { class: \"rui-json-tree-children\", \"data-open\": open ? \"true\" : \"false\" });\n if (open) appendJsonChildren(children, entries, expanded, depth);\n toggle.onclick = (event) => {\n // Walk to the live siblings — morph copies this handler onto the kept\n // toggle but the closure's `toggle`/`children` are detached.\n const liveToggle = event.currentTarget as HTMLElement;\n const liveChildren = liveToggle.nextElementSibling as HTMLElement | null;\n if (!liveChildren) return;\n const next = liveChildren.getAttribute(\"data-open\") !== \"true\";\n liveChildren.setAttribute(\"data-open\", next ? \"true\" : \"false\");\n liveToggle.setAttribute(\"aria-expanded\", next ? \"true\" : \"false\");\n if (liveToggle.firstChild) liveToggle.firstChild.textContent = next ? \"▼\" : \"▶\";\n if (next && liveChildren.childElementCount === 0) {\n appendJsonChildren(liveChildren, entries, expanded, depth);\n } else if (!next) {\n // Collapse: drop the rendered rows so re-opening rebuilds them\n // against the latest data (and keeps the DOM small for big trees).\n liveChildren.replaceChildren();\n }\n };\n root.append(toggle, children);\n return root;\n}\n\n/* ----------------------------------------------------------------------- *\n * Tier 1\n * ----------------------------------------------------------------------- */\n\nexport const IconButton: ComponentSpec = {\n name: \"IconButton\",\n description:\n \"Icon-only button with an accessible label. Use for toolbars, table row actions, and compact controls.\",\n props: [\n { name: \"icon\", type: \"string\", description: \"Font Awesome icon name\" },\n { name: \"label\", type: \"string\", description: \"Accessible label (visually hidden)\" },\n { name: \"action\", type: \"callable\", optional: true, aliases: [\"onClick\", \"onclick\"] },\n { name: \"variant\", type: \"string\", optional: true, aliases: [\"tone\"], enum: BUTTON_VARIANTS },\n { name: \"size\", type: \"string\", optional: true, enum: BUTTON_SIZES },\n { name: \"disabled\", type: \"boolean\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const btn = el(\"button\", {\n class: \"rui-icon-button\",\n type: \"button\",\n \"data-variant\": asString(props.variant, \"ghost\"),\n \"data-size\": normaliseButtonSize(props.size),\n \"aria-label\": asString(props.label),\n title: asString(props.label),\n disabled: asBoolean(props.disabled) ? \"\" : null,\n });\n const iconNode = renderIcon(props.icon, { className: \"rui-icon-button-icon\" });\n if (iconNode) btn.append(iconNode);\n btn.onclick = () => helpers.invoke(props.action);\n return btn;\n },\n};\n\nexport const CommandPalette: ComponentSpec = {\n name: \"CommandPalette\",\n description:\n \"Cmd-K style searchable command list. Pass `items` as `{label, value, group?, shortcut?, action?}` objects.\",\n props: [\n { name: \"items\", type: \"any[]\" },\n { name: \"open\", type: \"boolean\", optional: true, description: \"Whether the palette is visible (default true)\" },\n { name: \"placeholder\", type: \"string\", optional: true },\n { name: \"shortcut\", type: \"string\", optional: true, description: \"Hint label, e.g. Cmd+K\" },\n ],\n render: (_node, props, helpers) => {\n const items = readCommandItems(props.items);\n // The palette is \"controlled\" whenever the script supplies an `open`\n // prop (so `open: $atom` updates the visibility on every change), and\n // \"uncontrolled\" otherwise (the internal slot tracks open/closed for\n // demo programs). When controlled, dismiss handlers still write to\n // the slot so the next host re-render keeps the visual state in sync\n // if the script also clears the bound atom.\n const propProvided = props.open !== undefined;\n const propOpen = propProvided ? asBoolean(props.open) : true;\n const openSlot = helpers.useInstanceState<boolean>(\"open\", propOpen);\n // Sync the slot to the latest prop value on every render so internal\n // dismiss handlers operate against the current \"open\" state.\n if (propProvided && openSlot.get() !== propOpen) openSlot.set(propOpen);\n const filterSlot = helpers.useInstanceState<string>(\"filter\", \"\");\n const isOpen = propProvided ? propOpen : openSlot.get();\n\n const host = el(\"div\", { class: \"rui-command-palette\", \"data-open\": isOpen ? \"true\" : \"false\" });\n if (!isOpen) return host;\n\n const backdrop = el(\"div\", { class: \"rui-command-palette-backdrop\" });\n const shell = el(\"div\", { class: \"rui-command-palette-panel\", role: \"dialog\", \"aria-modal\": \"true\" });\n const header = el(\"div\", { class: \"rui-command-palette-header\" });\n const search = el(\"input\", {\n type: \"text\",\n class: \"rui-command-palette-input\",\n placeholder: asString(props.placeholder, \"Search commands…\"),\n value: filterSlot.get(),\n autocomplete: \"off\",\n }) as HTMLInputElement;\n header.append(search);\n const shortcut = asString(props.shortcut);\n if (shortcut) header.append(el(\"span\", { class: \"rui-command-palette-shortcut\" }, [shortcut]));\n shell.append(header);\n\n const list = el(\"div\", { class: \"rui-command-palette-list\", role: \"listbox\" });\n const paintList = (target: HTMLElement, filter: string): void => {\n target.replaceChildren();\n const lower = filter.trim().toLowerCase();\n const matches = lower === \"\"\n ? items\n : items.filter((i) =>\n i.label.toLowerCase().includes(lower) ||\n i.value.toLowerCase().includes(lower) ||\n (i.group ?? \"\").toLowerCase().includes(lower),\n );\n let lastGroup = \"\";\n for (const item of matches.slice(0, 50)) {\n if (item.group && item.group !== lastGroup) {\n lastGroup = item.group;\n target.append(el(\"div\", { class: \"rui-command-palette-group\" }, [lastGroup]));\n }\n const row = el(\"button\", {\n type: \"button\",\n class: \"rui-command-palette-item\",\n role: \"option\",\n \"data-value\": item.value,\n }, [item.label]);\n if (item.shortcut) row.append(el(\"span\", { class: \"rui-command-palette-item-kbd\" }, [item.shortcut]));\n row.onclick = (event) => {\n event.stopPropagation();\n helpers.invoke(item.action);\n openSlot.set(false);\n filterSlot.set(\"\");\n const liveHost = (event.currentTarget as Element).closest(\".rui-command-palette\") as HTMLElement | null;\n const liveShell = liveHost?.querySelector(\".rui-command-palette-panel\") as HTMLElement | null;\n liveHost?.setAttribute(\"data-open\", \"false\");\n disposeDismissListeners(liveShell ?? null);\n };\n target.append(row);\n }\n if (matches.length === 0) {\n target.append(el(\"div\", { class: \"rui-command-palette-empty\" }, [\"No commands found\"]));\n }\n };\n paintList(list, filterSlot.get());\n shell.append(list);\n\n backdrop.onclick = (event) => {\n const liveHost = (event.currentTarget as Element).closest(\".rui-command-palette\") as HTMLElement | null;\n const liveShell = liveHost?.querySelector(\".rui-command-palette-panel\") as HTMLElement | null;\n openSlot.set(false);\n liveHost?.setAttribute(\"data-open\", \"false\");\n disposeDismissListeners(liveShell ?? null);\n };\n host.append(backdrop, shell);\n\n search.oninput = (event) => {\n const target = event.currentTarget as HTMLInputElement;\n const liveList = target.closest(\".rui-command-palette-panel\")\n ?.querySelector(\".rui-command-palette-list\") as HTMLElement | null;\n filterSlot.set(target.value);\n if (liveList) paintList(liveList, target.value);\n };\n search.onkeydown = (event) => {\n if ((event as KeyboardEvent).key === \"Escape\") {\n const liveHost = (event.currentTarget as Element).closest(\".rui-command-palette\") as HTMLElement | null;\n const liveShell = liveHost?.querySelector(\".rui-command-palette-panel\") as HTMLElement | null;\n openSlot.set(false);\n liveHost?.setAttribute(\"data-open\", \"false\");\n disposeDismissListeners(liveShell ?? null);\n }\n };\n setTimeout(() => search.focus(), 0);\n installDismissListeners({\n liveRoot: shell,\n key: \"command-palette\",\n onDismiss: () => {\n openSlot.set(false);\n host.setAttribute(\"data-open\", \"false\");\n },\n });\n return host;\n },\n};\n\nexport const FilterChips: ComponentSpec = {\n name: \"FilterChips\",\n description: \"Removable filter chips with an optional clear-all control.\",\n props: [\n { name: \"chips\", type: \"any[]\", description: \"Array of strings or {label, value} objects\" },\n { name: \"onRemove\", type: \"callable\", optional: true, description: \"Receives the removed chip value as an argument\" },\n { name: \"onClear\", type: \"callable\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const chips = readChipList(props.chips);\n const root = el(\"div\", { class: \"rui-filter-chips\" });\n const row = el(\"div\", { class: \"rui-filter-chips-row\" });\n for (const chip of chips) {\n const pill = el(\"span\", { class: \"rui-filter-chip\", \"data-value\": chip.value });\n pill.append(el(\"span\", { class: \"rui-filter-chip-label\" }, [chip.label]));\n const remove = el(\"button\", {\n type: \"button\",\n class: \"rui-filter-chip-remove\",\n \"aria-label\": `Remove ${chip.label}`,\n });\n const xIcon = renderIcon(\"xmark\", { className: \"rui-filter-chip-remove-icon\" });\n if (xIcon) remove.append(xIcon);\n remove.onclick = () => helpers.invoke(props.onRemove, chip.value);\n pill.append(remove);\n row.append(pill);\n }\n root.append(row);\n if (chips.length > 0 && typeof props.onClear === \"function\") {\n const clear = el(\"button\", { type: \"button\", class: \"rui-filter-chips-clear\" }, [\"Clear all\"]);\n clear.onclick = () => helpers.invoke(props.onClear);\n root.append(clear);\n }\n return root;\n },\n};\n\nexport const FieldRepeater: ComponentSpec = {\n name: \"FieldRepeater\",\n description:\n \"Dynamic list of field groups. Pass `items` as row objects and `fields` as `{name, label, type?}` definitions.\",\n props: [\n { name: \"items\", type: \"any[]\" },\n { name: \"fields\", type: \"any[]\" },\n { name: \"onAdd\", type: \"callable\", optional: true },\n { name: \"onRemove\", type: \"callable\", optional: true, description: \"Receives the removed row's 0-indexed position\" },\n { name: \"addLabel\", type: \"string\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const rows = readPlainObjects(props.items);\n const fields = readFields(props.fields);\n const root = el(\"div\", { class: \"rui-field-repeater\" });\n rows.forEach((row, index) => {\n const card = el(\"div\", { class: \"rui-field-repeater-row\", \"data-index\": String(index) });\n const grid = el(\"div\", { class: \"rui-field-repeater-grid\" });\n for (const field of fields) {\n const wrap = el(\"label\", { class: \"rui-field-repeater-field\" });\n wrap.append(el(\"span\", { class: \"rui-field-repeater-label\" }, [field.label]));\n const input = el(\"input\", {\n class: \"rui-input\",\n type: field.type === \"number\" ? \"number\" : \"text\",\n name: `${field.name}-${index}`,\n value: asString(row[field.name]),\n readonly: \"\",\n });\n wrap.append(input);\n grid.append(wrap);\n }\n card.append(grid);\n if (typeof props.onRemove === \"function\") {\n const remove = el(\"button\", {\n type: \"button\",\n class: \"rui-field-repeater-remove\",\n \"aria-label\": \"Remove row\",\n }, [\"Remove\"]);\n remove.onclick = () => helpers.invoke(props.onRemove, index);\n card.append(remove);\n }\n root.append(card);\n });\n if (typeof props.onAdd === \"function\") {\n const add = el(\"button\", {\n type: \"button\",\n class: \"rui-field-repeater-add rui-button\",\n \"data-variant\": \"secondary\",\n }, [asString(props.addLabel, \"Add row\")]);\n add.onclick = () => helpers.invoke(props.onAdd);\n root.append(add);\n }\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * Tier 2\n * ----------------------------------------------------------------------- */\n\nexport const VirtualList: ComponentSpec = {\n name: \"VirtualList\",\n description:\n \"Windowed vertical list for large datasets. Pass pre-rendered nodes as `items` \" +\n \"or plain row objects plus a `renderItem` component node per row.\",\n props: [\n { name: \"items\", type: \"any[]\" },\n { name: \"itemHeight\", type: \"number\", optional: true, description: \"Fixed row height in px (default 40)\" },\n { name: \"renderItem\", type: \"Node\", optional: true, description: \"Template node rendered per data row\" },\n ],\n render: (_node, props, helpers) => {\n const itemHeight = Math.max(24, asNumber(props.itemHeight, 40));\n const rawItems = asArray<unknown>(props.items);\n const viewport = el(\"div\", { class: \"rui-virtual-list\" });\n const scrollEl = el(\"div\", { class: \"rui-virtual-list-scroller\" });\n const spacer = el(\"div\", { class: \"rui-virtual-list-spacer\" });\n const windowEl = el(\"div\", { class: \"rui-virtual-list-window\" });\n\n const total = rawItems.length;\n spacer.style.height = `${total * itemHeight}px`;\n spacer.style.position = \"relative\";\n windowEl.style.position = \"absolute\";\n windowEl.style.top = \"0\";\n windowEl.style.left = \"0\";\n windowEl.style.right = \"0\";\n scrollEl.style.maxHeight = `${Math.min(Math.max(total, 1), 12) * itemHeight}px`;\n scrollEl.style.overflow = \"auto\";\n\n const renderSlice = (startIndex: number): void => {\n windowEl.replaceChildren();\n const viewHeight = scrollEl.clientHeight || itemHeight * 12;\n const visible = Math.ceil(viewHeight / itemHeight) + 2;\n const start = Math.max(0, startIndex);\n const end = Math.min(total, start + visible);\n windowEl.style.transform = `translateY(${start * itemHeight}px)`;\n for (let i = start; i < end; i++) {\n const entry = rawItems[i];\n if (props.renderItem) {\n windowEl.append(helpers.renderNode(entry ?? props.renderItem));\n } else if (entry && typeof entry === \"object\" && (entry as { __kind?: string }).__kind) {\n windowEl.append(helpers.renderNode(entry));\n } else {\n const row = el(\"div\", { class: \"rui-virtual-list-item\", style: `height:${itemHeight}px` });\n row.append(el(\"span\", {}, [asString(entry)]));\n windowEl.append(row);\n }\n }\n };\n\n scrollEl.onscroll = () => {\n const start = Math.floor(scrollEl.scrollTop / itemHeight);\n renderSlice(start);\n };\n renderSlice(0);\n scrollEl.append(spacer, windowEl);\n viewport.append(scrollEl);\n return viewport;\n },\n};\n\nexport const QueryBuilder: ComponentSpec = {\n name: \"QueryBuilder\",\n description:\n \"Visual filter builder. Pass `fields` as `{name, label, type?}` and bind `value` to a rule array.\",\n props: [\n { name: \"fields\", type: \"any[]\" },\n { name: \"value\", type: \"any[]\", optional: true },\n { name: \"onChange\", type: \"callable\", optional: true, description: \"Receives the next rule array\" },\n ],\n render: (node, props, helpers) => {\n const fields = readFields(props.fields);\n const rules = readPlainObjects(props.value);\n const stateRef = node.argMeta?.[1]?.stateRef;\n const root = el(\"div\", { class: \"rui-query-builder\" });\n\n const paint = (current: Record<string, unknown>[]): void => {\n root.replaceChildren();\n current.forEach((rule, index) => {\n const row = el(\"div\", { class: \"rui-query-builder-row\", \"data-index\": String(index) });\n const fieldSelect = el(\"select\", { class: \"rui-select rui-query-builder-field\" });\n for (const f of fields) {\n fieldSelect.append(el(\"option\", { value: f.name }, [f.label]));\n }\n fieldSelect.value = asString(rule.field ?? fields[0]?.name);\n const opSelect = el(\"select\", { class: \"rui-select rui-query-builder-op\" }, []);\n for (const op of [\"equals\", \"contains\", \"gt\", \"lt\"]) {\n opSelect.append(el(\"option\", { value: op }, [op]));\n }\n opSelect.value = asString(rule.op, \"equals\");\n const valueInput = el(\"input\", {\n class: \"rui-input rui-query-builder-value\",\n value: asString(rule.value),\n });\n row.append(fieldSelect, opSelect, valueInput);\n const remove = el(\"button\", { type: \"button\", class: \"rui-query-builder-remove\" }, [\"×\"]);\n remove.onclick = () => {\n const next = current.filter((_, i) => i !== index);\n if (stateRef) helpers.setState(stateRef, next);\n else helpers.invoke(props.onChange, next);\n paint(next);\n };\n row.append(remove);\n root.append(row);\n });\n const add = el(\"button\", { type: \"button\", class: \"rui-query-builder-add\" }, [\"Add rule\"]);\n add.onclick = () => {\n const next = [...current, { field: fields[0]?.name ?? \"\", op: \"equals\", value: \"\" }];\n if (stateRef) helpers.setState(stateRef, next);\n else helpers.invoke(props.onChange, next);\n paint(next);\n };\n root.append(add);\n };\n\n paint(rules.length > 0 ? rules : [{ field: fields[0]?.name ?? \"\", op: \"equals\", value: \"\" }]);\n return root;\n },\n};\n\nexport const DiffViewer: ComponentSpec = {\n name: \"DiffViewer\",\n description: \"Side-by-side or unified diff of two text blobs.\",\n props: [\n { name: \"left\", type: \"string\" },\n { name: \"right\", type: \"string\" },\n { name: \"mode\", type: \"string\", optional: true, enum: [\"split\", \"unified\"], description: \"Default split\" },\n ],\n render: (_node, props) => {\n const left = asString(props.left);\n const right = asString(props.right);\n const mode = asString(props.mode, \"split\");\n const root = el(\"div\", { class: \"rui-diff-viewer\", \"data-mode\": mode });\n\n if (mode === \"unified\") {\n const body = el(\"pre\", { class: \"rui-diff-viewer-unified\" });\n for (const line of diffLines(left, right)) {\n body.append(el(\"div\", { class: `rui-diff-line rui-diff-line-${line.type}` }, [\n (line.type === \"add\" ? \"+ \" : line.type === \"remove\" ? \"- \" : \" \") + line.text,\n ]));\n }\n root.append(body);\n return root;\n }\n\n const panes = el(\"div\", { class: \"rui-diff-viewer-panes\" });\n const leftPane = el(\"pre\", { class: \"rui-diff-viewer-pane rui-diff-viewer-left\" }, [left]);\n const rightPane = el(\"pre\", { class: \"rui-diff-viewer-pane rui-diff-viewer-right\" }, [right]);\n panes.append(leftPane, rightPane);\n root.append(panes);\n return root;\n },\n};\n\nexport const JsonTree: ComponentSpec = {\n name: \"JsonTree\",\n description: \"Expandable JSON tree viewer for objects and arrays.\",\n props: [\n { name: \"data\", type: \"any\" },\n { name: \"expanded\", type: \"boolean\", optional: true, description: \"Expand all nodes (default: first level only)\" },\n ],\n render: (_node, props) => {\n const root = el(\"div\", { class: \"rui-json-tree\" });\n root.append(buildJsonTree(props.data, asBoolean(props.expanded)));\n return root;\n },\n};\n\nexport const Gantt: ComponentSpec = {\n name: \"Gantt\",\n description:\n \"Simple Gantt chart. Pass `tasks` as `{id, label, start, end, progress?}` ISO date strings.\",\n props: [\n { name: \"tasks\", type: \"any[]\" },\n { name: \"startDate\", type: \"string\", optional: true },\n { name: \"endDate\", type: \"string\", optional: true },\n ],\n render: (_node, props) => {\n const tasks = readGanttTasks(props.tasks);\n const starts = tasks.map((t) => parseIsoDate(t.start));\n const ends = tasks.map((t) => parseIsoDate(t.end));\n const rangeStart = props.startDate\n ? parseIsoDate(asString(props.startDate))\n : (starts.length ? Math.min(...starts) : Date.now());\n const rangeEnd = props.endDate\n ? parseIsoDate(asString(props.endDate))\n : (ends.length ? Math.max(...ends) : rangeStart + 86_400_000);\n const span = Math.max(rangeEnd - rangeStart, 1);\n\n const root = el(\"div\", { class: \"rui-gantt\" });\n const track = el(\"div\", { class: \"rui-gantt-track\" });\n for (const task of tasks) {\n const row = el(\"div\", { class: \"rui-gantt-row\" });\n row.append(el(\"div\", { class: \"rui-gantt-label\" }, [task.label]));\n const barWrap = el(\"div\", { class: \"rui-gantt-bars\" });\n const startPct = ((parseIsoDate(task.start) - rangeStart) / span) * 100;\n const widthPct = Math.max(\n ((parseIsoDate(task.end) - parseIsoDate(task.start)) / span) * 100,\n 2,\n );\n const bar = el(\"div\", {\n class: \"rui-gantt-bar\",\n style: `left:${startPct}%;width:${widthPct}%`,\n title: `${task.start} → ${task.end}`,\n });\n if (task.progress != null) {\n bar.append(el(\"div\", {\n class: \"rui-gantt-bar-progress\",\n style: `width:${Math.min(100, Math.max(0, task.progress))}%`,\n }));\n }\n barWrap.append(bar);\n row.append(barWrap);\n track.append(row);\n }\n root.append(track);\n return root;\n },\n};\n\n/* ----------------------------------------------------------------------- *\n * Tier 3\n * ----------------------------------------------------------------------- */\n\nexport const Truncate: ComponentSpec = {\n name: \"Truncate\",\n description: \"Clamp long text with an expand control.\",\n props: [\n { name: \"text\", type: \"string\" },\n { name: \"maxLines\", type: \"number\", optional: true, description: \"Lines before clamping (default 3)\" },\n { name: \"expandLabel\", type: \"string\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const maxLines = Math.max(1, Math.floor(asNumber(props.maxLines, 3)));\n const expandedSlot = helpers.useInstanceState<boolean>(\"expanded\", false);\n const clampStyle = `display:-webkit-box;-webkit-line-clamp:${maxLines};-webkit-box-orient:vertical;overflow:hidden`;\n const root = el(\"div\", { class: \"rui-truncate\", \"data-expanded\": expandedSlot.get() ? \"true\" : \"false\" });\n const body = el(\"p\", {\n class: \"rui-truncate-text\",\n style: expandedSlot.get() ? \"\" : clampStyle,\n }, [asString(props.text)]);\n const toggle = el(\"button\", {\n type: \"button\",\n class: \"rui-truncate-toggle\",\n }, [expandedSlot.get() ? \"Show less\" : asString(props.expandLabel, \"Show more\")]);\n toggle.onclick = (event) => {\n // Walk to the live `.rui-truncate` root and find the live <p>; the\n // closure-captured nodes are detached once morph reuses the kept DOM.\n const liveToggle = event.currentTarget as HTMLElement;\n const liveRoot = liveToggle.closest(\".rui-truncate\") as HTMLElement | null;\n const liveBody = liveRoot?.querySelector(\".rui-truncate-text\") as HTMLElement | null;\n if (!liveRoot || !liveBody) return;\n const next = !expandedSlot.get();\n expandedSlot.set(next);\n liveBody.style.cssText = next ? \"\" : clampStyle;\n liveToggle.textContent = next ? \"Show less\" : asString(props.expandLabel, \"Show more\");\n liveRoot.setAttribute(\"data-expanded\", next ? \"true\" : \"false\");\n };\n root.append(body, toggle);\n return root;\n },\n};\n\nexport const InlineEdit: ComponentSpec = {\n name: \"InlineEdit\",\n description: \"Click-to-edit inline field with save on Enter or blur.\",\n props: [\n { name: \"value\", type: \"string\" },\n { name: \"label\", type: \"string\", optional: true },\n { name: \"onSave\", type: \"callable\", optional: true, description: \"Receives the committed draft string\" },\n ],\n render: (node, props, helpers) => {\n const editingSlot = helpers.useInstanceState<boolean>(\"editing\", false);\n const draftSlot = helpers.useInstanceState<string>(\"draft\", asString(props.value));\n const stateRef = node.argMeta?.[0]?.stateRef;\n const root = el(\"div\", { class: \"rui-inline-edit\", \"data-editing\": editingSlot.get() ? \"true\" : \"false\" });\n const label = asString(props.label);\n if (label) root.append(el(\"span\", { class: \"rui-inline-edit-label\" }, [label]));\n\n const display = el(\"button\", {\n type: \"button\",\n class: \"rui-inline-edit-display\",\n }, [asString(props.value)]);\n const input = el(\"input\", {\n class: \"rui-inline-edit-input rui-input\",\n value: draftSlot.get(),\n }) as HTMLInputElement;\n\n const resolveLive = (origin: Element): {\n root: HTMLElement; input: HTMLInputElement;\n } | null => {\n const liveRoot = origin.closest(\".rui-inline-edit\") as HTMLElement | null;\n const liveInput = liveRoot?.querySelector(\".rui-inline-edit-input\") as HTMLInputElement | null;\n if (!liveRoot || !liveInput) return null;\n return { root: liveRoot, input: liveInput };\n };\n\n const commit = (origin: Element): void => {\n const live = resolveLive(origin);\n editingSlot.set(false);\n live?.root.setAttribute(\"data-editing\", \"false\");\n const draft = draftSlot.get();\n if (stateRef) helpers.setState(stateRef, draft);\n helpers.invoke(props.onSave, draft);\n };\n\n display.onclick = (event) => {\n const live = resolveLive(event.currentTarget as Element);\n draftSlot.set(asString(props.value));\n editingSlot.set(true);\n if (live) {\n live.root.setAttribute(\"data-editing\", \"true\");\n live.input.value = draftSlot.get();\n setTimeout(() => live.input.focus(), 0);\n }\n };\n input.oninput = (event) => draftSlot.set((event.currentTarget as HTMLInputElement).value);\n input.onkeydown = (event) => {\n const kev = event as KeyboardEvent;\n if (kev.key === \"Enter\") commit(event.currentTarget as Element);\n if (kev.key === \"Escape\") {\n const live = resolveLive(event.currentTarget as Element);\n editingSlot.set(false);\n live?.root.setAttribute(\"data-editing\", \"false\");\n }\n };\n input.onblur = (event) => commit(event.currentTarget as Element);\n\n root.append(display, input);\n return root;\n },\n};\n\nexport const NotificationBell: ComponentSpec = {\n name: \"NotificationBell\",\n description: \"Bell icon with unread count badge and dropdown notification list.\",\n props: [\n { name: \"count\", type: \"number\", optional: true },\n { name: \"items\", type: \"any[]\", optional: true, description: \"{title, message?, time?} objects\" },\n { name: \"onOpen\", type: \"callable\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const count = Math.max(0, Math.floor(asNumber(props.count, 0)));\n const items = readPlainObjects(props.items);\n const openSlot = helpers.useInstanceState<boolean>(\"open\", false);\n const isOpen = openSlot.get();\n\n const root = el(\"div\", { class: \"rui-notification-bell\", \"data-open\": isOpen ? \"true\" : \"false\" });\n const trigger = el(\"button\", {\n type: \"button\",\n class: \"rui-notification-bell-trigger\",\n \"aria-expanded\": isOpen ? \"true\" : \"false\",\n \"aria-haspopup\": \"true\",\n });\n const bell = renderIcon(\"bell\", { className: \"rui-notification-bell-icon\" });\n if (bell) trigger.append(bell);\n if (count > 0) {\n trigger.append(el(\"span\", { class: \"rui-notification-bell-badge\" }, [\n count > 99 ? \"99+\" : String(count),\n ]));\n }\n root.append(trigger);\n\n const panel = el(\"div\", { class: \"rui-notification-bell-panel\", role: \"menu\" });\n if (items.length === 0) {\n panel.append(el(\"div\", { class: \"rui-notification-bell-empty\" }, [\"No notifications\"]));\n } else {\n for (const item of items) {\n const row = el(\"div\", { class: \"rui-notification-bell-item\" });\n row.append(el(\"div\", { class: \"rui-notification-bell-item-title\" }, [asString(item.title)]));\n const msg = asString(item.message);\n if (msg) row.append(el(\"div\", { class: \"rui-notification-bell-item-message\" }, [msg]));\n const time = asString(item.time);\n if (time) row.append(el(\"div\", { class: \"rui-notification-bell-item-time\" }, [time]));\n panel.append(row);\n }\n }\n root.append(panel);\n\n trigger.onclick = (event) => {\n event.stopPropagation();\n // Resolve the *live* DOM nodes from the event target so this\n // handler keeps working after the morph reconciler copies it onto\n // the kept DOM (the closure-captured `root`/`trigger` reference\n // the freshly-built fragment, which is detached after morph).\n const liveTrigger = event.currentTarget as HTMLElement;\n const liveRoot = liveTrigger.closest(\".rui-notification-bell\") as HTMLElement | null;\n if (!liveRoot) return;\n const next = !openSlot.get();\n openSlot.set(next);\n liveRoot.setAttribute(\"data-open\", next ? \"true\" : \"false\");\n liveTrigger.setAttribute(\"aria-expanded\", next ? \"true\" : \"false\");\n if (next) {\n helpers.invoke(props.onOpen);\n installDismissListeners({\n liveRoot,\n key: \"notification-bell\",\n onDismiss: () => {\n openSlot.set(false);\n liveRoot.setAttribute(\"data-open\", \"false\");\n liveTrigger.setAttribute(\"aria-expanded\", \"false\");\n },\n });\n } else {\n disposeDismissListeners(liveRoot);\n }\n };\n return root;\n },\n};\n","/**\n * Aktion 0.5 standard helper components.\n *\n * These are the \"frameworky\" features that ship as library components\n * rather than language constructs (per spec §24). Keeping them as\n * components keeps the language core small and the runtime tractable.\n *\n * - `Async(resource, loading:, error:, empty:, data:)` — branches on a\n * `$query` / `$mutation` / `$subscription` resource state.\n * - `ErrorBoundary(fallback:, onError:, children)` — subtree error catcher.\n * - `Portal(target?, children)` — escape-hatch render to another DOM node.\n * - `Redirect(path)` — navigate then unmount. Recognised by the router.\n * - `Lazy(loader, fallback?)` — defer the children until `loader` resolves.\n * - `Show(when, fallback?, children)` — sugar over `if`.\n */\n\nimport type { ComponentSpec, RenderHelpers } from \"../types.js\";\nimport { el, asArray, asString } from \"../utils.js\";\n\nconst renderChild = (helpers: RenderHelpers, value: unknown): Node => {\n if (value == null) return document.createDocumentFragment();\n return helpers.renderNode(value);\n};\n\nconst isResourceShape = (\n value: unknown,\n): value is { state?: string; data?: unknown; error?: unknown; loading?: boolean } => {\n return Boolean(value && typeof value === \"object\");\n};\n\n/**\n * `Async(resource, loading:, error:, empty:, data:)` — render the\n * appropriate branch based on the resource's `state`. The resource is\n * expected to expose at least `{ state, data, error, loading }`.\n */\nexport const Async: ComponentSpec = {\n name: \"Async\",\n description:\n \"Render `loading`, `error`, `empty`, or `data` slot based on an `http({...})` resource's state.\",\n props: [\n { name: \"resource\", type: \"any\", positional: true, required: true },\n { name: \"loading\", type: \"Node\", optional: true },\n { name: \"error\", type: \"Node\", optional: true },\n { name: \"empty\", type: \"Node\", optional: true },\n { name: \"data\", type: \"Node\", optional: true },\n ],\n render: (_node, props, helpers) => {\n const resource = props.resource;\n const slots = {\n loading: props.loading,\n error: props.error,\n empty: props.empty,\n data: props.data,\n };\n if (!isResourceShape(resource)) {\n return renderChild(helpers, slots.empty ?? slots.data ?? null);\n }\n const state = (resource as { state?: string }).state;\n if (state === \"loading\" || (resource as { loading?: boolean }).loading) {\n return renderChild(helpers, slots.loading ?? null);\n }\n if (state === \"error\" || (resource as { error?: unknown }).error) {\n return renderChild(helpers, slots.error ?? null);\n }\n const data = (resource as { data?: unknown }).data;\n if (data === undefined || data === null || (Array.isArray(data) && data.length === 0)) {\n return renderChild(helpers, slots.empty ?? slots.data ?? null);\n }\n return renderChild(helpers, slots.data ?? null);\n },\n};\n\n/**\n * `Show(when, fallback?, children)` — sugar over `if`. Renders `children`\n * when `when` is truthy; falls back to `fallback` (or nothing) otherwise.\n */\nexport const Show: ComponentSpec = {\n name: \"Show\",\n description: \"Conditional renderer. Sugar over `if expr { children } else { fallback }`.\",\n props: [\n { name: \"when\", type: \"any\", positional: true, required: true },\n { name: \"fallback\", type: \"Node\", optional: true },\n { name: \"children\", type: \"Node[]\", optional: true },\n ],\n render: (_node, props, helpers) => {\n if (props.when) {\n return renderChild(helpers, props.children ?? null);\n }\n return renderChild(helpers, props.fallback ?? null);\n },\n};\n\n/**\n * `Portal(target?, children)` — render `children` outside the normal\n * subtree. `target` accepts a CSS selector; falls back to `document.body`.\n */\nexport const Portal: ComponentSpec = {\n name: \"Portal\",\n description: \"Render children outside the parent subtree (e.g. into document.body).\",\n props: [\n { name: \"target\", type: \"string\", optional: true },\n { name: \"children\", type: \"Node[]\", positional: true },\n ],\n render: (_node, props, helpers) => {\n const target = asString(props.target);\n let mount: Element | null = null;\n if (target) {\n try {\n mount = document.querySelector(target);\n } catch {\n mount = null;\n }\n }\n if (!mount) mount = document.body;\n const container = el(\"div\", { class: \"rui-portal\" });\n for (const child of asArray(props.children)) {\n container.append(helpers.renderNode(child));\n }\n if (mount) {\n mount.append(container);\n // Schedule removal on next render — the renderer owns the lifecycle.\n helpers.registerDisposer(() => {\n if (container.parentNode) container.parentNode.removeChild(container);\n });\n }\n // Render an empty placeholder in the original position so morph\n // diffing keeps a stable node identity.\n return el(\"span\", { class: \"rui-portal-anchor\", \"data-portal\": target ?? \"body\" });\n },\n};\n\n/**\n * `Redirect(path)` — Issued by a route guard component. The runtime\n * recognises the rendered output and redirects the router immediately.\n */\nexport const Redirect: ComponentSpec = {\n name: \"Redirect\",\n description: \"Navigate to `path` and unmount the rest of the subtree.\",\n props: [\n { name: \"path\", type: \"string\", positional: true, required: true },\n ],\n render: (_node, props, helpers) => {\n const path = asString(props.path);\n if (path) {\n try {\n helpers.router.navigate(path);\n } catch {\n // Router may be unavailable (SSR); fall through to no-op.\n }\n }\n return el(\"span\", { class: \"rui-redirect\", \"data-path\": path, hidden: \"true\" });\n },\n};\n\n/**\n * `Lazy(loader, fallback?)` — Defer the children until the `loader`\n * promise resolves. The `loader` can be either a function returning a\n * promise or a promise directly.\n */\nexport const Lazy: ComponentSpec = {\n name: \"Lazy\",\n description: \"Defer rendering `children` until `loader` resolves.\",\n props: [\n { name: \"loader\", type: \"any\", positional: true, required: true },\n { name: \"fallback\", type: \"Node\", optional: true },\n { name: \"children\", type: \"Node[]\", optional: true },\n ],\n render: (_node, props, helpers) => {\n // Best-effort static rendering: invoke the loader if it's a function;\n // if it returns a promise, render the fallback. The full streaming\n // resolution belongs to the runtime — see status file §24.\n const loader = props.loader;\n if (typeof loader === \"function\") {\n try {\n const result = (loader as () => unknown)();\n if (result && typeof (result as { then?: unknown }).then === \"function\") {\n return renderChild(helpers, props.fallback ?? null);\n }\n return renderChild(helpers, result ?? props.children ?? null);\n } catch {\n return renderChild(helpers, props.fallback ?? null);\n }\n }\n return renderChild(helpers, props.children ?? null);\n },\n};\n\n/**\n * `ErrorBoundary(fallback?, onError?, children)` — catches rendering\n * errors raised by descendants and renders the fallback instead.\n */\nexport const ErrorBoundary: ComponentSpec = {\n name: \"ErrorBoundary\",\n description: \"Render a fallback subtree when rendering children throws.\",\n props: [\n { name: \"fallback\", type: \"Node\", optional: true },\n { name: \"onError\", type: \"callable\", optional: true },\n { name: \"children\", type: \"Node[]\", positional: true },\n ],\n render: (_node, props, helpers) => {\n const wrapper = el(\"div\", { class: \"rui-error-boundary\" });\n try {\n for (const child of asArray(props.children)) {\n wrapper.append(helpers.renderNode(child));\n }\n return wrapper;\n } catch (err) {\n try { helpers.invoke(props.onError, err); } catch { /* swallow */ }\n const fallback = renderChild(helpers, props.fallback ?? null);\n const errorWrapper = el(\"div\", { class: \"rui-error-boundary rui-error-boundary--fallback\" });\n errorWrapper.append(fallback);\n // Surface the error message in a hidden attribute for diagnostics.\n errorWrapper.setAttribute(\"data-error\", err instanceof Error ? err.message : String(err));\n return errorWrapper;\n }\n },\n};\n\n","/**\n * Built-in component library for `<aktion-app>`.\n *\n * Exports a single `defaultLibrary` that ships with the package. Consumers can\n * extend it via `<aktion-app>.registerComponents([...])`.\n */\n\nimport { assertOnePositionalMax } from \"./types.js\";\nimport type { ComponentLibrary, ComponentSpec, ComponentGroup } from \"./types.js\";\nimport {\n Stack, StackItem, Grid, GridItem, Box, Card, CardHeader, CardFooter, Separator,\n Tabs, TabItem, Accordion, AccordionItem, Modal, Steps,\n AspectRatio, ScrollArea,\n} from \"./components/layout.js\";\nimport {\n Text, TextContent, Image, Link, Badge, BadgeList,\n Callout, CodeBlock, Skeleton, Markdown,\n Container, Spacer, Quote, Icon, Spinner,\n} from \"./components/content.js\";\nimport {\n Form, FormControl, Input, TextArea, Select, SelectItem, Checkbox,\n CheckBoxGroup, CheckBoxItem, Radio, Button, Buttons, SearchBar,\n Slider, NumberInput, DatePicker, FileUpload, Combobox,\n MultiSelect, DateRangePicker,\n} from \"./components/forms.js\";\nimport {\n Table, Col, List, ListItem, StatCard, Tree, TreeNode, Sparkline,\n} from \"./components/data.js\";\nimport { BarChart, LineChart, PieChart, Series } from \"./components/charts.js\";\nimport {\n SectionBlock, ListBlock, FollowUpBlock, FollowUpItem, ActionLink,\n} from \"./components/chat.js\";\nimport {\n Avatar, AvatarGroup, Progress, Switch, ToggleGroup,\n Tooltip, HoverCard, Popover, Toast, Kbd, Rating, ProgressRing, ChatBubble,\n} from \"./components/feedback.js\";\nimport {\n Breadcrumb, BreadcrumbItem, Pagination, Navbar, NavbarItem,\n} from \"./components/navigation.js\";\nimport {\n DropdownMenu, MenuItem, MenuSeparator, MenuLabel,\n} from \"./components/menu.js\";\nimport {\n Hero, PageHeader, EmptyState,\n Timeline, TimelineItem, FeatureGrid, FeatureItem,\n Testimonial, ProfileCard, Comment, Banner,\n KanbanBoard, KanbanColumn, KanbanCard,\n SectionHeader, Toolbar, Sidebar, SidebarSection, SidebarItem,\n AppShell, SplitView, DescriptionList, DescriptionItem,\n StatusDot, PricingTable, PricingCard,\n MediaCard, Stats, Tile, Notification, PersonChip,\n} from \"./components/patterns.js\";\nimport {\n DataGrid, CalendarView, ActivityLog, ComparisonTable, InfiniteList,\n} from \"./components/advanced-data.js\";\nimport {\n VideoPlayer, AudioPlayer, Carousel, Gallery, Lightbox, Map,\n} from \"./components/media.js\";\nimport {\n RichTextEditor, CodeEditor, ContextMenu, ColorPicker,\n} from \"./components/editors.js\";\nimport {\n Gauge, Heatmap, RadarChart, ScatterChart, Histogram,\n} from \"./components/advanced-charts.js\";\nimport {\n PinInput, PasswordInput, TagInput, MentionInput,\n TimePicker, DateTimePicker, MaskedInput,\n FormSection, FieldSet, ValidationSummary, MultiStepForm,\n} from \"./components/advanced-forms.js\";\nimport {\n InboxPanel, OnboardingChecklist, LoadingState, ErrorState, SuccessState,\n Tour, Spotlight, Sticky, ResizablePanels, MasonryGrid, Drawer, TopBar,\n} from \"./components/advanced-patterns.js\";\nimport { Theme } from \"./components/theme.js\";\nimport { NavLink } from \"./components/router.js\";\nimport {\n IconButton, CommandPalette, FilterChips, FieldRepeater,\n VirtualList, QueryBuilder, DiffViewer, JsonTree, Gantt,\n Truncate, InlineEdit, NotificationBell,\n} from \"./components/new-components.js\";\nimport {\n Async, Show, Portal, Redirect, Lazy, ErrorBoundary,\n} from \"./components/helpers.js\";\n\nexport * from \"./types.js\";\nexport * from \"./registry.js\";\nexport { validateProgramSchema, validateProgram } from \"./validate.js\";\n\nconst components: ComponentSpec[] = [\n Stack, StackItem, Grid, GridItem, Box, Card, CardHeader, CardFooter, Separator,\n Tabs, TabItem, Accordion, AccordionItem, Modal, Steps,\n AspectRatio, ScrollArea, Container, Spacer,\n Text, TextContent, Image, Link, Badge, BadgeList,\n Callout, CodeBlock, Skeleton, Markdown, Quote, Icon, Spinner,\n Form, FormControl, Input, TextArea, Select, SelectItem, Checkbox,\n CheckBoxGroup, CheckBoxItem, Radio, Button, Buttons, SearchBar,\n Slider, NumberInput, DatePicker, FileUpload, Combobox,\n MultiSelect, DateRangePicker,\n Table, Col, List, ListItem, StatCard, Sparkline, Tree, TreeNode,\n BarChart, LineChart, PieChart, Series,\n SectionBlock, ListBlock, FollowUpBlock, FollowUpItem, ActionLink, ChatBubble,\n Avatar, AvatarGroup, Progress, ProgressRing, Switch, ToggleGroup,\n Tooltip, HoverCard, Popover, Toast, Kbd, Rating,\n Breadcrumb, BreadcrumbItem, Pagination, Navbar, NavbarItem,\n DropdownMenu, MenuItem, MenuSeparator, MenuLabel,\n Hero, PageHeader, Stats, Tile, EmptyState,\n Timeline, TimelineItem, FeatureGrid, FeatureItem,\n Testimonial, ProfileCard, PersonChip, Comment, Banner, Notification,\n MediaCard, KanbanBoard, KanbanColumn, KanbanCard,\n SectionHeader, Toolbar, Sidebar, SidebarSection, SidebarItem,\n AppShell, SplitView, DescriptionList, DescriptionItem,\n StatusDot, PricingTable, PricingCard,\n // Advanced data\n DataGrid, CalendarView, ActivityLog, ComparisonTable, InfiniteList,\n // Media\n VideoPlayer, AudioPlayer, Carousel, Gallery, Lightbox, Map,\n // Editors\n RichTextEditor, CodeEditor, ContextMenu, ColorPicker,\n // More charts\n Gauge, Heatmap, RadarChart, ScatterChart, Histogram,\n // Advanced forms\n PinInput, PasswordInput, TagInput, MentionInput,\n TimePicker, DateTimePicker, MaskedInput,\n FormSection, FieldSet, ValidationSummary, MultiStepForm,\n // Advanced patterns + state cards\n InboxPanel, OnboardingChecklist, LoadingState, ErrorState, SuccessState,\n Tour, Spotlight, Sticky, ResizablePanels, MasonryGrid, Drawer, TopBar,\n Theme,\n NavLink,\n IconButton, CommandPalette, FilterChips, FieldRepeater,\n VirtualList, QueryBuilder, DiffViewer, JsonTree, Gantt,\n Truncate, InlineEdit, NotificationBell,\n // Aktion 0.5 standard helpers\n Async, Show, Portal, Redirect, Lazy, ErrorBoundary,\n];\n\nconst componentGroups: ComponentGroup[] = [\n {\n name: \"Layout\",\n components: [\n \"Stack\", \"StackItem\", \"Grid\", \"GridItem\", \"Box\", \"Container\", \"Spacer\",\n \"Card\", \"CardHeader\", \"CardFooter\", \"Separator\", \"Tabs\", \"TabItem\",\n \"Accordion\", \"AccordionItem\", \"Modal\", \"Drawer\", \"Steps\",\n \"AspectRatio\", \"ScrollArea\", \"Sticky\", \"ResizablePanels\", \"MasonryGrid\",\n ],\n notes: [\n \"- `root` MUST be `Stack(...)` and contain at least one child.\",\n \"- Wrap each major chunk of content in a `Card(...)` for visual grouping.\",\n \"- Prefer `Grid(...)` over `Stack` with `direction=\\\"row\\\" wrap=true` when children should size uniformly (KPIs, feature tiles, card grids).\",\n \"- Use `Container(children, size?)` to centre a wide page within a comfortable max-width (landing pages, articles, marketing sections).\",\n \"- Use `Spacer()` inside `Stack(direction=\\\"row\\\")` to push the next item to the far edge; pass a `size` for an explicit fixed gap.\",\n \"- Use `Separator(orientation?, label?)` between sections to add visual breaks. Pass a `label` for a centered \\\"OR\\\"-style separator.\",\n \"- Use `Drawer` for side-panel detail views, `Modal` for centered dialogs.\",\n \"- Use `Sticky(children, side?, offset?)` to pin a toolbar/banner while the surrounding content scrolls.\",\n \"- Use `ResizablePanels(primary, secondary, initialPrimaryWidth?)` for user-resizable two-pane layouts (code editors, file browsers).\",\n \"- Use `MasonryGrid([...])` for Pinterest-style mixed-height card walls — prefer `Grid` when rows should share a height.\",\n \"- Use `StackItem(child, grow?, shrink?, basis?, alignSelf?)` inside `Stack(direction=\\\"row\\\", uniform=false)` for toolbars.\",\n \"- Use `Grid(columns: 12, [GridItem(child, span: \\\"1/4\\\"), GridItem(main, span: \\\"3/4\\\")])` for sidebar layouts; fractional spans `\\\"1/2\\\"`…`\\\"1/12\\\"` resolve on a 12-column track.\",\n \"- Use `Box(children, padding?, margin?, border?, background?)` for spacing and surfaces without raw CSS.\",\n ],\n },\n {\n name: \"Content\",\n components: [\n \"Text\", \"Image\", \"Link\", \"Badge\", \"BadgeList\",\n \"Callout\", \"Quote\", \"CodeBlock\", \"Skeleton\", \"Spinner\",\n \"Markdown\", \"Kbd\", \"Icon\",\n ],\n notes: [\n \"- Prefer `Markdown(...)` for rich paragraph text with inline formatting — the parser supports headings, blockquotes, fenced code, numbered/bullet lists, links, images, and bare-URL auto-linking.\",\n \"- Use `Callout(variant, title, description, icon?, compact?)` for highlighted notices; pass `compact: true` for a one-line inline note.\",\n \"- Use `Quote(text, cite?)` for inline pull-quotes inside articles and marketing sections (use `Testimonial` when you also have author/role/rating).\",\n \"- Use `CodeBlock(language, codeString, showLineNumbers?, highlightLines?)` for read-only code snippets. The header always renders a copy-to-clipboard button.\",\n \"- Use `Badge(label, variant?, icon?, size?)` for a single pill and `BadgeList([\\\"a\\\",\\\"b\\\",\\\"c\\\"], variant?, size?)` to render an array of strings as Badge pills.\",\n \"- Use `Skeleton(variant?, lines?, height?, shape?, width?)` for loading placeholders; `variant` accepts `paragraph` (default), `card`, `table-row`, `avatar`, `image`.\",\n \"- Use `Spinner(size?, label?, tone?)` for tiny inline loading indicators inside buttons, toolbars, or table cells.\",\n \"- Use `Image(src, alt?, caption?, ratio?, fit?, fallback?)` — `ratio` (e.g. `\\\"16:9\\\"`) makes the image self-constrain so you do not need an outer `AspectRatio`.\",\n \"- Use `Kbd([\\\"Cmd\\\", \\\"K\\\"])` when referring to keyboard shortcuts.\",\n \"- Use `Icon(name, variant?, size?)` to render a standalone Font Awesome icon (`name` is the FA name without the `fa-` prefix, e.g. `\\\"house\\\"`, `\\\"chart-line\\\"`, `\\\"regular:star\\\"`, `\\\"brands:github\\\"`).\",\n \"- For page-level titles reach for `PageHeader(...)` (top of dashboards/detail pages) or `SectionHeader(...)` (inside a Card). For tiny inline titles use `Text(value, variant=\\\"large-heavy\\\")`.\",\n ],\n },\n {\n name: \"Forms\",\n components: [\n \"Form\", \"FormControl\", \"FormSection\", \"FieldSet\", \"ValidationSummary\",\n \"Input\", \"TextArea\", \"PasswordInput\", \"MaskedInput\", \"MentionInput\", \"TagInput\",\n \"Select\", \"SelectItem\", \"Combobox\", \"MultiSelect\",\n \"Checkbox\", \"CheckBoxGroup\", \"CheckBoxItem\", \"Radio\", \"Switch\",\n \"ToggleGroup\", \"Button\", \"Buttons\", \"SearchBar\",\n \"Slider\", \"NumberInput\", \"ColorPicker\",\n \"DatePicker\", \"DateRangePicker\", \"TimePicker\", \"DateTimePicker\",\n \"FileUpload\", \"PinInput\",\n \"MultiStepForm\",\n ],\n notes: [\n \"- Each FormControl should be a separate reference for progressive streaming.\",\n \"- Pass a `$variable` as the last argument to `Input`, `Select`, `Checkbox`, `Switch`, `MultiSelect`, or `CheckBoxGroup` for two-way binding.\",\n \"- Prefer `Switch` over `Checkbox` for settings; use `ToggleGroup` for view-mode pickers and mutually-exclusive filters.\",\n \"- Reach for `SearchBar(id, placeholder?, value?, shortcut?)` instead of a raw `Input` whenever the field's purpose is to filter content. It ships with the magnifier icon and keyboard hint baked in.\",\n \"- `Slider(id, min?, max?, step?, value?, label?, showValue?)` is the canonical control for numeric ranges (volume, brightness, filters); pass a `$variable` as `value` for two-way binding.\",\n \"- `NumberInput(id, value?, min?, max?, step?, placeholder?)` is friendlier than `Input(type=\\\"number\\\")` for quantity steppers and integer settings — it ships with +/- buttons that respect `min`/`max`.\",\n \"- `DatePicker(id, value?, label?, min?, max?, placeholder?)` wraps the native date picker; pass `value` as a `$variable` for two-way binding (ISO `YYYY-MM-DD`).\",\n \"- `DateRangePicker(id, from?, to?, label?, min?, max?)` is the paired-date variant — bind both `from` and `to` to `$variable`s for a single shared range.\",\n \"- `Combobox(id, items, value?, placeholder?, emptyLabel?)` is the searchable single-select alternative to `Select` — type to filter long option lists (countries, currencies, users).\",\n \"- `MultiSelect(id, items, value?, placeholder?, emptyLabel?, max?)` is the multi-select equivalent — bind a `$variable` array as `value` for two-way binding, the trigger renders the picks as removable chips.\",\n \"- `FileUpload(id, label?, hint?, accept?, multiple?, action?)` is the styled file picker; the picked files cannot pass through a `$variable`, so wire the `action` prop to an `action` block (use a `js{ … }` body if you need to read file contents directly).\",\n \"- A submit button should call an `action` that awaits the relevant `$mutation` resource, optionally refetches a `$query`, and resets the form `$variable`s (e.g. `$title = \\\"\\\"`).\",\n \"- Button `size` accepts both `sm|md|lg` (canonical) and the legacy `small|normal|large`. Pass `icon` for an inline leading icon.\",\n \"- `FormSection(label, children, helper?)` is the canonical wrapper for related fields. Reach for it INSTEAD of nesting fields in Card + SectionHeader by hand.\",\n \"- `FieldSet(legend, children, helper?)` is the accessible `<fieldset>` for radio/checkbox groups; prefer `FormSection` for purely visual grouping.\",\n \"- `ValidationSummary(errors, title?)` renders an aggregate error panel at the top of the form. Pass `errors` as `{label, message}` objects.\",\n \"- `PasswordInput(id, value?, placeholder?, strengthMeter?)` adds a show/hide toggle and an optional 4-step strength meter — prefer over `Input(type=\\\"password\\\")` for sign-up flows.\",\n \"- `PinInput(id, length?, value?, type?)` renders per-digit code entry for 2FA / SMS verification (use `length=6` for OTP codes).\",\n \"- `TagInput(id, value?, placeholder?)` lets the user add comma- or Enter-separated chips bound to a `$variable` array.\",\n \"- `MentionInput(id, people, value?)` is a textarea with inline @-mention suggestions — use for comments, task notes, chat composers.\",\n \"- `MaskedInput(id, mask, value?)` formats input against a mask string (`9` digit, `A` letter, `*` any). Use for phone numbers, postal codes.\",\n \"- `TimePicker(id, value?)` and `DateTimePicker(id, value?)` wrap the corresponding native inputs with consistent styling.\",\n \"- `ColorPicker(id, value?, label?, swatches?)` pairs a color chip with a hex input and preset swatches — bind a $variable holding a hex string.\",\n \"- `MultiStepForm(steps, current, onSubmit?)` replaces ad-hoc `Steps` + content + manual prev/next wiring. Each step is `{title, details?, content}`.\",\n ],\n },\n {\n name: \"Data\",\n components: [\"Table\", \"Col\", \"DataGrid\", \"List\", \"ListItem\", \"StatCard\", \"Stats\", \"Sparkline\", \"Tile\", \"Progress\", \"ProgressRing\", \"Pagination\", \"Tree\", \"TreeNode\", \"CalendarView\", \"ComparisonTable\", \"InfiniteList\"],\n notes: [\n \"- Build columns using array pluck: `Col(\\\"Title\\\", data.rows.title, format?, align?)`.\",\n \"- For per-row controls inside a Col, use `@Each(data.rows, \\\"row\\\", ...)` and reference `row.field` inline.\",\n \"- `Table(cols, caption?, density?, striped?, sticky?, emptyLabel?)` — pass `density=\\\"compact\\\"` for dense data, `sticky=true` to pin the header in a scrolling parent, and `emptyLabel` for the zero-state cell.\",\n \"- `DataGrid(cols, rowIds?, caption?, sort, selectedIds, selectable?, page, perPage?, …)` is the advanced Table — adds sortable headers (`sortable=true` on Col), per-column filter chips (`filterable=true`), checkbox row selection bound to `$selectedIds`, sticky header / first column, pagination, and an optional bulk-action toolbar. Reach for this whenever a user needs to sort, filter, or page through a list.\",\n \"- `CalendarView(value?, month?, events?, view?, firstDay?, onSelect?)` renders a full-month (or week) calendar grid for scheduling apps — distinct from the `DatePicker` input. Bind `value` to a `$variable` for the selected ISO date.\",\n \"- `ComparisonTable(columns, rows, highlightColumn?)` is the generic counterpart of `PricingTable` — pass rows of `{label, values, hint?, group?}`. Use for feature comparisons, spec sheets, plan grids.\",\n \"- `InfiniteList(items, onLoadMore?, loading?, hasMore?)` is a scroll-to-load list; the action fires when the sentinel scrolls into view.\",\n \"- Use `Progress(value, max?, label?, tone?, indeterminate?, segments?, buffered?)` for linear bars — `segments` renders an N-step strip (onboarding flows), `buffered` adds a secondary buffer indicator.\",\n \"- `ProgressRing(value, max?, label?, tone?, size?)` is the circular variant for quotas/completion.\",\n \"- `Stats([{label, value, hint?, tone?, spark?}, …], layout?)` — `layout=\\\"strip\\\"` (default) for inline KPIs; `layout=\\\"grid\\\"` for a responsive StatCard grid. Pass `spark` for an inline trend line.\",\n \"- `StatCard(label, value, trend?, delta?, icon?, spark?, tone?)` gains an optional inline `Sparkline` via the `spark` prop. Use `Sparkline(values, tone?)` standalone for tiny trend chips in table cells.\",\n \"- `Tile(label, icon?, value?, description?, tone?, action?)` is the dense icon tile for quick-action menus and category grids; pair with `Grid` for uniform rows.\",\n \"- `Tree([TreeNode(label, children?, icon?, expanded?, active?, badge?, action?)])` renders a hierarchical tree (file browsers, nested navigation, category pickers); use `expanded=true` to open a branch by default.\",\n \"- `Pagination(page, totalPages, siblings?, total?, perPage?, perPageOptions?, compact?)` — bind `page` (and optionally `perPage`) to a `$variable`; pass `total` to render the \\\"Showing N–M of T\\\" summary. Reuse the same variable when slicing data with `@Filter` / `@Each`.\",\n ],\n },\n {\n name: \"Charts\",\n components: [\n \"BarChart\", \"LineChart\", \"PieChart\", \"RadarChart\",\n \"ScatterChart\", \"Histogram\", \"Heatmap\", \"Gauge\", \"Series\",\n ],\n notes: [\n \"- Use `LineChart` for trends (pass `filled=true` for area-style charts), `BarChart` for comparisons, `PieChart` for proportions, `RadarChart` for multi-axis scorecards.\",\n \"- `Heatmap(xLabels, yLabels, values)` renders a color-intensity matrix — perfect for calendar heatmaps, correlation grids, schedule density.\",\n \"- `ScatterChart(series, xLabel?, yLabel?)` plots XY points; pass each Series as `Series(name, points)` where points are `{x, y, label?}`.\",\n \"- `Histogram(values, binCount?)` bins raw numbers; pass pre-computed `bins=[{label, count}]` instead when you control the bucketing.\",\n \"- `Gauge(value, min?, max?, label?, tone?, size?)` is the half-doughnut KPI indicator for thresholds (uptime %, score, NPS).\",\n \"- Pass series via `Series(\\\"Name\\\", [...numbers])`.\",\n ],\n },\n {\n name: \"Feedback & Media\",\n components: [\n \"Avatar\", \"AvatarGroup\", \"PersonChip\", \"Tooltip\", \"HoverCard\", \"Popover\",\n \"Rating\", \"Toast\",\n \"VideoPlayer\", \"AudioPlayer\", \"Carousel\", \"Gallery\", \"Lightbox\", \"Map\",\n ],\n notes: [\n \"- `Avatar(name, src?, size?, status?)` falls back to initials when the image is missing.\",\n \"- Use `AvatarGroup` to render contributor strips with a `+N` overflow chip.\",\n \"- `PersonChip(name, role?, avatarSrc?, size?, status?, action?)` is the inline avatar + name + role pill — use everywhere a person is referenced (table cells, list rows, sidebar footers, kanban cards) instead of a raw `Avatar` next to `Text`.\",\n \"- Wrap any node in `Tooltip(label, trigger)` for inline hints.\",\n \"- Use `HoverCard(trigger, content)` when the popover needs rich content (profile preview, link target) and the trigger should open on hover.\",\n \"- `Popover(trigger, content, title?, side?, align?, width?)` is the click-triggered counterpart of `HoverCard` — use for filter panels, color pickers, share menus, and small settings flyouts. Always renders an × close button in the header; clicking the trigger again, clicking outside, or pressing Escape also closes it.\",\n \"- `Rating(value, max?, label?, count?, size?, interactive?, halfStep?, icon?)` renders stars for product reviews, testimonials, and ranked lists. Pass a `$variable` as `value` with `interactive=true` to let users rate; add `halfStep=true` so clicking the left half of a star sets a half-value. Set `icon=\\\"heart\\\"|\\\"thumb\\\"|\\\"fire\\\"|\\\"bolt\\\"` (or any FA name) to swap glyphs.\",\n \"- `Toast(title, message?, tone?, icon?, duration?, action?, onClose?, position?)` pins a transient notice; pass `duration` (ms) for auto-dismiss. Drive lists from an `action` body: `$toasts = [...$toasts, item]` to append and `$toasts = @Filter($toasts, \\\"id\\\", \\\"!=\\\", id)` to dismiss. Use `Banner` for top-of-page announcements and `Notification` for permanent inbox entries.\",\n \"- `NotificationBell(count?, items?, onOpen?)` — compact inbox trigger; `CommandPalette` for Cmd-K action search.\",\n ],\n },\n {\n name: \"Navigation\",\n components: [\"Breadcrumb\", \"BreadcrumbItem\", \"Navbar\", \"NavbarItem\", \"DropdownMenu\", \"MenuItem\", \"MenuSeparator\", \"MenuLabel\"],\n notes: [\n \"- Use `Breadcrumb([\\\"Workspace\\\", \\\"Reports\\\", \\\"Q3\\\"])` at the top of every detail page so users see the path.\",\n \"- For per-item links, pass `BreadcrumbItem(label, href)` nodes instead of strings.\",\n \"- `Navbar(brand?, items?, actions?, sticky?, variant?)` + `NavbarItem(label, to?, href?, icon?, active?, action?, external?)` produces a top navigation bar with brand on the left, links in the middle, and actions on the right — the canonical companion of `Sidebar` for marketing pages, docs, or any product surface without left-side nav.\",\n \"- `DropdownMenu(trigger, items, side?, align?, label?)` is the click-triggered dropdown menu — use it for user-profile menus, row \\\"…\\\" action menus, and any compact list of actions hanging off a single trigger. Children must be `MenuItem`, `MenuSeparator`, or `MenuLabel` entries.\",\n \"- `MenuItem(label, action?, icon?, shortcut?, variant?, disabled?)` renders a single row inside a `DropdownMenu`; use `variant=\\\"danger\\\"` for destructive actions and `MenuSeparator()`/`MenuLabel(label)` to group related items.\",\n ],\n },\n {\n name: \"Chat\",\n components: [\"SectionBlock\", \"ListBlock\", \"FollowUpBlock\", \"FollowUpItem\", \"ActionLink\", \"ChatBubble\"],\n notes: [\n \"- End most responses with a `FollowUpBlock` of 2–4 short prompts to keep the conversation moving.\",\n \"- `ChatBubble(author, body, time?, avatarSrc?, from?)` renders a single message bubble; use `from=\\\"me\\\"` for the active speaker and `from=\\\"agent\\\"` for the assistant. Compose transcripts as `Stack([ChatBubble(...), ChatBubble(...), …])` inside a `Card`.\",\n ],\n },\n {\n name: \"Patterns\",\n components: [\n \"Hero\", \"PageHeader\", \"EmptyState\",\n \"Timeline\", \"TimelineItem\", \"ActivityLog\",\n \"FeatureGrid\", \"FeatureItem\",\n \"Testimonial\", \"ProfileCard\", \"Comment\", \"Banner\", \"Notification\",\n \"InboxPanel\", \"OnboardingChecklist\",\n \"MediaCard\", \"TopBar\",\n \"KanbanBoard\", \"KanbanColumn\", \"KanbanCard\",\n \"SectionHeader\", \"Toolbar\", \"DescriptionList\", \"DescriptionItem\",\n \"StatusDot\", \"PricingTable\", \"PricingCard\",\n \"LoadingState\", \"ErrorState\", \"SuccessState\",\n \"Tour\", \"Spotlight\",\n ],\n notes: [\n \"- Patterns are **opinionated composites** that pack an entire UI idiom into one component. Reach for them BEFORE composing equivalent layouts by hand with Card+Stack — the result will look more polished and require fewer tokens.\",\n \"- `Hero(title, subtitle, primary, secondary, eyebrow?, highlights?, tone?)` — landing-style text-first header. Use `layout=\\\"cover\\\"` with `imageSrc`, `height`, and optional `caption` for image-backed hero bands.\",\n \"- `PageHeader(title, subtitle?, breadcrumbs?, actions?, status?)` — the canonical first child for any dashboard or detail page. If you omit `breadcrumbs`, the component auto-derives `[\\\"Home\\\", title]`.\",\n \"- `TopBar(title?, search?, actions?, sticky?)` — compact top strip for a content surface (panels, dialogs, embedded views). Use `AppShell` when you need a full sidebar; use `TopBar` for narrower headers above scrolling content.\",\n \"- `SectionHeader(title, subtitle?, eyebrow?, status?, actions?)` — sub-header inside a Card or panel. Use instead of bare `CardHeader` when the section also needs eyebrow / actions / status.\",\n \"- `Stats(items, layout?)` — KPI strip (`layout=\\\"strip\\\"`, default) or responsive grid (`layout=\\\"grid\\\"` with StatCard children). Prefer over hand-rolled StatCard rows.\",\n \"- `Toolbar(left?, right?, center?, searchable?, searchPlaceholder?, searchValue?)` — filter/search/actions row above a list, table, or board. Pass `searchable: true` to auto-mount a `SearchBar` (use `searchValue` to bind it to a `$variable`).\",\n \"- `EmptyState(title, description?, icon?, illustration?, actions?, action?)` — render this when a list is empty rather than an empty Card. The icon is auto-picked from the title keywords if you omit it (inbox/messages → `inbox`, charts/analytics → `chart-pie`, files/folders → `folder-open`, etc.).\",\n \"- `Timeline([TimelineItem(...)])` — vertical event feed (audit log, changelog, activity).\",\n \"- `ActivityLog(entries, variant?)` — purpose-built feed of user actions. Pass `entries` of `{actor, title, description?, time?, icon?, tone?, meta?}`; use `variant=\\\"audit\\\"` for security/admin trails with monospace meta.\",\n \"- `FeatureGrid([FeatureItem(...)])` — feature highlights with iconography.\",\n \"- `MediaCard(title, imageSrc?, description?, tags?, meta?, actions?, badge?, orientation?, ratio?)` — image + content card. Use for article previews, product cards, project highlights. Pair with `Grid` for uniform card rows.\",\n \"- `KanbanBoard([KanbanColumn(\\\"To do\\\", [KanbanCard(...), ...])])` — task boards.\",\n \"- `DescriptionList([DescriptionItem(\\\"Status\\\", Badge(...)), …])` — detail-page key/value summary. Always preferable to a Stack of Text rows on profile, billing, or metadata panels.\",\n \"- `StatusDot(label, tone?, pulse?)` — inline status pip. Use in toolbars, list rows, table cells, sidebars.\",\n \"- `Notification(title, message?, time?, icon?, avatarSrc?, tone?, unread?, actions?)` — inline notification card for notification panels / inboxes (prefer `Banner` for top-of-page announcements).\",\n \"- `InboxPanel(items, title?, onMarkAllRead?)` — `Notification` cards grouped into Unread / Earlier sections, with a shared mark-all-read action.\",\n \"- `OnboardingChecklist(items, title?, description?)` — checklist of `{title, description?, done?, action?}` items with progress. Use for product onboarding, setup wizards, getting-started panels.\",\n \"- `PricingTable([PricingCard(plan, price, period?, description?, features?, action?, badge?, featured?)])` — full pricing page block.\",\n \"- `LoadingState(title?, description?, tone?, action?)`, `ErrorState(title, description?, action?, secondaryAction?, retryLabel?)`, `SuccessState(title, description?, action?, secondaryAction?)` — full-card empty-state alternatives for asynchronous content states.\",\n \"- `Tour(steps, current, onFinish?)` and `Spotlight(title?, description?, action?)` are the product-tour primitives. `Spotlight` is a single highlighted call-out; `Tour` walks the user through multiple `{title, description, image?}` steps with Prev/Next/Skip controls and a progress dots indicator.\",\n ],\n },\n {\n name: \"Editors & overlays\",\n components: [\"RichTextEditor\", \"CodeEditor\", \"ContextMenu\"],\n notes: [\n \"- `RichTextEditor(id, value?, placeholder?, minHeight?)` is the contenteditable WYSIWYG editor — toolbar ships with bold/italic/underline/strike/heading/lists/link. Bind `value` to a `$variable` holding HTML.\",\n \"- `CodeEditor(id, value?, language?, placeholder?, minHeight?)` is a lightweight `<textarea>` with a synced line-number gutter and tab indentation. Use for snippet editors, prompt sandboxes, settings JSON.\",\n \"- `ContextMenu(target, items)` attaches a right-click menu to any node. `items` are `MenuItem` or `{label, action?, icon?, shortcut?, variant?, disabled?}` objects; pass a `MenuSeparator()` to split groups.\",\n ],\n },\n {\n name: \"App shell\",\n components: [\n \"AppShell\", \"Sidebar\", \"SidebarSection\", \"SidebarItem\", \"SplitView\",\n ],\n notes: [\n \"- App shell components produce a **full SaaS-style layout in a single statement**. Use them whenever the response represents a complete product surface (dashboards with nav, settings sections, admin consoles, inboxes).\",\n \"- `AppShell(sidebar, content, topbar?, collapsible?, sidebarOpen?)` — fixed-left navigation + scrollable main area. Pass `collapsible=true` to enable a hamburger that turns the sidebar into a slide-over drawer on mobile; bind `sidebarOpen` to a `$variable` if you want to drive that drawer programmatically.\",\n \"- `Sidebar(items, brand?, tagline?, footer?, collapsed?)` + `SidebarItem(label, icon?, active?, badge?, action?)` + `SidebarSection(label, items)` — group nav links into sections, mark the current page with `active=true`, attach badges for counts. Pass `collapsed=true` (or bind to a `$variable`) to collapse it to an icon rail.\",\n \"- `SplitView(primary, detail, primaryWidth?)` — master/detail layout (inboxes, file browsers, contact lists). Both panes are scrollable.\",\n ],\n },\n {\n name: \"Theming\",\n components: [\"Theme\"],\n notes: [\n \"- `Theme({...})` applies a partial token override **on top of** the base theme set by the host (attribute / `setTheme()`). Use it to brand a single response without changing host configuration.\",\n \"- Assign the result to a top-level binding called `theme` so the runtime picks it up:\",\n \" `theme = Theme({ colors: { primary: \\\"#0969da\\\" }, radius: { button: \\\"6px\\\" } })`\",\n \"- Tokens MUST use the structured form. Top-level groups: `colors`, `radius`, `font`, `motion`, `elevation` (plus metadata: `name`, `direction`).\",\n \"- Common tokens (each lives inside its group): `colors.primary`, `colors.primaryHover`, `colors.primaryText`, `colors.accent`, `colors.bg`, `colors.surface`, `colors.text`, `colors.textMuted`, `colors.border`, `colors.focusRing`; `radius.md`, `radius.button`, `radius.input`; `font.family`, `font.familyHeading`, `font.sizeBase`, `font.weightHeading`; `motion.transitionDuration`; `elevation.md`.\",\n \"- The legacy flat-shape form (`Theme({colorPrimary: ...})`) and free-form `--css-vars` are removed in Aktion 0.5 — the runtime drops them and the schema validator surfaces a migration warning.\",\n \"- Tokens are CSS values (`\\\"#0969da\\\"`, `\\\"'Inter', sans-serif\\\"`, `\\\"6px\\\"`, `\\\"600\\\"`). The runtime ignores unknown keys inside a group, so typos fail silent.\",\n \"- Removing the `Theme(...)` line snaps the UI back to the base theme without a reload.\",\n ],\n },\n {\n name: \"Advanced UI\",\n components: [\n \"IconButton\", \"CommandPalette\", \"FilterChips\", \"FieldRepeater\",\n \"VirtualList\", \"QueryBuilder\", \"DiffViewer\", \"JsonTree\", \"Gantt\",\n \"Truncate\", \"InlineEdit\", \"NotificationBell\",\n ],\n notes: [\n \"- `IconButton(icon, label, action?, variant?, size?, disabled?)` — accessible icon-only control.\",\n \"- `CommandPalette(items, open?, placeholder?, shortcut?)` — Cmd-K searchable actions.\",\n \"- `FilterChips(chips, onRemove?, onClear?)` — applied filter pills with remove.\",\n \"- `FieldRepeater(items, fields, onAdd?, onRemove?)` — dynamic form rows.\",\n \"- `VirtualList(items, itemHeight?, renderItem)` — windowed long lists.\",\n \"- `QueryBuilder(fields, value?)` — visual AND/OR filter builder.\",\n \"- `DiffViewer(left, right, mode?)` — side-by-side or unified diff.\",\n \"- `JsonTree(data)` — collapsible JSON inspector.\",\n \"- `Gantt(tasks, startDate?, endDate?)` — horizontal schedule timeline.\",\n \"- `Truncate(text, maxLines?)` / `InlineEdit(value, onSave?)` / `NotificationBell(count?, items?)`.\",\n ],\n },\n {\n name: \"Routing\",\n components: [\"NavLink\"],\n notes: [\n \"- Declare routes with the `_router_({...})` call form: `pages = _router_({ \\\"/\\\": Dashboard(), \\\"/orders/:id\\\": OrderDetail(id: params.id), default: NotFound() })`. The matched arm's `params` object is in scope on the right-hand side; nest `_router_` inside components for layout-preserving sub-routes.\",\n \"- `Redirect(path)` is a router-aware component: returning it from a route's body navigates and unmounts the rest of the subtree.\",\n \"- `NavLink(label, to)` is a thin link wrapper that reads `_route_.path` and dispatches `_route_.navigate(to)` — use it for sidebars, navbars and breadcrumbs.\",\n \"- Read URL params via `_route_.params.<name>` (e.g. `_route_.params.id` for `/users/:id`) and the current path via `_route_.path`.\",\n ],\n },\n {\n name: \"Helpers\",\n components: [\"Async\", \"Show\", \"Portal\", \"Redirect\", \"Lazy\", \"ErrorBoundary\"],\n notes: [\n \"- `Async(resource, loading:, error:, empty:, data:)` switches a `$query` / `$mutation` / `$subscription` resource on its `state` field.\",\n \"- `Show(when, fallback?, children)` is sugar over `if expr { children } else { fallback }`.\",\n \"- `Portal(target?, children)` renders into a different DOM subtree (defaults to `document.body`).\",\n \"- `Redirect(path)` is a router-aware component — see Routing.\",\n \"- `Lazy(loader, fallback?)` defers children until `loader` resolves.\",\n \"- `ErrorBoundary(fallback?, onError?, children)` catches rendering errors thrown by descendants.\",\n ],\n },\n];\n\n// Aktion 0.5 §19.1 — fail-fast guard: no library spec may\n// declare more than one `positional: true` prop. Surfaces as a clear\n// SyntaxError at module load so a broken spec never ships.\nassertOnePositionalMax(components);\n\nexport const defaultLibrary: ComponentLibrary = {\n root: \"Stack\",\n components,\n componentGroups,\n};\n","/**\n * Render an evaluated program tree into the shadow DOM.\n *\n * The renderer walks the tree and asks the library for a render function\n * per component. Each component still produces a fresh DOM subtree, but the\n * renderer keeps a stable identity per instance (derived from its path in\n * the tree) so:\n *\n * - `helpers.useInstanceState(key, initial)` returns the same storage\n * cell across re-renders. Stateful primitives (`Tabs`, `Accordion`,\n * custom widgets) use it to keep UI state stable while unrelated\n * re-renders sweep through.\n * - `helpers.bindState(...)` attaches its event listener as a DOM\n * property (`el.oninput = fn`) so the `morph` reconciler can transfer\n * the closure onto a kept element when the tree is patched in place.\n */\n\nimport {\n isComponentNode,\n isUserComponentNode,\n evaluateUserComponent,\n type ComponentNode,\n type EvaluationContext,\n type UserComponentNode,\n} from \"../runtime/evaluator.js\";\nimport type { StateStore } from \"../runtime/state.js\";\nimport type { Router } from \"../runtime/router.js\";\nimport { sanitiseHref } from \"../library/utils.js\";\nimport { findComponent } from \"../library/registry.js\";\nimport {\n mapPositionalArgs,\n type ComponentLibrary,\n type InstanceStateSlot,\n type RenderHelpers,\n} from \"../library/types.js\";\n\nexport interface RenderOptions {\n library: ComponentLibrary;\n state: StateStore;\n /** Hash-based router. Required: components read the active path through it. */\n router: Router;\n /** Optional callback for `helpers.sendToAssistant(message)` dispatch. */\n onAssistantMessage?: (message: string) => void;\n /** Optional override for `helpers.openUrl(url)` (defaults to `window.open`). */\n onOpenUrl?: (url: string) => void;\n /**\n * Evaluation context used to expand user-declared `component` calls\n * (per-instance state isolation, lazy body evaluation, §7). The host\n * element passes its program context here; if absent, user components\n * render as `[unknown component: <Name>]` so the failure is visible.\n */\n evaluationContext?: () => EvaluationContext;\n}\n\nconst ROOT_PATH = \"$\";\n\nexport class Renderer {\n /**\n * Persistent state cells, keyed by `instancePath::userKey`. Lives as long\n * as the component instance is rendered. Stale entries are garbage-\n * collected at the end of each render (see `endRender`).\n */\n private readonly instanceStates = new Map<string, unknown>();\n /**\n * Cleanup callbacks per instance path. Each entry holds either a single\n * disposer (anonymous registration) or a map keyed by user-provided\n * identifier so callers can register, replace, and (transitively) cancel\n * prior cleanups for the same logical concern.\n */\n private readonly instanceDisposers = new Map<string, Map<string, () => void>>();\n /** Instance paths seen during the current render — used to GC stale state. */\n private aliveInstances = new Set<string>();\n\n constructor(private options: RenderOptions) {}\n\n /**\n * Swap the component library backing this renderer. Used when the host\n * element calls `registerComponents(...)` after first paint — preserves\n * any `useInstanceState` slots so stateful primitives (Tabs, Popover,\n * DropdownMenu, …) don't snap back to their initial values mid-session.\n */\n setLibrary(library: ComponentLibrary): void {\n this.options = { ...this.options, library };\n }\n\n /**\n * Drop all persistent per-instance state. Called when the host element\n * is `clear()`ed so a fresh program starts with a clean slate.\n */\n reset(): void {\n // Run every registered disposer before dropping references so timers /\n // listeners installed by primitives don't outlive a `clear()` call.\n for (const disposers of this.instanceDisposers.values()) {\n for (const dispose of disposers.values()) {\n this.safeDispose(dispose);\n }\n }\n this.instanceDisposers.clear();\n this.instanceStates.clear();\n this.aliveInstances = new Set<string>();\n }\n\n /** Begin a fresh render pass; tracks which instances are still alive. */\n beginRender(): void {\n this.aliveInstances = new Set<string>();\n }\n\n /**\n * End the current render pass. Drops instance state for components that\n * disappeared from the tree so the map doesn't grow unbounded.\n */\n endRender(): void {\n const alive = this.aliveInstances;\n for (const key of [...this.instanceStates.keys()]) {\n // `key` has the form `${instancePath}::${userKey}`. Walk back to the\n // instance prefix and check liveness in one go.\n const sepIdx = key.lastIndexOf(\"::\");\n const instancePath = sepIdx === -1 ? key : key.slice(0, sepIdx);\n if (!alive.has(instancePath)) {\n this.instanceStates.delete(key);\n }\n }\n // Run disposers for any instance that disappeared from the tree so\n // background work (setTimeout handles, listener installs) does not\n // outlive the component the user can see.\n for (const [instancePath, disposers] of [...this.instanceDisposers.entries()]) {\n if (alive.has(instancePath)) continue;\n for (const dispose of disposers.values()) this.safeDispose(dispose);\n this.instanceDisposers.delete(instancePath);\n }\n }\n\n private safeDispose(dispose: () => void): void {\n try {\n dispose();\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\"[aktion] disposer threw\", err);\n }\n }\n\n render(value: unknown): Node {\n return this.renderAt(value, ROOT_PATH);\n }\n\n private renderAt(value: unknown, path: string): Node {\n if (value === null || value === undefined) return document.createTextNode(\"\");\n if (Array.isArray(value)) {\n const fragment = document.createDocumentFragment();\n value.forEach((item, idx) => {\n fragment.append(this.renderAt(item, `${path}/${idx}`));\n });\n return fragment;\n }\n if (isUserComponentNode(value)) return this.renderUserComponent(value, path);\n if (isComponentNode(value)) return this.renderComponent(value, path);\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return document.createTextNode(String(value));\n }\n return document.createTextNode(\"\");\n }\n\n /**\n * Expand a user-declared `component Foo(p) { ... }` invocation. Each\n * instance gets a stable instance key derived from its render path (or\n * the caller's explicit `key:` override); the evaluator then evaluates\n * the component's body with a fresh per-instance state-alias scope so\n * two `Counter()` instances hold independent atoms (§7).\n */\n private renderUserComponent(node: UserComponentNode, path: string): Node {\n const ctxRef = this.options.evaluationContext;\n if (!ctxRef) {\n const placeholder = document.createElement(\"div\");\n placeholder.className = \"rui-unknown-component\";\n placeholder.textContent = `[unknown component: ${node.decl.name}]`;\n return placeholder;\n }\n const ctx = ctxRef();\n // Instance key combines the structural render path with the\n // declaration name and source location so reordering siblings doesn't\n // accidentally reuse another instance's state. An explicit `key:` arg\n // takes precedence (§13 — content-addressed identity).\n const keyPart = node.explicitKey != null\n ? `=${String(node.explicitKey)}`\n : `@${node.source?.line ?? 0}:${node.source?.column ?? 0}`;\n const instancePath = `${path}#${node.decl.name}${keyPart}`;\n this.aliveInstances.add(instancePath);\n const body = evaluateUserComponent(node, ctx, instancePath);\n return this.renderAt(body, instancePath);\n }\n\n private renderComponent(node: ComponentNode, path: string): Node {\n const spec = findComponent(this.options.library, node.name);\n if (!spec) {\n const placeholder = document.createElement(\"div\");\n placeholder.className = \"rui-unknown-component\";\n placeholder.textContent = `[unknown component: ${node.name}]`;\n return placeholder;\n }\n const props = mapPositionalArgs(spec, node.args);\n // §13 — when the author passes `key:`, use it as the instance suffix\n // so reordering siblings keeps per-instance state attached to the\n // right node. Otherwise fall back to the source location which is\n // stable for non-reordered trees.\n const keySuffix = node.explicitKey != null\n ? `=${String(node.explicitKey)}`\n : `@${node.source?.line ?? 0}:${node.source?.column ?? 0}`;\n const instancePath = `${path}#${node.name}${keySuffix}`;\n this.aliveInstances.add(instancePath);\n\n // Track an auto-increment counter so `helpers.renderNode(child)` calls\n // get a stable sibling index even when a component renders several\n // children in a row.\n let childCounter = 0;\n const helpers: RenderHelpers = {\n renderNode: (childValue) => this.renderAt(childValue, `${instancePath}>${childCounter++}`),\n invoke: (callable, ...args) => {\n if (typeof callable !== \"function\") return;\n try {\n const result = callable(...args);\n if (result && typeof (result as Promise<unknown>).then === \"function\") {\n (result as Promise<unknown>).catch((err) => {\n // eslint-disable-next-line no-console\n console.error(\"[aktion] handler rejected\", err);\n });\n }\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\"[aktion] handler threw\", err);\n }\n },\n setState: (name, value) => {\n this.options.state.set(name, value);\n },\n resetState: (...names) => {\n this.options.state.reset(...names);\n },\n sendToAssistant: (message) => {\n this.options.onAssistantMessage?.(message);\n },\n openUrl: (url) => {\n const safeUrl = sanitiseHref(url, \"#\");\n const opener = this.options.onOpenUrl;\n if (opener) opener(safeUrl);\n else if (safeUrl !== \"#\" && typeof window !== \"undefined\") {\n window.open(safeUrl, \"_blank\", \"noopener,noreferrer\");\n }\n },\n bindState: (element, name, options) => {\n const eventName = options?.event ?? this.eventFor(element);\n const propKey = `on${eventName}`;\n const getter = options?.getValue ?? this.defaultValueGetter(element);\n // Property-based assignment so the morph reconciler can transfer\n // this handler onto a kept element. CRITICAL: read the value off\n // `event.currentTarget` (the element the listener fires on, which\n // is always the *live* DOM node) rather than the closure-captured\n // `element` — the fresh render's element becomes detached the\n // moment morph reuses the previous DOM node, and its `.value`\n // never sees the user's keystroke.\n (element as unknown as Record<string, unknown>)[propKey] = (event: Event) => {\n const target = (event.currentTarget ?? event.target ?? element) as HTMLElement;\n this.options.state.set(name, getter(target));\n };\n },\n useInstanceState: <T>(key: string, initialValue: T): InstanceStateSlot<T> => {\n const storageKey = `${instancePath}::${key}`;\n if (!this.instanceStates.has(storageKey)) {\n this.instanceStates.set(storageKey, initialValue);\n }\n return {\n get: () => this.instanceStates.get(storageKey) as T,\n set: (value: T) => {\n this.instanceStates.set(storageKey, value);\n },\n };\n },\n registerDisposer: (cleanup: () => void, key?: string): void => {\n let bucket = this.instanceDisposers.get(instancePath);\n if (!bucket) {\n bucket = new Map();\n this.instanceDisposers.set(instancePath, bucket);\n }\n // Generate a stable key when the caller didn't provide one so each\n // anonymous registration gets its own slot (and never replaces a\n // previous one by accident).\n const slot = key ?? `__anon::${bucket.size}`;\n const prior = bucket.get(slot);\n if (prior && prior !== cleanup) this.safeDispose(prior);\n bucket.set(slot, cleanup);\n },\n router: this.options.router,\n };\n try {\n return spec.render(node, props, helpers);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(`[aktion] failed to render ${spec.name}`, err);\n const fallback = document.createElement(\"div\");\n fallback.className = \"rui-render-error\";\n fallback.textContent = `[render error in ${spec.name}]`;\n return fallback;\n }\n }\n\n private eventFor(element: HTMLElement): string {\n if (element instanceof HTMLSelectElement) return \"change\";\n if (element instanceof HTMLInputElement && (element.type === \"checkbox\" || element.type === \"radio\")) return \"change\";\n return \"input\";\n }\n\n private defaultValueGetter(element: HTMLElement): (el: HTMLElement) => unknown {\n if (element instanceof HTMLInputElement && element.type === \"checkbox\") {\n return (el) => (el as HTMLInputElement).checked;\n }\n if (element instanceof HTMLInputElement && element.type === \"radio\") {\n return (el) => (el as HTMLInputElement).value;\n }\n if (element instanceof HTMLInputElement && element.type === \"number\") {\n // Empty input → null (Number(\"\") would coerce to 0 and silently\n // overwrite a cleared field with a sentinel value). Invalid input\n // also returns null so $variables see a typed value or \"no value\".\n return (el) => {\n const raw = (el as HTMLInputElement).value;\n if (raw === \"\") return null;\n const n = Number(raw);\n return Number.isFinite(n) ? n : null;\n };\n }\n if (element instanceof HTMLInputElement && element.type === \"range\") {\n return (el) => Number((el as HTMLInputElement).value);\n }\n return (el) => (el as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement).value;\n }\n}\n","/**\n * Minimal DOM reconciler (\"morph\").\n *\n * The renderer used to discard the whole subtree on every state change and\n * recreate it from scratch (`replaceChildren(newTree)`). That works for static\n * UIs but destroys any state the browser owns on the live DOM:\n *\n * - text-input value, selection, IME composition\n * - scroll position of a long list\n * - <details>.open after the user clicked the summary\n * - focus on a typed input (email/number/url, where setSelectionRange\n * throws and the cursor jumps to the start)\n *\n * `morphChildren(container, newRoot)` walks the live DOM in parallel with the\n * freshly-rendered DOM, keeps as many existing nodes as possible, and only\n * patches what changed. The result is a React-like reconciliation pass that\n * keeps form fields stable while still letting the renderer rebuild the\n * tree every tick.\n *\n * Two contracts the rest of the runtime relies on:\n *\n * 1. Event handlers are attached as DOM properties (`el.onclick = fn`)\n * rather than via `addEventListener`. This lets the morph copy the\n * fresh closure (`newEl.onclick`) onto the kept node (`oldEl.onclick`)\n * without leaking the previous listener.\n * 2. Components that own UI state across re-renders (e.g. `Tabs` active\n * pane) use `helpers.useInstanceState(...)`. The morph just reuses\n * the existing DOM; whatever attribute values land in the fresh tree\n * are the ones that get applied.\n */\n\nconst EVENT_PROPS = [\n \"onclick\",\n \"oninput\",\n \"onchange\",\n \"onsubmit\",\n \"onfocus\",\n \"onblur\",\n \"onkeydown\",\n \"onkeyup\",\n \"onkeypress\",\n \"onerror\",\n \"onmouseenter\",\n \"onmouseleave\",\n \"onmousedown\",\n \"onmouseup\",\n \"onpointerdown\",\n \"onpointerup\",\n] as const;\n\ntype EventHandlerKey = (typeof EVENT_PROPS)[number];\n\n/**\n * Patch `container` so its children match `newRoot`. `newRoot` can be a\n * `DocumentFragment` (treated as a sibling list) or a single node (treated\n * as the sole child).\n */\nexport function morphChildren(container: Element, newRoot: Node): void {\n const newChildren: Node[] =\n newRoot.nodeType === Node.DOCUMENT_FRAGMENT_NODE\n ? Array.from(newRoot.childNodes)\n : [newRoot];\n reconcileChildren(container, newChildren);\n}\n\n/**\n * Reconcile a single live node against its freshly-rendered counterpart.\n * Returns the resulting node (either the patched `oldNode` or a freshly\n * inserted `newNode`).\n */\nexport function morphNode(oldNode: Node, newNode: Node): Node {\n if (oldNode === newNode) return oldNode;\n if (oldNode.nodeType !== newNode.nodeType) {\n return replaceNode(oldNode, newNode);\n }\n if (oldNode.nodeType === Node.TEXT_NODE) {\n if (oldNode.textContent !== newNode.textContent) {\n oldNode.textContent = newNode.textContent;\n }\n return oldNode;\n }\n if (oldNode.nodeType !== Node.ELEMENT_NODE) {\n return oldNode;\n }\n const oldEl = oldNode as Element;\n const newEl = newNode as Element;\n if (oldEl.tagName !== newEl.tagName) {\n return replaceNode(oldEl, newEl);\n }\n patchElement(oldEl, newEl);\n return oldEl;\n}\n\nfunction replaceNode(oldNode: Node, newNode: Node): Node {\n oldNode.parentNode?.replaceChild(newNode, oldNode);\n return newNode;\n}\n\nfunction patchElement(oldEl: Element, newEl: Element): void {\n syncAttributes(oldEl, newEl);\n syncEventHandlers(oldEl, newEl);\n // Reconcile children FIRST so that <select>.value can resolve against\n // its freshly-patched <option>s, and so descendant inputs are stable\n // before we apply any parent-level form-state updates.\n reconcileChildren(oldEl, Array.from(newEl.childNodes));\n syncFormState(oldEl, newEl);\n}\n\nfunction syncAttributes(oldEl: Element, newEl: Element): void {\n const oldAttrs = oldEl.attributes;\n for (let i = oldAttrs.length - 1; i >= 0; i -= 1) {\n const attr = oldAttrs[i]!;\n if (newEl.hasAttribute(attr.name)) continue;\n // `<details>.open` is user-toggleable. Never strip it just because the\n // fresh render didn't emit it (it usually never does — the LLM only\n // sets the initial value via the `open` prop).\n if (attr.name === \"open\" && oldEl.tagName === \"DETAILS\") continue;\n oldEl.removeAttribute(attr.name);\n }\n const newAttrs = newEl.attributes;\n for (let i = 0; i < newAttrs.length; i += 1) {\n const attr = newAttrs[i]!;\n if (oldEl.getAttribute(attr.name) !== attr.value) {\n oldEl.setAttribute(attr.name, attr.value);\n }\n }\n}\n\nfunction syncEventHandlers(oldEl: Element, newEl: Element): void {\n // Property-based events (e.g. `el.onclick = fn`) are copied verbatim from\n // the freshly-rendered node onto the kept node so the closure captures\n // the latest props / actions. Listeners registered via addEventListener\n // are not transferable — see this module's header.\n for (const key of EVENT_PROPS) {\n const fresh = (newEl as unknown as Record<EventHandlerKey, unknown>)[key];\n const current = (oldEl as unknown as Record<EventHandlerKey, unknown>)[key];\n if (fresh === current) continue;\n (oldEl as unknown as Record<EventHandlerKey, unknown>)[key] = (fresh ?? null) as unknown;\n }\n}\n\nfunction syncFormState(oldEl: Element, newEl: Element): void {\n if (oldEl instanceof HTMLInputElement && newEl instanceof HTMLInputElement) {\n syncInput(oldEl, newEl);\n return;\n }\n if (oldEl instanceof HTMLTextAreaElement && newEl instanceof HTMLTextAreaElement) {\n syncTextArea(oldEl, newEl);\n return;\n }\n if (oldEl instanceof HTMLSelectElement && newEl instanceof HTMLSelectElement) {\n if (!isFocused(oldEl) && oldEl.value !== newEl.value) {\n oldEl.value = newEl.value;\n }\n return;\n }\n // <details>.open is intentionally treated as user-owned state — see the\n // attribute pass above; the property never gets touched here.\n}\n\nfunction syncInput(oldEl: HTMLInputElement, newEl: HTMLInputElement): void {\n if (oldEl.type === \"checkbox\" || oldEl.type === \"radio\") {\n const desired = newEl.hasAttribute(\"checked\") || newEl.checked;\n if (oldEl.checked !== desired && !isFocused(oldEl)) {\n oldEl.checked = desired;\n }\n return;\n }\n // For text-like inputs, only overwrite `.value` when the user isn't\n // actively focused (otherwise we'd nuke an in-flight keystroke / IME\n // composition). When focused, two-way binding has already pushed the\n // freshest characters into the DOM property anyway.\n const desired = newEl.getAttribute(\"value\") ?? newEl.value ?? \"\";\n if (!isFocused(oldEl) && oldEl.value !== desired) {\n oldEl.value = desired;\n }\n}\n\nfunction syncTextArea(oldEl: HTMLTextAreaElement, newEl: HTMLTextAreaElement): void {\n const desired = newEl.value ?? newEl.textContent ?? \"\";\n if (!isFocused(oldEl) && oldEl.value !== desired) {\n oldEl.value = desired;\n }\n}\n\nfunction isFocused(el: Element): boolean {\n const root = el.getRootNode();\n if (root instanceof ShadowRoot || root instanceof Document) {\n return root.activeElement === el;\n }\n return el.ownerDocument?.activeElement === el;\n}\n\nfunction reconcileChildren(parent: Element, newChildren: Node[]): void {\n // Index live keyed elements so we can reuse them even when a sibling\n // shifts position (e.g. the LLM reorders a list).\n const keyedOld = new Map<string, Element>();\n for (const child of Array.from(parent.childNodes)) {\n const key = keyFor(child);\n if (key) keyedOld.set(key, child as Element);\n }\n\n let cursorIndex = 0;\n for (const newChild of newChildren) {\n const live = parent.childNodes[cursorIndex] ?? null;\n const newKey = keyFor(newChild);\n\n if (newKey && keyedOld.has(newKey)) {\n const matched = keyedOld.get(newKey)!;\n keyedOld.delete(newKey);\n if (matched !== live) {\n parent.insertBefore(matched, live);\n }\n morphNode(matched, newChild);\n cursorIndex += 1;\n continue;\n }\n\n if (!live) {\n parent.appendChild(newChild);\n cursorIndex += 1;\n continue;\n }\n\n const liveKey = keyFor(live);\n if (liveKey && (!newKey || liveKey !== newKey)) {\n // The live child is keyed and we still need it for a later slot.\n // Park it: insert the new (unkeyed) child before it.\n parent.insertBefore(newChild, live);\n cursorIndex += 1;\n continue;\n }\n\n morphNode(live, newChild);\n cursorIndex += 1;\n }\n\n // Drop any leftover live children that the new tree no longer wants —\n // including keyed ones that were never reclaimed.\n while (parent.childNodes.length > newChildren.length) {\n const surplus = parent.childNodes[parent.childNodes.length - 1]!;\n parent.removeChild(surplus);\n }\n}\n\nfunction keyFor(node: Node): string | null {\n if (node.nodeType !== Node.ELEMENT_NODE) return null;\n const el = node as Element;\n if (el.id) return `#${el.id}`;\n const dataKey = el.getAttribute(\"data-rui-key\");\n if (dataKey) return `@${dataKey}`;\n return null;\n}\n","/**\n * Built-in `@Name(...)` catalog.\n *\n * Sourced (by name) from `src/runtime/builtins.ts` plus the action steps\n * handled directly in the evaluator. Each entry carries a short description\n * and parameter signature so editors can show argument hints.\n *\n * Adding a new builtin to the runtime? Add an entry here too — the test\n * suite guards the union (see `tests/language.test.ts`).\n */\n\nimport { dataBuiltins } from \"../runtime/builtins.js\";\n\nexport interface BuiltinParam {\n name: string;\n type: string;\n required: boolean;\n description?: string;\n}\n\nexport interface BuiltinEntry {\n name: string;\n category: \"data\" | \"iteration\";\n description: string;\n params: BuiltinParam[];\n signature: string;\n}\n\nconst DATA_DESCRIPTIONS: Record<string, Omit<BuiltinEntry, \"name\" | \"category\" | \"signature\">> = {\n Count: {\n description: \"Number of items in an array.\",\n params: [{ name: \"array\", type: \"any[]\", required: true }],\n },\n Sum: {\n description: \"Sum of numeric values in an array.\",\n params: [{ name: \"array\", type: \"number[]\", required: true }],\n },\n Avg: {\n description: \"Average of numeric values in an array.\",\n params: [{ name: \"array\", type: \"number[]\", required: true }],\n },\n Min: {\n description: \"Minimum of numeric values in an array.\",\n params: [{ name: \"array\", type: \"number[]\", required: true }],\n },\n Max: {\n description: \"Maximum of numeric values in an array.\",\n params: [{ name: \"array\", type: \"number[]\", required: true }],\n },\n First: {\n description: \"First element of an array, or null.\",\n params: [{ name: \"array\", type: \"any[]\", required: true }],\n },\n Last: {\n description: \"Last element of an array, or null.\",\n params: [{ name: \"array\", type: \"any[]\", required: true }],\n },\n Filter: {\n description: \"Filter an array by a field/operator/value comparison.\",\n params: [\n { name: \"array\", type: \"any[]\", required: true },\n { name: \"field\", type: \"string\", required: true },\n { name: \"op\", type: \"'=='|'!='|'>'|'<'|'>='|'<='|'contains'\", required: true },\n { name: \"value\", type: \"any\", required: true },\n ],\n },\n FilterBy: {\n description: \"Alias for `@Filter` — filter an array by a field/operator/value comparison.\",\n params: [\n { name: \"array\", type: \"any[]\", required: true },\n { name: \"field\", type: \"string\", required: true },\n { name: \"op\", type: \"'=='|'!='|'>'|'<'|'>='|'<='|'contains'\", required: true },\n { name: \"value\", type: \"any\", required: true },\n ],\n },\n Sort: {\n description: \"Sort an array by a field, ascending or descending.\",\n params: [\n { name: \"array\", type: \"any[]\", required: true },\n { name: \"field\", type: \"string\", required: true },\n { name: \"direction\", type: \"'asc'|'desc'\", required: false },\n ],\n },\n Round: {\n description: \"Round a number to N decimals (default 0).\",\n params: [\n { name: \"value\", type: \"number\", required: true },\n { name: \"decimals\", type: \"number\", required: false },\n ],\n },\n Abs: {\n description: \"Absolute value of a number.\",\n params: [{ name: \"value\", type: \"number\", required: true }],\n },\n Floor: {\n description: \"Round a number down to the nearest integer.\",\n params: [{ name: \"value\", type: \"number\", required: true }],\n },\n Ceil: {\n description: \"Round a number up to the nearest integer.\",\n params: [{ name: \"value\", type: \"number\", required: true }],\n },\n Find: {\n description: \"Find the first item matching a field/op/value comparator.\",\n params: [\n { name: \"array\", type: \"any[]\", required: true },\n { name: \"field\", type: \"string\", required: true },\n { name: \"op\", type: \"'=='|'!='|'>'|'<'|'>='|'<='|'contains'\", required: true },\n { name: \"value\", type: \"any\", required: true },\n ],\n },\n GroupBy: {\n description: \"Group items into `{groupKey: [items…]}` by a field value.\",\n params: [\n { name: \"array\", type: \"any[]\", required: true },\n { name: \"field\", type: \"string\", required: true },\n ],\n },\n Slice: {\n description: \"Slice an array by `[start, end)` — both indices optional.\",\n params: [\n { name: \"array\", type: \"any[]\", required: true },\n { name: \"start\", type: \"number\", required: false },\n { name: \"end\", type: \"number\", required: false },\n ],\n },\n Unique: {\n description: \"Deduplicate. With a `field`, dedupes by that field (first wins).\",\n params: [\n { name: \"array\", type: \"any[]\", required: true },\n { name: \"field\", type: \"string\", required: false },\n ],\n },\n Reverse: {\n description: \"Return a reversed copy of the array (non-mutating).\",\n params: [{ name: \"array\", type: \"any[]\", required: true }],\n },\n Range: {\n description: \"Inclusive integer range. Third arg is the step (default 1 / -1).\",\n params: [\n { name: \"start\", type: \"number\", required: true },\n { name: \"end\", type: \"number\", required: true },\n { name: \"step\", type: \"number\", required: false },\n ],\n },\n Repeat: {\n description: \"Repeat a value N times. Useful for skeleton/placeholder grids.\",\n params: [\n { name: \"value\", type: \"any\", required: true },\n { name: \"count\", type: \"number\", required: true },\n ],\n },\n Pick: {\n description: \"Keep only the listed keys from an object — `@Pick(obj, [\\\"a\\\",\\\"b\\\"])`.\",\n params: [\n { name: \"object\", type: \"object\", required: true },\n { name: \"keys\", type: \"string[]\", required: true },\n ],\n },\n Format: {\n description: \"Locale-aware number formatter. Modes: 'currency', 'percent', 'number'.\",\n params: [\n { name: \"value\", type: \"number\", required: true },\n { name: \"mode\", type: \"'currency'|'percent'|'number'\", required: false },\n { name: \"currencyOrLocale\", type: \"string\", required: false },\n { name: \"locale\", type: \"string\", required: false },\n ],\n },\n FormatDate: {\n description: \"Format a date. Pattern tokens (MMM D, YYYY-MM-DD) or named: 'relative', 'date', 'time', 'datetime', 'iso'.\",\n params: [\n { name: \"value\", type: \"Date|number|string\", required: true },\n { name: \"format\", type: \"string\", required: false },\n ],\n },\n Now: {\n description: \"Current moment as epoch ms — pair with `@FormatDate`.\",\n params: [],\n },\n Today: {\n description: \"Today's date at midnight, as an ISO string.\",\n params: [],\n },\n AddDays: {\n description: \"Shift a date by N days (negative N moves backward).\",\n params: [\n { name: \"date\", type: \"Date|number|string\", required: true },\n { name: \"days\", type: \"number\", required: true },\n ],\n },\n AddHours: {\n description: \"Shift a date by N hours (negative N moves backward).\",\n params: [\n { name: \"date\", type: \"Date|number|string\", required: true },\n { name: \"hours\", type: \"number\", required: true },\n ],\n },\n DiffDays: {\n description: \"Whole-day difference from start to end (end − start).\",\n params: [\n { name: \"start\", type: \"Date|number|string\", required: true },\n { name: \"end\", type: \"Date|number|string\", required: true },\n ],\n },\n StartOfWeek: {\n description: \"Local Sunday 00:00:00 for the week containing the date.\",\n params: [{ name: \"date\", type: \"Date|number|string\", required: true }],\n },\n EndOfMonth: {\n description: \"Last moment of the calendar month containing the date.\",\n params: [{ name: \"date\", type: \"Date|number|string\", required: true }],\n },\n Plural: {\n description: \"Pluralisation: `@Plural(n, \\\"order\\\", \\\"orders\\\")` → \\\"1 order\\\" / \\\"2 orders\\\".\",\n params: [\n { name: \"count\", type: \"number\", required: true },\n { name: \"singular\", type: \"string\", required: true },\n { name: \"plural\", type: \"string\", required: false },\n ],\n },\n Capitalize: {\n description: \"Uppercase the first character.\",\n params: [{ name: \"value\", type: \"string\", required: true }],\n },\n Lowercase: {\n description: \"Lowercase every character.\",\n params: [{ name: \"value\", type: \"string\", required: true }],\n },\n Uppercase: {\n description: \"Uppercase every character.\",\n params: [{ name: \"value\", type: \"string\", required: true }],\n },\n Titlecase: {\n description: \"Capitalise the first letter of each word.\",\n params: [{ name: \"value\", type: \"string\", required: true }],\n },\n Case: {\n description: \"Convert casing — mode: \\\"camel\\\", \\\"snake\\\", \\\"kebab\\\", or \\\"pascal\\\".\",\n params: [\n { name: \"value\", type: \"string\", required: true },\n { name: \"mode\", type: \"'camel'|'snake'|'kebab'|'pascal'\", required: true },\n ],\n },\n Join: {\n description: \"Join array values into a string (default separator \\\",\\\").\",\n params: [\n { name: \"array\", type: \"any[]\", required: true },\n { name: \"separator\", type: \"string\", required: false },\n ],\n },\n Split: {\n description: \"Split a string by a separator (default \\\",\\\").\",\n params: [\n { name: \"value\", type: \"string\", required: true },\n { name: \"separator\", type: \"string\", required: false },\n ],\n },\n Trim: {\n description: \"Trim leading and trailing whitespace.\",\n params: [{ name: \"value\", type: \"string\", required: true }],\n },\n Replace: {\n description: \"Replace all occurrences of search with replacement.\",\n params: [\n { name: \"value\", type: \"string\", required: true },\n { name: \"search\", type: \"string\", required: true },\n { name: \"replacement\", type: \"string\", required: false },\n ],\n },\n Substring: {\n description: \"Extract a substring — `start`, optional `end`.\",\n params: [\n { name: \"value\", type: \"string\", required: true },\n { name: \"start\", type: \"number\", required: true },\n { name: \"end\", type: \"number\", required: false },\n ],\n },\n StartsWith: {\n description: \"True when the string starts with the given prefix.\",\n params: [\n { name: \"value\", type: \"string\", required: true },\n { name: \"prefix\", type: \"string\", required: true },\n ],\n },\n EndsWith: {\n description: \"True when the string ends with the given suffix.\",\n params: [\n { name: \"value\", type: \"string\", required: true },\n { name: \"suffix\", type: \"string\", required: true },\n ],\n },\n Contains: {\n description: \"True when the string contains the given substring.\",\n params: [\n { name: \"value\", type: \"string\", required: true },\n { name: \"needle\", type: \"string\", required: true },\n ],\n },\n Match: {\n description: \"Test a string against a RegExp pattern (invalid patterns return false).\",\n params: [\n { name: \"value\", type: \"string\", required: true },\n { name: \"pattern\", type: \"string\", required: true },\n ],\n },\n Clamp: {\n description: \"Clamp a number into `[min, max]`.\",\n params: [\n { name: \"value\", type: \"number\", required: true },\n { name: \"min\", type: \"number\", required: true },\n { name: \"max\", type: \"number\", required: true },\n ],\n },\n Pow: {\n description: \"Raise a number to a power — `Math.pow(base, exp)`.\",\n params: [\n { name: \"base\", type: \"number\", required: true },\n { name: \"exp\", type: \"number\", required: true },\n ],\n },\n Sqrt: {\n description: \"Square root of a number.\",\n params: [{ name: \"value\", type: \"number\", required: true }],\n },\n Random: {\n description: \"Pseudo-random number in [0, 1) — `Math.random()`.\",\n params: [],\n },\n Log: {\n description: \"Natural logarithm — `Math.log(value)`.\",\n params: [{ name: \"value\", type: \"number\", required: true }],\n },\n};\n\n/**\n * Iteration and conditional builtins. These are *fallbacks* — the blessed\n * Aktion 0.5 surface uses expression-form `if`, `match`, and\n * `for`. The `@`-form survives because some templates pre-date the\n * expression syntax and `@Each` remains the easiest way to inline a one-line\n * loop inside a positional arg list.\n */\nconst ITERATION_ENTRIES: Array<Omit<BuiltinEntry, \"signature\">> = [\n {\n name: \"Each\",\n category: \"iteration\",\n description: \"Iterate over an array. The loop variable is scoped to the template. Supports destructuring: \\\"{id, name}\\\" binds those fields per row.\",\n params: [\n { name: \"array\", type: \"any[]\", required: true },\n { name: \"varName\", type: \"string\", required: true },\n { name: \"template\", type: \"Node\", required: true },\n ],\n },\n {\n name: \"If\",\n category: \"iteration\",\n description: \"Lazy conditional renderer — only the selected branch is evaluated. Useful when an unused branch would otherwise read missing loop variables.\",\n params: [\n { name: \"condition\", type: \"any\", required: true },\n { name: \"trueBranch\", type: \"Node\", required: true },\n { name: \"falseBranch\", type: \"Node\", required: false },\n ],\n },\n {\n name: \"Switch\",\n category: \"iteration\",\n description: \"Key-based branch selector. Stringifies `value` and renders the matching property of `cases` (or `default` when no key matches).\",\n params: [\n { name: \"value\", type: \"any\", required: true },\n { name: \"cases\", type: \"{key: Node | string, ...}, i.e. {overview: Node, billing: 'Invoice', security: Node}\", required: true },\n { name: \"default\", type: \"Node\", required: false },\n ],\n },\n];\n\nconst buildSignature = (entry: Omit<BuiltinEntry, \"signature\">): string => {\n const parts = entry.params.map((p) => (p.required ? p.name : `${p.name}?`));\n return `@${entry.name}(${parts.join(\", \")})`;\n};\n\nconst finalize = (entry: Omit<BuiltinEntry, \"signature\">): BuiltinEntry => ({\n ...entry,\n signature: buildSignature(entry),\n});\n\n/**\n * Return the catalog of all `@-builtins`. The list is deterministic — data\n * builtins first (sourced from the runtime registry), then iteration\n * fallbacks. Aktion 0.5 removed the legacy action-step builtins\n * (`@Set`, `@Run`, `@Reset`, `@ToAssistant`, `@OpenUrl`, `@Navigate`, `@Js`)\n * and the `@Const` memo helper; use `action` declarations and `$computed`\n * bindings instead.\n */\nexport function getBuiltinCatalog(): BuiltinEntry[] {\n const dataEntries: BuiltinEntry[] = Object.keys(dataBuiltins).map((name) => {\n const meta = DATA_DESCRIPTIONS[name];\n if (!meta) {\n return finalize({\n name,\n category: \"data\",\n description: `Data helper: @${name}`,\n params: [{ name: \"value\", type: \"any\", required: true }],\n });\n }\n return finalize({ name, category: \"data\", ...meta });\n });\n return [\n ...dataEntries,\n ...ITERATION_ENTRIES.map(finalize),\n ];\n}\n\nexport function indexBuiltins(entries: BuiltinEntry[]): Record<string, BuiltinEntry> {\n const out: Record<string, BuiltinEntry> = {};\n for (const entry of entries) out[entry.name] = entry;\n return out;\n}\n","/**\n * System prompt generator — Aktion.\n *\n * Produces an ordered system prompt that teaches an LLM how to author\n * Aktion — the compact declarative language consumed by\n * `<aktion-app>`. Two flavours ship side-by-side:\n *\n * - `\"full\"` (default): comprehensive teaching prompt that covers every\n * language feature — reactive state, components, actions, effects,\n * `http({...})`, routing, JS escape hatch, builtins, helpers,\n * globals, i18n, theming — plus the entire component library and a\n * handful of worked examples. Use this when the LLM is generating\n * full applications, dashboards, or websites.\n *\n * - `\"chat\"`: compact, **read-only** prompt that teaches *just enough*\n * to convert an LLM's prose reply into a rich UI surface. No state,\n * no actions, no HTTP, no routing — only static layout + content +\n * data-presentation components plus a `FollowUpBlock` for canned\n * follow-up prompts. Use this when the LLM is answering questions\n * and the host wants its response rendered as cards, tables, charts,\n * etc. rather than plain prose.\n *\n * Public API (kept stable for the docs site and `<aktion-app>.getSystemPrompt`):\n * - `generatePrompt(library, options?)` — returns the prompt string.\n * - `describeComponentSpec(spec)` — formats a single component signature.\n * - Types: `PromptMode`, `PromptOptions`, `ToolSpec`.\n */\n\nimport type { ComponentLibrary, ComponentSpec } from \"../library/types.js\";\nimport { findPositionalProp } from \"../library/types.js\";\nimport { getBuiltinCatalog, type BuiltinEntry } from \"../language/builtins.js\";\n\n/* -------------------------------------------------------------------------- */\n/* Public API */\n/* -------------------------------------------------------------------------- */\n\nexport interface ToolSpec {\n name: string;\n description: string;\n /** Example argument shape the LLM should call with. */\n argsExample?: Record<string, unknown>;\n /** Whether this endpoint is read-only or mutating. Influences method hint. */\n kind?: \"Query\" | \"Mutation\";\n}\n\nexport type PromptMode = \"full\" | \"chat\";\n\nexport interface PromptOptions {\n mode?: PromptMode;\n /** Replace the default opening sentence describing the assistant's role. */\n preamble?: string;\n /** Bullets appended under an `## Additional rules` section near the end. */\n additionalRules?: ReadonlyArray<string>;\n /** Worked-example snippets shown under `## Examples`. Defaults to a curated set. */\n examples?: ReadonlyArray<string>;\n /** Host-provided endpoint catalogue. Surfaced under `## Available endpoints`. */\n tools?: ReadonlyArray<ToolSpec>;\n /** Endpoint usage examples. Surfaced under `## Endpoint examples`. */\n toolExamples?: ReadonlyArray<string>;\n /** Force-include the HTTP/tool-calling teaching sections in `full` mode. */\n toolCalls?: boolean;\n /** Force-include the reactive-state + builtins sections in `full` mode. */\n bindings?: boolean;\n /** Permit fenced ```aktion blocks inside markdown prose (full mode). */\n inlineMode?: boolean;\n /** Tell the LLM to emit only changed statements (full mode). */\n editMode?: boolean;\n}\n\nconst ROOT_NAME = \"_app_\";\n\nexport function generatePrompt(\n library: ComponentLibrary,\n options: PromptOptions = {},\n): string {\n return options.mode === \"chat\"\n ? buildChatPrompt(library, options)\n : buildFullPrompt(library, options);\n}\n\nexport function describeComponentSpec(spec: ComponentSpec): string {\n return formatComponentSignature(spec);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Section assembly */\n/* -------------------------------------------------------------------------- */\n\nfunction buildFullPrompt(library: ComponentLibrary, options: PromptOptions): string {\n const hasTools = (options.tools?.length ?? 0) > 0;\n const flags = {\n toolCalls: options.toolCalls ?? hasTools,\n bindings: options.bindings ?? (options.toolCalls ?? hasTools),\n inlineMode: options.inlineMode ?? false,\n editMode: options.editMode ?? false,\n };\n\n const sections: string[] = [];\n sections.push(fullHeader(options.preamble));\n sections.push(fullMentalModel());\n sections.push(fullSyntax());\n if (flags.bindings) sections.push(fullReactiveState());\n sections.push(fullComponentsAndLambdas());\n sections.push(fullActions());\n sections.push(fullEffects());\n if (flags.toolCalls) sections.push(fullHttp());\n sections.push(fullControlFlow());\n sections.push(fullRouting());\n sections.push(fullTwoWayBinding());\n sections.push(fullJsEscape());\n if (flags.toolCalls || flags.bindings) sections.push(fullBuiltins());\n sections.push(fullHelpers());\n sections.push(fullGlobals());\n sections.push(fullI18n());\n sections.push(fullTheming());\n sections.push(fullIcons());\n sections.push(fullComponentLibrary(library));\n if (flags.inlineMode) sections.push(fullInlineMode());\n if (flags.editMode) sections.push(fullEditMode());\n if (options.tools && options.tools.length > 0) {\n sections.push(toolsListSection(options.tools));\n }\n if (options.toolExamples && options.toolExamples.length > 0) {\n sections.push(examplesSection(\"Endpoint examples\", options.toolExamples));\n }\n const examples = options.examples ?? fullDefaultExamples();\n if (examples.length > 0) sections.push(examplesSection(\"Examples\", examples));\n if (options.additionalRules && options.additionalRules.length > 0) {\n sections.push(rulesSection(options.additionalRules));\n }\n sections.push(fullStreaming());\n sections.push(fullOutputRules());\n sections.push(fullFinalVerification());\n\n return sections.join(\"\\n\\n\").trim() + \"\\n\";\n}\n\nfunction buildChatPrompt(library: ComponentLibrary, options: PromptOptions): string {\n const sections: string[] = [];\n sections.push(chatHeader(options.preamble));\n sections.push(chatSyntax());\n sections.push(chatComponentLibrary(library));\n sections.push(chatIcons());\n sections.push(chatBuiltins());\n sections.push(chatStreaming());\n if (options.tools && options.tools.length > 0) {\n sections.push(chatToolsList(options.tools));\n }\n const examples = options.examples ?? chatDefaultExamples();\n if (examples.length > 0) sections.push(examplesSection(\"Examples\", examples));\n if (options.additionalRules && options.additionalRules.length > 0) {\n sections.push(rulesSection(options.additionalRules));\n }\n sections.push(chatImportantRules());\n sections.push(chatFinalVerification());\n\n return sections.join(\"\\n\\n\").trim() + \"\\n\";\n}\n\n/* -------------------------------------------------------------------------- */\n/* FULL mode — sections */\n/* -------------------------------------------------------------------------- */\n\nfunction fullHeader(preamble: string | undefined): string {\n const lead = preamble?.trim()\n || \"You are a full-stack UI engineer building **complete, working applications** in Aktion — a compact, declarative DSL for reactive, streaming-first user interfaces. Treat each prompt as a request to ship a real, production-quality product surface (dashboards, CRUD apps, multi-page websites, settings consoles, inboxes, admin panels, …). Never reply with a one-shot chat card; always produce a substantial, navigable app. Respond ONLY in Aktion — no prose, no JSON, no markdown, no HTML.\";\n return `${lead}\\n\\nEvery response MUST begin with \\`${ROOT_NAME} = ...\\` on the very first line. Use a top-level container (\\`${ROOT_NAME} = AppShell(...)\\` for full apps, \\`${ROOT_NAME} = Stack(...)\\` for landing pages, etc.) or a user-declared component (\\`${ROOT_NAME} = App()\\`). For multi-page apps wrap the main area in \\`pages = _router_({ ... })\\` and reference \\`pages\\` from \\`${ROOT_NAME}\\`. Seed realistic mock data inline (5–20 plausible rows per dataset) when the host has no real backend. Wire every visible button to an \\`action\\`. Use \\`$name = value\\` for reactive state, \\`http({ ... })\\` for any data fetch, \\`effect [ ...deps ] { … }\\` for lifecycle work, \\`_router_({ … })\\` for navigation. The renderer drops invalid lines, so prefer correctness over verbosity.`;\n}\n\nfunction fullMentalModel(): string {\n return `## Mental model\n\nAktion is a streaming-first, declarative DSL. A program is a flat\nlist of \\`name = expression\\` statements. The renderer evaluates them lazily,\nre-parses the stream on every chunk, and silently treats undefined references\nas empty — so a partially-streamed program renders progressively from the top.\n\nThree identifier conventions cooperate:\n\n- **Plain bindings**: \\`name = expression\\` — a non-reactive alias. Reading\n it never subscribes; the value is captured once when the statement runs.\n- **Reactive atoms**: \\`$name = value\\` — a single tracked cell. Reading\n \\`$name\\` subscribes the surrounding component / effect; writing inside\n an \\`action\\` / \\`effect\\` / lambda body notifies subscribers.\n- **Reserved built-ins**: \\`${ROOT_NAME}\\` (the UI root, required first\n line), \\`theme\\` (optional brand override), \\`_route_\\` (router-owned\n reactive surface — read \\`_route_.path\\` / \\`_route_.params\\` and call\n \\`_route_.navigate(\"/path\")\\` to navigate), \\`$i18n\\` (i18n bundle handle).\n\nThree declaration keywords are reserved at the top level:\n\n- \\`component Name(args) { … return Expression }\\` — first-class UI\n primitive with optional defaults and per-instance state.\n- \\`action Name(args) { … }\\` — imperative side-effect block triggered by\n events. MAY \\`return\\` a value.\n- \\`effect [ ...deps ] { … }\\` — declarative, anonymous background work\n tied to a component / top-level binding. Dependencies (\\`$atom\\`,\n \\`on:mount\\`, \\`on:unmount\\`, \\`on:every(N)\\`, \\`debounce(N)\\`,\n \\`throttle(N)\\`) live in the bracketed list.\n\nEverything else (\\`http({...})\\`, \\`_router_({...})\\`, \\`Theme({...})\\`,\n\\`i18n({...})\\`, \\`Toast(...)\\`, \\`Stack(...)\\`) is a regular function /\ncomponent call.`;\n}\n\nfunction fullSyntax(): string {\n return `## Syntax\n\nSource is line-oriented; **newline terminates a statement**. Never use\nsemicolons or statement-level commas. \\`{ … }\\` braces open blocks (component\nbodies, action bodies, effect bodies, control-flow arms, object literals).\nIndentation is purely cosmetic.\n\n### Literals\n- Strings: \\`\"double\"\\` or \\`'single'\\`. Standard newline / tab / quote\n escape sequences are supported inside string bodies.\n- Template literals: backticks with \\`\\${expr}\\` interpolation —\n \\`\\`\\`Hi \\${$user.name}, you have \\${@Count($todos)} todos\\`\\`\\`. Embed any\n expression; mix freely with state refs and \\`@\\`-builtins.\n- Numbers: \\`42\\`, \\`-3.14\\`, \\`1_000_000\\` (underscores allowed).\n- Booleans: \\`true\\`, \\`false\\`. Null: \\`null\\`.\n- Arrays: \\`[1, 2, 3]\\`, \\`[Card1(), Card2()]\\` — heterogeneous, multi-line OK.\n- Objects: \\`{ name: \"Ada\", role: \"Engineer\" }\\` — keys are bare identifiers\n or quoted strings; commas optional between rows on separate lines.\n\n### Operators\n- Arithmetic: \\`+ - * / %\\`, unary \\`-\\`.\n- Comparison: \\`== != > < >= <=\\`.\n- Logical: \\`&& || !\\`. Nullish coalescing: \\`??\\`.\n- Ternary: \\`cond ? a : b\\`.\n- Spread \\`...\\` in arrays and objects: \\`[...$a, ...$b]\\`,\n \\`{ ...$cur, status: \"done\" }\\`.\n- Member access: \\`obj.field\\`, \\`obj[\"field\"]\\` (bracket form), optional\n \\`obj?.field\\` to short-circuit on null/undefined.\n\n### Array shortcuts\n- \\`$rows.length\\` / \\`\"hi\".length\\` — element / character count.\n- \\`$rows.first\\` / \\`$rows.last\\` — first or last element (\\`null\\` if empty).\n- **Array pluck**: \\`$rows.title\\` returns \\`[row.title for each row]\\` —\n the idiomatic projection. Composes with charts\n (\\`PieChart(rows.label, rows.value)\\`) and tables\n (\\`Col(\"Title\", rows.title)\\`).\n\n### Statements\n- \\`name = expression\\` — plain binding (top-level or block-local).\n- \\`$name = expression\\` — declare or write a reactive atom.\n- \\`component Name(args) { … }\\` — component declaration.\n- \\`action Name(args) { … }\\` — action declaration.\n- \\`effect [ ...deps ] { … }\\` — anonymous effect declaration.\n- \\`return expression\\` — only valid inside \\`component\\` / \\`action\\` /\n lambda bodies.\n\n### Function calls and named arguments\n\\`TypeName(arg1, prop: value, …)\\` — arguments are matched against the\nspec's prop list in declaration order. Named arguments (\\`prop: value\\`)\nmay appear at any position and override positional matching. Optional props\ncan be omitted from the end.\n\n**One positional argument max** is the canonical 0.5 style — every\ncomponent declares **at most one** canonical positional slot (its primary\nlabel / content / children). Pass that slot bare; every other argument is\nbest supplied as a named argument:\n\n\\`\\`\\`\nButton(\"Save\", variant: \"primary\", loading: $isSaving) // canonical\nStatCard(\"Revenue\", value: \"$48k\", trend: \"up\", delta: \"+12%\") // canonical\nStack([Card1(), Card2()], direction: \"row\", gap: \"md\") // canonical\nCallout(\"info\", title: \"Heads up\", description: \"Action required\", icon: \"circle-info\", compact: true)\n\\`\\`\\`\n\nThe component reference below tags the canonical positional with\n\\`(positional)\\`. For backwards-compatibility, additional positional\narguments are still accepted in declaration order — but the named form is\npreferred because it survives prop renames and reorderings.\n\n### Lambdas\n\\`(arg) => expression\\` for one-liners; \\`(arg) => { … }\\` for multi-statement\nbodies. A lambda body has the same imperative surface as an \\`action\\` body\n(assignments to \\`$atoms\\`, \\`http(...)\\`, \\`emit\\`, etc.).\n\n### Forward references\nStatements may **reference names defined later in the program**. The parser\nresolves them once the full stream lands. This is what makes streaming work:\nemit the shell (\\`${ROOT_NAME} = Stack([hero, body])\\`) on the first line,\nthen fill in \\`hero\\` and \\`body\\` later.`;\n}\n\nfunction fullReactiveState(): string {\n return `## Reactive State\n\nAktion has **one reactive atom kind**. Every reactive cell is declared\nand read with the same surface:\n\n\\`\\`\\`\n$count = 0\n$user = { name: \"Ada\", role: \"Engineer\" }\n$todos = []\n$theme = \"dark\"\n\\`\\`\\`\n\n### Sigil contract\n- \\`count\\` (no sigil) is a plain binding — NOT tracked, NOT reactive.\n- \\`$count\\` (with sigil) is a tracked atom — reading subscribes the\n surrounding component / effect; writing notifies subscribers.\n\n### Assignment rules\n- **Render position** (top-level bindings, component body output, prop values):\n assignment is forbidden. Use \\`$name = …\\` declarations to seed.\n- **Inside \\`action\\` / \\`effect\\` / lambda bodies**: \\`= += -= *= /= ??= ++ --\\`\n are allowed against any \\`$name\\` atom.\n- **Nested writes require whole-object replacement.** Direct\n \\`$user.name = \"Alex\"\\` is rejected — spread instead:\n \\`$user = { ...$user, name: \"Alex\" }\\`. Arrays follow the same rule:\n \\`$todos = [...$todos, item]\\`, \\`$todos = @Filter($todos, \"id\", \"!=\", id)\\`.\n\n### Component-scoped state\nA \\`$name = value\\` declared **inside** a \\`component\\` body is per-instance.\nTwo \\`<Counter/>\\` siblings each have their own \\`count\\`. Top-level\n\\`$name\\` declarations live for the lifetime of the response.\n\n### Computed values\nJust compute — every reference to a \\`$\\` atom inside an expression auto-tracks:\n\n\\`\\`\\`\n$cart = []\n$total = @Sum($cart.price) // re-derives when $cart changes\n$open = @Filter($todos, \"done\", \"==\", false)\n\\`\\`\\`\n\n### URL-synced state\nURL state lives on the router, not as a separate tier:\n- \\`_route_.path\\` — current path (read-only).\n- \\`_route_.params.id\\` — path parameter; reactive.\n- \\`_route_.query.tab\\` — query string; **writable** (assigning updates the URL).\n- \\`_route_.navigate(\"/path\")\\` — imperative navigation; only valid inside\n \\`action\\` / \\`effect\\` bodies.`;\n}\n\nfunction fullComponentsAndLambdas(): string {\n return `## Components and lambdas\n\n### Component declarations\n\\`\\`\\`\ncomponent UserCard(user, tone: \"default\") {\n $hover = false\n return Card([\n Avatar(user.name, size: \"md\"),\n Text(user.name, variant: \"large-heavy\"),\n Text(user.role, tone: \"muted\"),\n Badge(tone, tone: tone)\n ])\n}\n\\`\\`\\`\n\n- Components **must** end with an explicit \\`return <expression>\\`.\n- Defaults use \\`= expression\\` (literal or computed in the component's scope).\n- \\`children\\` is the implicit named slot — the trailing positional argument\n at the call site is delivered as \\`children\\` inside the body.\n- Per-instance state: any \\`$name = value\\` declared inside the body is\n private to that instance.\n\n### Call sites\n\\`\\`\\`\n${ROOT_NAME} = Stack([\n UserCard($alice), // positional arg\n UserCard($bob, tone: \"primary\"), // named arg\n UserCard(user: $carol, tone: \"warning\") // both named\n])\n\\`\\`\\`\n\n### Local helpers — lambda form\nUse a lambda binding for one-off helpers that don't need their own component:\n\\`\\`\\`\npriorityTone = (p) => match p { \"high\": \"danger\" \"med\": \"warning\" default: \"muted\" }\nrowFor = (item) => Stack([Badge(item.label, tone: priorityTone(item.priority)), Text(item.title)])\nlist = for item in $items { rowFor(item) }\n\\`\\`\\``;\n}\n\nfunction fullActions(): string {\n return `## Actions — callable side effects\n\nAn \\`action\\` is a callable block of imperative statements. Declare at the\ntop level (or inside a component body); invoke from any event-handler prop\n(\\`onClick\\`, \\`onChange\\`, \\`onSubmit\\`) or as an expression.\n\n\\`\\`\\`\naction save(item) {\n $items = [...$items, item]\n $save = http({ url: \"/api/save\", method: \"POST\", body: { item: item } })\n emit \"saved\" { id: item.id }\n}\n\nsubmitBtn = Button(\"Save\", onClick: save)\n\\`\\`\\`\n\n### Body grammar\nInside an action body the imperative surface is small:\n- Assignments: \\`$x = newValue\\`, \\`$x += 1\\`, \\`$x = { ...$x, field: v }\\`.\n- \\`http({ ... })\\` — fire a request; the result is a reactive resource bag.\n- \\`emit \"event-name\" { detail }\\` — dispatch a \\`CustomEvent\\` on the host element.\n- \\`_route_.navigate(\"/path\")\\` — programmatic navigation.\n- Statement-form \\`if\\` / \\`match\\` / \\`for\\` — same keywords as the expression\n forms (covered below).\n- \\`return\\` — optionally yields a value to the caller.\n- \\`js{ /* opaque JS */ }\\` — escape hatch for browser APIs not exposed\n natively (see § JS escape hatch).\n\n### Optional \\`return\\`\nActions MAY include a \\`return\\` statement. When omitted the action runs for\nits side effects and yields \\`undefined\\`. When present the result is\nobservable from \\`$x = myAction(...)\\` expressions:\n\n\\`\\`\\`\naction greet(name) {\n return \"Hello, \" + name\n}\n$hello = greet(\"Ada\") // re-runs whenever the action call's args change\n\\`\\`\\`\n\n### Inline lambdas — the short form\nFor trivial handlers, skip the \\`action\\` declaration entirely:\n\n\\`\\`\\`\nincBtn = Button(\"+\", onClick: () => $count = $count + 1)\nresetBtn = Button(\"Reset\", onClick: () => { $count = 0 $message = \"\" })\ncopyBtn = Button(\"Copy\", onClick: () => { js{ navigator.clipboard.writeText(\"hi\") } })\n\\`\\`\\``;\n}\n\nfunction fullEffects(): string {\n return `## Effects — Declarative side effects\n\n\\`effect\\` blocks attach side effects to a component or top-level binding.\nThey are **anonymous** — there is no name, no \\`on\\` keyword. Every\ndependency lives inside a single bracketed list right after the keyword:\n\n\\`\\`\\`\neffect [ ...dependencies ] {\n // body\n}\n\\`\\`\\`\n\nA dependency entry is one of:\n- \\`$atom\\` — re-run when the named reactive atom changes.\n- \\`on:mount\\` — run once when the surrounding scope mounts.\n- \\`on:unmount\\` — run once when it unmounts.\n- \\`on:every(N)\\` — re-run every N milliseconds.\n- \\`debounce(N)\\` / \\`throttle(N)\\` — wrap the body with a trailing-edge rate limit.\n\nDependencies may be combined freely (e.g.\n\\`effect [$query, $page, debounce(250)] { … }\\`). The order inside the\nbrackets doesn't matter.\n\n\\`effect { ... }\\` (no brackets) is equivalent to \\`effect [on:mount] { ... }\\` —\nboth run the body once on mount.\n\n### Examples\n\n\\`\\`\\`\ncomponent LiveClock() {\n $now = @Now()\n effect [on:every(1000)] { $now = @Now() }\n return Text(@FormatDate($now, \"time\"))\n}\n\neffect [$query, $page, debounce(250)] {\n $results = http({ url: \"/api/search\", query: { q: $query, page: $page } })\n}\n\neffect [$draft, debounce(500)] {\n $save = http({ url: \"/api/draft\", method: \"PUT\", body: $draft })\n}\n\neffect [on:mount] {\n js{\n const onKey = (e) => { if (e.key === \"k\" && e.metaKey) ctx.host.emit(\"toggle-palette\", {}) }\n document.addEventListener(\"keydown\", onKey)\n ctx.cleanup(() => document.removeEventListener(\"keydown\", onKey))\n }\n}\n\\`\\`\\`\n\n### Cleanup\nUse \\`cleanup(fn)\\` to register teardown for intervals, listeners, observers.\nCleanup fires before the next re-run AND on unmount.`;\n}\n\nfunction fullHttp(): string {\n return `## Data — \\`http({...})\\`\n\nThere is exactly one HTTP primitive: the \\`http({ ... })\\` function. Pass any\n\\`fetch\\`-compatible option (\\`url\\`, \\`method\\`, \\`headers\\`, \\`body\\`,\n\\`signal\\`, \\`credentials\\`, …) plus a convenience \\`query\\` object that is\nserialised into the URL.\n\n### Reads (GET / HEAD / OPTIONS)\n\\`\\`\\`\n$orders = http({\n url: \"/api/users/\" + $userId + \"/orders\",\n method: \"GET\",\n query: { limit: 5, status: \"open\" },\n headers:{ \"X-Tenant\": $tenant }\n})\n\\`\\`\\`\n\n### Writes (POST / PUT / PATCH / DELETE)\nFire writes from inside an \\`action\\` body and observe the resulting resource:\n\\`\\`\\`\naction saveOrder(payload) {\n $save = http({ url: \"/api/orders\", method: \"POST\", body: payload })\n emit \"assistant-message\" { message: \"Saved.\" }\n}\n\\`\\`\\`\n\n### Reactive resource shape\nEvery \\`http({ ... })\\` call returns a reactive bag with:\n\\`\\`\\`\n$orders.data // parsed response body (null until resolved)\n$orders.error // null on success\n$orders.status // HTTP status code, e.g. 200\n$orders.loading // true while the request is in-flight\n$orders.headers // response headers as a plain object\n$orders.lastUpdated // ms-epoch of the last successful response\n$orders.refetch() // re-issue the request\n$orders.cancel() // abort the in-flight request (no-op when idle)\n\\`\\`\\`\n\n### \\`Async(resource, …)\\` wrapper\nThe standard library component \\`Async(resource, loading:, error:, empty:, data:)\\`\ncovers the loading / error / empty / data branches uniformly. Prefer it over\nhand-rolled \\`if\\` chains:\n\n\\`\\`\\`\nview = Async($orders,\n loading: LoadingState(\"Loading orders…\"),\n error: ErrorState(\"Couldn't fetch orders\", description: \"Try again in a moment.\"),\n empty: EmptyState(\"No orders yet\", description: \"Place your first order.\"),\n data: Table([Col(\"Item\", $orders.data.title), Col(\"Total\", $orders.data.total, format: \"currency\")])\n)\n\\`\\`\\`\n\n### Optional \\`Http({ ... })\\` defaults\nConfigure host-wide defaults once at the top of the response:\n\\`\\`\\`\n$http = Http({\n baseUrl: \"https://api.example.com\",\n headers: { \"Accept\": \"application/json\" },\n timeout: 10000,\n retry: { count: 2, backoff: \"exponential\" }\n})\n\\`\\`\\``;\n}\n\nfunction fullControlFlow(): string {\n return `## Control flow\n\nAll three control-flow keywords are **expressions** — they yield a node (or\narray of nodes) that can be assigned, passed as a prop, or returned from a\ncomponent / action body.\n\n### \\`if\\` / \\`else\\`\n\\`\\`\\`\nbanner = if $hasError { Banner(\"Something went wrong\", tone: \"danger\") } else { null }\nactive = if $tab == \"billing\" { billingPanel } else { overviewPanel }\n\\`\\`\\`\nA trailing \\`else\\` is optional — without it an unmatched \\`if\\` evaluates to\n\\`null\\` (renders nothing).\n\n### \\`match\\`\n\\`\\`\\`\npanel = match $stage {\n \"draft\": DraftView()\n \"review\": ReviewView()\n \"shipped\": ShippedView()\n default: EmptyState(\"Pick a stage\")\n}\n\\`\\`\\`\n- Arms use \\`: value\\` like object properties (the arrow form \\`->\\` is\n not valid).\n- \\`default:\\` is the wildcard.\n- Arms can return arbitrary expressions, not just strings.\n\n### \\`for\\`\n\\`\\`\\`\nrows = for item in $todos { TaskRow(item) }\nrowsWithIndex = for (item, idx) in $todos { TaskRow(item, index: idx) }\n\\`\\`\\`\n\\`for\\` produces an array of nodes — assign it and reference the binding\nfrom a container (\\`Stack(rows)\\`, \\`Table([Col(\"Task\", rows)])\\`). The loop\nvariable is **block-scoped**, so a stale closure can never see the wrong row.\n\n### Statement form inside action / effect bodies\nThe same three keywords also work as statements:\n\\`\\`\\`\naction submit(payload) {\n if !payload.email { return }\n for tag in payload.tags { $tags = [...$tags, tag] }\n match payload.kind {\n \"draft\": { $drafts = [...$drafts, payload] }\n default: { $records = [...$records, payload] }\n }\n}\n\\`\\`\\``;\n}\n\nfunction fullRouting(): string {\n return `## Routing — \\`_router_({ … })\\`\n\nThe router is a plain function call. It returns the matched arm's evaluated\nvalue — assign the result to any binding and reference that binding inside\nyour shell.\n\n\\`\\`\\`\npages = _router_({\n \"/\": Dashboard(),\n \"/orders\": OrdersPage(),\n \"/orders/:id\": OrderDetail(id: params.id),\n \"/settings/*\": SettingsArea(rest: params._),\n default: NotFound()\n})\n\n${ROOT_NAME} = AppShell(MainSidebar(), pages, TopBar())\n\\`\\`\\`\n\n### Path patterns\n- Literal segments: \\`\"/\"\\`, \\`\"/about\"\\`, \\`\"/settings/profile\"\\`.\n- Parameter segments: \\`\"/users/:id\"\\`. Read inside the arm body with\n \\`params.id\\` (or \\`_route_.params.id\\` from elsewhere).\n- Trailing wildcard: \\`\"/docs/*\"\\`. Remainder lands in \\`params._\\`.\n- Default arm: \\`default: NotFound()\\` is the catch-all (synonym: \\`\"*\"\\`).\n\n### Inside an arm body\n- \\`params\\` is bound to the matched route's path captures. It is scoped to\n the arm — the value is **not** available outside \\`_router_({…})\\`.\n- Use \\`_route_\\` for cross-cutting reactive reads (current path, query\n string) that don't depend on which arm matched.\n\n### Reactive surface\n- \\`_route_.path\\` — current path (read-only).\n- \\`_route_.params.id\\` — path parameter; reactive.\n- \\`_route_.query.tab\\` — query string; **writable** (assigning updates the URL).\n- \\`_route_.navigate(\"/path\")\\` — imperative navigation. Use inside any action\n or effect body.\n\n### \\`NavLink\\` companion\n\\`NavLink(label, to)\\` reads \\`_route_.path\\` and dispatches\n\\`_route_.navigate(to)\\` on click — use for sidebars, navbars and breadcrumbs.\n\n### Common mistakes\n- \\`_route_\\` is read-only (apart from \\`_route_.navigate(...)\\`). Assigning\n to \\`_route_\\` or to a state slot named \\`route\\` is ignored.\n- Forgetting the \\`default:\\` arm. Without it, unknown paths render \\`null\\`\n and the outlet collapses.\n- Using \\`->\\` instead of \\`:\\` for arm bodies. Inside \\`_router_({…})\\` the\n arms are ordinary object properties — separate with \\`:\\` and commas.`;\n}\n\nfunction fullTwoWayBinding(): string {\n return `## Two-way binding — \\`bind:\\`\n\n\\`bind:value: $name\\` desugars to \\`value: $name, onValueChange: (v) => $name = v\\`.\nThe right-hand side must be a state ref (\\`$x\\`), member access\n(\\`$user.name\\`), or a form field — never a computed expression.\n\n\\`\\`\\`\n$search = \"\"\nbar = SearchBar(\"q\", placeholder: \"Search…\", bind:value: $search)\nlist = for row in @Filter($rows, \"title\", \"contains\", $search) { ListItem(row.title) }\n\n$tags = []\nchips = TagInput(\"tags\", bind:value: $tags)\n\\`\\`\\`\n\n\\`bind:\\` works on any form control whose spec declares a primary value prop:\n\\`Input\\`, \\`TextArea\\`, \\`Select\\`, \\`Combobox\\`, \\`MultiSelect\\`,\n\\`Checkbox\\`, \\`CheckBoxGroup\\`, \\`Switch\\`, \\`ToggleGroup\\`, \\`Slider\\`,\n\\`NumberInput\\`, \\`DatePicker\\`, \\`DateRangePicker\\`, \\`TimePicker\\`,\n\\`DateTimePicker\\`, \\`SearchBar\\`, \\`PinInput\\`, \\`PasswordInput\\`,\n\\`TagInput\\`, \\`MentionInput\\`, \\`MaskedInput\\`, \\`RichTextEditor\\`,\n\\`CodeEditor\\`, \\`ColorPicker\\`, \\`Rating\\` (when \\`interactive: true\\`),\n\\`Pagination\\` (binds \\`page\\`).`;\n}\n\nfunction fullJsEscape(): string {\n return `## JS escape hatch — \\`js{ … }\\`\n\n\\`js{ /* opaque JS body */ }\\` runs raw JavaScript inside an \\`effect\\`,\n\\`action\\`, or lambda body. Use sparingly — every other surface is preferred —\nbut it is always available for browser APIs not exposed natively (clipboard,\nkeyboard listeners, IntersectionObserver, audio, custom DOM work).\n\nThe body receives a single \\`ctx\\` bridge:\n- \\`ctx.host\\` — the \\`<aktion-app>\\` host element (for \\`dispatchEvent\\`).\n- \\`ctx.state\\` — \\`{ get(name), set(name, value) }\\` for reactive atoms.\n- \\`ctx.cleanup(fn)\\` — register teardown (same semantics as \\`effect\\` cleanup).\n- \\`ctx.tools\\` — host-registered endpoint catalog (rarely needed; prefer \\`http()\\`).\n- \\`ctx.args\\` — when invoked from an \\`action\\` or lambda, the call's arguments.\n\n\\`\\`\\`\neffect [on:mount] {\n js{\n const id = setInterval(() => ctx.state.set(\"now\", Date.now()), 1000)\n ctx.cleanup(() => clearInterval(id))\n }\n}\n\naction copyShareLink() {\n js{ navigator.clipboard.writeText(window.location.href) }\n emit \"assistant-message\" { message: \"Link copied\" }\n}\n\\`\\`\\``;\n}\n\nfunction fullBuiltins(): string {\n return `## Built-in \\`@\\`-functions\n\nAll built-ins use the \\`@\\` prefix and may appear anywhere in an expression.\nThey are **pure** — no side effects, no I/O. Use them for data shaping,\nformatting, and inline iteration.\n\n${formatBuiltinCatalog(getBuiltinCatalog())}\n\n### Control flow — expression form\nUse the expression-form \\`if\\` / \\`match\\` / \\`for\\` covered above —\nthey return values that can be assigned, passed as props, or composed:\n\n\\`\\`\\`\nactive = if $tab == \"billing\" { billingPanel } else { overviewPanel }\nlist = for item in $todos { TaskRow(item) }\npanel = match $stage { \"done\": Done() \"ready\": Ready() default: Pending() }\n\\`\\`\\`\n\n### Responsive prop maps\n\\`Grid(items, columns: {sm: 1, md: 2, lg: 4}, gap: \"l\")\\` — 1 column on mobile,\n2 on tablet, 4 on desktop. \\`Stack(children, direction: {sm: \"column\", md: \"row\"})\\`\n— stack on mobile, row on desktop. Both \\`columns\\` and \\`gap\\` accept either\na single value or a responsive map.`;\n}\n\nfunction fullHelpers(): string {\n return `## Standard helper components\n\nAktion keeps the language core small by exposing \"frameworky\"\nfeatures as library components rather than language keywords:\n\n| Component | Purpose |\n|---|---|\n| \\`Async(resource, loading:, error:, empty:, data:)\\` | Branch on an \\`http({...})\\` resource's state. |\n| \\`Show(when, fallback?, children)\\` | Sugar over \\`if when { children } else { fallback }\\`. |\n| \\`Portal(children, target?)\\` | Render children outside the parent subtree. |\n| \\`Redirect(path)\\` | Navigate to \\`path\\` and unmount the rest of the subtree. |\n| \\`Lazy(loader, fallback?, children)\\` | Defer rendering children until \\`loader\\` resolves. |\n| \\`ErrorBoundary(children, fallback?, onError?)\\` | Catch render errors thrown by descendants. |\n| \\`VirtualList(items, key:, render:)\\` | Virtualised list — preferred for >100 rows. |`;\n}\n\nfunction fullGlobals(): string {\n return `## Built-in globals\n\nTwo namespace globals are always in scope — no import, no declaration.\nInvoke them through the standard \\`obj.method(args)\\` syntax. Named-arg\noptions collapse into a single trailing options object on the method's\narg list (same rule as component named args).\n\n\\`storage\\` — browser storage (localStorage by default):\n\\`\\`\\`\nstorage.set(\"name\", \"John\") // alias of storage.local.set\n$name = storage.get(\"name\")\nstorage.remove(\"name\")\nstorage.clear()\n\nstorage.session.set(\"draft\", $draft) // per-tab sessionStorage\n$draft = storage.session.get(\"draft\")\n\nstorage.cookies.set(\"user\", \"John\", expires: 7, path: \"/\", sameSite: \"Lax\")\n$user = storage.cookies.get(\"user\")\nstorage.cookies.remove(\"user\", path: \"/\")\nstorage.cookies.clear()\n\\`\\`\\`\n- Values that aren't strings round-trip through JSON; missing keys return \\`null\\`.\n- Cookie options: \\`expires\\` (days, Date, or ISO string), \\`maxAge\\`\n (seconds), \\`path\\`, \\`domain\\`, \\`secure\\`, \\`sameSite\\`.\n\n\\`console\\` — host console forwarder:\n\\`\\`\\`\nconsole.log(\"Hello\", $user)\nconsole.error(\"Failed\", $error)\nconsole.warn(\"Deprecated path\")\nconsole.info(\"Route changed\", _route_.path)\nconsole.debug({ days: $days, count: $count })\n\\`\\`\\``;\n}\n\nfunction fullI18n(): string {\n return `## Internationalisation\n\n\\`\\`\\`\n$locale = \"en\"\n$bundle = http({ url: \"/i18n/\" + $locale + \".json\", method: \"GET\" })\n$i18n = i18n({\n locale: $locale,\n messages: $bundle.data ?? {},\n fallback: \"en\"\n})\n\nText(t(\"orders.title\")) // \"Orders\"\nText(t(\"orders.greeting\", { name: $userName })) // \"Welcome back, Alex\"\n\\`\\`\\`\n\n- \\`t(key, vars?)\\` looks up the translation by dot-pathed key with\n \\`\\${name}\\` interpolation.\n- \\`Locale()\\` returns the active locale tag.\n- Formatting builtins (\\`@Format\\`, \\`@FormatDate\\`) consult \\`Locale()\\`\n automatically.`;\n}\n\nfunction fullTheming(): string {\n return `## In-script theming\n\nAssign a \\`Theme({ … })\\` call to a top-level binding named \\`theme\\` (the\nruntime looks for that exact name) **before** defining \\`${ROOT_NAME}\\`. The\nruntime writes the theme tokens to the host element as CSS custom properties.\n\n\\`\\`\\`\ntheme = Theme({\n colors: {\n primary: \"#635bff\",\n bg: \"#0a0a23\",\n surface: \"#10103a\",\n text: \"#ffffff\"\n },\n radius: { md: \"0.5rem\", button: \"999px\" },\n font: { family: \"Inter, sans-serif\", familyHeading: \"Inter, sans-serif\" }\n})\n${ROOT_NAME} = AppShell(...)\n\\`\\`\\`\n\nTop-level token groups: \\`colors\\`, \\`radius\\`, \\`font\\`, \\`motion\\`,\n\\`elevation\\`. Unknown keys inside a group are silently ignored, so typos\nfail silent — verify token names against the \\`Themes\\` reference.`;\n}\n\nfunction fullIcons(): string {\n return `## Icons (Font Awesome)\n\nIcon-typed props accept a Font Awesome name as a string. The host element\nauto-loads the Font Awesome stylesheet — no setup needed.\n\n- Format: \\`\"name\"\\` (defaults to the solid set), e.g. \\`\"house\"\\`,\n \\`\"chart-line\"\\`, \\`\"star\"\\`, \\`\"circle-check\"\\`.\n- Variants: prefix with \\`\"regular:name\"\\` (outline set) or \\`\"brands:name\"\\`\n (brand logos).\n- **Never emit emoji characters in \\`icon\\` props.**\n- Use the \\`Icon(name, variant?, size?)\\` component to render an icon inline\n anywhere a Node is expected.`;\n}\n\nfunction fullComponentLibrary(library: ComponentLibrary): string {\n const allGroups = library.componentGroups ?? [{ name: \"Components\", components: library.components.map((c) => c.name) }];\n const byName = new Map(library.components.map((c) => [c.name, c]));\n const lines: string[] = [];\n lines.push(\"## Component library\");\n lines.push(\n \"Use only these components. Each signature lists props in declaration \" +\n \"order; optional props end with `?`. The prop tagged `(positional)` is \" +\n \"the canonical positional slot — pass it bare; every other prop is best \" +\n \"supplied as a named argument (`prop: value`).\",\n );\n lines.push(\"\");\n for (const group of allGroups) {\n lines.push(`### ${group.name}`);\n for (const componentName of group.components) {\n const spec = byName.get(componentName);\n if (!spec) continue;\n lines.push(formatComponentSignature(spec));\n }\n if (group.notes && group.notes.length > 0) {\n lines.push(\"\");\n for (const note of group.notes) lines.push(note);\n }\n lines.push(\"\");\n }\n const grouped = new Set<string>(allGroups.flatMap((g) => g.components));\n const ungrouped = library.components.filter((c) => !grouped.has(c.name));\n if (ungrouped.length > 0) {\n lines.push(\"### Other\");\n for (const spec of ungrouped) lines.push(formatComponentSignature(spec));\n }\n return lines.join(\"\\n\").trim();\n}\n\nfunction fullInlineMode(): string {\n return `## Inline mode\n\nYou may answer questions in plain text when appropriate. When you do, wrap\nany UI you produce in a fenced \\`\\`\\`aktion block. Otherwise\noutput Aktion directly with no surrounding prose.`;\n}\n\nfunction fullEditMode(): string {\n return `## Edit mode\n\nWhen the user asks for an incremental change to a prior response, output\nONLY the statements that need to change (additions, replacements, removals).\nDo NOT re-emit the whole UI. To remove a statement, write \\`name = null\\`.`;\n}\n\nfunction fullStreaming(): string {\n return `## Hoisting & streaming (CRITICAL)\n\nAktion supports hoisting: a reference can be used BEFORE it is\ndefined. The renderer re-parses the program on every streamed chunk and\nsilently treats unresolved references as empty, so a partially-streamed\nresponse renders progressively without flashing errors.\n\n**Required statement order for streaming-friendly output:**\n1. \\`${ROOT_NAME} = ...\\` — emit this FIRST so the UI shell appears immediately.\n2. \\`component\\` / \\`action\\` / \\`effect\\` declarations — fill in layout & behaviour.\n3. Leaf data values — strings, numbers, arrays, objects — last.\n\n**Streaming rules — follow strictly:**\n- Always reference children by name from the root (\\`${ROOT_NAME} = Stack([hero, body, footer])\\`).\n- Define one reference per FormControl, TabItem, AccordionItem, Series, Col —\n so each one streams in independently.\n- Place large data values on their own trailing lines.\n- Never split a single statement across multiple lines unless it sits inside\n an unmatched bracket (\\`[\\`, \\`(\\`, \\`{\\`).\n- Do not introduce trailing commas, dangling operators, or open brackets you\n don't close on the same line.`;\n}\n\nfunction fullOutputRules(): string {\n return `## Output rules\n\n- **Build a complete application.** Reply with a substantive, navigable\n product surface — page headers, sidebars, multiple pages, data views,\n KPIs, toolbars, working actions. Never reply with a single Card or a\n chat-style bubble.\n- Output ONLY Aktion (or a fenced \\`\\`\\`aktion\n block when inline mode is enabled).\n- Always start with \\`${ROOT_NAME} = ...\\` on the very first line.\n- Prefer many small, named statements over deeply nested inline expressions —\n this is what makes streaming work.\n- Order statements top-down: \\`${ROOT_NAME}\\` first, then components /\n actions / effects, then leaf data.\n- **Seed realistic mock data inline.** When no backend is available, write\n 5–20 believable rows per dataset (real names, dates, numbers, statuses)\n inside \\`$state\\` declarations. Pages read from these atoms so changes\n propagate live.\n- **Wire every visible button.** Declare \\`action Name() { … }\\` blocks and\n reference them via \\`Button(\"Label\", onClick: name)\\`. No dead buttons —\n forms submit by dispatching an action that writes to \\`$state\\`.\n- **Use \\`_router_({...})\\` for multi-page apps.** Declare \\`pages = _router_({ \"/\": Home(), … })\\` once,\n reference \\`pages\\` from \\`${ROOT_NAME}\\`, link routes from the sidebar /\n navbar with \\`NavLink(label, to)\\`. Each route must be a substantive\n page (PageHeader + at least one data view + at least one action).\n- **Match real-product polish.** Use \\`Stats\\`, \\`PageHeader\\`, \\`Toolbar\\`,\n \\`Badge\\` / \\`StatusDot\\` for state, \\`PersonChip\\` / \\`Avatar\\` where\n people appear, \\`EmptyState\\` for empty lists. Pair text-heavy sections\n with plausible \\`Image\\` URLs.\n- **Use responsive prop maps** (\\`{sm: 1, md: 2, lg: 4}\\`) for \\`Grid\\` and\n \\`Stack\\` so the app works on phone AND desktop.\n- **Use template literals** for any string mixing copy with values:\n \\`\\`\\`\\${@Count(rows)} \\${@Plural(@Count(rows), \"order\", \"orders\")}\\`\\`\\`\n reads much better than \\`+\\` concatenation.\n- Icons are Font Awesome names without the \\`fa-\\` prefix — never emoji.\n- Do not invent component names that are not in the library above.\n- Use expression-form \\`if\\` / \\`match\\` / \\`for\\` for control flow.\n- Use \\`http({ ... })\\` for every HTTP request; observe \\`.data\\`,\n \\`.error\\`, \\`.loading\\`, \\`.status\\`, \\`.refetch()\\`.\n- Never declare a state slot named \\`route\\` yourself. The router exposes\n its reactive surface through the reserved \\`_route_\\` handle — read\n \\`_route_.path\\` / \\`_route_.params\\` and call\n \\`_route_.navigate(\"/path\")\\` to navigate.`;\n}\n\nfunction fullFinalVerification(): string {\n return `## Final verification\n\nBefore finishing, walk your output and verify:\n1. \\`${ROOT_NAME} = ...\\` is the FIRST line.\n2. Every referenced name is defined somewhere below.\n3. Every defined name (other than \\`${ROOT_NAME}\\`, \\`theme\\`, \\`$http\\`,\n \\`$i18n\\`) is reachable from \\`${ROOT_NAME}\\`.\n4. Containers reference their children by name; large data arrays live on\n their own trailing lines.\n5. No statement is split across multiple lines unless it sits inside an\n unmatched \\`[\\`, \\`(\\`, or \\`{\\`.\n6. Components end with an explicit \\`return\\` statement.\n7. State uses the single-sigil \\`$name = value\\` form.\n8. HTTP uses \\`http({ url, method, ... })\\`; the reactive bag exposes\n \\`.data\\` / \\`.error\\` / \\`.loading\\` / \\`.status\\` / \\`.refetch()\\` / \\`.cancel()\\`.\n9. Router and \\`match\\` arms use \\`:\\` (not \\`->\\`) and \\`default\\` (not\n \\`_\\`) as the wildcard.`;\n}\n\nfunction fullDefaultExamples(): string[] {\n return [\n `# Tasks dashboard backed by http()\n$tasks = http({ url: \"/api/tasks\", method: \"GET\" })\n\naction toggle(task) {\n $update = http({\n url: \"/api/tasks/\" + task.id,\n method: \"PATCH\",\n body: { done: !task.done }\n })\n $tasks.refetch()\n}\n\naction removeTask(task) {\n $delete = http({ url: \"/api/tasks/\" + task.id, method: \"DELETE\" })\n $tasks.refetch()\n}\n\nrenderRow = (task) => Card([Stack([\n Badge(task.done ? \"done\" : \"open\", tone: task.done ? \"success\" : \"neutral\"),\n Text(task.title, tone: task.done ? \"muted\" : \"default\"),\n Buttons([\n Button(task.done ? \"Reopen\" : \"Done\", onClick: () => toggle(task), variant: \"primary\", size: \"sm\"),\n Button(\"Delete\", onClick: () => removeTask(task), variant: \"ghost\", size: \"sm\")\n ])\n])])\n\ncomponent TasksPage() {\n return Stack([\n PageHeader(\"Tasks\", subtitle: \\`\\${@Count($tasks.data)} items\\`, actions: [Button(\"Refresh\", onClick: $tasks.refetch, variant: \"ghost\")]),\n Async($tasks,\n loading: LoadingState(\"Loading tasks…\"),\n error: ErrorState(\"We couldn't fetch tasks\", description: \"Try again in a moment.\", action: Button(\"Retry\", onClick: $tasks.refetch, variant: \"primary\")),\n empty: EmptyState(\"No tasks yet\", description: \"Create your first task to get started.\", icon: \"list-check\"),\n data: Stack(for t in $tasks.data { renderRow(t) }, direction: \"column\", gap: \"s\")\n )\n ], direction: \"column\", gap: \"l\")\n}\n\n${ROOT_NAME} = TasksPage()`,\n `# App shell with router\naction selectNav(label, path) { _route_.navigate(path) }\n\npages = _router_({\n \"/\": Overview(),\n \"/projects\": Projects(),\n \"/calendar\": Calendar(),\n default: NotFound()\n})\n\nrenderNav = (label, icon, path) => SidebarItem(label, icon: icon, active: _route_.path == path, action: () => selectNav(label, path))\n\nnav = Sidebar([\n SidebarSection(\"Workspace\", [\n renderNav(\"Overview\", \"house\", \"/\"),\n renderNav(\"Projects\", \"folder\", \"/projects\"),\n renderNav(\"Calendar\", \"calendar\", \"/calendar\")\n ])\n])\n\n${ROOT_NAME} = AppShell(nav, pages)\n\ncomponent Overview() {\n return Stack([\n PageHeader(\"Overview\", subtitle: \"Everything happening across your workspace\"),\n Stats([\n StatCard(\"MRR\", value: \"$48.2k\", trend: \"up\", delta: \"+12% vs last month\", icon: \"sack-dollar\"),\n StatCard(\"Active users\", value: \"2,184\", trend: \"up\", delta: \"+184\", icon: \"users\"),\n StatCard(\"Open tickets\", value: \"23\", trend: \"down\", delta: \"-9\", icon: \"ticket\")\n ])\n ], direction: \"column\", gap: \"l\")\n}\n\ncomponent Projects() { return Stack([PageHeader(\"Projects\")], direction: \"column\", gap: \"l\") }\ncomponent Calendar() { return Stack([PageHeader(\"Calendar\")], direction: \"column\", gap: \"l\") }\ncomponent NotFound() { return Stack([PageHeader(\"Not found\")], direction: \"column\", gap: \"l\") }`,\n `# Contact form with two-way binding and validation\n$name = \"\"\n$email = \"\"\n$message = \"\"\n$sent = false\n\naction submit() {\n if !$name || !$email { return }\n $post = http({ url: \"/api/contact\", method: \"POST\", body: { name: $name, email: $email, message: $message } })\n $sent = true\n}\n\naction reset() { $name = \"\" $email = \"\" $message = \"\" $sent = false }\n\nformCard = Card([\n CardHeader(\"Get in touch\", subtitle: \"We typically reply within one business day.\"),\n Form(\"contact\", btns, [\n FormControl(\"Name\", Input(\"name\", placeholder: \"Your name\", bind:value: $name)),\n FormControl(\"Email\", Input(\"email\", placeholder: \"you@example.com\", type: \"email\", bind:value: $email)),\n FormControl(\"Message\", TextArea(\"message\", placeholder: \"Tell us more…\", rows: 4, bind:value: $message))\n ])\n])\n\nbtns = Buttons([\n Button(\"Send\", onClick: submit, variant: \"primary\", icon: \"paper-plane\"),\n Button(\"Reset\", onClick: reset, variant: \"ghost\")\n])\n\nresultCard = if $sent {\n Card([Callout(\"success\", \"Message sent\", description: \\`Thanks \\${$name}, we'll be in touch at \\${$email}.\\`, icon: \"envelope-circle-check\")])\n} else { null }\n\n${ROOT_NAME} = Stack([formCard, resultCard], direction: \"column\", gap: \"l\")`,\n ];\n}\n\n/* -------------------------------------------------------------------------- */\n/* CHAT mode — read-only UI rendering */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The chat prompt teaches **just enough** to convert an LLM's prose\n * response into a rich UI surface. The LLM is NOT expected to emit any\n * interactive behaviour — no `$state` writes, no `action`, no `effect`,\n * no `http(...)`, no `_router_(...)`, no `js{…}`. Only static layout,\n * content, data-presentation, and `FollowUpBlock` for canned follow-up\n * prompts.\n */\nconst CHAT_COMPONENT_ALLOWLIST: ReadonlyArray<string> = [\n // Layout\n \"Stack\", \"StackItem\", \"Grid\", \"GridItem\", \"Box\", \"Container\", \"Spacer\",\n \"Card\", \"CardHeader\", \"CardFooter\", \"Separator\",\n \"Tabs\", \"TabItem\", \"Accordion\", \"AccordionItem\", \"Steps\",\n \"AspectRatio\",\n // Content\n \"Text\", \"Markdown\", \"Quote\", \"Callout\", \"CodeBlock\", \"Image\",\n \"Link\", \"Badge\", \"BadgeList\", \"Icon\", \"Kbd\", \"Spinner\", \"Skeleton\",\n // Data presentation (read-only)\n \"Table\", \"Col\", \"List\", \"ListItem\", \"StatCard\", \"Stats\", \"Sparkline\",\n \"Tile\", \"Progress\", \"ProgressRing\", \"DescriptionList\", \"DescriptionItem\",\n \"StatusDot\", \"Tree\", \"TreeNode\",\n // Charts (read-only)\n \"BarChart\", \"LineChart\", \"PieChart\", \"RadarChart\", \"ScatterChart\",\n \"Histogram\", \"Heatmap\", \"Gauge\", \"Series\",\n // Feedback / media (display)\n \"Avatar\", \"AvatarGroup\", \"PersonChip\", \"Rating\", \"ChatBubble\",\n \"Banner\", \"Notification\",\n // Patterns (display)\n \"Hero\", \"PageHeader\", \"SectionHeader\", \"EmptyState\",\n \"Timeline\", \"TimelineItem\", \"ActivityLog\",\n \"FeatureGrid\", \"FeatureItem\",\n \"Testimonial\", \"ProfileCard\", \"Comment\",\n \"MediaCard\",\n \"LoadingState\", \"ErrorState\", \"SuccessState\",\n \"DiffViewer\", \"JsonTree\",\n // Chat\n \"SectionBlock\", \"ListBlock\", \"FollowUpBlock\", \"FollowUpItem\",\n];\n\nfunction chatHeader(preamble: string | undefined): string {\n const lead = preamble?.trim()\n || \"You are an AI assistant that responds using Aktion — a compact declarative language whose output is rendered as a rich, read-only UI surface. Your entire response must be valid Aktion, with no markdown, no commentary, no JSON.\";\n return `${lead}\nEvery response MUST start with \\`${ROOT_NAME} = ...\\` on the very first line.\n\nYou are operating in **read-only UI mode**. Use ONLY the layout, content,\ndata-presentation, and feedback components listed below. Do NOT emit any\nof the following — they are interactive surfaces reserved for full-app\nmode and will not function here:\n\n- Reactive-state writes, \\`action\\` blocks, \\`effect\\` blocks, raw \\`js\\`\n escape hatches, HTTP calls, or routing primitives.\n- Form controls and clickable buttons (text inputs, dropdowns, submit\n controls, file pickers, etc.).\n- App shells, sidebars, split views, and kanban-style boards.\n- Floating overlays and menus (modals, drawers, popovers, hover-cards,\n tooltips, dropdown menus, command palettes, context menus).\n\nThe single exception is \\`FollowUpBlock\\` — it is a read-only block of\nsuggested follow-up prompts which the host renders as plain buttons.`;\n}\n\nfunction chatSyntax(): string {\n return `## Syntax (read-only subset)\n\nA program is a flat list of \\`name = expression\\` statements terminated by\nnewlines. \\`${ROOT_NAME}\\` is the entry point — every program MUST begin\nwith \\`${ROOT_NAME} = ...\\` (typically \\`${ROOT_NAME} = Stack([...])\\`).\n\n### Expressions\n- Strings: \\`\"hello\"\\` or \\`'hello'\\`. Both forms support escapes.\n- Template literals: backticks with \\`\\${expr}\\` interpolation —\n \\`\\`\\`\\${@Count(rows)} results\\`\\`\\`. Mix copy with values without manual \\`+\\` concatenation.\n- Numbers (\\`42\\`, \\`-3.14\\`), booleans (\\`true\\`, \\`false\\`), \\`null\\`.\n- Arrays: \\`[1, 2, 3]\\`, \\`[Card1(), Card2()]\\` — multi-line OK.\n- Objects: \\`{ key: value, \"quoted-key\": value }\\`.\n- Operators: \\`+ - * / %\\`, \\`== != > < >= <=\\`, \\`&& || !\\`, ternary\n \\`cond ? a : b\\`, nullish coalescing \\`a ?? b\\`, spread \\`[...a, ...b]\\`,\n member access \\`obj.field\\`, optional chaining \\`obj?.field\\`.\n\n### Component calls\n\\`TypeName(arg1, arg2, prop: value, …)\\`. Arguments are matched against the\nspec's prop list in declaration order; named arguments (\\`prop: value\\`) may\nappear at any position and override positional matching. Optional props can\nbe omitted from the end.\n\n\\`\\`\\`\nCallout(\"info\", \"Heads up\", description: \"Action required\", icon: \"circle-info\", compact: true)\nStack([card1, card2], direction: \"row\", gap: \"m\")\nBadge(\"Live\", tone: \"success\", icon: \"circle-dot\")\n\\`\\`\\`\n\n### Repeating UI from data\nUse the expression-form \\`for\\` loop to render an array of items into\nmultiple nodes:\n\n\\`\\`\\`\nrows = for item in items { ListItem(item.title, description: item.desc) }\nlist = List(rows)\n\\`\\`\\`\n\n### Branching (optional)\nUse \\`if\\` / \\`match\\` when the UI depends on a literal you computed:\n\n\\`\\`\\`\ngreeting = if isMorning { \"Good morning\" } else { \"Hello\" }\ntone = match status { \"ok\": \"success\" \"warn\": \"warning\" default: \"neutral\" }\n\\`\\`\\`\n\n### Array helpers\n- \\`rows.length\\` — element count.\n- \\`rows.first\\` / \\`rows.last\\` — first / last element (\\`null\\` if empty).\n- **Array pluck**: \\`rows.title\\` returns \\`[row.title for each row]\\` —\n the idiomatic way to feed per-column arrays (\\`Col(\"Title\", rows.title)\\`)\n or per-segment number arrays (\\`PieChart(rows.label, rows.value)\\`).\n\n### Statement ordering — required for streaming\n\\`\\`\\`\n${ROOT_NAME} = Stack([heroCard, statsRow, table, follow])\n\nheroCard = Card([CardHeader(\"Q4 results\", subtitle: \"Across all teams\")])\nstatsRow = Stats(stats)\ntable = Table([Col(\"Region\", rows.region), Col(\"Revenue\", rows.revenue, format: \"currency\")])\nfollow = FollowUpBlock([\"Break down by region\", \"Compare to Q3\"])\n\nstats = [\n { label: \"MRR\", value: \"$48.2k\", hint: \"+12% vs Q3\" },\n { label: \"Active users\", value: \"2,184\", hint: \"+184\" }\n]\nrows = [\n { region: \"North America\", revenue: 184000 },\n { region: \"Europe\", revenue: 122000 },\n { region: \"APAC\", revenue: 89000 }\n]\n\\`\\`\\`\n\nAlways declare \\`${ROOT_NAME}\\` FIRST. Then container/composition statements\n(\\`heroCard\\`, \\`statsRow\\`, …). Then leaf data arrays last. This produces a\nclean top-down reveal as the response streams in.`;\n}\n\nfunction chatComponentLibrary(library: ComponentLibrary): string {\n const allGroups = library.componentGroups ?? [{ name: \"Components\", components: library.components.map((c) => c.name) }];\n const byName = new Map(library.components.map((c) => [c.name, c]));\n const lines: string[] = [\n \"## Component library (read-only)\",\n \"Use only these components. Each signature lists props in declaration \" +\n \"order; optional props end with `?`. Pass props positionally in order, \" +\n \"or as `prop: value` named arguments for clarity.\",\n ];\n for (const group of allGroups) {\n const filtered = group.components.filter((name) => CHAT_COMPONENT_ALLOWLIST.includes(name));\n if (filtered.length === 0) continue;\n lines.push(`\\n### ${group.name}`);\n for (const componentName of filtered) {\n const spec = byName.get(componentName);\n if (!spec) continue;\n lines.push(formatComponentSignature(spec));\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction chatIcons(): string {\n return `## Icons (Font Awesome)\n\nIcon-typed props (\\`icon\\`, \\`avatarSrc\\`, etc.) expect a Font Awesome name\nas a string — no \\`fa-\\` prefix, no emoji characters.\n\n- Format: \\`\"name\"\\` (defaults to the solid set), e.g. \\`\"house\"\\`,\n \\`\"chart-line\"\\`, \\`\"star\"\\`, \\`\"circle-check\"\\`.\n- Variants: prefix with \\`\"regular:name\"\\` (outline set) or\n \\`\"brands:name\"\\` (brand logos).\n- Render an icon inline anywhere a Node is expected with\n \\`Icon(name, variant?, size?)\\`.`;\n}\n\nfunction chatBuiltins(): string {\n const catalog = getBuiltinCatalog();\n const data = catalog.filter((e) => e.category === \"data\");\n const iter = catalog.filter((e) => e.category === \"iteration\");\n\n const dataLines = data.map(formatBuiltinEntry).join(\"\\n\");\n const iterLines = iter.map(formatBuiltinEntry).join(\"\\n\");\n\n return `## Built-in \\`@\\`-functions\n\n\\`@\\`-prefixed functions are **pure helpers** — no side effects. Use them\nfor data shaping, counts, sums, formatting, and inline iteration when the\nexpression-form \\`for\\` / \\`if\\` / \\`match\\` would be awkward.\n\n### Data helpers\n${dataLines}\n\n### Iteration helpers\n${iterLines}\n\nTemplate literals (\\`backticks with \\${expr}\\`) compose naturally with these\nhelpers — \\`\\`\\`Found \\${@Count(rows)} \\${@Plural(@Count(rows), \"result\", \"results\")} (\\${@Format(@Sum(rows.amount), \"currency\", \"USD\")} total)\\`\\`\\``;\n}\n\nfunction chatStreaming(): string {\n return `## Hoisting & streaming (CRITICAL)\n\nAktion supports hoisting: a reference can be used BEFORE it is\ndefined. The output is re-parsed on every streamed chunk, so undefined\nreferences render as empty until their definitions arrive. This produces a\nsmooth top-down reveal.\n\n**Required statement order:**\n1. \\`${ROOT_NAME} = ...\\` — emit FIRST so the UI shell appears immediately.\n2. Container statements (\\`heroCard\\`, \\`tableBlock\\`, \\`statsRow\\`, …) — next.\n3. Leaf data values (arrays, objects, strings) — last.\n\n**Streaming rules:**\n- Always reference children by name from the root\n (\\`${ROOT_NAME} = Stack([hero, body, footer])\\`).\n- Define one reference per \\`Col\\`, \\`TabItem\\`, \\`AccordionItem\\`,\n \\`Series\\`, \\`FollowUpItem\\`, etc. — each one streams in independently.\n- Place large data values on their own trailing lines.\n- Never split a single statement across multiple lines unless it sits\n inside an unmatched \\`[\\`, \\`(\\`, or \\`{\\`.`;\n}\n\nfunction chatToolsList(tools: ReadonlyArray<ToolSpec>): string {\n const lines: string[] = [\n \"## Available data sources (context only)\",\n \"These endpoints are available to the host. You cannot call them from \" +\n \"read-only mode, but you may incorporate the data they describe when \" +\n \"composing the UI:\",\n ];\n for (const tool of tools) {\n lines.push(`- **${tool.name}** — ${tool.description}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction chatDefaultExamples(): ReadonlyArray<string> {\n return [\n `# Comparison table reply with template literal summary\n${ROOT_NAME} = Stack([title, tbl, totals, follow])\ntitle = Text(\"Top languages by users\", variant: \"large-heavy\")\ntbl = Table([\n Col(\"Language\", langs.name),\n Col(\"Users (M)\", langs.users, format: \"number\"),\n Col(\"First seen\", langs.year, format: \"number\")\n])\ntotals = Callout(\"info\", \\`Tracking \\${@Count(langs)} languages · \\${@Sum(langs.users)}M users combined\\`, icon: \"chart-line\", compact: true)\nfollow = FollowUpBlock([\"Sort by users\", \"Show this as a chart\", \"Tell me about TypeScript\"])\n\nlangs = [\n { name: \"Python\", users: 15.7, year: 1991 },\n { name: \"JavaScript\", users: 14.2, year: 1995 },\n { name: \"Java\", users: 12.1, year: 1995 },\n { name: \"TypeScript\", users: 8.5, year: 2012 },\n { name: \"Go\", users: 5.2, year: 2009 }\n]`,\n `# Bar chart reply with a summary callout\n${ROOT_NAME} = Stack([title, chart, summary, follow])\ntitle = Text(\"Q4 revenue by product\", variant: \"large-heavy\")\nchart = BarChart(labels, [Series(\"Product A\", a), Series(\"Product B\", b)])\nsummary = Callout(\"info\", \\`Q4 total: \\${@Format(@Sum(a) + @Sum(b), \"currency\", \"USD\")} across \\${@Count(labels)} months\\`, icon: \"chart-column\", compact: true)\nfollow = FollowUpBlock([\"Compare to Q3\", \"Break down by region\", \"Show as a line chart\"])\n\nlabels = [\"Oct\", \"Nov\", \"Dec\"]\na = [120, 150, 180]\nb = [90, 110, 140]`,\n `# Article-style reply with Markdown body and a KPI strip\n${ROOT_NAME} = Stack([header, body, kpis, related])\nheader = Hero(\n \"The fastest open-source UI runtime\",\n subtitle: \"Three releases in, the renderer parses and paints 38,000 LLM responses per second.\",\n eyebrow: \"Engineering update\"\n)\nbody = Markdown(article)\nkpis = Stats([\n { label: \"Open issues\", value: \"184\", hint: \"-23 vs last week\" },\n { label: \"PRs merged\", value: \"1,204\", hint: \"this quarter\" },\n { label: \"Avg latency\", value: \"84ms\", hint: \"p99\" }\n])\nrelated = SectionBlock(\"Related reads\", [\n ListBlock([\n \"How streaming UI got 2× faster\",\n \"The case for a single reactive sigil\",\n \"Lazy hydration in practice\"\n ])\n])\n\narticle = \"The renderer started as a hack to display LLM responses without a framework. Today it ships **130+ components**, a single-sigil reactive model, and a tiny streaming-first parser. Read on for the architecture deep-dive.\"`,\n `# Code-snippet reply — title + Markdown + summary callout\n${ROOT_NAME} = Stack([header, answer, hint, follow])\nheader = Text(\"Recommended Postgres index\", variant: \"large-heavy\")\nanswer = CodeBlock(\"sql\", indexSql, showLineNumbers: true)\nhint = Callout(\"success\", \"Composite index cuts query time ~12×\", description: \"Postgres reads index entries already in the requested order, so the planner skips the sort step entirely.\", icon: \"lightbulb\")\nfollow = FollowUpBlock([\"Show EXPLAIN ANALYZE output\", \"How big is the index?\", \"Compare to a partial index\"])\n\nindexSql = \"CREATE INDEX idx_orders_user_status_created\\\\n ON orders (user_id, status, created_at DESC);\"`,\n ];\n}\n\nfunction chatImportantRules(): string {\n return `## Important rules\n\n- **Choose components that best represent the content.** Tables for\n comparisons, charts for trends, \\`Callout\\` / \\`Banner\\` for highlights,\n \\`Markdown\\` for paragraph prose with inline formatting, \\`Hero\\` /\n \\`PageHeader\\` for top-of-reply titles, \\`Stats\\` for KPI strips.\n- **Lead with a clear title.** Use \\`Text(text, variant: \"large-heavy\")\\`,\n \\`SectionHeader(...)\\`, \\`PageHeader(...)\\`, or \\`Hero(...)\\` so the user sees\n what the reply is about at a glance.\n- **Generate realistic data.** When asked about data, write believable\n names, numbers, and dates. Never write Lorem Ipsum.\n- **Tables are column-oriented**: \\`Table([Col(\"Label\", arr1), Col(\"Count\", arr2, format: \"number\")])\\`.\n- **Charts need numeric arrays**, not arrays of objects. Use array pluck:\n \\`PieChart(rows.label, rows.value)\\` instead of passing \\`rows\\` directly.\n- **End conversational replies with \\`FollowUpBlock([...])\\`** — 2–4 short\n next-prompt suggestions keep the conversation flowing.\n- **Use \\`Markdown\\`** for rich paragraph prose with bold, lists, code\n fences, links, and headings. Use \\`Text\\` for short labelled lines.\n- **Icons are Font Awesome names** (no \\`fa-\\` prefix, no emoji). Example\n values: \\`\"house\"\\`, \\`\"chart-line\"\\`, \\`\"star\"\\`, \\`\"circle-check\"\\`.\n- **Use template literals** for any string that mixes copy with values:\n \\`\\`\\`\\${@Count(rows)} results\\`\\`\\` instead of \\`\"...\" + ... + \"...\"\\` concatenation.`;\n}\n\nfunction chatFinalVerification(): string {\n return `## Final verification\n\nBefore finishing, walk your output and verify:\n1. \\`${ROOT_NAME} = ...\\` is the FIRST line.\n2. Every referenced name is defined somewhere below.\n3. Every defined name (other than \\`${ROOT_NAME}\\`) is reachable from\n \\`${ROOT_NAME}\\` (directly or transitively).\n4. Only the read-only components listed above are used — no forms,\n clickable buttons, modal overlays, app shells, reactive-state writes,\n action blocks, effect blocks, HTTP calls, routing primitives, or raw\n \\`js\\` escape hatches.\n5. No statement is split across multiple lines unless it sits inside an\n unmatched \\`[\\`, \\`(\\`, or \\`{\\`.\n6. Tables are column-oriented; charts use numeric arrays (use array pluck\n like \\`rows.value\\` when needed).`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Shared helpers */\n/* -------------------------------------------------------------------------- */\n\nfunction formatComponentSignature(spec: ComponentSpec): string {\n const positional = findPositionalProp(spec);\n const params = spec.props.map((prop) => {\n const typePart = prop.enum\n ? prop.enum.map((v) => `\"${v}\"`).join(\"|\")\n : prop.type;\n const positionalTag =\n prop === positional && prop.positional === true ? \" (positional)\" : \"\";\n return `${prop.name}${prop.optional ? \"?\" : \"\"}: ${typePart}${positionalTag}`;\n }).join(\", \");\n return `- ${spec.name}(${params}) — ${spec.description}`;\n}\n\nfunction formatBuiltinCatalog(entries: ReadonlyArray<BuiltinEntry>): string {\n const data = entries.filter((e) => e.category === \"data\");\n const iter = entries.filter((e) => e.category === \"iteration\");\n const lines: string[] = [];\n if (data.length > 0) {\n lines.push(\"### Data helpers\");\n for (const entry of data) lines.push(formatBuiltinEntry(entry));\n lines.push(\"\");\n }\n if (iter.length > 0) {\n lines.push(\"### Iteration helpers\");\n for (const entry of iter) lines.push(formatBuiltinEntry(entry));\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatBuiltinEntry(entry: BuiltinEntry): string {\n return `- \\`${entry.signature}\\` — ${entry.description}`;\n}\n\nfunction examplesSection(title: string, examples: ReadonlyArray<string>): string {\n const lines = [`## ${title}`];\n for (const example of examples) {\n lines.push(\"```\");\n lines.push(example.trim());\n lines.push(\"```\");\n }\n return lines.join(\"\\n\");\n}\n\nfunction rulesSection(rules: ReadonlyArray<string>): string {\n const lines = [\"## Additional rules\"];\n for (const rule of rules) lines.push(`- ${rule}`);\n return lines.join(\"\\n\");\n}\n\nfunction toolsListSection(tools: ReadonlyArray<ToolSpec>): string {\n const lines: string[] = [\n \"## Available endpoints\",\n \"These endpoints are provided by the host. Fire requests with \" +\n \"`http({ url, method, body, headers, ... })` and observe the reactive \" +\n \"bag (`.data`, `.error`, `.loading`, `.status`, `.refetch()`).\",\n ];\n for (const tool of tools) {\n const kind = tool.kind === \"Mutation\" ? \"POST/PUT/PATCH/DELETE\" : \"GET\";\n const argsLine = tool.argsExample\n ? ` example body: ${JSON.stringify(tool.argsExample)}`\n : \" example body: {}\";\n lines.push(`- ${tool.name} (${kind}) — ${tool.description}\\n${argsLine}`);\n }\n return lines.join(\"\\n\");\n}\n","/**\n * Theme tokens applied as CSS custom properties on the host element.\n *\n * Built-in themes:\n * - \"light\" (default)\n * - \"dark\"\n * - \"neon\" (cyberpunk-inspired, dark with glowing accents)\n * - \"pastel\" (soft, friendly, light & rounded)\n * - \"glass\" (frosted glass, translucent surfaces, vivid gradient bg)\n * - \"brutalist\" (neo-brutalism, hard edges, thick borders, bold colors)\n * - \"skyline\" (deep navy + cyan, crisp & calm)\n *\n * Consumers can also pass a JSON object via the `theme` attribute, call\n * `element.setTheme({...})`, or declare `theme = Theme({...})` inside a\n * Aktion program. All three paths flow through `mergeTheme`\n * so partial token maps are layered on top of the `light` defaults.\n *\n * Token taxonomy:\n * - **Color** — surface, semantic, brand accents, focus ring.\n * - **Typography** — body and heading families, sizes, weights, line\n * heights, letter spacing, and heading text-transform. Enough surface\n * to mirror brand systems (GitHub, Stripe, Apple, IONOS, Notion, …).\n * - **Shape & spacing** — radii (xs/sm/md/lg/pill/button/input), border\n * width, shadows, spacing scale.\n * - **Buttons** — font-weight, text-transform, letter-spacing, padding.\n * - **Charts** — six rotating series colors.\n * - **Motion** — transition duration shared by hover / focus animations.\n */\n\nexport interface ThemeTokens {\n /* ----- Surface & semantic colors --------------------------------- */\n colorBg: string;\n colorBgSubtle: string;\n colorSurface: string;\n colorSurfaceMuted: string;\n colorBorder: string;\n colorBorderSubtle: string;\n colorText: string;\n colorTextMuted: string;\n colorPrimary: string;\n colorPrimaryHover: string;\n colorPrimaryText: string;\n /** Secondary brand accent (links, chips, callouts). Defaults to primary. */\n colorAccent: string;\n colorAccentHover: string;\n colorAccentText: string;\n /** Focus ring color (CSS color). Defaults to primary. */\n colorFocusRing: string;\n colorSuccess: string;\n colorWarning: string;\n colorDanger: string;\n colorInfo: string;\n /* ----- Typography ------------------------------------------------- */\n fontFamily: string;\n /** Font stack used for headings (Card title, Page header, SectionHeader…). */\n fontFamilyHeading: string;\n fontFamilyMono: string;\n /** Root font size — body text defaults to this value. */\n fontSizeBase: string;\n fontSizeSm: string;\n fontSizeLg: string;\n /** Font size for Card/Section headings. */\n fontSizeHeading: string;\n /** Font size for page-level titles (PageHeader, Cover, Hero). */\n fontSizeTitle: string;\n fontWeightBody: string;\n fontWeightHeading: string;\n lineHeightBody: string;\n lineHeightHeading: string;\n /** Letter spacing applied to titles & headings (e.g. \"-0.01em\"). */\n letterSpacingHeading: string;\n /** `text-transform` applied to titles & headings (e.g. \"uppercase\"). */\n headingTextTransform: string;\n /* ----- Shape ------------------------------------------------------ */\n /** Micro radius (pills, dots, status chips). */\n radiusXs: string;\n radiusSm: string;\n radiusMd: string;\n radiusLg: string;\n /** Fully-rounded radius — `999px` by default. */\n radiusPill: string;\n /** Button-specific radius. Falls back to `radiusSm`. */\n radiusButton: string;\n /** Input-specific radius. Falls back to `radiusSm`. */\n radiusInput: string;\n /** Width of every solid border (default 1px; brutalist uses 2px). */\n borderWidth: string;\n shadowSm: string;\n shadowMd: string;\n shadowLg: string;\n /* ----- Spacing ---------------------------------------------------- */\n spacingXs: string;\n spacingS: string;\n spacingM: string;\n spacingL: string;\n spacingXl: string;\n /* ----- Buttons ---------------------------------------------------- */\n buttonFontWeight: string;\n buttonTextTransform: string;\n buttonLetterSpacing: string;\n buttonPaddingY: string;\n buttonPaddingX: string;\n /* ----- Motion ----------------------------------------------------- */\n transitionDuration: string;\n /* ----- Chart palette --------------------------------------------- */\n chart1: string;\n chart2: string;\n chart3: string;\n chart4: string;\n chart5: string;\n chart6: string;\n}\n\nconst baseFonts = {\n fontFamily: \"system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n fontFamilyHeading: \"system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n fontFamilyMono: \"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n} as const;\n\nconst baseFontScale = {\n fontSizeBase: \"14px\",\n fontSizeSm: \"12px\",\n fontSizeLg: \"16px\",\n fontSizeHeading: \"16px\",\n fontSizeTitle: \"22px\",\n fontWeightBody: \"400\",\n fontWeightHeading: \"700\",\n lineHeightBody: \"1.5\",\n lineHeightHeading: \"1.2\",\n letterSpacingHeading: \"0\",\n headingTextTransform: \"none\",\n} as const;\n\nconst baseSpacing = {\n spacingXs: \"4px\",\n spacingS: \"8px\",\n spacingM: \"12px\",\n spacingL: \"20px\",\n spacingXl: \"32px\",\n} as const;\n\nconst baseRadii = {\n radiusXs: \"4px\",\n radiusSm: \"6px\",\n radiusMd: \"10px\",\n radiusLg: \"16px\",\n radiusPill: \"999px\",\n radiusButton: \"6px\",\n radiusInput: \"6px\",\n} as const;\n\nconst baseButtons = {\n buttonFontWeight: \"600\",\n buttonTextTransform: \"none\",\n buttonLetterSpacing: \"0\",\n buttonPaddingY: \"8px\",\n buttonPaddingX: \"14px\",\n} as const;\n\nconst baseMotion = {\n transitionDuration: \"120ms\",\n} as const;\n\nexport const lightTheme: ThemeTokens = {\n colorBg: \"#ffffff\",\n colorBgSubtle: \"#f8fafc\",\n colorSurface: \"#ffffff\",\n colorSurfaceMuted: \"#f1f5f9\",\n colorBorder: \"#e2e8f0\",\n colorBorderSubtle: \"rgba(15, 23, 42, 0.08)\",\n colorText: \"#0f172a\",\n colorTextMuted: \"#475569\",\n colorPrimary: \"#6366f1\",\n colorPrimaryHover: \"#4f46e5\",\n colorPrimaryText: \"#ffffff\",\n colorAccent: \"#6366f1\",\n colorAccentHover: \"#4f46e5\",\n colorAccentText: \"#ffffff\",\n colorFocusRing: \"#6366f1\",\n colorSuccess: \"#10b981\",\n colorWarning: \"#f59e0b\",\n colorDanger: \"#ef4444\",\n colorInfo: \"#06b6d4\",\n shadowSm: \"0 1px 2px rgba(15, 23, 42, 0.06)\",\n shadowMd: \"0 6px 24px rgba(15, 23, 42, 0.08)\",\n shadowLg: \"0 18px 60px rgba(15, 23, 42, 0.12)\",\n borderWidth: \"1px\",\n chart1: \"#6366f1\",\n chart2: \"#10b981\",\n chart3: \"#f59e0b\",\n chart4: \"#ef4444\",\n chart5: \"#06b6d4\",\n chart6: \"#8b5cf6\",\n ...baseFonts,\n ...baseFontScale,\n ...baseSpacing,\n ...baseRadii,\n ...baseButtons,\n ...baseMotion,\n};\n\nexport const darkTheme: ThemeTokens = {\n ...lightTheme,\n colorBg: \"#0b1220\",\n colorBgSubtle: \"#0f172a\",\n colorSurface: \"#111827\",\n colorSurfaceMuted: \"#1e293b\",\n colorBorder: \"#1f2937\",\n colorBorderSubtle: \"rgba(248, 250, 252, 0.08)\",\n colorText: \"#f8fafc\",\n colorTextMuted: \"#94a3b8\",\n colorPrimary: \"#818cf8\",\n colorPrimaryHover: \"#6366f1\",\n colorPrimaryText: \"#0b1220\",\n colorAccent: \"#818cf8\",\n colorAccentHover: \"#6366f1\",\n colorAccentText: \"#0b1220\",\n colorFocusRing: \"#818cf8\",\n shadowSm: \"0 1px 2px rgba(0, 0, 0, 0.4)\",\n shadowMd: \"0 8px 24px rgba(0, 0, 0, 0.4)\",\n shadowLg: \"0 22px 60px rgba(0, 0, 0, 0.55)\",\n};\n\n/**\n * Neon — cyberpunk-flavoured dark mode. Magenta/cyan glow, sharper corners,\n * monospace headings, and high-contrast surfaces.\n */\nexport const neonTheme: ThemeTokens = {\n ...lightTheme,\n colorBg: \"#05060f\",\n colorBgSubtle: \"#0a0c1c\",\n colorSurface: \"#0d1024\",\n colorSurfaceMuted: \"#161a36\",\n colorBorder: \"#2a2f6b\",\n colorBorderSubtle: \"rgba(236, 72, 153, 0.18)\",\n colorText: \"#f5f3ff\",\n colorTextMuted: \"#a5b4fc\",\n colorPrimary: \"#ec4899\",\n colorPrimaryHover: \"#f472b6\",\n colorPrimaryText: \"#05060f\",\n colorAccent: \"#22d3ee\",\n colorAccentHover: \"#67e8f9\",\n colorAccentText: \"#05060f\",\n colorFocusRing: \"#ec4899\",\n colorSuccess: \"#34d399\",\n colorWarning: \"#fbbf24\",\n colorDanger: \"#f87171\",\n colorInfo: \"#22d3ee\",\n fontFamily: \"'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n fontFamilyHeading: \"'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n fontFamilyMono: \"'JetBrains Mono', 'Fira Code', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n letterSpacingHeading: \"0.02em\",\n radiusXs: \"2px\",\n radiusSm: \"2px\",\n radiusMd: \"4px\",\n radiusLg: \"6px\",\n radiusButton: \"2px\",\n radiusInput: \"2px\",\n shadowSm: \"0 0 0 1px rgba(236, 72, 153, 0.25), 0 0 12px rgba(34, 211, 238, 0.18)\",\n shadowMd: \"0 0 0 1px rgba(236, 72, 153, 0.35), 0 0 28px rgba(34, 211, 238, 0.22)\",\n shadowLg: \"0 0 0 1px rgba(236, 72, 153, 0.45), 0 0 48px rgba(34, 211, 238, 0.35)\",\n spacingXs: \"4px\",\n spacingS: \"8px\",\n spacingM: \"14px\",\n spacingL: \"22px\",\n spacingXl: \"36px\",\n chart1: \"#ec4899\",\n chart2: \"#22d3ee\",\n chart3: \"#fbbf24\",\n chart4: \"#a78bfa\",\n chart5: \"#34d399\",\n chart6: \"#f472b6\",\n};\n\n/**\n * Pastel — soft, friendly, light and rounded. Larger paddings, big radii,\n * lavender + mint palette, gentle shadows.\n */\nexport const pastelTheme: ThemeTokens = {\n ...lightTheme,\n colorBg: \"#fdf6ff\",\n colorBgSubtle: \"#fbf2ff\",\n colorSurface: \"#ffffff\",\n colorSurfaceMuted: \"#f4ecff\",\n colorBorder: \"#ead8ff\",\n colorBorderSubtle: \"rgba(168, 132, 232, 0.18)\",\n colorText: \"#3b1f56\",\n colorTextMuted: \"#7d6193\",\n colorPrimary: \"#a78bfa\",\n colorPrimaryHover: \"#8b5cf6\",\n colorPrimaryText: \"#ffffff\",\n colorAccent: \"#5eead4\",\n colorAccentHover: \"#2dd4bf\",\n colorAccentText: \"#0f3a35\",\n colorFocusRing: \"#a78bfa\",\n colorSuccess: \"#5eead4\",\n colorWarning: \"#fcd34d\",\n colorDanger: \"#fda4af\",\n colorInfo: \"#93c5fd\",\n fontFamily: \"'Quicksand', 'Nunito', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n fontFamilyHeading: \"'Quicksand', 'Nunito', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n fontFamilyMono: \"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n radiusXs: \"8px\",\n radiusSm: \"12px\",\n radiusMd: \"20px\",\n radiusLg: \"28px\",\n radiusButton: \"16px\",\n radiusInput: \"16px\",\n shadowSm: \"0 4px 14px rgba(168, 132, 232, 0.12)\",\n shadowMd: \"0 18px 40px rgba(168, 132, 232, 0.18)\",\n shadowLg: \"0 28px 70px rgba(168, 132, 232, 0.22)\",\n spacingXs: \"6px\",\n spacingS: \"12px\",\n spacingM: \"18px\",\n spacingL: \"28px\",\n spacingXl: \"44px\",\n chart1: \"#a78bfa\",\n chart2: \"#5eead4\",\n chart3: \"#fcd34d\",\n chart4: \"#fda4af\",\n chart5: \"#93c5fd\",\n chart6: \"#f9a8d4\",\n};\n\n/**\n * Glass — modern glassmorphism. Vivid gradient backdrop, frosted translucent\n * surfaces (real backdrop-filter blur applied via the stylesheet), generous\n * radii, and a cool indigo→cyan accent. Designed for hero sections and\n * marketing-style UIs.\n */\nexport const glassTheme: ThemeTokens = {\n ...lightTheme,\n colorBg: \"#0f1730\",\n colorBgSubtle: \"#13204a\",\n colorSurface: \"rgba(255, 255, 255, 0.08)\",\n colorSurfaceMuted: \"rgba(255, 255, 255, 0.04)\",\n colorBorder: \"rgba(255, 255, 255, 0.18)\",\n colorBorderSubtle: \"rgba(255, 255, 255, 0.10)\",\n colorText: \"#f1f5ff\",\n colorTextMuted: \"#b6c3e6\",\n colorPrimary: \"#60a5fa\",\n colorPrimaryHover: \"#3b82f6\",\n colorPrimaryText: \"#0b132b\",\n colorAccent: \"#22d3ee\",\n colorAccentHover: \"#67e8f9\",\n colorAccentText: \"#0b132b\",\n colorFocusRing: \"#60a5fa\",\n colorSuccess: \"#34d399\",\n colorWarning: \"#fbbf24\",\n colorDanger: \"#fb7185\",\n colorInfo: \"#22d3ee\",\n fontFamily: \"'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n fontFamilyHeading: \"'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n fontFamilyMono: \"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n radiusXs: \"6px\",\n radiusSm: \"10px\",\n radiusMd: \"16px\",\n radiusLg: \"24px\",\n radiusButton: \"12px\",\n radiusInput: \"12px\",\n shadowSm: \"0 1px 2px rgba(15, 23, 42, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.08)\",\n shadowMd: \"0 18px 50px rgba(7, 14, 33, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.10)\",\n shadowLg: \"0 28px 80px rgba(7, 14, 33, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.12)\",\n spacingXs: \"4px\",\n spacingS: \"10px\",\n spacingM: \"16px\",\n spacingL: \"24px\",\n spacingXl: \"40px\",\n chart1: \"#60a5fa\",\n chart2: \"#22d3ee\",\n chart3: \"#a78bfa\",\n chart4: \"#f472b6\",\n chart5: \"#34d399\",\n chart6: \"#fbbf24\",\n};\n\n/**\n * Brutalist — neo-brutalism. Hard 2px black borders, chunky offset shadows,\n * loud primary colors, all-caps display type, and zero gradients. Designed\n * to look hand-built and unapologetically bold.\n */\nexport const brutalistTheme: ThemeTokens = {\n ...lightTheme,\n colorBg: \"#fef9c3\",\n colorBgSubtle: \"#fde68a\",\n colorSurface: \"#ffffff\",\n colorSurfaceMuted: \"#fef3c7\",\n colorBorder: \"#0a0a0a\",\n colorBorderSubtle: \"#0a0a0a\",\n colorText: \"#0a0a0a\",\n colorTextMuted: \"#3f3f46\",\n colorPrimary: \"#1d4ed8\",\n colorPrimaryHover: \"#1e40af\",\n colorPrimaryText: \"#ffffff\",\n colorAccent: \"#dc2626\",\n colorAccentHover: \"#b91c1c\",\n colorAccentText: \"#ffffff\",\n colorFocusRing: \"#0a0a0a\",\n colorSuccess: \"#16a34a\",\n colorWarning: \"#ea580c\",\n colorDanger: \"#dc2626\",\n colorInfo: \"#0891b2\",\n fontFamily: \"'Space Grotesk', 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif\",\n fontFamilyHeading: \"'Space Grotesk', 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif\",\n fontFamilyMono: \"'JetBrains Mono', 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n fontWeightHeading: \"800\",\n letterSpacingHeading: \"-0.01em\",\n headingTextTransform: \"uppercase\",\n radiusXs: \"0px\",\n radiusSm: \"0px\",\n radiusMd: \"0px\",\n radiusLg: \"0px\",\n radiusPill: \"0px\",\n radiusButton: \"0px\",\n radiusInput: \"0px\",\n borderWidth: \"2px\",\n shadowSm: \"3px 3px 0 0 #0a0a0a\",\n shadowMd: \"6px 6px 0 0 #0a0a0a\",\n shadowLg: \"10px 10px 0 0 #0a0a0a\",\n spacingXs: \"4px\",\n spacingS: \"10px\",\n spacingM: \"16px\",\n spacingL: \"22px\",\n spacingXl: \"36px\",\n buttonFontWeight: \"800\",\n buttonTextTransform: \"uppercase\",\n buttonLetterSpacing: \"0.02em\",\n chart1: \"#dc2626\",\n chart2: \"#1d4ed8\",\n chart3: \"#16a34a\",\n chart4: \"#ea580c\",\n chart5: \"#7c3aed\",\n chart6: \"#0a0a0a\",\n};\n\n/**\n * Skyline — enterprise cloud-console aesthetic. Deep navy primary, calm\n * cyan accents, very pale blue page background, white surfaces with crisp\n * 1px borders, small radii, and a clean Inter type stack. The look should\n * feel at home in an admin panel: dense, scannable, minimal chrome.\n */\nexport const skylineTheme: ThemeTokens = {\n ...lightTheme,\n colorBg: \"#eff2f7\",\n colorBgSubtle: \"#e6ecf3\",\n colorSurface: \"#ffffff\",\n colorSurfaceMuted: \"#f4f7fb\",\n colorBorder: \"#d6deea\",\n colorBorderSubtle: \"rgba(13, 27, 58, 0.08)\",\n colorText: \"#0d1b3a\",\n colorTextMuted: \"#5a6a85\",\n colorPrimary: \"#003580\",\n colorPrimaryHover: \"#002a66\",\n colorPrimaryText: \"#ffffff\",\n colorAccent: \"#0095d6\",\n colorAccentHover: \"#0078ad\",\n colorAccentText: \"#ffffff\",\n colorFocusRing: \"#0095d6\",\n colorSuccess: \"#1b8f4f\",\n colorWarning: \"#c47e00\",\n colorDanger: \"#c8362b\",\n colorInfo: \"#0095d6\",\n fontFamily: \"'Inter', 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n fontFamilyHeading: \"'Inter', 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif\",\n fontFamilyMono: \"'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\",\n radiusXs: \"3px\",\n radiusSm: \"4px\",\n radiusMd: \"6px\",\n radiusLg: \"10px\",\n radiusButton: \"4px\",\n radiusInput: \"4px\",\n shadowSm: \"0 1px 0 rgba(13, 27, 58, 0.04), 0 1px 3px rgba(13, 27, 58, 0.06)\",\n shadowMd: \"0 4px 16px rgba(13, 27, 58, 0.08), 0 1px 3px rgba(13, 27, 58, 0.04)\",\n shadowLg: \"0 16px 40px rgba(13, 27, 58, 0.12), 0 2px 6px rgba(13, 27, 58, 0.06)\",\n spacingXs: \"4px\",\n spacingS: \"8px\",\n spacingM: \"14px\",\n spacingL: \"20px\",\n spacingXl: \"32px\",\n chart1: \"#003580\",\n chart2: \"#0095d6\",\n chart3: \"#1b8f4f\",\n chart4: \"#c47e00\",\n chart5: \"#d43594\",\n chart6: \"#5a6a85\",\n};\n\nexport const builtInThemes: Record<string, ThemeTokens> = {\n light: lightTheme,\n dark: darkTheme,\n neon: neonTheme,\n pastel: pastelTheme,\n glass: glassTheme,\n brutalist: brutalistTheme,\n skyline: skylineTheme,\n};\n\nconst TOKEN_TO_CSS: Record<keyof ThemeTokens, string> = {\n colorBg: \"--rui-color-bg\",\n colorBgSubtle: \"--rui-color-bg-subtle\",\n colorSurface: \"--rui-color-surface\",\n colorSurfaceMuted: \"--rui-color-surface-muted\",\n colorBorder: \"--rui-color-border\",\n colorBorderSubtle: \"--rui-color-border-subtle\",\n colorText: \"--rui-color-text\",\n colorTextMuted: \"--rui-color-text-muted\",\n colorPrimary: \"--rui-color-primary\",\n colorPrimaryHover: \"--rui-color-primary-hover\",\n colorPrimaryText: \"--rui-color-primary-text\",\n colorAccent: \"--rui-color-accent\",\n colorAccentHover: \"--rui-color-accent-hover\",\n colorAccentText: \"--rui-color-accent-text\",\n colorFocusRing: \"--rui-color-focus-ring\",\n colorSuccess: \"--rui-color-success\",\n colorWarning: \"--rui-color-warning\",\n colorDanger: \"--rui-color-danger\",\n colorInfo: \"--rui-color-info\",\n fontFamily: \"--rui-font-family\",\n fontFamilyHeading: \"--rui-font-family-heading\",\n fontFamilyMono: \"--rui-font-family-mono\",\n fontSizeBase: \"--rui-font-size-base\",\n fontSizeSm: \"--rui-font-size-sm\",\n fontSizeLg: \"--rui-font-size-lg\",\n fontSizeHeading: \"--rui-font-size-heading\",\n fontSizeTitle: \"--rui-font-size-title\",\n fontWeightBody: \"--rui-font-weight-body\",\n fontWeightHeading: \"--rui-font-weight-heading\",\n lineHeightBody: \"--rui-line-height-body\",\n lineHeightHeading: \"--rui-line-height-heading\",\n letterSpacingHeading: \"--rui-letter-spacing-heading\",\n headingTextTransform: \"--rui-heading-text-transform\",\n radiusXs: \"--rui-radius-xs\",\n radiusSm: \"--rui-radius-sm\",\n radiusMd: \"--rui-radius-md\",\n radiusLg: \"--rui-radius-lg\",\n radiusPill: \"--rui-radius-pill\",\n radiusButton: \"--rui-radius-button\",\n radiusInput: \"--rui-radius-input\",\n borderWidth: \"--rui-border-width\",\n shadowSm: \"--rui-shadow-sm\",\n shadowMd: \"--rui-shadow-md\",\n shadowLg: \"--rui-shadow-lg\",\n spacingXs: \"--rui-spacing-xs\",\n spacingS: \"--rui-spacing-s\",\n spacingM: \"--rui-spacing-m\",\n spacingL: \"--rui-spacing-l\",\n spacingXl: \"--rui-spacing-xl\",\n buttonFontWeight: \"--rui-button-font-weight\",\n buttonTextTransform: \"--rui-button-text-transform\",\n buttonLetterSpacing: \"--rui-button-letter-spacing\",\n buttonPaddingY: \"--rui-button-padding-y\",\n buttonPaddingX: \"--rui-button-padding-x\",\n transitionDuration: \"--rui-transition-duration\",\n chart1: \"--rui-chart-1\",\n chart2: \"--rui-chart-2\",\n chart3: \"--rui-chart-3\",\n chart4: \"--rui-chart-4\",\n chart5: \"--rui-chart-5\",\n chart6: \"--rui-chart-6\",\n};\n\nexport type ThemeInput = string | Partial<ThemeTokens>;\n\nexport interface ResolvedTheme {\n /** Built-in theme name when known, otherwise \"custom\". Drives `data-rui-theme`. */\n name: string;\n tokens: ThemeTokens;\n}\n\nexport function resolveTheme(input: ThemeInput | null | undefined): ResolvedTheme {\n if (!input) return { name: \"light\", tokens: lightTheme };\n if (typeof input === \"string\") {\n const key = input.trim().toLowerCase();\n if (key.startsWith(\"{\")) {\n try {\n return { name: \"custom\", tokens: mergeTheme(JSON.parse(input) as Partial<ThemeTokens>) };\n } catch {\n return { name: \"light\", tokens: lightTheme };\n }\n }\n const tokens = builtInThemes[key];\n if (tokens) return { name: key, tokens };\n return { name: \"light\", tokens: lightTheme };\n }\n return { name: \"custom\", tokens: mergeTheme(input) };\n}\n\n/**\n * Apply theme tokens to the host element. Also sets `data-rui-theme` so the\n * shadow-DOM stylesheet can hook into theme-specific overrides (fonts,\n * gradients, animations, etc.) that go beyond raw token values.\n */\nexport function applyTheme(host: HTMLElement, theme: ResolvedTheme | ThemeTokens): void {\n const resolved: ResolvedTheme =\n \"tokens\" in theme ? theme : { name: \"custom\", tokens: theme };\n for (const [key, cssVar] of Object.entries(TOKEN_TO_CSS) as Array<[keyof ThemeTokens, string]>) {\n host.style.setProperty(cssVar, resolved.tokens[key]);\n }\n host.setAttribute(\"data-rui-theme\", resolved.name);\n}\n\n/**\n * Apply *only* the tokens explicitly listed in `partial`. Leaves every other\n * CSS variable untouched, so this composes cleanly on top of whatever base\n * theme `applyTheme(...)` last wrote. Used by the in-script `Theme(...)`\n * construct so authors can override just a handful of tokens without\n * wiping the rest of the active theme.\n *\n * Unknown keys are ignored — both for forward compatibility and to keep\n * malformed LLM output from polluting the host's inline styles.\n */\nexport function applyPartialTheme(\n host: HTMLElement,\n partial: Partial<ThemeTokens>,\n): ReadonlyArray<keyof ThemeTokens> {\n const applied: Array<keyof ThemeTokens> = [];\n for (const key of Object.keys(partial) as Array<keyof ThemeTokens>) {\n const cssVar = TOKEN_TO_CSS[key];\n if (!cssVar) continue;\n const value = partial[key];\n if (typeof value !== \"string\" || value === \"\") continue;\n host.style.setProperty(cssVar, value);\n applied.push(key);\n }\n return applied;\n}\n\n/**\n * Remove an array of token CSS variables from the host's inline style. Used\n * to \"undo\" a previous `applyPartialTheme(...)` call so the next render\n * inherits whatever the base theme provides rather than the stale override.\n */\nexport function clearTokenOverrides(\n host: HTMLElement,\n keys: ReadonlyArray<keyof ThemeTokens>,\n): void {\n for (const key of keys) {\n const cssVar = TOKEN_TO_CSS[key];\n if (cssVar) host.style.removeProperty(cssVar);\n }\n}\n\n/**\n * Filter an arbitrary object down to the keys recognised by `ThemeTokens`,\n * stringifying primitive values along the way. Used when an Aktion program\n * declares `theme = Theme({...})` — the evaluator hands us\n * a plain JS object, and we want to ignore anything that isn't a real token\n * (LLM typo guard) before applying it.\n */\nexport function sanitiseThemeTokens(input: unknown): Partial<ThemeTokens> {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) return {};\n const out: Partial<ThemeTokens> = {};\n for (const [key, value] of Object.entries(input as Record<string, unknown>)) {\n if (!(key in TOKEN_TO_CSS)) continue;\n if (value == null) continue;\n if (typeof value === \"string\") {\n if (value.trim() === \"\") continue;\n out[key as keyof ThemeTokens] = value;\n } else if (typeof value === \"number\") {\n out[key as keyof ThemeTokens] = String(value);\n }\n }\n return out;\n}\n\nfunction mergeTheme(partial: Partial<ThemeTokens>): ThemeTokens {\n return { ...lightTheme, ...partial };\n}\n","/**\n * Single CSS bundle for the shadow root. Uses CSS custom properties so that\n * theme switches at the host element propagate without re-rendering.\n *\n * Built-in themes additionally hook into `:host([data-rui-theme=\"...\"])`\n * overrides so that themes can change layout, fonts, animations, etc., not\n * only color tokens.\n */\n\nexport const componentStyles = `\n:host {\n display: block;\n box-sizing: border-box;\n color: var(--rui-color-text);\n background: var(--rui-host-bg, var(--rui-color-bg));\n font-family: var(--rui-font-family);\n font-weight: var(--rui-font-weight-body);\n line-height: var(--rui-line-height-body);\n font-size: var(--rui-font-size-base);\n /* Surface & semantic */\n --rui-color-bg: #ffffff;\n --rui-color-bg-subtle: #f8fafc;\n --rui-color-surface: #ffffff;\n --rui-color-surface-muted: #f1f5f9;\n --rui-color-border: #e2e8f0;\n --rui-color-border-subtle: rgba(15, 23, 42, 0.08);\n --rui-color-text: #0f172a;\n --rui-color-text-muted: #475569;\n --rui-color-primary: #6366f1;\n --rui-color-primary-hover: #4f46e5;\n --rui-color-primary-text: #ffffff;\n --rui-color-accent: #6366f1;\n --rui-color-accent-hover: #4f46e5;\n --rui-color-accent-text: #ffffff;\n --rui-color-focus-ring: #6366f1;\n --rui-color-success: #10b981;\n --rui-color-warning: #f59e0b;\n --rui-color-danger: #ef4444;\n --rui-color-info: #06b6d4;\n /* Typography */\n --rui-font-family: system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n --rui-font-family-heading: system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n --rui-font-family-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n --rui-font-size-base: 14px;\n --rui-font-size-sm: 12px;\n --rui-font-size-lg: 16px;\n --rui-font-size-heading: 16px;\n --rui-font-size-title: 22px;\n --rui-font-weight-body: 400;\n --rui-font-weight-heading: 700;\n --rui-line-height-body: 1.5;\n --rui-line-height-heading: 1.2;\n --rui-letter-spacing-heading: 0;\n --rui-heading-text-transform: none;\n /* Shape */\n --rui-radius-xs: 4px;\n --rui-radius-sm: 6px;\n --rui-radius-md: 10px;\n --rui-radius-lg: 16px;\n --rui-radius-pill: 999px;\n --rui-radius-button: 6px;\n --rui-radius-input: 6px;\n --rui-border-width: 1px;\n --rui-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);\n --rui-shadow-md: 0 6px 24px rgba(15, 23, 42, 0.08);\n --rui-shadow-lg: 0 18px 60px rgba(15, 23, 42, 0.12);\n /* Spacing */\n --rui-spacing-xs: 4px;\n --rui-spacing-s: 8px;\n --rui-spacing-m: 12px;\n --rui-spacing-l: 20px;\n --rui-spacing-xl: 32px;\n /* Buttons */\n --rui-button-font-weight: 600;\n --rui-button-text-transform: none;\n --rui-button-letter-spacing: 0;\n --rui-button-padding-y: 8px;\n --rui-button-padding-x: 14px;\n /* Motion */\n --rui-transition-duration: 120ms;\n}\n\n* { box-sizing: border-box; }\nbutton { font-family: inherit; font-size: inherit; cursor: pointer; }\ninput, textarea, select, button { color: inherit; font-family: inherit; }\n\n/* Font Awesome icon wrapper used by Icon(...) and every icon-typed prop.\n The element is given Font Awesome's own classes (fa-solid, fa-house, etc.)\n so the FA stylesheet does the glyph rendering; .rui-icon only handles\n sizing + alignment. */\n.rui-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n.rui-icon[data-icon-size=\"xs\"] { font-size: 10px; }\n.rui-icon[data-icon-size=\"sm\"] { font-size: 12px; }\n.rui-icon[data-icon-size=\"md\"] { font-size: 14px; }\n.rui-icon[data-icon-size=\"lg\"] { font-size: 18px; }\n.rui-icon[data-icon-size=\"xl\"] { font-size: 24px; }\n\n/* Additional attributes: render the host with no background so it inherits the parent\n container's color. Useful when embedding inside a themed page where the\n surrounding chrome already carries the background. The internal cards\n keep their own surface colors so the UI stays legible. */\n:host([transparent]),\n:host([transparent=\"true\"]) {\n background: transparent;\n}\n\n.rui-root {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n}\n\n.rui-error-banner {\n border: 1px solid var(--rui-color-danger);\n background: color-mix(in srgb, var(--rui-color-danger) 8%, transparent);\n color: var(--rui-color-danger);\n border-radius: var(--rui-radius-md);\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n font-size: 13px;\n margin-bottom: var(--rui-spacing-s);\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n.rui-error-banner[hidden] { display: none; }\n.rui-error-banner ul { margin: 0; padding-left: 18px; }\n\n/* Stack */\n.rui-stack {\n display: flex;\n gap: var(--rui-spacing-m);\n}\n.rui-stack[data-direction=\"row\"] { flex-direction: row; }\n.rui-stack[data-direction=\"column\"] { flex-direction: column; }\n.rui-stack[data-gap=\"xs\"] { gap: var(--rui-spacing-xs); }\n.rui-stack[data-gap=\"s\"] { gap: var(--rui-spacing-s); }\n.rui-stack[data-gap=\"m\"] { gap: var(--rui-spacing-m); }\n.rui-stack[data-gap=\"l\"] { gap: var(--rui-spacing-l); }\n.rui-stack[data-gap=\"xl\"] { gap: var(--rui-spacing-xl); }\n.rui-stack[data-align=\"start\"] { align-items: flex-start; }\n.rui-stack[data-align=\"center\"] { align-items: center; }\n.rui-stack[data-align=\"end\"] { align-items: flex-end; }\n.rui-stack[data-align=\"stretch\"] { align-items: stretch; }\n.rui-stack[data-justify=\"start\"] { justify-content: flex-start; }\n.rui-stack[data-justify=\"center\"] { justify-content: center; }\n.rui-stack[data-justify=\"end\"] { justify-content: flex-end; }\n.rui-stack[data-justify=\"between\"] { justify-content: space-between; }\n.rui-stack[data-justify=\"around\"] { justify-content: space-around; }\n.rui-stack[data-justify=\"evenly\"] { justify-content: space-evenly; }\n.rui-stack[data-align-content=\"start\"] { align-content: flex-start; }\n.rui-stack[data-align-content=\"center\"] { align-content: center; }\n.rui-stack[data-align-content=\"end\"] { align-content: flex-end; }\n.rui-stack[data-align-content=\"between\"] { align-content: space-between; }\n.rui-stack[data-align-content=\"around\"] { align-content: space-around; }\n.rui-stack[data-align-content=\"stretch\"] { align-content: stretch; }\n.rui-stack[data-wrap=\"true\"] { flex-wrap: wrap; }\n.rui-stack[data-inline=\"true\"] { display: inline-flex; }\n.rui-stack[data-direction=\"row-reverse\"] { flex-direction: row-reverse; }\n.rui-stack[data-direction=\"column-reverse\"] { flex-direction: column-reverse; }\n.rui-stack[data-padding=\"xs\"] { padding: var(--rui-spacing-xs); }\n.rui-stack[data-padding=\"s\"] { padding: var(--rui-spacing-s); }\n.rui-stack[data-padding=\"m\"] { padding: var(--rui-spacing-m); }\n.rui-stack[data-padding=\"l\"] { padding: var(--rui-spacing-l); }\n.rui-stack[data-padding=\"xl\"] { padding: var(--rui-spacing-xl); }\n.rui-stack[data-direction=\"row\"][data-uniform=\"true\"] > *:not(.rui-stack-item) { flex: 1 1 auto; min-width: 0; }\n.rui-stack[data-direction=\"row-reverse\"][data-uniform=\"true\"] > *:not(.rui-stack-item) { flex: 1 1 auto; min-width: 0; }\n/* Compact inline pills should hug their content, even inside a row Stack\n that flex-grows its children. Without this they get stretched to fill the\n leftover space and look like full-width banners. */\n.rui-stack[data-direction=\"row\"] > .rui-tag,\n.rui-stack[data-direction=\"row\"] > .rui-badge,\n.rui-stack[data-direction=\"row\"] > .rui-status-dot,\n.rui-stack[data-direction=\"row\"] > .rui-kbd-group,\n.rui-stack[data-direction=\"row\"] > .rui-icon,\n.rui-stack[data-direction=\"row\"] > .rui-rating,\n.rui-stack[data-direction=\"row-reverse\"] > .rui-tag,\n.rui-stack[data-direction=\"row-reverse\"] > .rui-badge,\n.rui-stack[data-direction=\"row-reverse\"] > .rui-status-dot,\n.rui-stack[data-direction=\"row-reverse\"] > .rui-kbd-group,\n.rui-stack[data-direction=\"row-reverse\"] > .rui-icon,\n.rui-stack[data-direction=\"row-reverse\"] > .rui-rating { flex: 0 0 auto; }\n\n/* StackItem — per-child flex control inside Stack */\n.rui-stack-item { min-width: 0; }\n.rui-stack-item[data-grow=\"0\"] { flex-grow: 0; }\n.rui-stack-item[data-grow=\"1\"] { flex-grow: 1; }\n.rui-stack-item[data-shrink=\"0\"] { flex-shrink: 0; }\n.rui-stack-item[data-shrink=\"1\"] { flex-shrink: 1; }\n.rui-stack-item[data-basis=\"auto\"] { flex-basis: auto; }\n.rui-stack-item[data-basis=\"0\"] { flex-basis: 0; }\n.rui-stack-item[data-align-self=\"start\"] { align-self: flex-start; }\n.rui-stack-item[data-align-self=\"center\"] { align-self: center; }\n.rui-stack-item[data-align-self=\"end\"] { align-self: flex-end; }\n.rui-stack-item[data-align-self=\"stretch\"] { align-self: stretch; }\n\n/* Section */\n.rui-section { display: flex; flex-direction: column; gap: var(--rui-spacing-s); }\n.rui-section-title {\n margin: 0;\n font-family: var(--rui-font-family-heading);\n font-size: var(--rui-font-size-heading);\n font-weight: var(--rui-font-weight-heading);\n line-height: var(--rui-line-height-heading);\n letter-spacing: var(--rui-letter-spacing-heading);\n text-transform: var(--rui-heading-text-transform);\n color: var(--rui-color-text);\n}\n\n/* Card */\n.rui-card {\n background: var(--rui-color-surface);\n border: var(--rui-border-width) solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n padding: var(--rui-spacing-l);\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n box-shadow: var(--rui-shadow-sm);\n}\n.rui-card[data-variant=\"elevated\"] { box-shadow: var(--rui-shadow-md); }\n.rui-card[data-variant=\"outlined\"] { box-shadow: none; }\n.rui-card-header { display: flex; flex-direction: column; gap: var(--rui-spacing-xs); }\n.rui-card-title {\n margin: 0;\n font-family: var(--rui-font-family-heading);\n font-size: var(--rui-font-size-heading);\n font-weight: var(--rui-font-weight-heading);\n line-height: var(--rui-line-height-heading);\n letter-spacing: var(--rui-letter-spacing-heading);\n text-transform: var(--rui-heading-text-transform);\n}\n.rui-card-subtitle { margin: 0; color: var(--rui-color-text-muted); font-size: 13px; }\n.rui-card-body { display: flex; flex-direction: column; gap: var(--rui-spacing-m); }\n.rui-card-footer { display: flex; gap: var(--rui-spacing-s); justify-content: flex-end; flex-wrap: wrap; }\n\n/* Header */\n.rui-header { display: flex; flex-direction: column; gap: var(--rui-spacing-xs); }\n.rui-header-title {\n margin: 0;\n font-family: var(--rui-font-family-heading);\n font-size: var(--rui-font-size-title);\n font-weight: var(--rui-font-weight-heading);\n line-height: var(--rui-line-height-heading);\n letter-spacing: var(--rui-letter-spacing-heading);\n text-transform: var(--rui-heading-text-transform);\n}\n.rui-header-subtitle { margin: 0; color: var(--rui-color-text-muted); font-size: 14px; }\n\n/* Text */\n.rui-text { display: inline; }\n.rui-text[data-variant=\"small\"] { font-size: var(--rui-font-size-sm); color: var(--rui-color-text-muted); }\n.rui-text[data-variant=\"small-heavy\"] { font-size: var(--rui-font-size-sm); font-weight: 600; }\n.rui-text[data-variant=\"body\"] { font-size: var(--rui-font-size-base); }\n.rui-text[data-variant=\"body-heavy\"] { font-size: var(--rui-font-size-base); font-weight: 600; }\n.rui-text[data-variant=\"large\"] { font-size: 18px; }\n.rui-text[data-variant=\"large-heavy\"] {\n font-size: var(--rui-font-size-title);\n font-family: var(--rui-font-family-heading);\n font-weight: var(--rui-font-weight-heading);\n line-height: var(--rui-line-height-heading);\n letter-spacing: var(--rui-letter-spacing-heading);\n text-transform: var(--rui-heading-text-transform);\n display: block;\n}\n.rui-text[data-variant=\"heading\"] {\n font-size: 20px;\n font-family: var(--rui-font-family-heading);\n font-weight: var(--rui-font-weight-heading);\n line-height: var(--rui-line-height-heading);\n letter-spacing: var(--rui-letter-spacing-heading);\n text-transform: var(--rui-heading-text-transform);\n display: block;\n}\n.rui-text[data-variant=\"title\"] {\n font-size: calc(var(--rui-font-size-title) + 6px);\n font-family: var(--rui-font-family-heading);\n font-weight: var(--rui-font-weight-heading);\n line-height: var(--rui-line-height-heading);\n letter-spacing: var(--rui-letter-spacing-heading);\n text-transform: var(--rui-heading-text-transform);\n display: block;\n}\n.rui-text[data-color=\"muted\"] { color: var(--rui-color-text-muted); }\n.rui-text[data-color=\"primary\"] { color: var(--rui-color-primary); }\n.rui-text[data-color=\"success\"] { color: var(--rui-color-success); }\n.rui-text[data-color=\"warning\"] { color: var(--rui-color-warning); }\n.rui-text[data-color=\"danger\"] { color: var(--rui-color-danger); }\n\n/* Image */\n.rui-image { margin: 0; display: flex; flex-direction: column; gap: var(--rui-spacing-xs); }\n.rui-image img { max-width: 100%; height: auto; border-radius: var(--rui-radius-md); display: block; }\n.rui-image-caption { color: var(--rui-color-text-muted); font-size: 12px; }\n\n/* Link */\n.rui-link {\n color: var(--rui-color-accent);\n text-decoration: none;\n font-weight: 500;\n word-break: break-word;\n transition: color var(--rui-transition-duration) ease;\n}\n.rui-link:hover { color: var(--rui-color-accent-hover); text-decoration: underline; }\n\n/* Routing — NavLink anchor + Routes outlet. NavLink is a hash-aware anchor\n that reflects the current route via data-active=\"true\". Routes wraps\n the matched page so themes can target it without leaking styles into\n surrounding content. */\n.rui-routes {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n width: 100%;\n}\n.rui-route { display: contents; }\n.rui-nav-link {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: var(--rui-radius-sm);\n font-weight: 500;\n color: var(--rui-color-text);\n text-decoration: none;\n background: transparent;\n border: 1px solid transparent;\n transition: background 150ms ease, border-color 150ms ease, color 150ms ease;\n}\n.rui-nav-link:hover {\n background: var(--rui-color-surface-muted);\n text-decoration: none;\n}\n.rui-nav-link[data-active=\"true\"] {\n background: color-mix(in srgb, var(--rui-color-primary) 14%, transparent);\n color: var(--rui-color-primary);\n border-color: color-mix(in srgb, var(--rui-color-primary) 28%, transparent);\n}\n.rui-nav-link[data-variant=\"primary\"] {\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n}\n.rui-nav-link[data-variant=\"primary\"]:hover { background: var(--rui-color-primary-hover); }\n.rui-nav-link[data-variant=\"primary\"][data-active=\"true\"] {\n background: var(--rui-color-primary-hover);\n border-color: transparent;\n}\n.rui-nav-link[data-variant=\"ghost\"] {\n background: transparent;\n}\n.rui-nav-link[data-variant=\"ghost\"]:hover {\n background: var(--rui-color-surface-muted);\n}\n.rui-nav-link[data-variant=\"pill\"] {\n border-radius: 999px;\n padding: 6px 14px;\n background: var(--rui-color-surface-muted);\n}\n.rui-nav-link[data-variant=\"pill\"][data-active=\"true\"] {\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n border-color: transparent;\n}\n.rui-nav-link[data-routes-enabled=\"false\"] { opacity: 0.6; }\n.rui-nav-link-icon { display: inline-flex; align-items: center; }\n\n/* Badge & Tag */\n.rui-badge-icon {\n margin-right: 4px;\n}\n.rui-badge-list {\n display: flex;\n flex-wrap: wrap;\n gap: var(--rui-spacing-xs);\n}\n\n.rui-badge {\n display: inline-flex;\n align-items: center;\n border-radius: var(--rui-radius-pill);\n padding: 2px 10px;\n font-size: 12px;\n font-weight: 600;\n background: var(--rui-color-surface-muted);\n color: var(--rui-color-text);\n}\n.rui-badge[data-variant=\"primary\"] { background: var(--rui-color-primary); color: var(--rui-color-primary-text); }\n.rui-badge[data-variant=\"success\"] { background: color-mix(in srgb, var(--rui-color-success) 18%, transparent); color: var(--rui-color-success); }\n.rui-badge[data-variant=\"warning\"] { background: color-mix(in srgb, var(--rui-color-warning) 18%, transparent); color: var(--rui-color-warning); }\n.rui-badge[data-variant=\"danger\"] { background: color-mix(in srgb, var(--rui-color-danger) 18%, transparent); color: var(--rui-color-danger); }\n.rui-badge[data-variant=\"info\"] { background: color-mix(in srgb, var(--rui-color-info) 18%, transparent); color: var(--rui-color-info); }\n\n.rui-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n border-radius: var(--rui-radius-pill);\n padding: 2px 10px;\n font-size: 12px;\n font-weight: 500;\n background: var(--rui-color-surface-muted);\n border: 1px solid var(--rui-color-border-subtle);\n}\n.rui-tag[data-size=\"sm\"] { font-size: 11px; padding: 1px 8px; }\n.rui-tag[data-size=\"lg\"] { font-size: 14px; padding: 4px 12px; }\n.rui-tag[data-variant=\"success\"] { background: color-mix(in srgb, var(--rui-color-success) 16%, transparent); color: var(--rui-color-success); border-color: transparent; }\n.rui-tag[data-variant=\"warning\"] { background: color-mix(in srgb, var(--rui-color-warning) 16%, transparent); color: var(--rui-color-warning); border-color: transparent; }\n.rui-tag[data-variant=\"danger\"] { background: color-mix(in srgb, var(--rui-color-danger) 16%, transparent); color: var(--rui-color-danger); border-color: transparent; }\n.rui-tag[data-variant=\"primary\"] { background: color-mix(in srgb, var(--rui-color-primary) 16%, transparent); color: var(--rui-color-primary); border-color: transparent; }\n\n/* Alert */\n.rui-alert {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: var(--rui-spacing-m) var(--rui-spacing-l);\n border-radius: var(--rui-radius-md);\n border: 1px solid var(--rui-color-border);\n}\n.rui-alert-title { font-weight: 600; }\n.rui-alert[data-variant=\"info\"] { background: color-mix(in srgb, var(--rui-color-info) 12%, transparent); border-color: transparent; color: var(--rui-color-info); }\n.rui-alert[data-variant=\"success\"] { background: color-mix(in srgb, var(--rui-color-success) 12%, transparent); border-color: transparent; color: var(--rui-color-success); }\n.rui-alert[data-variant=\"warning\"] { background: color-mix(in srgb, var(--rui-color-warning) 12%, transparent); border-color: transparent; color: var(--rui-color-warning); }\n.rui-alert[data-variant=\"danger\"] { background: color-mix(in srgb, var(--rui-color-danger) 12%, transparent); border-color: transparent; color: var(--rui-color-danger); }\n\n/* Skeleton */\n.rui-skeleton { display: flex; flex-direction: column; gap: 6px; }\n.rui-skeleton-line {\n background: linear-gradient(90deg, var(--rui-color-surface-muted) 0%, color-mix(in srgb, var(--rui-color-surface-muted) 60%, var(--rui-color-bg)) 50%, var(--rui-color-surface-muted) 100%);\n background-size: 200% 100%;\n animation: rui-skeleton-shimmer 1.4s ease infinite;\n border-radius: var(--rui-radius-sm);\n}\n@keyframes rui-skeleton-shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* Markdown */\n.rui-markdown { display: flex; flex-direction: column; gap: var(--rui-spacing-s); word-break: break-word; }\n.rui-markdown p { margin: 0; }\n.rui-markdown ul { margin: 0; padding-left: var(--rui-spacing-l); }\n.rui-markdown code {\n background: var(--rui-color-surface-muted);\n border-radius: 4px;\n padding: 0 4px;\n font-family: var(--rui-font-family-mono);\n font-size: 0.92em;\n}\n\n/* Divider */\n.rui-divider { border: none; height: var(--rui-border-width); background: var(--rui-color-border); margin: var(--rui-spacing-s) 0; }\n.rui-divider-with-label {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n height: auto;\n background: none;\n}\n.rui-divider-line { flex: 1; height: var(--rui-border-width); background: var(--rui-color-border); }\n.rui-divider-label { color: var(--rui-color-text-muted); font-size: 12px; }\n\n/* Separator */\n.rui-separator {\n background: var(--rui-color-border);\n flex-shrink: 0;\n}\n.rui-separator[data-orientation=\"horizontal\"] {\n width: 100%;\n height: var(--rui-border-width);\n margin: var(--rui-spacing-s) 0;\n}\n.rui-separator[data-orientation=\"vertical\"] {\n width: var(--rui-border-width);\n height: auto;\n align-self: stretch;\n margin: 0 var(--rui-spacing-s);\n}\n\n/* Steps */\n.rui-steps {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n counter-reset: rui-steps;\n}\n.rui-steps-item {\n position: relative;\n padding-left: 44px;\n counter-increment: rui-steps;\n}\n.rui-steps-item::before {\n content: counter(rui-steps);\n position: absolute;\n left: 0;\n top: 0;\n width: 28px;\n height: 28px;\n border-radius: 999px;\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n font-size: 13px;\n}\n.rui-steps-title { font-weight: 600; line-height: 28px; }\n.rui-steps-details { color: var(--rui-color-text-muted); font-size: 13px; margin-top: 2px; }\n\n/* TagBlock */\n.rui-tag-block {\n display: flex;\n flex-wrap: wrap;\n gap: var(--rui-spacing-xs);\n}\n\n/* Callout */\n.rui-callout {\n display: flex;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-m) var(--rui-spacing-l);\n border-radius: var(--rui-radius-md);\n border: 1px solid var(--rui-color-border);\n background: var(--rui-color-surface);\n}\n.rui-callout-icon {\n flex-shrink: 0;\n width: 22px;\n height: 22px;\n border-radius: 999px;\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n font-size: 13px;\n background: var(--rui-color-info);\n color: #ffffff;\n}\n.rui-callout-body { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n.rui-callout-title { font-weight: 600; }\n.rui-callout-description { color: var(--rui-color-text-muted); font-size: 13px; }\n.rui-callout[data-variant=\"info\"] { background: color-mix(in srgb, var(--rui-color-info) 8%, var(--rui-color-surface)); border-color: color-mix(in srgb, var(--rui-color-info) 30%, transparent); }\n.rui-callout[data-variant=\"info\"] .rui-callout-icon { background: var(--rui-color-info); }\n.rui-callout[data-variant=\"success\"] { background: color-mix(in srgb, var(--rui-color-success) 8%, var(--rui-color-surface)); border-color: color-mix(in srgb, var(--rui-color-success) 30%, transparent); }\n.rui-callout[data-variant=\"success\"] .rui-callout-icon { background: var(--rui-color-success); }\n.rui-callout[data-variant=\"warning\"] { background: color-mix(in srgb, var(--rui-color-warning) 10%, var(--rui-color-surface)); border-color: color-mix(in srgb, var(--rui-color-warning) 32%, transparent); }\n.rui-callout[data-variant=\"warning\"] .rui-callout-icon { background: var(--rui-color-warning); }\n.rui-callout[data-variant=\"danger\"], .rui-callout[data-variant=\"error\"] {\n background: color-mix(in srgb, var(--rui-color-danger) 8%, var(--rui-color-surface));\n border-color: color-mix(in srgb, var(--rui-color-danger) 32%, transparent);\n}\n.rui-callout[data-variant=\"danger\"] .rui-callout-icon, .rui-callout[data-variant=\"error\"] .rui-callout-icon {\n background: var(--rui-color-danger);\n}\n.rui-callout[data-variant=\"neutral\"] .rui-callout-icon {\n background: var(--rui-color-text-muted);\n}\n\n/* CodeBlock */\n.rui-code-block {\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface-muted);\n overflow: hidden;\n font-size: 13px;\n}\n.rui-code-block-language {\n font-family: var(--rui-font-family-mono);\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--rui-color-text-muted);\n padding: 6px 12px;\n border-bottom: 1px solid var(--rui-color-border-subtle);\n}\n.rui-code-block-pre {\n margin: 0;\n padding: var(--rui-spacing-m);\n font-family: var(--rui-font-family-mono);\n white-space: pre;\n overflow-x: auto;\n color: var(--rui-color-text);\n}\n\n/* CheckBoxGroup */\n.rui-checkbox-group {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n}\n.rui-checkbox-group .rui-checkbox-item {\n display: flex;\n align-items: flex-start;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-s);\n border: 1px solid var(--rui-color-border-subtle);\n border-radius: var(--rui-radius-sm);\n background: var(--rui-color-surface);\n cursor: pointer;\n transition: border-color 120ms ease, background 120ms ease;\n}\n.rui-checkbox-group .rui-checkbox-item:hover {\n border-color: var(--rui-color-border);\n background: var(--rui-color-surface-muted);\n}\n.rui-checkbox-item-text { display: flex; flex-direction: column; gap: 2px; }\n.rui-checkbox-item-label { font-weight: 500; font-size: 13px; }\n.rui-checkbox-item-description { color: var(--rui-color-text-muted); font-size: 12px; }\n\n/* Tabs */\n.rui-tabs { display: flex; flex-direction: column; gap: var(--rui-spacing-m); }\n.rui-tab-list {\n display: flex;\n gap: var(--rui-spacing-xs);\n border-bottom: 1px solid var(--rui-color-border);\n flex-wrap: wrap;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n.rui-tab-trigger {\n border: none;\n background: transparent;\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n font-weight: 500;\n color: var(--rui-color-text-muted);\n border-bottom: 2px solid transparent;\n margin-bottom: -1px;\n transition: color 150ms ease, border-color 150ms ease;\n white-space: nowrap;\n}\n.rui-tab-trigger:hover { color: var(--rui-color-text); }\n.rui-tab-trigger[aria-selected=\"true\"] {\n color: var(--rui-color-primary);\n border-bottom-color: var(--rui-color-primary);\n}\n.rui-tab-panels { display: block; }\n.rui-tab-content { display: flex; flex-direction: column; gap: var(--rui-spacing-m); }\n.rui-tab-content[data-active=\"false\"] { display: none; }\n\n/* Accordion */\n.rui-accordion { display: flex; flex-direction: column; gap: var(--rui-spacing-xs); }\n.rui-accordion-item {\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface);\n overflow: hidden;\n}\n.rui-accordion-trigger {\n cursor: pointer;\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n font-weight: 600;\n list-style: none;\n}\n.rui-accordion-body { padding: 0 var(--rui-spacing-m) var(--rui-spacing-m); }\n\n/* Modal */\n.rui-modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(15, 23, 42, 0.45);\n display: none;\n align-items: center;\n justify-content: center;\n padding: var(--rui-spacing-l);\n z-index: 50;\n}\n.rui-modal-overlay[data-open=\"true\"] { display: flex; }\n.rui-modal {\n background: var(--rui-color-surface);\n border-radius: var(--rui-radius-lg);\n box-shadow: var(--rui-shadow-md);\n max-width: 480px;\n width: 100%;\n padding: var(--rui-spacing-l);\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n max-height: calc(100vh - 2 * var(--rui-spacing-l));\n overflow-y: auto;\n}\n.rui-modal-header { display: flex;justify-content: space-between; }\n.rui-modal-title { margin: 0; font-size: 18px; }\n.rui-modal-close { background: none; border: none; padding: 5px; margin: 0; cursor: pointer; font-size: 18px; color: var(--rui-color-primary); }\n\n/* Forms */\n.rui-form { display: flex; flex-direction: column; gap: var(--rui-spacing-m); }\n.rui-form-control { display: flex; flex-direction: column; gap: 4px; }\n.rui-form-label { font-size: 13px; font-weight: 600; color: var(--rui-color-text); }\n.rui-form-hint { font-size: 12px; color: var(--rui-color-text-muted); margin: 0; }\n.rui-form-actions {\n display: flex;\n gap: var(--rui-spacing-s);\n justify-content: flex-end;\n margin-top: var(--rui-spacing-s);\n flex-wrap: wrap;\n}\n\n.rui-input, .rui-select, .rui-textarea {\n width: 100%;\n border: var(--rui-border-width) solid var(--rui-color-border);\n border-radius: var(--rui-radius-input);\n padding: 8px 12px;\n background: var(--rui-color-surface);\n color: var(--rui-color-text);\n font: inherit;\n transition: border-color var(--rui-transition-duration) ease, box-shadow var(--rui-transition-duration) ease;\n}\n.rui-input:focus, .rui-select:focus, .rui-textarea:focus {\n outline: none;\n border-color: var(--rui-color-focus-ring);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-focus-ring) 22%, transparent);\n}\n.rui-textarea { min-height: 80px; resize: vertical; }\n\n.rui-checkbox, .rui-radio {\n display: inline-flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n cursor: pointer;\n font-size: 14px;\n}\n.rui-radio-group { display: flex; flex-direction: column; gap: var(--rui-spacing-xs); }\n\n.rui-button {\n border: var(--rui-border-width) solid transparent;\n border-radius: var(--rui-radius-button);\n padding: var(--rui-button-padding-y) var(--rui-button-padding-x);\n font-weight: var(--rui-button-font-weight);\n letter-spacing: var(--rui-button-letter-spacing);\n text-transform: var(--rui-button-text-transform);\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n transition: background var(--rui-transition-duration) ease, border-color var(--rui-transition-duration) ease, transform var(--rui-transition-duration) ease, box-shadow var(--rui-transition-duration) ease;\n}\n.rui-button-icon {\n margin-right: 4px;\n}\n.rui-button:hover:not(:disabled) { background: var(--rui-color-primary-hover); }\n.rui-button:disabled { opacity: 0.5; cursor: not-allowed; }\n.rui-button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-focus-ring) 35%, transparent);\n}\n.rui-button[data-variant=\"secondary\"] { background: var(--rui-color-surface); color: var(--rui-color-text); border-color: var(--rui-color-border); }\n.rui-button[data-variant=\"secondary\"]:hover:not(:disabled) { background: var(--rui-color-surface-muted); }\n.rui-button[data-variant=\"ghost\"] { background: transparent; color: var(--rui-color-text); }\n.rui-button[data-variant=\"ghost\"]:hover:not(:disabled) { background: var(--rui-color-surface-muted); }\n.rui-button[data-variant=\"danger\"] { background: var(--rui-color-danger); color: #fff; }\n.rui-button[data-variant=\"danger\"]:hover:not(:disabled) { background: color-mix(in srgb, var(--rui-color-danger) 80%, black); }\n.rui-button[data-size=\"xs\"] { padding: calc(var(--rui-button-padding-y) * 0.45) calc(var(--rui-button-padding-x) * 0.6); font-size: 11px; }\n.rui-button[data-size=\"sm\"],\n.rui-button[data-size=\"small\"] { padding: calc(var(--rui-button-padding-y) * 0.55) calc(var(--rui-button-padding-x) * 0.7); font-size: var(--rui-font-size-sm); }\n.rui-button[data-size=\"lg\"],\n.rui-button[data-size=\"large\"] { padding: calc(var(--rui-button-padding-y) * 1.4) calc(var(--rui-button-padding-x) * 1.3); font-size: var(--rui-font-size-lg); }\n.rui-button[data-size=\"xl\"] { padding: calc(var(--rui-button-padding-y) * 1.6) calc(var(--rui-button-padding-x) * 1.5); font-size: var(--rui-font-size-lg); }\n.rui-button[data-full-width=\"true\"] { width: 100%; }\n.rui-button[data-icon-only=\"true\"] .rui-button-label { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; }\n.rui-button[data-icon-position=\"trailing\"] .rui-button-icon { margin-right: 0; margin-left: 4px; order: 2; }\n.rui-button[data-loading=\"true\"] { pointer-events: none; }\n.rui-button-spinner { margin-right: 4px; }\n.rui-button[data-icon-position=\"trailing\"] .rui-button-spinner { margin-right: 0; margin-left: 4px; }\n\n.rui-buttons {\n display: flex;\n gap: var(--rui-spacing-s);\n flex-wrap: wrap;\n}\n.rui-buttons[data-direction=\"column\"] { flex-direction: column; align-items: stretch; }\n.rui-buttons[data-direction=\"column\"] > .rui-button { width: 100%; }\n\n/* Table — wrapper provides horizontal scroll when columns overflow the\n viewport so tables stay readable on phones and tablets. */\n.rui-table-wrapper {\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface);\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n max-width: 100%;\n}\n.rui-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n min-width: max-content;\n}\n.rui-table-caption {\n text-align: left;\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n font-weight: 600;\n color: var(--rui-color-text-muted);\n}\n.rui-table th, .rui-table td {\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n text-align: left;\n border-bottom: 1px solid var(--rui-color-border);\n white-space: nowrap;\n}\n.rui-table th {\n background: var(--rui-color-bg-subtle);\n font-weight: 600;\n position: sticky;\n top: 0;\n}\n.rui-table td[data-format=\"number\"], .rui-table td[data-format=\"currency\"] {\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n.rui-table tbody tr:last-child td { border-bottom: none; }\n.rui-table-empty {\n text-align: center;\n color: var(--rui-color-text-muted);\n padding: var(--rui-spacing-l) !important;\n white-space: normal;\n}\n\n/* List */\n.rui-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--rui-spacing-s); }\n.rui-list-item {\n display: flex;\n align-items: flex-start;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-s);\n border-radius: var(--rui-radius-sm);\n border: 1px solid var(--rui-color-border-subtle);\n background: var(--rui-color-surface);\n}\n.rui-list-icon { font-size: 20px; }\n.rui-list-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }\n.rui-list-title { font-weight: 600; }\n.rui-list-description { color: var(--rui-color-text-muted); font-size: 13px; }\n\n/* StatCard */\n.rui-stat-card {\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface);\n padding: var(--rui-spacing-l);\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 140px;\n}\n.rui-stat-label-row { display: flex; align-items: center; gap: 6px; }\n.rui-stat-icon {\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 6px;\n color: var(--rui-color-primary);\n font-size: 16px;\n}\n.rui-stat-label { color: var(--rui-color-text-muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; }\n.rui-stat-value {\n font-family: var(--rui-font-family-heading);\n font-size: 24px;\n font-weight: var(--rui-font-weight-heading);\n line-height: var(--rui-line-height-heading);\n letter-spacing: var(--rui-letter-spacing-heading);\n}\n.rui-stat-trend { font-size: 12px; font-weight: 600; }\n.rui-stat-trend[data-trend=\"up\"] { color: var(--rui-color-success); }\n.rui-stat-trend[data-trend=\"down\"] { color: var(--rui-color-danger); }\n\n/* Charts */\n.rui-chart {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-m);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface);\n}\n.rui-chart-title { font-weight: 600; font-size: 14px; }\n.rui-chart-svg { width: 100%; height: auto; max-height: 240px; }\n.rui-chart-svg text { fill: var(--rui-color-text-muted); font-size: 12px; font-family: var(--rui-font-family); }\n.rui-chart-tick { font-size: 10px; }\n.rui-chart-legend {\n display: flex;\n flex-wrap: wrap;\n gap: var(--rui-spacing-s);\n font-size: 12px;\n color: var(--rui-color-text-muted);\n}\n.rui-chart-legend-item { display: inline-flex; align-items: center; gap: 6px; }\n.rui-chart-legend-swatch { width: 10px; height: 10px; border-radius: 999px; }\n\n/* Chat blocks */\n.rui-section-block {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n}\n.rui-section-block-title { margin: 0; font-size: 16px; font-weight: 600; }\n.rui-section-block-description { margin: 0; color: var(--rui-color-text-muted); font-size: 13px; }\n.rui-list-block { margin: 0; padding-left: var(--rui-spacing-l); }\n.rui-list-block li { margin-bottom: 4px; }\n\n.rui-follow-up { display: flex; flex-direction: column; gap: var(--rui-spacing-s); margin-top: var(--rui-spacing-m); }\n.rui-follow-up-title { font-size: 12px; color: var(--rui-color-text-muted); text-transform: uppercase; letter-spacing: 0.04em; }\n.rui-follow-up-list { display: flex; flex-wrap: wrap; gap: var(--rui-spacing-s); }\n.rui-follow-up-button {\n border: 1px solid var(--rui-color-border);\n background: var(--rui-color-surface);\n color: var(--rui-color-text);\n border-radius: 999px;\n padding: 6px 14px;\n font-size: 13px;\n cursor: pointer;\n transition: background 120ms ease;\n font-family: inherit;\n}\n.rui-follow-up-button:hover { background: var(--rui-color-surface-muted); }\n.rui-action-link {\n color: var(--rui-color-primary);\n cursor: pointer;\n text-decoration: underline;\n}\n\n/* ========================================================================\n New primitives (shadcn parity): Avatar, AvatarGroup, Progress, Switch,\n Toggle, ToggleGroup, Tooltip, HoverCard, Kbd, Breadcrumb, Pagination,\n Sheet, AspectRatio, ScrollArea, Grid.\n ======================================================================== */\n\n/* Grid — responsive CSS grid. Auto-fit fallback when no fixed column count. */\n.rui-grid {\n display: grid;\n gap: var(--rui-spacing-m);\n grid-template-columns: repeat(auto-fit, minmax(var(--rui-grid-min-item, 220px), 1fr));\n width: 100%;\n}\n.rui-grid[data-columns=\"1\"] { grid-template-columns: 1fr; }\n.rui-grid[data-columns=\"2\"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n.rui-grid[data-columns=\"3\"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }\n.rui-grid[data-columns=\"4\"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }\n.rui-grid[data-columns=\"5\"] { grid-template-columns: repeat(5, minmax(0, 1fr)); }\n.rui-grid[data-columns=\"6\"] { grid-template-columns: repeat(6, minmax(0, 1fr)); }\n.rui-grid[data-columns=\"7\"] { grid-template-columns: repeat(7, minmax(0, 1fr)); }\n.rui-grid[data-columns=\"8\"] { grid-template-columns: repeat(8, minmax(0, 1fr)); }\n.rui-grid[data-columns=\"9\"] { grid-template-columns: repeat(9, minmax(0, 1fr)); }\n.rui-grid[data-columns=\"10\"] { grid-template-columns: repeat(10, minmax(0, 1fr)); }\n.rui-grid[data-columns=\"11\"] { grid-template-columns: repeat(11, minmax(0, 1fr)); }\n.rui-grid[data-columns=\"12\"] { grid-template-columns: repeat(12, minmax(0, 1fr)); }\n.rui-grid[data-gap=\"xs\"] { gap: var(--rui-spacing-xs); }\n.rui-grid[data-gap=\"s\"] { gap: var(--rui-spacing-s); }\n.rui-grid[data-gap=\"m\"] { gap: var(--rui-spacing-m); }\n.rui-grid[data-gap=\"l\"] { gap: var(--rui-spacing-l); }\n.rui-grid[data-gap=\"xl\"] { gap: var(--rui-spacing-xl); }\n\n/* Responsive prop maps for Grid columns/gap and Stack direction/gap.\n * Components set --rui-grid-cols-{bp} / --rui-stack-dir-{bp} CSS vars for\n * each requested breakpoint; the cascade picks the most specific value\n * via mobile-first min-width media queries. */\n.rui-grid[data-responsive-cols] {\n grid-template-columns: repeat(var(--rui-grid-cols-base, 1), minmax(0, 1fr));\n}\n.rui-grid[data-responsive-gap] {\n gap: var(--rui-grid-gap-base, var(--rui-spacing-m));\n}\n.rui-stack[data-responsive-dir] {\n flex-direction: var(--rui-stack-dir-base, column);\n}\n.rui-stack[data-responsive-gap] {\n gap: var(--rui-stack-gap-base, var(--rui-spacing-m));\n}\n.rui-stack[data-responsive-align] {\n align-items: var(--rui-stack-align-base, stretch);\n}\n.rui-stack[data-responsive-justify] {\n justify-content: var(--rui-stack-justify-base, flex-start);\n}\n.rui-stack[data-responsive-padding] {\n padding: var(--rui-stack-padding-base, 0);\n}\n@media (min-width: 640px) {\n .rui-grid[data-responsive-cols] {\n grid-template-columns: repeat(var(--rui-grid-cols-sm, var(--rui-grid-cols-base, 1)), minmax(0, 1fr));\n }\n .rui-grid[data-responsive-gap] {\n gap: var(--rui-grid-gap-sm, var(--rui-grid-gap-base, var(--rui-spacing-m)));\n }\n .rui-stack[data-responsive-dir] {\n flex-direction: var(--rui-stack-dir-sm, var(--rui-stack-dir-base, column));\n }\n .rui-stack[data-responsive-gap] {\n gap: var(--rui-stack-gap-sm, var(--rui-stack-gap-base, var(--rui-spacing-m)));\n }\n .rui-stack[data-responsive-align] {\n align-items: var(--rui-stack-align-sm, var(--rui-stack-align-base, stretch));\n }\n .rui-stack[data-responsive-justify] {\n justify-content: var(--rui-stack-justify-sm, var(--rui-stack-justify-base, flex-start));\n }\n .rui-stack[data-responsive-padding] {\n padding: var(--rui-stack-padding-sm, var(--rui-stack-padding-base, 0));\n }\n}\n@media (min-width: 768px) {\n .rui-grid[data-responsive-cols] {\n grid-template-columns: repeat(var(--rui-grid-cols-md, var(--rui-grid-cols-sm, var(--rui-grid-cols-base, 1))), minmax(0, 1fr));\n }\n .rui-grid[data-responsive-gap] {\n gap: var(--rui-grid-gap-md, var(--rui-grid-gap-sm, var(--rui-grid-gap-base, var(--rui-spacing-m))));\n }\n .rui-stack[data-responsive-dir] {\n flex-direction: var(--rui-stack-dir-md, var(--rui-stack-dir-sm, var(--rui-stack-dir-base, column)));\n }\n .rui-stack[data-responsive-gap] {\n gap: var(--rui-stack-gap-md, var(--rui-stack-gap-sm, var(--rui-stack-gap-base, var(--rui-spacing-m))));\n }\n .rui-stack[data-responsive-align] {\n align-items: var(--rui-stack-align-md, var(--rui-stack-align-sm, var(--rui-stack-align-base, stretch)));\n }\n .rui-stack[data-responsive-justify] {\n justify-content: var(--rui-stack-justify-md, var(--rui-stack-justify-sm, var(--rui-stack-justify-base, flex-start)));\n }\n .rui-stack[data-responsive-padding] {\n padding: var(--rui-stack-padding-md, var(--rui-stack-padding-sm, var(--rui-stack-padding-base, 0)));\n }\n}\n@media (min-width: 1024px) {\n .rui-grid[data-responsive-cols] {\n grid-template-columns: repeat(var(--rui-grid-cols-lg, var(--rui-grid-cols-md, var(--rui-grid-cols-sm, var(--rui-grid-cols-base, 1)))), minmax(0, 1fr));\n }\n .rui-grid[data-responsive-gap] {\n gap: var(--rui-grid-gap-lg, var(--rui-grid-gap-md, var(--rui-grid-gap-sm, var(--rui-grid-gap-base, var(--rui-spacing-m)))));\n }\n .rui-stack[data-responsive-dir] {\n flex-direction: var(--rui-stack-dir-lg, var(--rui-stack-dir-md, var(--rui-stack-dir-sm, var(--rui-stack-dir-base, column))));\n }\n .rui-stack[data-responsive-gap] {\n gap: var(--rui-stack-gap-lg, var(--rui-stack-gap-md, var(--rui-stack-gap-sm, var(--rui-stack-gap-base, var(--rui-spacing-m)))));\n }\n .rui-stack[data-responsive-align] {\n align-items: var(--rui-stack-align-lg, var(--rui-stack-align-md, var(--rui-stack-align-sm, var(--rui-stack-align-base, stretch))));\n }\n .rui-stack[data-responsive-justify] {\n justify-content: var(--rui-stack-justify-lg, var(--rui-stack-justify-md, var(--rui-stack-justify-sm, var(--rui-stack-justify-base, flex-start))));\n }\n .rui-stack[data-responsive-padding] {\n padding: var(--rui-stack-padding-lg, var(--rui-stack-padding-md, var(--rui-stack-padding-sm, var(--rui-stack-padding-base, 0))));\n }\n}\n@media (min-width: 1280px) {\n .rui-grid[data-responsive-cols] {\n grid-template-columns: repeat(var(--rui-grid-cols-xl, var(--rui-grid-cols-lg, var(--rui-grid-cols-md, var(--rui-grid-cols-sm, var(--rui-grid-cols-base, 1))))), minmax(0, 1fr));\n }\n .rui-grid[data-responsive-gap] {\n gap: var(--rui-grid-gap-xl, var(--rui-grid-gap-lg, var(--rui-grid-gap-md, var(--rui-grid-gap-sm, var(--rui-grid-gap-base, var(--rui-spacing-m))))));\n }\n .rui-stack[data-responsive-dir] {\n flex-direction: var(--rui-stack-dir-xl, var(--rui-stack-dir-lg, var(--rui-stack-dir-md, var(--rui-stack-dir-sm, var(--rui-stack-dir-base, column)))));\n }\n .rui-stack[data-responsive-gap] {\n gap: var(--rui-stack-gap-xl, var(--rui-stack-gap-lg, var(--rui-stack-gap-md, var(--rui-stack-gap-sm, var(--rui-stack-gap-base, var(--rui-spacing-m))))));\n }\n .rui-stack[data-responsive-align] {\n align-items: var(--rui-stack-align-xl, var(--rui-stack-align-lg, var(--rui-stack-align-md, var(--rui-stack-align-sm, var(--rui-stack-align-base, stretch)))));\n }\n .rui-stack[data-responsive-justify] {\n justify-content: var(--rui-stack-justify-xl, var(--rui-stack-justify-lg, var(--rui-stack-justify-md, var(--rui-stack-justify-sm, var(--rui-stack-justify-base, flex-start)))));\n }\n .rui-stack[data-responsive-padding] {\n padding: var(--rui-stack-padding-xl, var(--rui-stack-padding-lg, var(--rui-stack-padding-md, var(--rui-stack-padding-sm, var(--rui-stack-padding-base, 0)))));\n }\n}\n\n/* Grid — 12-column mode + GridItem spans */\n.rui-grid[data-grid-mode=\"12\"] {\n grid-template-columns: repeat(12, minmax(0, 1fr));\n}\n.rui-grid[data-grid-mode=\"12\"][data-min-child-width] {\n grid-template-columns: repeat(12, minmax(var(--rui-grid-min-child, 0), 1fr));\n}\n.rui-grid[data-columns][data-min-child-width]:not([data-grid-mode=\"12\"]) {\n grid-template-columns: repeat(var(--rui-grid-col-count, 1), minmax(var(--rui-grid-min-child, 220px), 1fr));\n}\n.rui-grid[data-columns=\"1\"][data-min-child-width] { --rui-grid-col-count: 1; }\n.rui-grid[data-columns=\"2\"][data-min-child-width] { --rui-grid-col-count: 2; }\n.rui-grid[data-columns=\"3\"][data-min-child-width] { --rui-grid-col-count: 3; }\n.rui-grid[data-columns=\"4\"][data-min-child-width] { --rui-grid-col-count: 4; }\n.rui-grid[data-columns=\"5\"][data-min-child-width] { --rui-grid-col-count: 5; }\n.rui-grid[data-columns=\"6\"][data-min-child-width] { --rui-grid-col-count: 6; }\n.rui-grid[data-columns=\"7\"][data-min-child-width] { --rui-grid-col-count: 7; }\n.rui-grid[data-columns=\"8\"][data-min-child-width] { --rui-grid-col-count: 8; }\n.rui-grid[data-columns=\"9\"][data-min-child-width] { --rui-grid-col-count: 9; }\n.rui-grid[data-columns=\"10\"][data-min-child-width] { --rui-grid-col-count: 10; }\n.rui-grid[data-columns=\"11\"][data-min-child-width] { --rui-grid-col-count: 11; }\n.rui-grid[data-columns=\"12\"][data-min-child-width] { --rui-grid-col-count: 12; }\n.rui-grid[data-row-gap=\"xs\"] { row-gap: var(--rui-spacing-xs); }\n.rui-grid[data-row-gap=\"s\"] { row-gap: var(--rui-spacing-s); }\n.rui-grid[data-row-gap=\"m\"] { row-gap: var(--rui-spacing-m); }\n.rui-grid[data-row-gap=\"l\"] { row-gap: var(--rui-spacing-l); }\n.rui-grid[data-row-gap=\"xl\"] { row-gap: var(--rui-spacing-xl); }\n.rui-grid[data-column-gap=\"xs\"] { column-gap: var(--rui-spacing-xs); }\n.rui-grid[data-column-gap=\"s\"] { column-gap: var(--rui-spacing-s); }\n.rui-grid[data-column-gap=\"m\"] { column-gap: var(--rui-spacing-m); }\n.rui-grid[data-column-gap=\"l\"] { column-gap: var(--rui-spacing-l); }\n.rui-grid[data-column-gap=\"xl\"] { column-gap: var(--rui-spacing-xl); }\n.rui-grid[data-align-items=\"start\"] { align-items: start; }\n.rui-grid[data-align-items=\"center\"] { align-items: center; }\n.rui-grid[data-align-items=\"end\"] { align-items: end; }\n.rui-grid[data-align-items=\"stretch\"] { align-items: stretch; }\n.rui-grid[data-justify-items=\"start\"] { justify-items: start; }\n.rui-grid[data-justify-items=\"center\"] { justify-items: center; }\n.rui-grid[data-justify-items=\"end\"] { justify-items: end; }\n.rui-grid[data-justify-items=\"stretch\"] { justify-items: stretch; }\n.rui-grid[data-dense=\"true\"] { grid-auto-flow: dense; }\n.rui-grid-item {\n grid-column: span var(--rui-grid-item-span, 1);\n min-width: 0;\n}\n.rui-grid-item[data-offset] {\n grid-column-start: calc(var(--rui-grid-item-offset, 0) + 1);\n grid-column-end: span var(--rui-grid-item-span, 1);\n}\n.rui-grid-item[data-responsive-span] {\n grid-column: span var(--rui-grid-item-span-base, var(--rui-grid-item-span, 1));\n}\n@media (min-width: 640px) {\n .rui-grid-item[data-responsive-span] {\n grid-column: span var(--rui-grid-item-span-sm, var(--rui-grid-item-span-base, var(--rui-grid-item-span, 1)));\n }\n}\n@media (min-width: 768px) {\n .rui-grid-item[data-responsive-span] {\n grid-column: span var(--rui-grid-item-span-md, var(--rui-grid-item-span-sm, var(--rui-grid-item-span-base, var(--rui-grid-item-span, 1))));\n }\n}\n@media (min-width: 1024px) {\n .rui-grid-item[data-responsive-span] {\n grid-column: span var(--rui-grid-item-span-lg, var(--rui-grid-item-span-md, var(--rui-grid-item-span-sm, var(--rui-grid-item-span-base, var(--rui-grid-item-span, 1)))));\n }\n}\n@media (min-width: 1280px) {\n .rui-grid-item[data-responsive-span] {\n grid-column: span var(--rui-grid-item-span-xl, var(--rui-grid-item-span-lg, var(--rui-grid-item-span-md, var(--rui-grid-item-span-sm, var(--rui-grid-item-span-base, var(--rui-grid-item-span, 1))))));\n }\n}\n\n/* Box — spacing / surface wrapper */\n.rui-box { box-sizing: border-box; }\n.rui-box[data-padding=\"xs\"] { padding: var(--rui-spacing-xs); }\n.rui-box[data-padding=\"s\"] { padding: var(--rui-spacing-s); }\n.rui-box[data-padding=\"m\"] { padding: var(--rui-spacing-m); }\n.rui-box[data-padding=\"l\"] { padding: var(--rui-spacing-l); }\n.rui-box[data-padding=\"xl\"] { padding: var(--rui-spacing-xl); }\n.rui-box[data-margin=\"xs\"] { margin: var(--rui-spacing-xs); }\n.rui-box[data-margin=\"s\"] { margin: var(--rui-spacing-s); }\n.rui-box[data-margin=\"m\"] { margin: var(--rui-spacing-m); }\n.rui-box[data-margin=\"l\"] { margin: var(--rui-spacing-l); }\n.rui-box[data-margin=\"xl\"] { margin: var(--rui-spacing-xl); }\n.rui-box[data-border=\"subtle\"] { border: 1px solid color-mix(in srgb, var(--rui-color-border) 60%, transparent); border-radius: var(--rui-radius-md); }\n.rui-box[data-border=\"default\"] { border: 1px solid var(--rui-color-border); border-radius: var(--rui-radius-md); }\n.rui-box[data-background=\"surface\"] { background: var(--rui-color-surface); }\n.rui-box[data-background=\"muted\"] { background: var(--rui-color-surface-muted); }\n.rui-box[data-background=\"primary\"] { background: color-mix(in srgb, var(--rui-color-primary) 10%, var(--rui-color-surface)); }\n.rui-box[data-background=\"success\"] { background: color-mix(in srgb, var(--rui-color-success) 10%, var(--rui-color-surface)); }\n.rui-box[data-background=\"warning\"] { background: color-mix(in srgb, var(--rui-color-warning) 12%, var(--rui-color-surface)); }\n.rui-box[data-background=\"danger\"] { background: color-mix(in srgb, var(--rui-color-danger) 10%, var(--rui-color-surface)); }\n.rui-box[data-background=\"info\"] { background: color-mix(in srgb, var(--rui-color-info) 10%, var(--rui-color-surface)); }\n.rui-box[data-responsive-padding] { padding: var(--rui-box-padding-base, 0); }\n.rui-box[data-responsive-margin] { margin: var(--rui-box-margin-base, 0); }\n@media (min-width: 640px) {\n .rui-box[data-responsive-padding] { padding: var(--rui-box-padding-sm, var(--rui-box-padding-base, 0)); }\n .rui-box[data-responsive-margin] { margin: var(--rui-box-margin-sm, var(--rui-box-margin-base, 0)); }\n}\n@media (min-width: 768px) {\n .rui-box[data-responsive-padding] { padding: var(--rui-box-padding-md, var(--rui-box-padding-sm, var(--rui-box-padding-base, 0))); }\n .rui-box[data-responsive-margin] { margin: var(--rui-box-margin-md, var(--rui-box-margin-sm, var(--rui-box-margin-base, 0))); }\n}\n@media (min-width: 1024px) {\n .rui-box[data-responsive-padding] { padding: var(--rui-box-padding-lg, var(--rui-box-padding-md, var(--rui-box-padding-sm, var(--rui-box-padding-base, 0)))); }\n .rui-box[data-responsive-margin] { margin: var(--rui-box-margin-lg, var(--rui-box-margin-md, var(--rui-box-margin-sm, var(--rui-box-margin-base, 0)))); }\n}\n@media (min-width: 1280px) {\n .rui-box[data-responsive-padding] { padding: var(--rui-box-padding-xl, var(--rui-box-padding-lg, var(--rui-box-padding-md, var(--rui-box-padding-sm, var(--rui-box-padding-base, 0))))); }\n .rui-box[data-responsive-margin] { margin: var(--rui-box-margin-xl, var(--rui-box-margin-lg, var(--rui-box-margin-md, var(--rui-box-margin-sm, var(--rui-box-margin-base, 0))))); }\n}\n\n/* AspectRatio */\n.rui-aspect-ratio {\n position: relative;\n width: 100%;\n overflow: hidden;\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface-muted);\n}\n.rui-aspect-ratio > * {\n width: 100%;\n height: 100%;\n display: block;\n object-fit: cover;\n}\n\n/* ScrollArea */\n.rui-scroll-area {\n overflow: auto;\n border-radius: var(--rui-radius-sm);\n scrollbar-width: thin;\n scrollbar-color: var(--rui-color-border) transparent;\n}\n.rui-scroll-area[data-direction=\"vertical\"] { overflow-x: hidden; }\n.rui-scroll-area[data-direction=\"horizontal\"] { overflow-y: hidden; }\n.rui-scroll-area::-webkit-scrollbar { width: 8px; height: 8px; }\n.rui-scroll-area::-webkit-scrollbar-thumb {\n background: var(--rui-color-border);\n border-radius: 999px;\n}\n.rui-scroll-area::-webkit-scrollbar-track { background: transparent; }\n\n/* Avatar */\n.rui-avatar {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 999px;\n background: var(--rui-color-surface-muted);\n color: var(--rui-color-text);\n font-weight: 600;\n overflow: hidden;\n position: relative;\n flex-shrink: 0;\n user-select: none;\n}\n.rui-avatar img { width: 100%; height: 100%; object-fit: cover; }\n.rui-avatar-fallback {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: linear-gradient(135deg,\n color-mix(in srgb, var(--rui-color-primary) 14%, var(--rui-color-surface-muted)),\n color-mix(in srgb, var(--rui-color-primary) 30%, var(--rui-color-surface-muted)));\n color: color-mix(in srgb, var(--rui-color-primary) 90%, var(--rui-color-text));\n}\n.rui-avatar[data-size=\"sm\"] { width: 24px; height: 24px; font-size: 10px; }\n.rui-avatar[data-size=\"md\"] { width: 36px; height: 36px; font-size: 13px; }\n.rui-avatar[data-size=\"lg\"] { width: 52px; height: 52px; font-size: 18px; }\n.rui-avatar[data-size=\"xl\"] { width: 72px; height: 72px; font-size: 22px; }\n.rui-avatar-status {\n position: absolute;\n right: 2px;\n bottom: 2px;\n width: 25%;\n height: 25%;\n min-width: 8px;\n min-height: 8px;\n border-radius: 999px;\n border: 2px solid var(--rui-color-surface);\n background: var(--rui-color-text-muted);\n}\n.rui-avatar-status[data-status=\"online\"] { background: var(--rui-color-success); }\n.rui-avatar-status[data-status=\"busy\"] { background: var(--rui-color-danger); }\n.rui-avatar-status[data-status=\"away\"] { background: var(--rui-color-warning); }\n.rui-avatar-status[data-status=\"offline\"] { background: var(--rui-color-text-muted); }\n\n/* AvatarGroup — overlapping pile with ring border. */\n.rui-avatar-group {\n display: inline-flex;\n align-items: center;\n}\n.rui-avatar-group > .rui-avatar {\n border: 2px solid var(--rui-color-surface);\n margin-left: -8px;\n}\n.rui-avatar-group > .rui-avatar:first-child { margin-left: 0; }\n.rui-avatar-group[data-size=\"sm\"] > .rui-avatar { margin-left: -6px; }\n.rui-avatar-group[data-size=\"lg\"] > .rui-avatar { margin-left: -12px; }\n.rui-avatar-overflow .rui-avatar-fallback {\n background: var(--rui-color-surface-muted);\n color: var(--rui-color-text-muted);\n}\n\n/* Progress */\n.rui-progress {\n display: flex;\n flex-direction: column;\n gap: 6px;\n width: 100%;\n}\n.rui-progress-head {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--rui-color-text-muted);\n}\n.rui-progress-label { font-weight: 500; }\n.rui-progress-value { font-variant-numeric: tabular-nums; }\n.rui-progress-track {\n width: 100%;\n height: 8px;\n border-radius: 999px;\n background: var(--rui-color-surface-muted);\n overflow: hidden;\n}\n.rui-progress-bar {\n height: 100%;\n background: var(--rui-color-primary);\n border-radius: inherit;\n transition: width 220ms ease;\n}\n.rui-progress[data-tone=\"success\"] .rui-progress-bar { background: var(--rui-color-success); }\n.rui-progress[data-tone=\"warning\"] .rui-progress-bar { background: var(--rui-color-warning); }\n.rui-progress[data-tone=\"danger\"] .rui-progress-bar { background: var(--rui-color-danger); }\n.rui-progress[data-tone=\"info\"] .rui-progress-bar { background: var(--rui-color-info); }\n.rui-progress-track[data-indeterminate=\"true\"] .rui-progress-bar {\n width: 40%;\n animation: rui-progress-indeterminate 1.4s ease-in-out infinite;\n}\n@keyframes rui-progress-indeterminate {\n 0% { transform: translateX(-100%); }\n 100% { transform: translateX(250%); }\n}\n\n/* Switch */\n.rui-switch {\n display: inline-flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n cursor: pointer;\n user-select: none;\n}\n.rui-switch[data-disabled=\"true\"] { opacity: 0.5; cursor: not-allowed; }\n.rui-switch-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n}\n.rui-switch-track {\n width: 36px;\n height: 20px;\n border-radius: 999px;\n background: var(--rui-color-surface-muted);\n border: 1px solid var(--rui-color-border);\n position: relative;\n transition: background 160ms ease, border-color 160ms ease;\n flex-shrink: 0;\n}\n.rui-switch-thumb {\n position: absolute;\n top: 1px;\n left: 1px;\n width: 16px;\n height: 16px;\n background: var(--rui-color-surface);\n border-radius: 999px;\n box-shadow: 0 1px 2px rgba(15, 23, 42, 0.18);\n transition: transform 180ms cubic-bezier(0.5, 0.05, 0.5, 1.2);\n}\n.rui-switch-input:checked + .rui-switch-track {\n background: var(--rui-color-primary);\n border-color: var(--rui-color-primary);\n}\n.rui-switch-input:checked + .rui-switch-track .rui-switch-thumb { transform: translateX(16px); }\n.rui-switch-input:focus-visible + .rui-switch-track {\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-primary) 25%, transparent);\n}\n.rui-switch-meta { display: flex; flex-direction: column; gap: 2px; }\n.rui-switch-label { font-weight: 500; font-size: 14px; }\n.rui-switch-description { font-size: 12px; color: var(--rui-color-text-muted); }\n\n/* Toggle (single + group) */\n.rui-toggle {\n border: 1px solid transparent;\n border-radius: var(--rui-radius-sm);\n background: transparent;\n color: var(--rui-color-text);\n padding: 6px 12px;\n font: inherit;\n font-weight: 500;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n transition: background 120ms ease, border-color 120ms ease, color 120ms ease;\n}\n.rui-toggle[data-size=\"sm\"] { padding: 4px 8px; font-size: 12px; }\n.rui-toggle[data-size=\"lg\"] { padding: 9px 16px; font-size: 15px; }\n.rui-toggle[data-variant=\"outline\"] {\n border-color: var(--rui-color-border);\n background: var(--rui-color-surface);\n}\n.rui-toggle[data-variant=\"ghost\"] { background: transparent; }\n.rui-toggle:hover:not([data-state=\"on\"]) { background: var(--rui-color-surface-muted); }\n.rui-toggle[data-state=\"on\"] {\n background: color-mix(in srgb, var(--rui-color-primary) 14%, transparent);\n color: var(--rui-color-primary);\n border-color: color-mix(in srgb, var(--rui-color-primary) 32%, transparent);\n}\n.rui-toggle-icon { display: inline-flex; align-items: center; }\n.rui-toggle-group {\n display: inline-flex;\n align-items: stretch;\n gap: 0;\n border-radius: var(--rui-radius-sm);\n border: 1px solid var(--rui-color-border);\n background: var(--rui-color-surface);\n padding: 2px;\n}\n.rui-toggle-group .rui-toggle {\n border: none;\n border-radius: calc(var(--rui-radius-sm) - 2px);\n background: transparent;\n}\n.rui-toggle-group .rui-toggle[data-state=\"on\"] {\n background: var(--rui-color-surface-muted);\n color: var(--rui-color-primary);\n}\n\n/* Tooltip — CSS-only hover/focus reveal. */\n.rui-tooltip {\n position: relative;\n display: inline-flex;\n align-items: center;\n outline: none;\n}\n.rui-tooltip-trigger { display: contents; }\n.rui-tooltip-content {\n position: absolute;\n padding: 4px 8px;\n border-radius: var(--rui-radius-sm);\n background: var(--rui-color-text);\n color: var(--rui-color-bg);\n font-size: 12px;\n font-weight: 500;\n line-height: 1.3;\n white-space: nowrap;\n max-width: 240px;\n opacity: 0;\n pointer-events: none;\n transition: opacity 140ms ease, transform 140ms ease;\n z-index: 30;\n box-shadow: var(--rui-shadow-sm);\n}\n.rui-tooltip[data-side=\"top\"] .rui-tooltip-content { bottom: calc(100% + 6px); left: 50%; transform: translate(-50%, 4px); }\n.rui-tooltip[data-side=\"bottom\"] .rui-tooltip-content { top: calc(100% + 6px); left: 50%; transform: translate(-50%, -4px); }\n.rui-tooltip[data-side=\"left\"] .rui-tooltip-content { right: calc(100% + 6px); top: 50%; transform: translate(4px, -50%); }\n.rui-tooltip[data-side=\"right\"] .rui-tooltip-content { left: calc(100% + 6px); top: 50%; transform: translate(-4px, -50%); }\n.rui-tooltip:hover .rui-tooltip-content,\n.rui-tooltip:focus-visible .rui-tooltip-content,\n.rui-tooltip:focus-within .rui-tooltip-content {\n opacity: 1;\n transform: translate(0, 0);\n}\n.rui-tooltip[data-side=\"top\"]:hover .rui-tooltip-content { transform: translate(-50%, 0); }\n.rui-tooltip[data-side=\"bottom\"]:hover .rui-tooltip-content { transform: translate(-50%, 0); }\n.rui-tooltip[data-side=\"left\"]:hover .rui-tooltip-content { transform: translate(0, -50%); }\n.rui-tooltip[data-side=\"right\"]:hover .rui-tooltip-content { transform: translate(0, -50%); }\n\n/* HoverCard */\n.rui-hover-card {\n position: relative;\n display: inline-flex;\n outline: none;\n}\n.rui-hover-card-trigger { display: contents; }\n.rui-hover-card-content {\n position: absolute;\n min-width: 240px;\n max-width: 320px;\n padding: var(--rui-spacing-m);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n box-shadow: var(--rui-shadow-md);\n opacity: 0;\n pointer-events: none;\n transition: opacity 160ms ease, transform 160ms ease;\n z-index: 25;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n}\n.rui-hover-card[data-side=\"bottom\"] .rui-hover-card-content { top: calc(100% + 6px); left: 0; transform: translateY(-4px); }\n.rui-hover-card[data-side=\"top\"] .rui-hover-card-content { bottom: calc(100% + 6px); left: 0; transform: translateY(4px); }\n.rui-hover-card[data-side=\"left\"] .rui-hover-card-content { right: calc(100% + 6px); top: 0; transform: translateX(4px); }\n.rui-hover-card[data-side=\"right\"] .rui-hover-card-content { left: calc(100% + 6px); top: 0; transform: translateX(-4px); }\n.rui-hover-card:hover .rui-hover-card-content,\n.rui-hover-card:focus-visible .rui-hover-card-content,\n.rui-hover-card:focus-within .rui-hover-card-content,\n.rui-hover-card[data-open=\"true\"] .rui-hover-card-content {\n opacity: 1;\n pointer-events: auto;\n transform: translate(0, 0);\n}\n\n/* Kbd */\n.rui-kbd-group { display: inline-flex; align-items: center; gap: 4px; }\n.rui-kbd {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--rui-color-surface-muted);\n border: 1px solid var(--rui-color-border);\n border-bottom-width: 2px;\n font-family: var(--rui-font-family-mono, ui-monospace, SFMono-Regular, Menlo, monospace);\n font-size: 11px;\n font-weight: 600;\n color: var(--rui-color-text);\n line-height: 1.2;\n box-shadow: inset 0 -1px 0 rgba(15, 23, 42, 0.04);\n}\n.rui-kbd-group[data-size=\"sm\"] .rui-kbd { padding: 1px 4px; font-size: 10px; }\n.rui-kbd-sep { color: var(--rui-color-text-muted); font-size: 10px; }\n\n/* Breadcrumb */\n.rui-breadcrumb { display: flex; }\n.rui-breadcrumb-list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n list-style: none;\n padding: 0;\n margin: 0;\n font-size: 13px;\n color: var(--rui-color-text-muted);\n}\n.rui-breadcrumb-item { display: inline-flex; align-items: center; }\n.rui-breadcrumb-separator { color: var(--rui-color-border); }\n.rui-breadcrumb-link {\n color: var(--rui-color-text-muted);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n.rui-breadcrumb-link:hover { color: var(--rui-color-primary); text-decoration: underline; }\n.rui-breadcrumb-current {\n color: var(--rui-color-text);\n font-weight: 600;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n/* Pagination */\n.rui-pagination {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px;\n border-radius: var(--rui-radius-sm);\n}\n.rui-pagination-button {\n min-width: 32px;\n height: 32px;\n border-radius: var(--rui-radius-sm);\n border: 1px solid transparent;\n background: transparent;\n color: var(--rui-color-text);\n font: inherit;\n font-weight: 500;\n font-size: 13px;\n padding: 0 8px;\n cursor: pointer;\n transition: background 120ms ease, border-color 120ms ease;\n}\n.rui-pagination-button:hover:not([disabled]):not([data-active=\"true\"]) {\n background: var(--rui-color-surface-muted);\n}\n.rui-pagination-button[data-active=\"true\"] {\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n border-color: var(--rui-color-primary);\n}\n.rui-pagination-button:disabled { opacity: 0.45; cursor: not-allowed; }\n.rui-pagination-ellipsis {\n min-width: 32px;\n height: 32px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--rui-color-text-muted);\n}\n\n/* Sheet — side drawer overlay. */\n.rui-sheet-overlay {\n position: fixed;\n inset: 0;\n background: rgba(15, 23, 42, 0.40);\n display: flex;\n z-index: 50;\n opacity: 0;\n pointer-events: none;\n transition: opacity 200ms ease;\n}\n.rui-sheet-overlay[data-side=\"right\"] { justify-content: flex-end; }\n.rui-sheet-overlay[data-side=\"left\"] { justify-content: flex-start; }\n.rui-sheet-overlay[data-side=\"top\"],\n.rui-sheet-overlay[data-side=\"bottom\"] { flex-direction: column; }\n.rui-sheet-overlay[data-side=\"bottom\"] { justify-content: flex-end; }\n.rui-sheet-overlay[data-open=\"true\"] {\n opacity: 1;\n pointer-events: auto;\n}\n.rui-sheet {\n background: var(--rui-color-surface);\n display: flex;\n flex-direction: column;\n width: min(420px, 100vw);\n height: 100%;\n box-shadow: var(--rui-shadow-md);\n transition: transform 240ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n.rui-sheet[data-side=\"right\"] { transform: translateX(100%); }\n.rui-sheet[data-side=\"left\"] { transform: translateX(-100%); }\n.rui-sheet[data-side=\"top\"] { width: 100%; height: auto; max-height: 80vh; transform: translateY(-100%); }\n.rui-sheet[data-side=\"bottom\"] { width: 100%; height: auto; max-height: 80vh; transform: translateY(100%); }\n.rui-sheet-overlay[data-open=\"true\"] .rui-sheet { transform: translate(0, 0); }\n.rui-sheet-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--rui-spacing-l);\n border-bottom: 1px solid var(--rui-color-border);\n}\n.rui-sheet-title { margin: 0; font-size: 16px; font-weight: 600; }\n.rui-sheet-close {\n background: transparent;\n border: none;\n font-size: 22px;\n line-height: 1;\n color: var(--rui-color-text-muted);\n cursor: pointer;\n padding: 4px 8px;\n border-radius: var(--rui-radius-sm);\n}\n.rui-sheet-close:hover { background: var(--rui-color-surface-muted); }\n.rui-sheet-body {\n padding: var(--rui-spacing-l);\n overflow-y: auto;\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n}\n.rui-sheet-footer {\n display: flex;\n gap: var(--rui-spacing-s);\n justify-content: flex-end;\n padding: var(--rui-spacing-l);\n border-top: 1px solid var(--rui-color-border);\n}\n\n/* ========================================================================\n Pattern composites: Hero, PageHeader, MetricGrid, EmptyState, Timeline,\n FeatureGrid, Testimonial, ProfileCard, Comment, Banner, KanbanBoard.\n ======================================================================== */\n\n.rui-pattern-actions {\n display: flex;\n gap: var(--rui-spacing-s);\n flex-wrap: wrap;\n}\n\n/* Hero */\n.rui-hero {\n position: relative;\n display: grid;\n grid-template-columns: 1fr;\n gap: var(--rui-spacing-l);\n align-items: center;\n padding: clamp(28px, 4vw, 56px);\n border-radius: var(--rui-radius-lg);\n background:\n radial-gradient(60% 60% at 0% 0%, color-mix(in srgb, var(--rui-color-primary) 18%, transparent), transparent 60%),\n radial-gradient(50% 50% at 100% 100%, color-mix(in srgb, var(--rui-color-info) 18%, transparent), transparent 60%),\n var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n overflow: hidden;\n}\n.rui-hero[data-has-image=\"true\"] { grid-template-columns: 1.2fr 1fr; }\n.rui-hero[data-tone=\"success\"] { background:\n radial-gradient(60% 60% at 0% 0%, color-mix(in srgb, var(--rui-color-success) 18%, transparent), transparent 60%),\n var(--rui-color-surface); }\n.rui-hero[data-tone=\"warning\"] { background:\n radial-gradient(60% 60% at 0% 0%, color-mix(in srgb, var(--rui-color-warning) 22%, transparent), transparent 60%),\n var(--rui-color-surface); }\n.rui-hero[data-tone=\"danger\"] { background:\n radial-gradient(60% 60% at 0% 0%, color-mix(in srgb, var(--rui-color-danger) 18%, transparent), transparent 60%),\n var(--rui-color-surface); }\n.rui-hero-body {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n align-items: flex-start;\n min-width: 0;\n}\n.rui-hero-eyebrow {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--rui-color-primary);\n padding: 4px 10px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--rui-color-primary) 14%, transparent);\n}\n.rui-hero-title {\n margin: 0;\n font-family: var(--rui-font-family-heading);\n font-size: clamp(28px, 3.4vw, 44px);\n font-weight: calc(var(--rui-font-weight-heading) + 100);\n line-height: 1.05;\n letter-spacing: var(--rui-letter-spacing-heading);\n text-transform: var(--rui-heading-text-transform);\n}\n.rui-hero-subtitle {\n margin: 0;\n font-size: clamp(15px, 1.4vw, 17px);\n color: var(--rui-color-text-muted);\n max-width: 60ch;\n line-height: 1.5;\n}\n.rui-hero-highlights { display: flex; flex-wrap: wrap; gap: 8px; }\n.rui-hero-highlight {\n font-size: 12px;\n font-weight: 600;\n padding: 4px 10px;\n border-radius: 999px;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n color: var(--rui-color-text);\n}\n.rui-hero-ctas { display: flex; flex-wrap: wrap; gap: var(--rui-spacing-s); margin-top: 4px; }\n.rui-hero-media {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-width: 0;\n}\n.rui-hero-media img {\n max-width: 100%;\n height: auto;\n border-radius: var(--rui-radius-md);\n box-shadow: var(--rui-shadow-md);\n}\n\n/* PageHeader */\n.rui-page-header {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding-bottom: var(--rui-spacing-m);\n border-bottom: var(--rui-border-width) solid var(--rui-color-border);\n}\n.rui-page-header-breadcrumbs {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--rui-color-text-muted);\n}\n.rui-page-header-crumb-sep { color: var(--rui-color-border); }\n.rui-page-header-crumb { color: var(--rui-color-text-muted); }\n.rui-page-header-crumb:last-child { color: var(--rui-color-text); font-weight: 600; }\n.rui-page-header-title-row {\n display: flex;\n align-items: flex-start;\n gap: var(--rui-spacing-m);\n flex-wrap: wrap;\n justify-content: space-between;\n}\n.rui-page-header-title-block { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }\n.rui-page-header-title-line {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n flex-wrap: wrap;\n}\n.rui-page-header-title {\n margin: 0;\n font-family: var(--rui-font-family-heading);\n font-size: clamp(20px, 2vw, calc(var(--rui-font-size-title) + 4px));\n font-weight: var(--rui-font-weight-heading);\n line-height: var(--rui-line-height-heading);\n letter-spacing: var(--rui-letter-spacing-heading);\n text-transform: var(--rui-heading-text-transform);\n}\n.rui-page-header-subtitle {\n margin: 0;\n color: var(--rui-color-text-muted);\n font-size: 14px;\n max-width: 70ch;\n}\n.rui-page-header-actions { gap: var(--rui-spacing-s); flex-wrap: wrap; }\n\n/* MetricGrid */\n.rui-metric-grid {\n display: grid;\n gap: var(--rui-spacing-m);\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n}\n.rui-metric-grid[data-columns=\"1\"] { grid-template-columns: 1fr; }\n.rui-metric-grid[data-columns=\"2\"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n.rui-metric-grid[data-columns=\"3\"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }\n.rui-metric-grid[data-columns=\"4\"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }\n.rui-metric-grid[data-columns=\"5\"] { grid-template-columns: repeat(5, minmax(0, 1fr)); }\n.rui-metric-grid[data-columns=\"6\"] { grid-template-columns: repeat(6, minmax(0, 1fr)); }\n\n/* EmptyState */\n.rui-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--rui-spacing-s);\n text-align: center;\n padding: clamp(24px, 5vw, 56px) var(--rui-spacing-l);\n border-radius: var(--rui-radius-md);\n border: 1px dashed var(--rui-color-border);\n background: var(--rui-color-bg-subtle);\n}\n.rui-empty-state-icon {\n font-size: 40px;\n line-height: 1;\n width: 72px;\n height: 72px;\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n border-radius: 999px;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n}\n.rui-empty-state-title { margin: 0; font-size: 16px; font-weight: 600; }\n.rui-empty-state-description {\n margin: 0;\n color: var(--rui-color-text-muted);\n font-size: 13px;\n max-width: 48ch;\n}\n.rui-empty-state-action { margin-top: var(--rui-spacing-s); }\n\n/* Timeline */\n.rui-timeline {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n position: relative;\n}\n.rui-timeline-item {\n display: grid;\n grid-template-columns: 32px 1fr;\n gap: var(--rui-spacing-s);\n position: relative;\n}\n.rui-timeline-item:not(:last-child)::before {\n content: \"\";\n position: absolute;\n left: 15px;\n top: 32px;\n bottom: -16px;\n width: 2px;\n background: var(--rui-color-border);\n}\n.rui-timeline-marker {\n width: 32px;\n height: 32px;\n border-radius: 999px;\n background: var(--rui-color-surface);\n border: 2px solid var(--rui-color-border);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: var(--rui-color-text);\n flex-shrink: 0;\n}\n.rui-timeline-item[data-tone=\"primary\"] .rui-timeline-marker { border-color: var(--rui-color-primary); color: var(--rui-color-primary); }\n.rui-timeline-item[data-tone=\"success\"] .rui-timeline-marker { border-color: var(--rui-color-success); color: var(--rui-color-success); }\n.rui-timeline-item[data-tone=\"warning\"] .rui-timeline-marker { border-color: var(--rui-color-warning); color: var(--rui-color-warning); }\n.rui-timeline-item[data-tone=\"danger\"] .rui-timeline-marker { border-color: var(--rui-color-danger); color: var(--rui-color-danger); }\n.rui-timeline-item[data-tone=\"info\"] .rui-timeline-marker { border-color: var(--rui-color-info); color: var(--rui-color-info); }\n.rui-timeline-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; padding-top: 6px; }\n.rui-timeline-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }\n.rui-timeline-title { font-weight: 600; }\n.rui-timeline-time {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n font-variant-numeric: tabular-nums;\n}\n.rui-timeline-description { color: var(--rui-color-text-muted); font-size: 13px; }\n\n/* FeatureGrid */\n.rui-feature-grid {\n display: grid;\n gap: var(--rui-spacing-l);\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n}\n.rui-feature-grid[data-columns=\"1\"] { grid-template-columns: 1fr; }\n.rui-feature-grid[data-columns=\"2\"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n.rui-feature-grid[data-columns=\"3\"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }\n.rui-feature-grid[data-columns=\"4\"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }\n.rui-feature-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: var(--rui-spacing-l);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;\n}\n.rui-feature-item:hover {\n transform: translateY(-2px);\n box-shadow: var(--rui-shadow-md);\n border-color: color-mix(in srgb, var(--rui-color-primary) 28%, var(--rui-color-border));\n}\n.rui-feature-icon {\n width: 40px;\n height: 40px;\n border-radius: var(--rui-radius-md);\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n margin-bottom: var(--rui-spacing-s);\n background: color-mix(in srgb, var(--rui-color-primary) 14%, transparent);\n color: var(--rui-color-primary);\n}\n.rui-feature-item[data-tone=\"success\"] .rui-feature-icon { background: color-mix(in srgb, var(--rui-color-success) 14%, transparent); color: var(--rui-color-success); }\n.rui-feature-item[data-tone=\"warning\"] .rui-feature-icon { background: color-mix(in srgb, var(--rui-color-warning) 14%, transparent); color: var(--rui-color-warning); }\n.rui-feature-item[data-tone=\"danger\"] .rui-feature-icon { background: color-mix(in srgb, var(--rui-color-danger) 14%, transparent); color: var(--rui-color-danger); }\n.rui-feature-item[data-tone=\"info\"] .rui-feature-icon { background: color-mix(in srgb, var(--rui-color-info) 14%, transparent); color: var(--rui-color-info); }\n.rui-feature-title { margin: 0; font-size: 16px; font-weight: 600; }\n.rui-feature-description { margin: 0; color: var(--rui-color-text-muted); font-size: 13px; line-height: 1.5; }\n\n/* Testimonial */\n.rui-testimonial {\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n padding: var(--rui-spacing-l);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n position: relative;\n}\n.rui-testimonial::before {\n content: \"“\";\n position: absolute;\n top: -8px;\n left: var(--rui-spacing-m);\n font-size: 64px;\n line-height: 1;\n color: color-mix(in srgb, var(--rui-color-primary) 28%, transparent);\n font-family: Georgia, serif;\n}\n.rui-testimonial-rating { color: var(--rui-color-warning); letter-spacing: 1px; }\n.rui-testimonial-quote {\n margin: 0;\n font-size: 15px;\n line-height: 1.6;\n color: var(--rui-color-text);\n}\n.rui-testimonial-author {\n margin: 0;\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n}\n.rui-testimonial-avatar { width: 36px; height: 36px; border-radius: 999px; object-fit: cover; }\n.rui-testimonial-meta { display: flex; flex-direction: column; }\n.rui-testimonial-name { font-weight: 600; font-size: 14px; }\n.rui-testimonial-role { font-size: 12px; color: var(--rui-color-text-muted); }\n\n/* ProfileCard */\n.rui-profile-card {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n padding: var(--rui-spacing-l);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n}\n.rui-profile-card-header { display: flex; align-items: center; gap: var(--rui-spacing-m); }\n.rui-profile-card-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }\n.rui-profile-card-name { margin: 0; font-size: 16px; font-weight: 600; }\n.rui-profile-card-role { margin: 0; font-size: 13px; color: var(--rui-color-text-muted); }\n.rui-profile-card-bio { margin: 0; color: var(--rui-color-text); font-size: 13px; line-height: 1.5; }\n.rui-profile-card-tags { display: flex; flex-wrap: wrap; gap: 6px; }\n.rui-profile-card-actions { gap: var(--rui-spacing-s); }\n\n/* Comment */\n.rui-comment {\n display: flex;\n align-items: flex-start;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-s) 0;\n}\n.rui-comment-body {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n background: var(--rui-color-bg-subtle);\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n border-radius: var(--rui-radius-md);\n border: 1px solid var(--rui-color-border-subtle);\n}\n.rui-comment-header { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }\n.rui-comment-author { font-weight: 600; font-size: 13px; }\n.rui-comment-time { font-size: 12px; color: var(--rui-color-text-muted); }\n.rui-comment-content { font-size: 14px; color: var(--rui-color-text); line-height: 1.5; }\n.rui-comment-actions { gap: var(--rui-spacing-xs); margin-top: 4px; }\n\n/* Banner */\n.rui-banner {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-m);\n padding: var(--rui-spacing-s) var(--rui-spacing-l);\n border-radius: var(--rui-radius-md);\n background: linear-gradient(135deg,\n color-mix(in srgb, var(--rui-color-primary) 18%, var(--rui-color-surface)),\n color-mix(in srgb, var(--rui-color-info) 12%, var(--rui-color-surface)));\n border: 1px solid color-mix(in srgb, var(--rui-color-primary) 28%, var(--rui-color-border));\n color: var(--rui-color-text);\n}\n.rui-banner[data-tone=\"success\"] {\n background: linear-gradient(135deg, color-mix(in srgb, var(--rui-color-success) 18%, var(--rui-color-surface)), var(--rui-color-surface));\n border-color: color-mix(in srgb, var(--rui-color-success) 28%, var(--rui-color-border));\n}\n.rui-banner[data-tone=\"warning\"] {\n background: linear-gradient(135deg, color-mix(in srgb, var(--rui-color-warning) 18%, var(--rui-color-surface)), var(--rui-color-surface));\n border-color: color-mix(in srgb, var(--rui-color-warning) 32%, var(--rui-color-border));\n}\n.rui-banner[data-tone=\"danger\"] {\n background: linear-gradient(135deg, color-mix(in srgb, var(--rui-color-danger) 18%, var(--rui-color-surface)), var(--rui-color-surface));\n border-color: color-mix(in srgb, var(--rui-color-danger) 32%, var(--rui-color-border));\n}\n.rui-banner-icon {\n font-size: 22px;\n flex-shrink: 0;\n}\n.rui-banner-body { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n.rui-banner-title { font-size: 14px; }\n.rui-banner-message { font-size: 13px; color: var(--rui-color-text-muted); }\n.rui-banner-action { flex-shrink: 0; }\n\n/* Kanban */\n.rui-kanban-board {\n display: flex;\n gap: var(--rui-spacing-m);\n overflow-x: auto;\n padding-bottom: var(--rui-spacing-s);\n -webkit-overflow-scrolling: touch;\n}\n.rui-kanban-column {\n flex: 0 0 280px;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-m);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-bg-subtle);\n border: 1px solid var(--rui-color-border);\n min-width: 0;\n}\n.rui-kanban-column-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; }\n.rui-kanban-column-title { font-weight: 600; font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--rui-color-text); }\n.rui-kanban-column-count {\n font-size: 12px;\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n color: var(--rui-color-text-muted);\n}\n.rui-kanban-column[data-tone=\"primary\"] .rui-kanban-column-title { color: var(--rui-color-primary); }\n.rui-kanban-column[data-tone=\"success\"] .rui-kanban-column-title { color: var(--rui-color-success); }\n.rui-kanban-column[data-tone=\"warning\"] .rui-kanban-column-title { color: var(--rui-color-warning); }\n.rui-kanban-column[data-tone=\"danger\"] .rui-kanban-column-title { color: var(--rui-color-danger); }\n.rui-kanban-column-body { display: flex; flex-direction: column; gap: var(--rui-spacing-s); }\n.rui-kanban-column-empty {\n text-align: center;\n padding: var(--rui-spacing-m);\n font-size: 12px;\n color: var(--rui-color-text-muted);\n border: 1px dashed var(--rui-color-border);\n border-radius: var(--rui-radius-sm);\n}\n.rui-kanban-card {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n border-radius: var(--rui-radius-sm);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n box-shadow: var(--rui-shadow-sm);\n}\n.rui-kanban-card[role=\"button\"] {\n cursor: pointer;\n transition: transform 120ms ease, box-shadow 160ms ease;\n}\n.rui-kanban-card[role=\"button\"]:hover { transform: translateY(-1px); box-shadow: var(--rui-shadow-md); }\n.rui-kanban-card-title { font-weight: 600; font-size: 14px; display: flex; align-items: center; gap: 6px; }\n.rui-kanban-card-icon { font-size: 14px; }\n.rui-kanban-card-description { margin: 0; color: var(--rui-color-text-muted); font-size: 12px; line-height: 1.4; }\n.rui-kanban-card-tags { display: flex; flex-wrap: wrap; gap: 4px; }\n.rui-kanban-card-footer { display: flex; align-items: center; gap: 6px; margin-top: 4px; }\n.rui-kanban-card-assignee { font-size: 12px; color: var(--rui-color-text-muted); }\n.rui-kanban-card[data-tone=\"primary\"] { border-left: 3px solid var(--rui-color-primary); }\n.rui-kanban-card[data-tone=\"success\"] { border-left: 3px solid var(--rui-color-success); }\n.rui-kanban-card[data-tone=\"warning\"] { border-left: 3px solid var(--rui-color-warning); }\n.rui-kanban-card[data-tone=\"danger\"] { border-left: 3px solid var(--rui-color-danger); }\n.rui-kanban-card[data-tone=\"info\"] { border-left: 3px solid var(--rui-color-info); }\n\n/* SectionHeader */\n.rui-section-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--rui-spacing-m);\n flex-wrap: wrap;\n padding-bottom: var(--rui-spacing-s);\n border-bottom: 1px solid var(--rui-color-border-subtle);\n margin-bottom: var(--rui-spacing-s);\n}\n.rui-section-header-left { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1 1 auto; }\n.rui-section-header-eyebrow {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n font-weight: 600;\n color: var(--rui-color-primary);\n}\n.rui-section-header-title-line {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n flex-wrap: wrap;\n}\n.rui-section-header-title {\n margin: 0;\n font-family: var(--rui-font-family-heading);\n font-size: var(--rui-font-size-heading);\n font-weight: var(--rui-font-weight-heading);\n line-height: var(--rui-line-height-heading);\n letter-spacing: var(--rui-letter-spacing-heading);\n text-transform: var(--rui-heading-text-transform);\n}\n.rui-section-header-subtitle {\n margin: 0;\n font-size: 13px;\n color: var(--rui-color-text-muted);\n max-width: 70ch;\n}\n.rui-section-header-actions {\n display: flex;\n gap: var(--rui-spacing-s);\n flex-wrap: wrap;\n flex-shrink: 0;\n}\n\n/* Toolbar */\n.rui-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--rui-spacing-m);\n flex-wrap: wrap;\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-bg-subtle);\n border: 1px solid var(--rui-color-border);\n}\n.rui-toolbar-side {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n flex-wrap: wrap;\n min-width: 0;\n}\n.rui-toolbar-left { flex: 1 1 auto; }\n.rui-toolbar-right { flex-shrink: 0; }\n.rui-toolbar .rui-form-control { gap: 4px; }\n.rui-toolbar .rui-form-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--rui-color-text-muted); }\n.rui-toolbar .rui-input,\n.rui-toolbar .rui-select { min-width: 160px; }\n\n/* Sidebar + AppShell */\n.rui-sidebar {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n padding: var(--rui-spacing-m);\n width: 240px;\n flex-shrink: 0;\n background: var(--rui-color-bg-subtle);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n align-self: stretch;\n}\n.rui-sidebar-header { display: flex; flex-direction: column; gap: 2px; padding-bottom: var(--rui-spacing-s); border-bottom: 1px solid var(--rui-color-border-subtle); }\n.rui-sidebar-brand { font-size: 14px; font-weight: 700; letter-spacing: -0.01em; color: var(--rui-color-text); }\n.rui-sidebar-tagline { font-size: 12px; color: var(--rui-color-text-muted); }\n.rui-sidebar-body { display: flex; flex-direction: column; gap: 2px; flex: 1; min-height: 0; }\n.rui-sidebar-section { display: flex; flex-direction: column; gap: 2px; margin-top: var(--rui-spacing-s); }\n.rui-sidebar-section:first-child { margin-top: 0; }\n.rui-sidebar-section-label {\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n font-weight: 600;\n color: var(--rui-color-text-muted);\n padding: 0 var(--rui-spacing-s);\n margin-bottom: 4px;\n}\n.rui-sidebar-item {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-xs) var(--rui-spacing-s);\n border-radius: var(--rui-radius-sm);\n background: transparent;\n border: 1px solid transparent;\n color: var(--rui-color-text);\n font-size: 13px;\n font-weight: 500;\n text-align: left;\n cursor: pointer;\n transition: background 140ms ease, color 140ms ease, border-color 140ms ease;\n width: 100%;\n}\n.rui-sidebar-item:hover {\n background: var(--rui-color-surface);\n color: var(--rui-color-primary);\n}\n.rui-sidebar-item[data-active=\"true\"] {\n background: color-mix(in srgb, var(--rui-color-primary) 14%, transparent);\n color: var(--rui-color-primary);\n border-color: color-mix(in srgb, var(--rui-color-primary) 32%, transparent);\n}\n.rui-sidebar-item-icon { font-size: 14px; width: 18px; text-align: center; }\n.rui-sidebar-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.rui-sidebar-item-badge {\n font-size: 11px;\n padding: 1px 7px;\n border-radius: 999px;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n color: var(--rui-color-text-muted);\n font-weight: 600;\n}\n.rui-sidebar-item[data-active=\"true\"] .rui-sidebar-item-badge {\n background: color-mix(in srgb, var(--rui-color-primary) 22%, var(--rui-color-surface));\n color: var(--rui-color-primary);\n border-color: color-mix(in srgb, var(--rui-color-primary) 40%, transparent);\n}\n.rui-sidebar-footer {\n padding-top: var(--rui-spacing-s);\n border-top: 1px solid var(--rui-color-border-subtle);\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n}\n\n.rui-app-shell {\n display: flex;\n gap: var(--rui-spacing-l);\n align-items: stretch;\n min-height: 0;\n}\n.rui-app-shell-main {\n flex: 1 1 auto;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-l);\n}\n.rui-app-shell-topbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--rui-spacing-m);\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n}\n.rui-app-shell-content {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-l);\n}\n\n/* SplitView */\n.rui-split-view {\n display: grid;\n grid-template-columns: var(--rui-split-primary, 320px) 1fr;\n gap: var(--rui-spacing-l);\n align-items: stretch;\n min-width: 0;\n}\n.rui-split-view-primary,\n.rui-split-view-detail {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-m);\n min-width: 0;\n}\n\n/* DescriptionList */\n.rui-description-list {\n display: grid;\n gap: var(--rui-spacing-s) var(--rui-spacing-l);\n grid-template-columns: 1fr;\n margin: 0;\n padding: var(--rui-spacing-m) 0;\n}\n.rui-description-list[data-columns=\"2\"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n.rui-description-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: var(--rui-spacing-s) 0;\n border-bottom: 1px dashed var(--rui-color-border-subtle);\n}\n.rui-description-label {\n margin: 0;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n font-weight: 600;\n color: var(--rui-color-text-muted);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.rui-description-icon { font-size: 13px; }\n.rui-description-value {\n margin: 0;\n font-size: 14px;\n color: var(--rui-color-text);\n font-weight: 500;\n word-break: break-word;\n}\n\n/* StatusDot */\n.rui-status-dot {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--rui-color-text-muted);\n}\n.rui-status-dot-marker {\n width: 8px;\n height: 8px;\n border-radius: 999px;\n background: var(--rui-color-text-muted);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--rui-color-text-muted) 18%, transparent);\n}\n.rui-status-dot[data-tone=\"primary\"] .rui-status-dot-marker { background: var(--rui-color-primary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--rui-color-primary) 20%, transparent); }\n.rui-status-dot[data-tone=\"success\"] .rui-status-dot-marker { background: var(--rui-color-success); box-shadow: 0 0 0 2px color-mix(in srgb, var(--rui-color-success) 22%, transparent); }\n.rui-status-dot[data-tone=\"warning\"] .rui-status-dot-marker { background: var(--rui-color-warning); box-shadow: 0 0 0 2px color-mix(in srgb, var(--rui-color-warning) 22%, transparent); }\n.rui-status-dot[data-tone=\"danger\"] .rui-status-dot-marker { background: var(--rui-color-danger); box-shadow: 0 0 0 2px color-mix(in srgb, var(--rui-color-danger) 22%, transparent); }\n.rui-status-dot[data-tone=\"info\"] .rui-status-dot-marker { background: var(--rui-color-info); box-shadow: 0 0 0 2px color-mix(in srgb, var(--rui-color-info) 22%, transparent); }\n.rui-status-dot-label { color: var(--rui-color-text); font-weight: 500; }\n.rui-status-dot[data-pulse=\"true\"] .rui-status-dot-marker {\n animation: rui-status-dot-pulse 1600ms ease-in-out infinite;\n}\n@keyframes rui-status-dot-pulse {\n 0%, 100% { box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 16%, transparent); }\n 50% { box-shadow: 0 0 0 6px color-mix(in srgb, currentColor 8%, transparent); }\n}\n\n/* Pricing */\n.rui-pricing-table {\n display: grid;\n gap: var(--rui-spacing-l);\n grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\n align-items: stretch;\n}\n.rui-pricing-table[data-columns=\"1\"] { grid-template-columns: 1fr; }\n.rui-pricing-table[data-columns=\"2\"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n.rui-pricing-table[data-columns=\"3\"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }\n.rui-pricing-table[data-columns=\"4\"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }\n\n.rui-pricing-card {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-l);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;\n}\n.rui-pricing-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--rui-shadow-md);\n border-color: color-mix(in srgb, var(--rui-color-primary) 22%, var(--rui-color-border));\n}\n.rui-pricing-card[data-featured=\"true\"] {\n border-color: color-mix(in srgb, var(--rui-color-primary) 48%, transparent);\n box-shadow: 0 0 0 1px color-mix(in srgb, var(--rui-color-primary) 24%, transparent), var(--rui-shadow-md);\n background: linear-gradient(180deg, color-mix(in srgb, var(--rui-color-primary) 6%, var(--rui-color-surface)) 0%, var(--rui-color-surface) 70%);\n}\n.rui-pricing-card-badge {\n position: absolute;\n top: -10px;\n right: var(--rui-spacing-l);\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n padding: 4px 10px;\n border-radius: 999px;\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n box-shadow: var(--rui-shadow-sm);\n}\n.rui-pricing-card-plan {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--rui-color-text-muted);\n}\n.rui-pricing-card-description { margin: 0; font-size: 13px; color: var(--rui-color-text-muted); line-height: 1.5; }\n.rui-pricing-card-price-row {\n display: flex;\n align-items: baseline;\n gap: 4px;\n padding: var(--rui-spacing-s) 0;\n}\n.rui-pricing-card-price {\n font-size: clamp(28px, 3.4vw, 36px);\n font-weight: 700;\n letter-spacing: -0.02em;\n color: var(--rui-color-text);\n}\n.rui-pricing-card-period { font-size: 13px; color: var(--rui-color-text-muted); }\n.rui-pricing-card-features {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n flex: 1 1 auto;\n}\n.rui-pricing-card-feature {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 13px;\n color: var(--rui-color-text);\n}\n.rui-pricing-card-check {\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--rui-color-success) 18%, transparent);\n color: var(--rui-color-success);\n font-size: 15px;\n font-weight: 700;\n flex-shrink: 0;\n margin-top: 1px;\n}\n.rui-pricing-card-action {\n margin-top: var(--rui-spacing-s);\n display: flex;\n}\n.rui-pricing-card-action .rui-button { width: 100%; }\n\n/* ========================================================================\n Richer composition primitives\n Cover · MediaCard · Stats · Tile · Notification · PersonChip ·\n Container · Spacer · Quote · Note · Rating · ProgressRing · ChatBubble ·\n SearchBar\n ======================================================================== */\n\n/* Container */\n.rui-container {\n width: 100%;\n}\n.rui-container[data-size=\"sm\"] { max-width: 640px; }\n.rui-container[data-size=\"md\"] { max-width: 820px; }\n.rui-container[data-size=\"lg\"] { max-width: 1040px; }\n.rui-container[data-size=\"xl\"] { max-width: 1280px; }\n.rui-container[data-size=\"full\"] { max-width: 100%; }\n.rui-container[data-padding=\"none\"] { padding-left: 0; padding-right: 0; }\n.rui-container[data-padding=\"s\"] { padding-left: var(--rui-spacing-s); padding-right: var(--rui-spacing-s); }\n.rui-container[data-padding=\"m\"] { padding-left: var(--rui-spacing-m); padding-right: var(--rui-spacing-m); }\n.rui-container[data-padding=\"l\"] { padding-left: var(--rui-spacing-l); padding-right: var(--rui-spacing-l); }\n\n/* Spacer */\n.rui-spacer { display: block; }\n.rui-spacer[data-flex=\"true\"] { flex: 1 1 auto; }\n.rui-spacer[data-size=\"xs\"] { min-width: var(--rui-spacing-xs); min-height: var(--rui-spacing-xs); }\n.rui-spacer[data-size=\"s\"] { min-width: var(--rui-spacing-s); min-height: var(--rui-spacing-s); }\n.rui-spacer[data-size=\"m\"] { min-width: var(--rui-spacing-m); min-height: var(--rui-spacing-m); }\n.rui-spacer[data-size=\"l\"] { min-width: var(--rui-spacing-l); min-height: var(--rui-spacing-l); }\n.rui-spacer[data-size=\"xl\"] { min-width: var(--rui-spacing-xl); min-height: var(--rui-spacing-xl); }\n\n/* Cover */\n.rui-cover {\n position: relative;\n display: flex;\n align-items: flex-end;\n border-radius: var(--rui-radius-lg);\n padding: var(--rui-spacing-xl) var(--rui-spacing-xl);\n color: #ffffff;\n overflow: hidden;\n background-size: cover;\n background-position: center;\n background-color: color-mix(in srgb, var(--rui-color-primary) 20%, #0f172a);\n box-shadow: var(--rui-shadow-md);\n}\n.rui-cover-body {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n max-width: 720px;\n z-index: 1;\n}\n.rui-cover-eyebrow {\n display: inline-flex;\n align-self: flex-start;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.1em;\n padding: 4px 10px;\n border-radius: 999px;\n background: rgba(255, 255, 255, 0.16);\n border: 1px solid rgba(255, 255, 255, 0.24);\n backdrop-filter: blur(6px);\n}\n.rui-cover-title {\n margin: 0;\n font-family: var(--rui-font-family-heading);\n font-size: clamp(24px, 3.5vw, 36px);\n font-weight: var(--rui-font-weight-heading);\n letter-spacing: var(--rui-letter-spacing-heading);\n text-transform: var(--rui-heading-text-transform);\n line-height: 1.15;\n text-shadow: 0 4px 16px rgba(15, 23, 42, 0.35);\n}\n.rui-cover-subtitle {\n margin: 0;\n font-size: 15px;\n color: rgba(255, 255, 255, 0.92);\n max-width: 640px;\n line-height: 1.55;\n}\n.rui-cover-caption {\n margin: 0;\n font-size: 13px;\n color: rgba(255, 255, 255, 0.82);\n}\n.rui-cover-actions { margin-top: var(--rui-spacing-s); }\n.rui-cover[data-tone=\"success\"] { background-color: color-mix(in srgb, var(--rui-color-success) 18%, #022c22); }\n.rui-cover[data-tone=\"warning\"] { background-color: color-mix(in srgb, var(--rui-color-warning) 18%, #1f1404); }\n.rui-cover[data-tone=\"danger\"] { background-color: color-mix(in srgb, var(--rui-color-danger) 18%, #1f0606); }\n.rui-cover[data-tone=\"info\"] { background-color: color-mix(in srgb, var(--rui-color-info) 18%, #03242a); }\n.rui-cover[data-tone=\"default\"] { background-color: #0f172a; }\n\n/* MediaCard */\n.rui-media-card {\n display: flex;\n flex-direction: column;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n overflow: hidden;\n transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;\n}\n.rui-media-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--rui-shadow-md);\n border-color: color-mix(in srgb, var(--rui-color-primary) 20%, var(--rui-color-border));\n}\n.rui-media-card-media {\n position: relative;\n width: 100%;\n background: color-mix(in srgb, var(--rui-color-text) 6%, var(--rui-color-surface-muted));\n overflow: hidden;\n}\n.rui-media-card-media img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n.rui-media-card-media-empty {\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--rui-color-text-muted);\n}\n.rui-media-card-placeholder { font-size: clamp(32px, 4vw, 48px); opacity: 0.55; }\n.rui-media-card-badge {\n position: absolute;\n top: var(--rui-spacing-s);\n left: var(--rui-spacing-s);\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n padding: 4px 10px;\n border-radius: 999px;\n background: rgba(15, 23, 42, 0.72);\n color: #ffffff;\n backdrop-filter: blur(6px);\n}\n.rui-media-card-body {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-m) var(--rui-spacing-l) var(--rui-spacing-l);\n}\n.rui-media-card-title {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n letter-spacing: -0.01em;\n color: var(--rui-color-text);\n}\n.rui-media-card-description {\n margin: 0;\n font-size: 13.5px;\n color: var(--rui-color-text-muted);\n line-height: 1.55;\n}\n.rui-media-card-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n.rui-media-card-meta {\n margin: 0;\n font-size: 12px;\n color: var(--rui-color-text-muted);\n border-top: 1px solid var(--rui-color-border-subtle);\n padding-top: var(--rui-spacing-s);\n}\n.rui-media-card-actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--rui-spacing-s);\n margin-top: var(--rui-spacing-xs);\n}\n.rui-media-card[data-orientation=\"horizontal\"] {\n flex-direction: row;\n align-items: stretch;\n}\n.rui-media-card[data-orientation=\"horizontal\"] .rui-media-card-media {\n width: 38%;\n max-width: 280px;\n min-height: 100%;\n}\n.rui-media-card[data-orientation=\"horizontal\"] .rui-media-card-body { flex: 1 1 auto; }\n\n/* Stats */\n.rui-stats {\n display: flex;\n flex-wrap: wrap;\n gap: var(--rui-spacing-l);\n padding: var(--rui-spacing-m) 0;\n}\n.rui-stats[data-align=\"center\"] { justify-content: center; }\n.rui-stats[data-align=\"end\"] { justify-content: flex-end; }\n.rui-stats-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 96px;\n padding: 0 var(--rui-spacing-m);\n border-left: 1px solid var(--rui-color-border-subtle);\n}\n.rui-stats-item:first-child { padding-left: 0; border-left: none; }\n.rui-stats-label {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n font-weight: 600;\n color: var(--rui-color-text-muted);\n}\n.rui-stats-value {\n font-size: 22px;\n font-weight: 700;\n letter-spacing: -0.01em;\n color: var(--rui-color-text);\n}\n.rui-stats-hint {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n}\n.rui-stats-item[data-tone=\"primary\"] .rui-stats-value { color: var(--rui-color-primary); }\n.rui-stats-item[data-tone=\"success\"] .rui-stats-value { color: var(--rui-color-success); }\n.rui-stats-item[data-tone=\"warning\"] .rui-stats-value { color: var(--rui-color-warning); }\n.rui-stats-item[data-tone=\"danger\"] .rui-stats-value { color: var(--rui-color-danger); }\n.rui-stats-item[data-tone=\"info\"] .rui-stats-value { color: var(--rui-color-info); }\n\n/* Tile */\n.rui-tile {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-m);\n padding: var(--rui-spacing-m) var(--rui-spacing-l);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n text-align: left;\n color: inherit;\n font: inherit;\n cursor: default;\n transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease;\n}\nbutton.rui-tile { cursor: pointer; }\nbutton.rui-tile:hover,\n.rui-tile:hover {\n transform: translateY(-1px);\n box-shadow: var(--rui-shadow-sm);\n border-color: color-mix(in srgb, var(--rui-color-primary) 18%, var(--rui-color-border));\n}\n.rui-tile-icon {\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n width: 38px;\n height: 38px;\n border-radius: var(--rui-radius-md);\n background: color-mix(in srgb, var(--rui-color-primary) 12%, var(--rui-color-surface-muted));\n font-size: 18px;\n flex-shrink: 0;\n}\n.rui-tile-body {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.rui-tile-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--rui-color-text);\n}\n.rui-tile-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--rui-color-text);\n}\n.rui-tile-description {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n line-height: 1.45;\n}\n.rui-tile[data-tone=\"primary\"] .rui-tile-icon { background: color-mix(in srgb, var(--rui-color-primary) 18%, transparent); color: var(--rui-color-primary); }\n.rui-tile[data-tone=\"success\"] .rui-tile-icon { background: color-mix(in srgb, var(--rui-color-success) 18%, transparent); color: var(--rui-color-success); }\n.rui-tile[data-tone=\"warning\"] .rui-tile-icon { background: color-mix(in srgb, var(--rui-color-warning) 18%, transparent); color: var(--rui-color-warning); }\n.rui-tile[data-tone=\"danger\"] .rui-tile-icon { background: color-mix(in srgb, var(--rui-color-danger) 18%, transparent); color: var(--rui-color-danger); }\n.rui-tile[data-tone=\"info\"] .rui-tile-icon { background: color-mix(in srgb, var(--rui-color-info) 18%, transparent); color: var(--rui-color-info); }\n\n/* Notification */\n.rui-notification {\n display: flex;\n gap: var(--rui-spacing-m);\n padding: var(--rui-spacing-m) var(--rui-spacing-l);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n position: relative;\n}\n.rui-notification[data-unread=\"true\"]::before {\n content: \"\";\n position: absolute;\n top: var(--rui-spacing-m);\n left: -1px;\n width: 3px;\n height: 24px;\n background: var(--rui-color-primary);\n border-radius: 999px;\n}\n.rui-notification[data-tone=\"success\"][data-unread=\"true\"]::before { background: var(--rui-color-success); }\n.rui-notification[data-tone=\"warning\"][data-unread=\"true\"]::before { background: var(--rui-color-warning); }\n.rui-notification[data-tone=\"danger\"][data-unread=\"true\"]::before { background: var(--rui-color-danger); }\n.rui-notification[data-tone=\"info\"][data-unread=\"true\"]::before { background: var(--rui-color-info); }\n.rui-notification-icon {\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 34px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--rui-color-primary) 12%, var(--rui-color-surface-muted));\n font-size: 16px;\n flex-shrink: 0;\n}\n.rui-notification[data-tone=\"success\"] .rui-notification-icon { background: color-mix(in srgb, var(--rui-color-success) 18%, transparent); color: var(--rui-color-success); }\n.rui-notification[data-tone=\"warning\"] .rui-notification-icon { background: color-mix(in srgb, var(--rui-color-warning) 18%, transparent); color: var(--rui-color-warning); }\n.rui-notification[data-tone=\"danger\"] .rui-notification-icon { background: color-mix(in srgb, var(--rui-color-danger) 18%, transparent); color: var(--rui-color-danger); }\n.rui-notification[data-tone=\"info\"] .rui-notification-icon { background: color-mix(in srgb, var(--rui-color-info) 18%, transparent); color: var(--rui-color-info); }\n.rui-notification-body {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n flex: 1 1 auto;\n}\n.rui-notification-head {\n display: flex;\n justify-content: space-between;\n gap: var(--rui-spacing-s);\n align-items: baseline;\n}\n.rui-notification-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--rui-color-text);\n}\n.rui-notification-time {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n flex-shrink: 0;\n}\n.rui-notification-message {\n margin: 0;\n font-size: 13px;\n color: var(--rui-color-text-muted);\n line-height: 1.5;\n}\n.rui-notification-actions {\n display: flex;\n gap: var(--rui-spacing-s);\n flex-wrap: wrap;\n margin-top: var(--rui-spacing-xs);\n}\n\n/* PersonChip */\n.rui-person-chip {\n display: inline-flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n padding: 4px 8px;\n background: transparent;\n border: none;\n color: inherit;\n font: inherit;\n text-align: left;\n border-radius: var(--rui-radius-md);\n}\nbutton.rui-person-chip {\n cursor: pointer;\n transition: background 140ms ease;\n}\nbutton.rui-person-chip:hover { background: color-mix(in srgb, var(--rui-color-primary) 8%, transparent); }\n.rui-person-chip-avatar { position: relative; display: inline-flex; }\n.rui-person-chip-status {\n position: absolute;\n bottom: -1px;\n right: -1px;\n width: 9px;\n height: 9px;\n border-radius: 999px;\n border: 2px solid var(--rui-color-surface);\n}\n.rui-person-chip-status[data-status=\"online\"] { background: var(--rui-color-success); }\n.rui-person-chip-status[data-status=\"busy\"] { background: var(--rui-color-danger); }\n.rui-person-chip-status[data-status=\"away\"] { background: var(--rui-color-warning); }\n.rui-person-chip-status[data-status=\"offline\"] { background: var(--rui-color-text-muted); }\n.rui-person-chip-meta {\n display: flex;\n flex-direction: column;\n line-height: 1.25;\n min-width: 0;\n}\n.rui-person-chip-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--rui-color-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.rui-person-chip-role {\n font-size: 11.5px;\n color: var(--rui-color-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.rui-person-chip[data-size=\"sm\"] .rui-person-chip-name { font-size: 12px; }\n.rui-person-chip[data-size=\"sm\"] .rui-person-chip-role { font-size: 11px; }\n.rui-person-chip[data-size=\"lg\"] .rui-person-chip-name { font-size: 14px; }\n.rui-person-chip[data-size=\"lg\"] .rui-person-chip-role { font-size: 12px; }\n\n/* Quote */\n.rui-quote {\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-m) var(--rui-spacing-l);\n border-left: 3px solid color-mix(in srgb, var(--rui-color-primary) 60%, transparent);\n background: color-mix(in srgb, var(--rui-color-primary) 4%, var(--rui-color-surface));\n border-radius: 0 var(--rui-radius-md) var(--rui-radius-md) 0;\n}\n.rui-quote-text {\n margin: 0;\n font-size: 15px;\n line-height: 1.55;\n font-style: italic;\n color: var(--rui-color-text);\n}\n.rui-quote-text::before { content: \"“\"; margin-right: 2px; opacity: 0.55; }\n.rui-quote-text::after { content: \"”\"; margin-left: 2px; opacity: 0.55; }\n.rui-quote-cite {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n font-style: normal;\n}\n.rui-quote[data-tone=\"success\"] { border-left-color: color-mix(in srgb, var(--rui-color-success) 60%, transparent); background: color-mix(in srgb, var(--rui-color-success) 4%, var(--rui-color-surface)); }\n.rui-quote[data-tone=\"warning\"] { border-left-color: color-mix(in srgb, var(--rui-color-warning) 60%, transparent); background: color-mix(in srgb, var(--rui-color-warning) 4%, var(--rui-color-surface)); }\n.rui-quote[data-tone=\"danger\"] { border-left-color: color-mix(in srgb, var(--rui-color-danger) 60%, transparent); background: color-mix(in srgb, var(--rui-color-danger) 4%, var(--rui-color-surface)); }\n.rui-quote[data-tone=\"info\"] { border-left-color: color-mix(in srgb, var(--rui-color-info) 60%, transparent); background: color-mix(in srgb, var(--rui-color-info) 4%, var(--rui-color-surface)); }\n\n/* Note */\n.rui-note {\n display: flex;\n align-items: flex-start;\n gap: var(--rui-spacing-s);\n padding: 8px var(--rui-spacing-m);\n border-radius: var(--rui-radius-md);\n background: color-mix(in srgb, var(--rui-color-info) 10%, var(--rui-color-surface-muted));\n border: 1px solid color-mix(in srgb, var(--rui-color-info) 22%, transparent);\n}\n.rui-note-icon {\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--rui-color-info) 28%, transparent);\n color: var(--rui-color-info);\n font-size: 11px;\n font-weight: 700;\n flex-shrink: 0;\n margin-top: 1px;\n}\n.rui-note-text { margin: 0; font-size: 13px; color: var(--rui-color-text); line-height: 1.5; }\n.rui-note[data-tone=\"success\"] { background: color-mix(in srgb, var(--rui-color-success) 10%, var(--rui-color-surface-muted)); border-color: color-mix(in srgb, var(--rui-color-success) 22%, transparent); }\n.rui-note[data-tone=\"success\"] .rui-note-icon { background: color-mix(in srgb, var(--rui-color-success) 28%, transparent); color: var(--rui-color-success); }\n.rui-note[data-tone=\"warning\"] { background: color-mix(in srgb, var(--rui-color-warning) 10%, var(--rui-color-surface-muted)); border-color: color-mix(in srgb, var(--rui-color-warning) 22%, transparent); }\n.rui-note[data-tone=\"warning\"] .rui-note-icon { background: color-mix(in srgb, var(--rui-color-warning) 28%, transparent); color: var(--rui-color-warning); }\n.rui-note[data-tone=\"danger\"] { background: color-mix(in srgb, var(--rui-color-danger) 10%, var(--rui-color-surface-muted)); border-color: color-mix(in srgb, var(--rui-color-danger) 22%, transparent); }\n.rui-note[data-tone=\"danger\"] .rui-note-icon { background: color-mix(in srgb, var(--rui-color-danger) 28%, transparent); color: var(--rui-color-danger); }\n.rui-note[data-tone=\"tip\"] { background: color-mix(in srgb, var(--rui-color-primary) 8%, var(--rui-color-surface-muted)); border-color: color-mix(in srgb, var(--rui-color-primary) 22%, transparent); }\n.rui-note[data-tone=\"tip\"] .rui-note-icon { background: color-mix(in srgb, var(--rui-color-primary) 28%, transparent); color: var(--rui-color-primary); }\n.rui-note[data-tone=\"default\"] { background: var(--rui-color-surface-muted); border-color: var(--rui-color-border); }\n.rui-note[data-tone=\"default\"] .rui-note-icon { background: color-mix(in srgb, var(--rui-color-text-muted) 22%, transparent); color: var(--rui-color-text-muted); }\n\n/* Rating */\n.rui-rating {\n display: inline-flex !important;\n align-items: center;\n gap: 6px;\n}\n.rui-rating-stars { display: inline-flex !important; gap: 2px; }\n.rui-rating-star {\n background: transparent;\n border: none;\n padding: 0;\n font-size: 16px;\n line-height: 1;\n color: color-mix(in srgb, var(--rui-color-text-muted) 40%, transparent);\n cursor: default;\n /*\n * Intentionally NO font-family declaration. Font Awesome fa-solid /\n * fa-regular classes are co-applied to this element and they set the\n * glyph font at specificity 0,1,0. The theme stylesheet ships through\n * adoptedStyleSheets, which the CSSOM spec cascades AFTER declared\n * stylesheets, so any same-specificity font-family declared here would\n * win the tie-break and prevent the FA ::before glyph from rendering\n * (the \"horizontal stripes instead of stars\" regression).\n */\n}\n.rui-rating-star[data-fill=\"full\"],\n.rui-rating-star[data-fill=\"half\"] { color: var(--rui-color-warning); }\n.rui-rating[data-interactive=\"true\"] .rui-rating-star { cursor: pointer; }\n.rui-rating[data-size=\"sm\"] .rui-rating-star { font-size: 13px; }\n.rui-rating[data-size=\"lg\"] .rui-rating-star { font-size: 20px; }\n.rui-rating-label { font-size: 13px; color: var(--rui-color-text); font-weight: 600; }\n.rui-rating-count { font-size: 12px; color: var(--rui-color-text-muted); }\n\n/* ProgressRing */\n.rui-progress-ring {\n display: inline-flex !important;\n flex-direction: column;\n align-items: center;\n gap: var(--rui-spacing-xs);\n}\n.rui-progress-ring-wrap {\n position: relative;\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n}\n.rui-progress-ring-svg { transform: rotate(-90deg); }\n.rui-progress-ring-track { stroke: var(--rui-color-border); }\n.rui-progress-ring-bar { stroke: var(--rui-color-primary); transition: stroke-dashoffset 360ms ease; }\n.rui-progress-ring[data-tone=\"success\"] .rui-progress-ring-bar { stroke: var(--rui-color-success); }\n.rui-progress-ring[data-tone=\"warning\"] .rui-progress-ring-bar { stroke: var(--rui-color-warning); }\n.rui-progress-ring[data-tone=\"danger\"] .rui-progress-ring-bar { stroke: var(--rui-color-danger); }\n.rui-progress-ring[data-tone=\"info\"] .rui-progress-ring-bar { stroke: var(--rui-color-info); }\n.rui-progress-ring-value {\n position: absolute;\n font-size: 16px;\n font-weight: 700;\n color: var(--rui-color-text);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n.rui-progress-ring[data-size=\"sm\"] .rui-progress-ring-value { font-size: 13px; }\n.rui-progress-ring[data-size=\"lg\"] .rui-progress-ring-value { font-size: 20px; }\n.rui-progress-ring-icon { font-size: 1.6em; }\n.rui-progress-ring[data-tone=\"primary\"] .rui-progress-ring-icon { color: var(--rui-color-primary); }\n.rui-progress-ring[data-tone=\"success\"] .rui-progress-ring-icon { color: var(--rui-color-success); }\n.rui-progress-ring[data-tone=\"warning\"] .rui-progress-ring-icon { color: var(--rui-color-warning); }\n.rui-progress-ring[data-tone=\"danger\"] .rui-progress-ring-icon { color: var(--rui-color-danger); }\n.rui-progress-ring[data-tone=\"info\"] .rui-progress-ring-icon { color: var(--rui-color-info); }\n.rui-progress-ring-caption {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--rui-color-text-muted);\n}\n.rui-progress-ring[data-indeterminate=\"true\"] .rui-progress-ring-bar {\n animation: rui-progress-ring-spin 1400ms linear infinite;\n transform-origin: center;\n}\n@keyframes rui-progress-ring-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n}\n.rui-progress-ring[data-indeterminate=\"true\"] .rui-progress-ring-svg {\n animation: rui-progress-ring-rotate 1600ms linear infinite;\n}\n@keyframes rui-progress-ring-rotate {\n from { transform: rotate(-90deg); }\n to { transform: rotate(270deg); }\n}\n\n/* ChatBubble */\n.rui-chat-bubble {\n display: flex;\n align-items: flex-end;\n gap: var(--rui-spacing-s);\n max-width: 100%;\n}\n.rui-chat-bubble[data-from=\"me\"] { justify-content: flex-end; }\n.rui-chat-bubble-avatar {\n display: inline-flex !important;\n width: 28px;\n height: 28px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--rui-color-primary) 14%, var(--rui-color-surface-muted));\n align-items: center;\n justify-content: center;\n overflow: hidden;\n flex-shrink: 0;\n}\n.rui-chat-bubble-avatar img { width: 100%; height: 100%; object-fit: cover; }\n.rui-chat-bubble-fallback { font-size: 11px; font-weight: 700; color: var(--rui-color-primary); }\n.rui-chat-bubble-bubble {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 8px var(--rui-spacing-m);\n border-radius: 16px;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n max-width: min(72ch, 100%);\n}\n.rui-chat-bubble[data-from=\"me\"] .rui-chat-bubble-bubble {\n background: color-mix(in srgb, var(--rui-color-primary) 14%, var(--rui-color-surface));\n border-color: color-mix(in srgb, var(--rui-color-primary) 24%, var(--rui-color-border));\n color: var(--rui-color-text);\n}\n.rui-chat-bubble[data-from=\"system\"] .rui-chat-bubble-bubble {\n background: var(--rui-color-surface-muted);\n font-style: italic;\n}\n.rui-chat-bubble-head {\n display: flex;\n align-items: baseline;\n gap: 8px;\n}\n.rui-chat-bubble-author {\n font-size: 12px;\n font-weight: 600;\n color: var(--rui-color-text);\n}\n.rui-chat-bubble-time {\n font-size: 11px;\n color: var(--rui-color-text-muted);\n}\n.rui-chat-bubble-body {\n margin: 0;\n font-size: 13.5px;\n color: var(--rui-color-text);\n line-height: 1.5;\n white-space: pre-wrap;\n}\n.rui-chat-bubble-status {\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--rui-color-text-muted);\n align-self: flex-end;\n}\n.rui-chat-bubble-status[data-status=\"error\"] { color: var(--rui-color-danger); }\n.rui-chat-bubble-status[data-status=\"read\"] { color: var(--rui-color-success); }\n\n/* SearchBar */\n.rui-search-bar {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n padding: 6px 10px;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n transition: border-color 140ms ease, box-shadow 140ms ease;\n width: 100%;\n min-width: 0;\n max-width: 100%;\n}\n.rui-search-bar:focus-within {\n border-color: var(--rui-color-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-primary) 18%, transparent);\n}\n.rui-search-bar-icon {\n display: inline-flex;\n font-size: 14px;\n color: var(--rui-color-text-muted);\n flex-shrink: 0;\n}\n.rui-search-bar-input {\n flex: 1 1 auto;\n min-width: 0;\n border: none;\n outline: none;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: 13.5px;\n padding: 4px 0;\n}\n.rui-search-bar-input::placeholder { color: var(--rui-color-text-muted); }\n.rui-search-bar-input::-webkit-search-cancel-button { -webkit-appearance: none; }\n.rui-search-bar-shortcut {\n display: inline-flex;\n align-items: center;\n font-family: var(--rui-font-family);\n font-size: 11px;\n color: var(--rui-color-text-muted);\n padding: 2px 6px;\n border: 1px solid var(--rui-color-border);\n border-radius: 6px;\n background: var(--rui-color-surface-muted);\n flex-shrink: 0;\n}\n.rui-search-bar-submit {\n border: none;\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n font: inherit;\n font-size: 12.5px;\n font-weight: 600;\n padding: 6px 12px;\n border-radius: var(--rui-radius-sm);\n cursor: pointer;\n flex-shrink: 0;\n}\n.rui-search-bar-submit:hover { background: var(--rui-color-primary-hover); }\n\n/* ========================================================================\n Responsive — phones & small tablets.\n The library targets phone-first layouts: stacks, table wrappers, and form\n action rows are most likely to overflow, so we relax their sizing here.\n ======================================================================== */\n\n@media (max-width: 720px) {\n :host {\n font-size: 14px;\n --rui-spacing-l: 16px;\n --rui-spacing-xl: 24px;\n }\n .rui-card { padding: var(--rui-spacing-m); }\n .rui-stat-card { padding: var(--rui-spacing-m); min-width: 120px; }\n .rui-stat-value { font-size: 20px; }\n .rui-text[data-variant=\"title\"] { font-size: 24px; }\n .rui-text[data-variant=\"large-heavy\"] { font-size: 18px; }\n .rui-header-title { font-size: 20px; }\n .rui-callout, .rui-alert { padding: var(--rui-spacing-s) var(--rui-spacing-m); }\n .rui-modal { padding: var(--rui-spacing-m); border-radius: var(--rui-radius-md); }\n .rui-modal-overlay { padding: var(--rui-spacing-s); }\n .rui-form-actions { justify-content: stretch; }\n .rui-form-actions .rui-button,\n .rui-form-actions .rui-buttons { flex: 1 1 auto; }\n .rui-buttons[data-direction=\"row\"] .rui-button { flex: 1 1 auto; }\n /* Row stacks collapse to columns on phones unless the author opted into\n wrapping (a horizontal scroll list, etc.) — wrap=true keeps the row\n layout because the user explicitly asked for it. */\n .rui-stack[data-direction=\"row\"]:not([data-wrap=\"true\"]),\n .rui-stack[data-direction=\"row-reverse\"]:not([data-wrap=\"true\"]) {\n flex-direction: column;\n align-items: stretch;\n }\n /* Hero collapses to a single column so the title stays readable. */\n .rui-hero[data-has-image=\"true\"] { grid-template-columns: 1fr; }\n .rui-hero-media { justify-content: center; }\n .rui-page-header-title-row { flex-direction: column; }\n .rui-page-header-actions { width: 100%; }\n .rui-sheet { width: 100vw; }\n /* App shell + split view collapse to single column on phones. */\n .rui-app-shell { flex-direction: column; }\n .rui-sidebar { width: 100%; }\n .rui-split-view { grid-template-columns: 1fr; }\n .rui-description-list[data-columns=\"2\"] { grid-template-columns: 1fr; }\n .rui-toolbar { padding: var(--rui-spacing-s); }\n .rui-toolbar .rui-input,\n .rui-toolbar .rui-select { min-width: 0; flex: 1 1 100%; }\n .rui-section-header { flex-direction: column; }\n .rui-section-header-actions { width: 100%; }\n /* Richer composition primitives shrink/wrap on phones. */\n .rui-cover { padding: var(--rui-spacing-l); border-radius: var(--rui-radius-md); }\n .rui-media-card[data-orientation=\"horizontal\"] {\n flex-direction: column;\n }\n .rui-media-card[data-orientation=\"horizontal\"] .rui-media-card-media {\n width: 100%;\n max-width: 100%;\n }\n .rui-stats { gap: var(--rui-spacing-m); }\n .rui-stats-item { padding: 0; border-left: none; padding-bottom: var(--rui-spacing-s); }\n .rui-notification { padding: var(--rui-spacing-s) var(--rui-spacing-m); }\n .rui-notification-head { flex-direction: column; align-items: flex-start; gap: 2px; }\n .rui-search-bar-shortcut { display: none; }\n .rui-chat-bubble-bubble { max-width: 86%; }\n}\n\n@media (max-width: 480px) {\n :host { font-size: 13.5px; }\n .rui-card { padding: var(--rui-spacing-m); }\n .rui-card-footer { justify-content: stretch; }\n .rui-card-footer .rui-button { flex: 1 1 auto; }\n .rui-tab-trigger { padding: var(--rui-spacing-xs) var(--rui-spacing-s); font-size: 13px; }\n .rui-stat-card { width: 100%; }\n}\n\n/* ========================================================================\n Theme-specific overrides.\n The host carries data-rui-theme so themes can change layout, fonts,\n shadows, and animations on top of their token map.\n ======================================================================== */\n\n/* Neon — subtle scanlines on cards, glowing focus rings, animated primary\n buttons, sharper typography. */\n:host([data-rui-theme=\"neon\"]) {\n letter-spacing: 0.01em;\n background:\n radial-gradient(60vw 60vw at 110% -10%, rgba(236, 72, 153, 0.18), transparent 60%),\n radial-gradient(50vw 50vw at -10% 110%, rgba(34, 211, 238, 0.18), transparent 60%),\n var(--rui-color-bg);\n}\n:host([data-rui-theme=\"neon\"][transparent]),\n:host([data-rui-theme=\"neon\"][transparent=\"true\"]) {\n background: transparent;\n}\n:host([data-rui-theme=\"neon\"]) .rui-card,\n:host([data-rui-theme=\"neon\"]) .rui-stat-card,\n:host([data-rui-theme=\"neon\"]) .rui-callout,\n:host([data-rui-theme=\"neon\"]) .rui-chart {\n background:\n linear-gradient(180deg, rgba(236, 72, 153, 0.04), rgba(34, 211, 238, 0.04)),\n var(--rui-color-surface);\n border-color: rgba(236, 72, 153, 0.35);\n box-shadow: var(--rui-shadow-sm);\n position: relative;\n}\n:host([data-rui-theme=\"neon\"]) .rui-card::before,\n:host([data-rui-theme=\"neon\"]) .rui-stat-card::before {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n border-radius: inherit;\n background: linear-gradient(transparent 96%, rgba(236, 72, 153, 0.08) 96%);\n background-size: 100% 4px;\n opacity: 0.45;\n}\n:host([data-rui-theme=\"neon\"]) .rui-card-title,\n:host([data-rui-theme=\"neon\"]) .rui-section-title,\n:host([data-rui-theme=\"neon\"]) .rui-header-title,\n:host([data-rui-theme=\"neon\"]) .rui-text[data-variant=\"title\"],\n:host([data-rui-theme=\"neon\"]) .rui-text[data-variant=\"heading\"],\n:host([data-rui-theme=\"neon\"]) .rui-text[data-variant=\"large-heavy\"] {\n text-transform: uppercase;\n letter-spacing: 0.08em;\n}\n:host([data-rui-theme=\"neon\"]) .rui-button {\n background: linear-gradient(135deg, #ec4899, #22d3ee);\n color: #05060f;\n border: 1px solid rgba(236, 72, 153, 0.6);\n box-shadow: 0 0 18px rgba(236, 72, 153, 0.45);\n}\n:host([data-rui-theme=\"neon\"]) .rui-button:hover:not(:disabled) {\n background: linear-gradient(135deg, #f472b6, #67e8f9);\n box-shadow: 0 0 24px rgba(34, 211, 238, 0.55);\n transform: translateY(-1px);\n}\n:host([data-rui-theme=\"neon\"]) .rui-button[data-variant=\"secondary\"] {\n background: rgba(236, 72, 153, 0.08);\n color: var(--rui-color-text);\n border-color: rgba(236, 72, 153, 0.45);\n box-shadow: none;\n}\n:host([data-rui-theme=\"neon\"]) .rui-button[data-variant=\"ghost\"] {\n background: transparent;\n border-color: rgba(34, 211, 238, 0.4);\n color: var(--rui-color-text);\n box-shadow: none;\n}\n:host([data-rui-theme=\"neon\"]) .rui-input:focus,\n:host([data-rui-theme=\"neon\"]) .rui-textarea:focus,\n:host([data-rui-theme=\"neon\"]) .rui-select:focus {\n box-shadow: 0 0 0 1px var(--rui-color-primary), 0 0 18px rgba(236, 72, 153, 0.45);\n}\n:host([data-rui-theme=\"neon\"]) .rui-tab-trigger[aria-selected=\"true\"] {\n text-shadow: 0 0 12px rgba(236, 72, 153, 0.55);\n}\n:host([data-rui-theme=\"neon\"]) .rui-table th {\n background: rgba(236, 72, 153, 0.08);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n font-size: 12px;\n}\n:host([data-rui-theme=\"neon\"]) .rui-follow-up-button {\n background: rgba(34, 211, 238, 0.06);\n border-color: rgba(34, 211, 238, 0.4);\n}\n:host([data-rui-theme=\"neon\"]) .rui-follow-up-button:hover {\n background: rgba(236, 72, 153, 0.15);\n border-color: rgba(236, 72, 153, 0.65);\n box-shadow: 0 0 18px rgba(236, 72, 153, 0.35);\n}\n\n/* Pastel — friendly, super-rounded everything, soft drop-shadows, cards\n subtly lift on hover, gentle pop animation when buttons are pressed. */\n:host([data-rui-theme=\"pastel\"]) {\n background:\n radial-gradient(80vw 60vw at 100% 0%, rgba(167, 139, 250, 0.18), transparent 60%),\n radial-gradient(70vw 50vw at 0% 100%, rgba(94, 234, 212, 0.18), transparent 60%),\n var(--rui-color-bg);\n}\n:host([data-rui-theme=\"pastel\"][transparent]),\n:host([data-rui-theme=\"pastel\"][transparent=\"true\"]) {\n background: transparent;\n}\n:host([data-rui-theme=\"pastel\"]) .rui-card,\n:host([data-rui-theme=\"pastel\"]) .rui-stat-card,\n:host([data-rui-theme=\"pastel\"]) .rui-chart,\n:host([data-rui-theme=\"pastel\"]) .rui-callout {\n border-color: var(--rui-color-border);\n transition: transform 220ms ease, box-shadow 220ms ease;\n}\n:host([data-rui-theme=\"pastel\"]) .rui-card:hover,\n:host([data-rui-theme=\"pastel\"]) .rui-stat-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--rui-shadow-md);\n}\n:host([data-rui-theme=\"pastel\"]) .rui-card-title,\n:host([data-rui-theme=\"pastel\"]) .rui-section-title,\n:host([data-rui-theme=\"pastel\"]) .rui-header-title,\n:host([data-rui-theme=\"pastel\"]) .rui-text[data-variant=\"title\"],\n:host([data-rui-theme=\"pastel\"]) .rui-text[data-variant=\"heading\"] {\n font-weight: 700;\n background: linear-gradient(135deg, #8b5cf6, #f9a8d4);\n -webkit-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n}\n:host([data-rui-theme=\"pastel\"]) .rui-button {\n background: linear-gradient(135deg, #a78bfa, #f9a8d4);\n border-radius: 999px;\n padding: 10px 18px;\n box-shadow: 0 6px 16px rgba(167, 139, 250, 0.28);\n}\n:host([data-rui-theme=\"pastel\"]) .rui-button:hover:not(:disabled) {\n transform: translateY(-1px) scale(1.02);\n box-shadow: 0 10px 22px rgba(167, 139, 250, 0.36);\n}\n:host([data-rui-theme=\"pastel\"]) .rui-button:active:not(:disabled) {\n transform: scale(0.98);\n}\n:host([data-rui-theme=\"pastel\"]) .rui-button[data-variant=\"secondary\"] {\n background: var(--rui-color-surface);\n color: var(--rui-color-text);\n box-shadow: 0 2px 8px rgba(167, 139, 250, 0.12);\n}\n:host([data-rui-theme=\"pastel\"]) .rui-button[data-variant=\"ghost\"] {\n background: transparent;\n border-color: var(--rui-color-border);\n color: var(--rui-color-text);\n box-shadow: none;\n}\n:host([data-rui-theme=\"pastel\"]) .rui-input,\n:host([data-rui-theme=\"pastel\"]) .rui-select,\n:host([data-rui-theme=\"pastel\"]) .rui-textarea {\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface);\n}\n:host([data-rui-theme=\"pastel\"]) .rui-tab-list { border-bottom-color: var(--rui-color-border); }\n:host([data-rui-theme=\"pastel\"]) .rui-tab-trigger[aria-selected=\"true\"] {\n background: rgba(167, 139, 250, 0.10);\n border-radius: var(--rui-radius-md) var(--rui-radius-md) 0 0;\n}\n:host([data-rui-theme=\"pastel\"]) .rui-badge[data-variant=\"primary\"] {\n background: linear-gradient(135deg, #a78bfa, #f9a8d4);\n}\n:host([data-rui-theme=\"pastel\"]) .rui-follow-up-button {\n background: linear-gradient(135deg, rgba(167, 139, 250, 0.10), rgba(249, 168, 212, 0.10));\n border-color: var(--rui-color-border);\n}\n:host([data-rui-theme=\"pastel\"]) .rui-follow-up-button:hover {\n background: linear-gradient(135deg, rgba(167, 139, 250, 0.22), rgba(249, 168, 212, 0.22));\n transform: translateY(-1px);\n}\n\n/* Glass — frosted translucent surfaces over a vivid gradient backdrop.\n Cards use real backdrop-filter blur so they pick up whatever sits behind\n the host. Buttons get a soft inner highlight. */\n:host([data-rui-theme=\"glass\"]) {\n background:\n radial-gradient(60vw 60vw at 0% 0%, rgba(96, 165, 250, 0.45), transparent 60%),\n radial-gradient(50vw 50vw at 100% 0%, rgba(167, 139, 250, 0.40), transparent 55%),\n radial-gradient(70vw 60vw at 50% 110%, rgba(34, 211, 238, 0.30), transparent 60%),\n linear-gradient(135deg, #0b132b 0%, #1a2454 60%, #1f3a8a 100%);\n background-attachment: local;\n}\n:host([data-rui-theme=\"glass\"][transparent]),\n:host([data-rui-theme=\"glass\"][transparent=\"true\"]) {\n background: transparent;\n}\n:host([data-rui-theme=\"glass\"]) .rui-card,\n:host([data-rui-theme=\"glass\"]) .rui-stat-card,\n:host([data-rui-theme=\"glass\"]) .rui-callout,\n:host([data-rui-theme=\"glass\"]) .rui-chart,\n:host([data-rui-theme=\"glass\"]) .rui-table-wrapper,\n:host([data-rui-theme=\"glass\"]) .rui-accordion-item,\n:host([data-rui-theme=\"glass\"]) .rui-list-item,\n:host([data-rui-theme=\"glass\"]) .rui-modal,\n:host([data-rui-theme=\"glass\"]) .rui-code-block {\n background: linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.04));\n backdrop-filter: blur(18px) saturate(140%);\n -webkit-backdrop-filter: blur(18px) saturate(140%);\n border: 1px solid rgba(255, 255, 255, 0.18);\n box-shadow:\n 0 18px 50px rgba(7, 14, 33, 0.45),\n inset 0 1px 0 rgba(255, 255, 255, 0.10);\n}\n:host([data-rui-theme=\"glass\"]) .rui-input,\n:host([data-rui-theme=\"glass\"]) .rui-select,\n:host([data-rui-theme=\"glass\"]) .rui-textarea {\n background: rgba(255, 255, 255, 0.08);\n border-color: rgba(255, 255, 255, 0.18);\n color: var(--rui-color-text);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n}\n:host([data-rui-theme=\"glass\"]) .rui-input::placeholder,\n:host([data-rui-theme=\"glass\"]) .rui-textarea::placeholder { color: rgba(241, 245, 255, 0.45); }\n:host([data-rui-theme=\"glass\"]) .rui-input:focus,\n:host([data-rui-theme=\"glass\"]) .rui-select:focus,\n:host([data-rui-theme=\"glass\"]) .rui-textarea:focus {\n border-color: rgba(96, 165, 250, 0.85);\n box-shadow: 0 0 0 4px rgba(96, 165, 250, 0.20);\n background: rgba(255, 255, 255, 0.14);\n}\n:host([data-rui-theme=\"glass\"]) .rui-button {\n background: linear-gradient(135deg, #60a5fa, #22d3ee);\n color: #0b132b;\n border: 1px solid rgba(255, 255, 255, 0.30);\n box-shadow: 0 10px 24px rgba(34, 211, 238, 0.30), inset 0 1px 0 rgba(255, 255, 255, 0.40);\n}\n:host([data-rui-theme=\"glass\"]) .rui-button:hover:not(:disabled) {\n transform: translateY(-1px);\n box-shadow: 0 14px 30px rgba(34, 211, 238, 0.40), inset 0 1px 0 rgba(255, 255, 255, 0.50);\n}\n:host([data-rui-theme=\"glass\"]) .rui-button[data-variant=\"secondary\"] {\n background: rgba(255, 255, 255, 0.10);\n color: var(--rui-color-text);\n border-color: rgba(255, 255, 255, 0.25);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.10);\n}\n:host([data-rui-theme=\"glass\"]) .rui-button[data-variant=\"ghost\"] {\n background: transparent;\n color: var(--rui-color-text);\n border-color: rgba(255, 255, 255, 0.20);\n box-shadow: none;\n}\n:host([data-rui-theme=\"glass\"]) .rui-card-title,\n:host([data-rui-theme=\"glass\"]) .rui-section-title,\n:host([data-rui-theme=\"glass\"]) .rui-header-title,\n:host([data-rui-theme=\"glass\"]) .rui-text[data-variant=\"title\"],\n:host([data-rui-theme=\"glass\"]) .rui-text[data-variant=\"heading\"] {\n background: linear-gradient(135deg, #ffffff, #c7d2fe 60%, #a5f3fc);\n -webkit-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n letter-spacing: -0.01em;\n}\n:host([data-rui-theme=\"glass\"]) .rui-tab-list { border-bottom-color: rgba(255, 255, 255, 0.15); }\n:host([data-rui-theme=\"glass\"]) .rui-tab-trigger { color: rgba(241, 245, 255, 0.65); }\n:host([data-rui-theme=\"glass\"]) .rui-tab-trigger:hover { color: #ffffff; }\n:host([data-rui-theme=\"glass\"]) .rui-tab-trigger[aria-selected=\"true\"] {\n color: #ffffff;\n border-bottom-color: #60a5fa;\n}\n:host([data-rui-theme=\"glass\"]) .rui-table th {\n background: rgba(255, 255, 255, 0.08);\n border-bottom-color: rgba(255, 255, 255, 0.15);\n}\n:host([data-rui-theme=\"glass\"]) .rui-table td { border-bottom-color: rgba(255, 255, 255, 0.10); }\n:host([data-rui-theme=\"glass\"]) .rui-follow-up-button {\n background: rgba(255, 255, 255, 0.08);\n border-color: rgba(255, 255, 255, 0.20);\n color: var(--rui-color-text);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n}\n:host([data-rui-theme=\"glass\"]) .rui-follow-up-button:hover {\n background: rgba(255, 255, 255, 0.14);\n border-color: rgba(96, 165, 250, 0.55);\n box-shadow: 0 6px 18px rgba(34, 211, 238, 0.20);\n}\n:host([data-rui-theme=\"glass\"]) .rui-skeleton-line {\n background: linear-gradient(90deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.20) 50%, rgba(255, 255, 255, 0.08) 100%);\n background-size: 200% 100%;\n}\n:host([data-rui-theme=\"glass\"]) .rui-divider { background: rgba(255, 255, 255, 0.15); }\n:host([data-rui-theme=\"glass\"]) .rui-separator { background: rgba(255, 255, 255, 0.15); }\n\n/* Brutalist — chunky borders, hard offset shadows, no gradients, all-caps\n display type. The aesthetic only works with sharp geometry, so we override\n the radii on every container in case the user passes a custom token map. */\n:host([data-rui-theme=\"brutalist\"]) {\n background:\n repeating-linear-gradient(\n 45deg,\n transparent 0,\n transparent 22px,\n rgba(10, 10, 10, 0.04) 22px,\n rgba(10, 10, 10, 0.04) 24px\n ),\n var(--rui-color-bg);\n font-weight: 500;\n}\n:host([data-rui-theme=\"brutalist\"][transparent]),\n:host([data-rui-theme=\"brutalist\"][transparent=\"true\"]) {\n background: transparent;\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-card,\n:host([data-rui-theme=\"brutalist\"]) .rui-stat-card,\n:host([data-rui-theme=\"brutalist\"]) .rui-chart,\n:host([data-rui-theme=\"brutalist\"]) .rui-callout,\n:host([data-rui-theme=\"brutalist\"]) .rui-table-wrapper,\n:host([data-rui-theme=\"brutalist\"]) .rui-accordion-item,\n:host([data-rui-theme=\"brutalist\"]) .rui-list-item,\n:host([data-rui-theme=\"brutalist\"]) .rui-modal,\n:host([data-rui-theme=\"brutalist\"]) .rui-code-block {\n border: 2px solid #0a0a0a;\n border-radius: 0;\n box-shadow: 6px 6px 0 0 #0a0a0a;\n background: var(--rui-color-surface);\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-card[data-variant=\"elevated\"] { box-shadow: 8px 8px 0 0 #0a0a0a; }\n:host([data-rui-theme=\"brutalist\"]) .rui-card[data-variant=\"outlined\"] { box-shadow: 3px 3px 0 0 #0a0a0a; }\n\n:host([data-rui-theme=\"brutalist\"]) .rui-card-title,\n:host([data-rui-theme=\"brutalist\"]) .rui-section-title,\n:host([data-rui-theme=\"brutalist\"]) .rui-header-title,\n:host([data-rui-theme=\"brutalist\"]) .rui-text[data-variant=\"title\"],\n:host([data-rui-theme=\"brutalist\"]) .rui-text[data-variant=\"heading\"],\n:host([data-rui-theme=\"brutalist\"]) .rui-text[data-variant=\"large-heavy\"] {\n text-transform: uppercase;\n letter-spacing: -0.01em;\n font-weight: 800;\n}\n\n:host([data-rui-theme=\"brutalist\"]) .rui-button {\n border: 2px solid #0a0a0a;\n border-radius: 0;\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n font-weight: 800;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n box-shadow: 4px 4px 0 0 #0a0a0a;\n transition: transform 80ms ease, box-shadow 80ms ease;\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-button:hover:not(:disabled) {\n transform: translate(-1px, -1px);\n box-shadow: 5px 5px 0 0 #0a0a0a;\n background: var(--rui-color-primary);\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-button:active:not(:disabled) {\n transform: translate(2px, 2px);\n box-shadow: 1px 1px 0 0 #0a0a0a;\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-button[data-variant=\"secondary\"] {\n background: #ffffff;\n color: #0a0a0a;\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-button[data-variant=\"ghost\"] {\n background: var(--rui-color-bg);\n color: #0a0a0a;\n box-shadow: 3px 3px 0 0 #0a0a0a;\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-button[data-variant=\"danger\"] {\n background: var(--rui-color-danger);\n color: #ffffff;\n}\n\n:host([data-rui-theme=\"brutalist\"]) .rui-input,\n:host([data-rui-theme=\"brutalist\"]) .rui-select,\n:host([data-rui-theme=\"brutalist\"]) .rui-textarea {\n border: 2px solid #0a0a0a;\n border-radius: 0;\n background: #ffffff;\n font-weight: 500;\n box-shadow: 3px 3px 0 0 #0a0a0a;\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-input:focus,\n:host([data-rui-theme=\"brutalist\"]) .rui-select:focus,\n:host([data-rui-theme=\"brutalist\"]) .rui-textarea:focus {\n border-color: var(--rui-color-primary);\n box-shadow: 3px 3px 0 0 var(--rui-color-primary);\n outline: none;\n}\n\n:host([data-rui-theme=\"brutalist\"]) .rui-tag,\n:host([data-rui-theme=\"brutalist\"]) .rui-badge {\n border: 2px solid #0a0a0a;\n border-radius: 0;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n background: var(--rui-color-warning);\n color: #0a0a0a;\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-badge[data-variant=\"primary\"] {\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-badge[data-variant=\"success\"] { background: var(--rui-color-success); color: #ffffff; }\n:host([data-rui-theme=\"brutalist\"]) .rui-badge[data-variant=\"warning\"] { background: var(--rui-color-warning); color: #0a0a0a; }\n:host([data-rui-theme=\"brutalist\"]) .rui-badge[data-variant=\"danger\"] { background: var(--rui-color-danger); color: #ffffff; }\n\n:host([data-rui-theme=\"brutalist\"]) .rui-tab-list { border-bottom: 2px solid #0a0a0a; }\n:host([data-rui-theme=\"brutalist\"]) .rui-tab-trigger {\n border: 2px solid transparent;\n border-bottom: none;\n margin-bottom: -2px;\n text-transform: uppercase;\n font-weight: 700;\n letter-spacing: 0.04em;\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-tab-trigger[aria-selected=\"true\"] {\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n border-color: #0a0a0a;\n border-bottom-color: var(--rui-color-primary);\n}\n\n:host([data-rui-theme=\"brutalist\"]) .rui-table th {\n background: #0a0a0a;\n color: #fef9c3;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n font-weight: 800;\n border-bottom: 2px solid #0a0a0a;\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-table td { border-bottom: 1px solid #0a0a0a; }\n:host([data-rui-theme=\"brutalist\"]) .rui-table-caption {\n background: var(--rui-color-warning);\n color: #0a0a0a;\n font-weight: 800;\n text-transform: uppercase;\n border-bottom: 2px solid #0a0a0a;\n}\n\n:host([data-rui-theme=\"brutalist\"]) .rui-follow-up-button {\n border: 2px solid #0a0a0a;\n border-radius: 0;\n background: var(--rui-color-warning);\n color: #0a0a0a;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n box-shadow: 3px 3px 0 0 #0a0a0a;\n}\n:host([data-rui-theme=\"brutalist\"]) .rui-follow-up-button:hover {\n transform: translate(-1px, -1px);\n box-shadow: 4px 4px 0 0 #0a0a0a;\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text);\n}\n\n:host([data-rui-theme=\"brutalist\"]) .rui-divider,\n:host([data-rui-theme=\"brutalist\"]) .rui-separator { background: #0a0a0a; height: 2px; }\n:host([data-rui-theme=\"brutalist\"]) .rui-separator[data-orientation=\"vertical\"] { width: 2px; height: auto; }\n\n:host([data-rui-theme=\"brutalist\"]) .rui-callout[data-variant=\"info\"] { background: #bfdbfe; color: #0a0a0a; }\n:host([data-rui-theme=\"brutalist\"]) .rui-callout[data-variant=\"success\"] { background: #bbf7d0; color: #0a0a0a; }\n:host([data-rui-theme=\"brutalist\"]) .rui-callout[data-variant=\"warning\"] { background: var(--rui-color-warning); color: #0a0a0a; }\n:host([data-rui-theme=\"brutalist\"]) .rui-callout[data-variant=\"danger\"],\n:host([data-rui-theme=\"brutalist\"]) .rui-callout[data-variant=\"error\"] { background: #fecaca; color: #0a0a0a; }\n:host([data-rui-theme=\"brutalist\"]) .rui-callout-icon {\n border: 2px solid #0a0a0a;\n border-radius: 0;\n width: 26px;\n height: 26px;\n}\n\n:host([data-rui-theme=\"brutalist\"]) .rui-stat-value { font-weight: 900; }\n:host([data-rui-theme=\"brutalist\"]) .rui-stat-label { font-weight: 800; color: #0a0a0a; }\n\n:host([data-rui-theme=\"brutalist\"]) .rui-steps-item::before {\n border-radius: 0;\n border: 2px solid #0a0a0a;\n background: var(--rui-color-warning);\n color: #0a0a0a;\n font-weight: 900;\n}\n\n:host([data-rui-theme=\"brutalist\"]) .rui-link {\n text-decoration: underline;\n text-decoration-thickness: 2px;\n text-underline-offset: 3px;\n font-weight: 700;\n}\n\n/* Skyline — enterprise cloud-console look. Calm navy + cyan, crisp 1px\n borders, small radii, accent strip on primary cards, animated underline\n on tabs. Designed to look at home in an admin dashboard. */\n:host([data-rui-theme=\"skyline\"]) {\n background:\n linear-gradient(180deg, #eff2f7 0%, #e6ecf3 100%);\n font-feature-settings: \"ss01\", \"cv11\";\n}\n:host([data-rui-theme=\"skyline\"][transparent]),\n:host([data-rui-theme=\"skyline\"][transparent=\"true\"]) {\n background: transparent;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-card,\n:host([data-rui-theme=\"skyline\"]) .rui-stat-card,\n:host([data-rui-theme=\"skyline\"]) .rui-callout,\n:host([data-rui-theme=\"skyline\"]) .rui-chart,\n:host([data-rui-theme=\"skyline\"]) .rui-table-wrapper,\n:host([data-rui-theme=\"skyline\"]) .rui-accordion-item,\n:host([data-rui-theme=\"skyline\"]) .rui-list-item,\n:host([data-rui-theme=\"skyline\"]) .rui-modal,\n:host([data-rui-theme=\"skyline\"]) .rui-code-block {\n border: 1px solid var(--rui-color-border);\n background: var(--rui-color-surface);\n box-shadow: var(--rui-shadow-sm);\n transition: border-color 160ms ease, box-shadow 200ms ease, transform 160ms ease;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-card:hover {\n border-color: color-mix(in srgb, var(--rui-color-primary) 28%, var(--rui-color-border));\n box-shadow: var(--rui-shadow-md);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-card[data-variant=\"elevated\"] {\n position: relative;\n overflow: hidden;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-card[data-variant=\"elevated\"]::before {\n content: \"\";\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(180deg, var(--rui-color-primary), var(--rui-color-info));\n}\n:host([data-rui-theme=\"skyline\"]) .rui-card-title,\n:host([data-rui-theme=\"skyline\"]) .rui-section-title,\n:host([data-rui-theme=\"skyline\"]) .rui-header-title,\n:host([data-rui-theme=\"skyline\"]) .rui-text[data-variant=\"title\"],\n:host([data-rui-theme=\"skyline\"]) .rui-text[data-variant=\"heading\"],\n:host([data-rui-theme=\"skyline\"]) .rui-text[data-variant=\"large-heavy\"] {\n color: var(--rui-color-primary);\n letter-spacing: -0.01em;\n font-weight: 600;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-button {\n border-radius: var(--rui-radius-sm);\n background: var(--rui-color-primary);\n font-weight: 500;\n letter-spacing: 0.01em;\n box-shadow: 0 1px 0 rgba(13, 27, 58, 0.06);\n transition: background 140ms ease, transform 80ms ease, box-shadow 160ms ease;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-button:hover:not(:disabled) {\n background: var(--rui-color-primary-hover);\n box-shadow: 0 4px 10px rgba(0, 53, 128, 0.18);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-button:active:not(:disabled) {\n transform: translateY(1px);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-button[data-variant=\"secondary\"] {\n background: var(--rui-color-surface);\n color: var(--rui-color-primary);\n border: 1px solid var(--rui-color-primary);\n box-shadow: none;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-button[data-variant=\"secondary\"]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--rui-color-primary) 6%, var(--rui-color-surface));\n}\n:host([data-rui-theme=\"skyline\"]) .rui-button[data-variant=\"ghost\"] {\n background: transparent;\n color: var(--rui-color-primary);\n border-color: transparent;\n box-shadow: none;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-button[data-variant=\"ghost\"]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--rui-color-primary) 8%, transparent);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-input,\n:host([data-rui-theme=\"skyline\"]) .rui-select,\n:host([data-rui-theme=\"skyline\"]) .rui-textarea {\n background: var(--rui-color-surface);\n border-color: var(--rui-color-border);\n border-radius: var(--rui-radius-sm);\n transition: border-color 140ms ease, box-shadow 160ms ease;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-input:focus,\n:host([data-rui-theme=\"skyline\"]) .rui-select:focus,\n:host([data-rui-theme=\"skyline\"]) .rui-textarea:focus {\n border-color: var(--rui-color-info);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-info) 22%, transparent);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-tab-list {\n border-bottom-color: var(--rui-color-border);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-tab-trigger {\n font-weight: 500;\n color: var(--rui-color-text-muted);\n border-bottom-width: 2px;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-tab-trigger:hover {\n color: var(--rui-color-primary);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-tab-trigger[aria-selected=\"true\"] {\n color: var(--rui-color-info);\n border-bottom-color: var(--rui-color-info);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-table th {\n background: var(--rui-color-surface-muted);\n color: var(--rui-color-text-muted);\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n border-bottom-color: var(--rui-color-border);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-table td {\n border-bottom-color: var(--rui-color-border-subtle);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-table tbody tr:hover td {\n background: color-mix(in srgb, var(--rui-color-info) 5%, transparent);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-tag,\n:host([data-rui-theme=\"skyline\"]) .rui-badge {\n border-radius: 999px;\n font-weight: 500;\n letter-spacing: 0.02em;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-tag::before {\n content: \"\";\n width: 6px;\n height: 6px;\n border-radius: 999px;\n background: currentColor;\n display: inline-block;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-badge[data-variant=\"primary\"] {\n background: color-mix(in srgb, var(--rui-color-info) 14%, transparent);\n color: var(--rui-color-info);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-stat-value {\n color: var(--rui-color-primary);\n font-weight: 700;\n letter-spacing: -0.02em;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-stat-label {\n letter-spacing: 0.06em;\n color: var(--rui-color-text-muted);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-callout[data-variant=\"info\"] .rui-callout-icon,\n:host([data-rui-theme=\"skyline\"]) .rui-callout[data-variant=\"success\"] .rui-callout-icon,\n:host([data-rui-theme=\"skyline\"]) .rui-callout[data-variant=\"warning\"] .rui-callout-icon,\n:host([data-rui-theme=\"skyline\"]) .rui-callout[data-variant=\"danger\"] .rui-callout-icon,\n:host([data-rui-theme=\"skyline\"]) .rui-callout[data-variant=\"error\"] .rui-callout-icon {\n border-radius: 999px;\n width: 20px;\n height: 20px;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-link {\n color: var(--rui-color-info);\n font-weight: 500;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-follow-up-button {\n background: var(--rui-color-surface);\n border-color: var(--rui-color-border);\n color: var(--rui-color-primary);\n font-weight: 500;\n border-radius: var(--rui-radius-sm);\n transition: background 140ms ease, border-color 140ms ease;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-follow-up-button:hover {\n background: color-mix(in srgb, var(--rui-color-info) 8%, var(--rui-color-surface));\n border-color: var(--rui-color-info);\n color: var(--rui-color-info);\n}\n:host([data-rui-theme=\"skyline\"]) .rui-steps-item::before {\n background: var(--rui-color-surface);\n color: var(--rui-color-primary);\n border: 1px solid var(--rui-color-primary);\n font-weight: 600;\n}\n:host([data-rui-theme=\"skyline\"]) .rui-divider,\n:host([data-rui-theme=\"skyline\"]) .rui-separator {\n background: var(--rui-color-border);\n}\n\n/* ----------------------------------------------------------------------- */\n/* DropdownMenu / MenuItem / MenuSeparator / MenuLabel */\n/* ----------------------------------------------------------------------- */\n.rui-dropdown-menu {\n position: relative;\n display: inline-flex;\n flex: 0 0 auto;\n}\n.rui-dropdown-menu-trigger {\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n border-radius: var(--rui-radius-sm);\n}\n.rui-dropdown-menu-trigger:focus-visible,\n.rui-dropdown-menu-trigger:focus-within {\n outline: 2px solid color-mix(in srgb, var(--rui-color-primary) 60%, transparent);\n outline-offset: 2px;\n}\n.rui-dropdown-menu-trigger[data-state=\"open\"] { z-index: 41; }\n.rui-dropdown-menu-content {\n position: absolute;\n z-index: 40;\n min-width: 200px;\n padding: 6px;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n box-shadow: var(--rui-shadow-md);\n display: none;\n flex-direction: column;\n gap: 2px;\n}\n.rui-dropdown-menu[data-open=\"true\"] > .rui-dropdown-menu-content { display: flex; }\n.rui-dropdown-menu[data-side=\"bottom\"] > .rui-dropdown-menu-content {\n top: calc(100% + 6px);\n}\n.rui-dropdown-menu[data-side=\"top\"] > .rui-dropdown-menu-content {\n bottom: calc(100% + 6px);\n}\n.rui-dropdown-menu[data-side=\"right\"] > .rui-dropdown-menu-content {\n left: calc(100% + 6px);\n top: 0;\n}\n.rui-dropdown-menu[data-side=\"left\"] > .rui-dropdown-menu-content {\n right: calc(100% + 6px);\n top: 0;\n}\n.rui-dropdown-menu[data-align=\"start\"][data-side=\"bottom\"] > .rui-dropdown-menu-content,\n.rui-dropdown-menu[data-align=\"start\"][data-side=\"top\"] > .rui-dropdown-menu-content { left: 0; }\n.rui-dropdown-menu[data-align=\"center\"][data-side=\"bottom\"] > .rui-dropdown-menu-content,\n.rui-dropdown-menu[data-align=\"center\"][data-side=\"top\"] > .rui-dropdown-menu-content {\n left: 50%; transform: translateX(-50%);\n}\n.rui-dropdown-menu[data-align=\"end\"][data-side=\"bottom\"] > .rui-dropdown-menu-content,\n.rui-dropdown-menu[data-align=\"end\"][data-side=\"top\"] > .rui-dropdown-menu-content { right: 0; }\n.rui-menu-item {\n appearance: none;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n padding: 6px 10px;\n border-radius: var(--rui-radius-sm);\n cursor: pointer;\n text-align: left;\n width: 100%;\n font-size: 13px;\n line-height: 1.2;\n}\n.rui-menu-item:hover:not(:disabled),\n.rui-menu-item:focus-visible {\n background: var(--rui-color-surface-muted);\n outline: none;\n}\n.rui-menu-item:disabled { opacity: 0.55; cursor: not-allowed; }\n.rui-menu-item[data-variant=\"danger\"] { color: var(--rui-color-danger); }\n.rui-menu-item[data-variant=\"danger\"]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--rui-color-danger) 12%, transparent);\n}\n.rui-menu-item-icon { width: 14px; display: inline-flex; justify-content: center; }\n.rui-menu-item-label { flex: 1; min-width: 0; }\n.rui-menu-item-shortcut {\n font-size: 11px;\n color: var(--rui-color-text-muted);\n font-family: var(--rui-font-family-mono, ui-monospace, SFMono-Regular, Menlo, monospace);\n}\n.rui-menu-separator {\n height: 1px;\n background: var(--rui-color-border-subtle);\n margin: 4px 0;\n}\n.rui-menu-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--rui-color-text-muted);\n padding: 6px 10px 4px;\n}\n\n/* ----------------------------------------------------------------------- */\n/* Popover */\n/* ----------------------------------------------------------------------- */\n.rui-popover {\n position: relative;\n display: inline-flex;\n flex: 0 0 auto;\n}\n.rui-popover-trigger {\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n border-radius: var(--rui-radius-sm);\n}\n.rui-popover-trigger:focus-visible,\n.rui-popover-trigger:focus-within {\n outline: 2px solid color-mix(in srgb, var(--rui-color-primary) 60%, transparent);\n outline-offset: 2px;\n}\n.rui-popover-trigger[data-state=\"open\"] { z-index: 41; }\n.rui-popover-content {\n position: absolute;\n z-index: 40;\n width: 280px;\n max-width: min(360px, calc(100vw - 32px));\n padding: var(--rui-spacing-m);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n box-shadow: var(--rui-shadow-md);\n display: none;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n animation: rui-popover-in 140ms ease-out;\n}\n.rui-popover[data-open=\"true\"] > .rui-popover-content { display: flex; }\n.rui-popover[data-side=\"bottom\"] > .rui-popover-content { top: calc(100% + 8px); }\n.rui-popover[data-side=\"top\"] > .rui-popover-content { bottom: calc(100% + 8px); }\n.rui-popover[data-side=\"right\"] > .rui-popover-content { left: calc(100% + 8px); top: 0; }\n.rui-popover[data-side=\"left\"] > .rui-popover-content { right: calc(100% + 8px); top: 0; }\n.rui-popover[data-align=\"start\"][data-side=\"bottom\"] > .rui-popover-content,\n.rui-popover[data-align=\"start\"][data-side=\"top\"] > .rui-popover-content { left: 0; }\n.rui-popover[data-align=\"center\"][data-side=\"bottom\"] > .rui-popover-content,\n.rui-popover[data-align=\"center\"][data-side=\"top\"] > .rui-popover-content {\n left: 50%; transform: translateX(-50%);\n}\n.rui-popover[data-align=\"end\"][data-side=\"bottom\"] > .rui-popover-content,\n.rui-popover[data-align=\"end\"][data-side=\"top\"] > .rui-popover-content { right: 0; }\n.rui-popover-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--rui-spacing-s);\n margin: calc(var(--rui-spacing-xs) * -1) calc(var(--rui-spacing-xs) * -1) 0;\n}\n.rui-popover-title {\n font-weight: 600;\n font-size: 13px;\n color: var(--rui-color-text);\n}\n.rui-popover-title-spacer { display: block; flex: 1; }\n.rui-popover-close {\n appearance: none;\n border: none;\n background: transparent;\n color: var(--rui-color-text-muted);\n cursor: pointer;\n width: 24px;\n height: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--rui-radius-sm);\n font-size: 18px;\n line-height: 1;\n transition: background 150ms ease, color 150ms ease;\n}\n.rui-popover-close:hover {\n background: var(--rui-color-surface-muted);\n color: var(--rui-color-text);\n}\n.rui-popover-close:focus-visible {\n outline: 2px solid color-mix(in srgb, var(--rui-color-primary) 60%, transparent);\n outline-offset: 1px;\n}\n@keyframes rui-popover-in {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.rui-popover[data-side=\"top\"] > .rui-popover-content { animation-name: rui-popover-in-up; }\n@keyframes rui-popover-in-up {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* ----------------------------------------------------------------------- */\n/* Toast / Toasts */\n/* ----------------------------------------------------------------------- */\n.rui-toasts {\n position: fixed;\n z-index: 60;\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n pointer-events: none;\n max-width: min(360px, calc(100% - 32px));\n}\n.rui-toasts > * { pointer-events: auto; }\n.rui-toasts[data-position=\"top-right\"] { top: 16px; right: 16px; align-items: flex-end; }\n.rui-toasts[data-position=\"top-left\"] { top: 16px; left: 16px; align-items: flex-start; }\n.rui-toasts[data-position=\"top-center\"] { top: 16px; left: 50%; transform: translateX(-50%); align-items: center; }\n.rui-toasts[data-position=\"bottom-right\"] { bottom: 16px; right: 16px; align-items: flex-end; flex-direction: column-reverse; }\n.rui-toasts[data-position=\"bottom-left\"] { bottom: 16px; left: 16px; align-items: flex-start; flex-direction: column-reverse; }\n.rui-toasts[data-position=\"bottom-center\"] { bottom: 16px; left: 50%; transform: translateX(-50%); align-items: center; flex-direction: column-reverse; }\n.rui-toast {\n display: flex;\n align-items: flex-start;\n gap: var(--rui-spacing-s);\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n box-shadow: var(--rui-shadow-md);\n min-width: 240px;\n animation: rui-toast-in 200ms ease-out;\n transition: opacity 180ms ease, transform 180ms ease;\n}\n.rui-toast.is-dismissed {\n opacity: 0;\n transform: translateX(12px);\n pointer-events: none;\n}\n.rui-toasts[data-position^=\"top-left\"] .rui-toast.is-dismissed,\n.rui-toasts[data-position=\"bottom-left\"] .rui-toast.is-dismissed {\n transform: translateX(-12px);\n}\n.rui-toast-placeholder { display: none !important; }\n.rui-toast-icon {\n flex-shrink: 0;\n width: 22px;\n height: 22px;\n border-radius: 999px;\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: #ffffff;\n background: var(--rui-color-text-muted);\n}\n.rui-toast-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }\n.rui-toast-title { font-weight: 600; font-size: 13px; }\n.rui-toast-message { color: var(--rui-color-text-muted); font-size: 12px; line-height: 1.45; }\n.rui-toast-action { margin-top: 6px; }\n.rui-toast-close {\n appearance: none;\n border: none;\n background: transparent;\n font-size: 18px;\n line-height: 1;\n color: var(--rui-color-text-muted);\n cursor: pointer;\n width: 24px;\n height: 24px;\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--rui-radius-sm);\n margin: -2px -4px -2px 0;\n transition: background 150ms ease, color 150ms ease;\n}\n.rui-toast-close:hover {\n background: var(--rui-color-surface-muted);\n color: var(--rui-color-text);\n}\n.rui-toast-close:focus-visible {\n outline: 2px solid color-mix(in srgb, var(--rui-color-primary) 60%, transparent);\n outline-offset: 1px;\n}\n.rui-toast[data-tone=\"primary\"] .rui-toast-icon { background: var(--rui-color-primary); }\n.rui-toast[data-tone=\"success\"] .rui-toast-icon { background: var(--rui-color-success); }\n.rui-toast[data-tone=\"warning\"] .rui-toast-icon { background: var(--rui-color-warning); }\n.rui-toast[data-tone=\"danger\"] .rui-toast-icon { background: var(--rui-color-danger); }\n.rui-toast[data-tone=\"info\"] .rui-toast-icon { background: var(--rui-color-info); }\n.rui-toast[data-tone=\"success\"] { border-color: color-mix(in srgb, var(--rui-color-success) 36%, transparent); }\n.rui-toast[data-tone=\"warning\"] { border-color: color-mix(in srgb, var(--rui-color-warning) 36%, transparent); }\n.rui-toast[data-tone=\"danger\"] { border-color: color-mix(in srgb, var(--rui-color-danger) 36%, transparent); }\n.rui-toast[data-tone=\"info\"] { border-color: color-mix(in srgb, var(--rui-color-info) 36%, transparent); }\n@keyframes rui-toast-in {\n from { opacity: 0; transform: translateY(-6px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* ----------------------------------------------------------------------- */\n/* Slider */\n/* ----------------------------------------------------------------------- */\n.rui-slider { display: flex; flex-direction: column; gap: var(--rui-spacing-xs); }\n.rui-slider-head { display: flex; justify-content: space-between; align-items: center; }\n.rui-slider-label { font-size: 13px; color: var(--rui-color-text); }\n.rui-slider-value {\n font-size: 13px;\n font-weight: 600;\n color: var(--rui-color-primary);\n font-variant-numeric: tabular-nums;\n}\n.rui-slider-input {\n appearance: none;\n width: 100%;\n height: 6px;\n background: var(--rui-color-surface-muted);\n border-radius: 999px;\n outline: none;\n cursor: pointer;\n}\n.rui-slider[data-disabled=\"true\"] .rui-slider-input { opacity: 0.55; cursor: not-allowed; }\n.rui-slider-input::-webkit-slider-thumb {\n appearance: none;\n width: 18px;\n height: 18px;\n border-radius: 999px;\n background: var(--rui-color-primary);\n border: 2px solid var(--rui-color-surface);\n box-shadow: var(--rui-shadow-sm);\n cursor: pointer;\n}\n.rui-slider-input::-moz-range-thumb {\n width: 18px;\n height: 18px;\n border-radius: 999px;\n background: var(--rui-color-primary);\n border: 2px solid var(--rui-color-surface);\n box-shadow: var(--rui-shadow-sm);\n cursor: pointer;\n}\n.rui-slider-input:focus-visible::-webkit-slider-thumb {\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-primary) 30%, transparent);\n}\n.rui-slider-input:focus-visible::-moz-range-thumb {\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-primary) 30%, transparent);\n}\n\n/* ----------------------------------------------------------------------- */\n/* NumberInput */\n/* ----------------------------------------------------------------------- */\n.rui-number-input {\n display: flex;\n align-items: stretch;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-sm);\n background: var(--rui-color-surface);\n overflow: hidden;\n transition: border-color 150ms ease, box-shadow 150ms ease;\n}\n.rui-number-input:focus-within {\n border-color: var(--rui-color-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-primary) 18%, transparent);\n}\n.rui-number-input-button {\n appearance: none;\n border: none;\n background: var(--rui-color-surface-muted);\n color: var(--rui-color-text);\n flex: 0 0 auto;\n width: 38px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n line-height: 1;\n transition: background 150ms ease, color 150ms ease;\n}\n.rui-number-input-button[data-direction=\"down\"] {\n border-right: 1px solid var(--rui-color-border);\n}\n.rui-number-input-button[data-direction=\"up\"] {\n border-left: 1px solid var(--rui-color-border);\n}\n.rui-number-input-button:hover:not(:disabled) {\n background: color-mix(in srgb, var(--rui-color-primary) 10%, var(--rui-color-surface-muted));\n color: var(--rui-color-primary);\n}\n.rui-number-input-button:active:not(:disabled) {\n background: color-mix(in srgb, var(--rui-color-primary) 18%, var(--rui-color-surface-muted));\n}\n.rui-number-input-button:disabled { opacity: 0.5; cursor: not-allowed; }\n.rui-number-input-field {\n appearance: none;\n border: none;\n background: transparent;\n padding: 8px 12px;\n color: inherit;\n font: inherit;\n flex: 1 1 auto;\n min-width: 0;\n width: auto;\n text-align: center;\n font-variant-numeric: tabular-nums;\n}\n.rui-number-input-field:focus { outline: none; }\n.rui-number-input-field::-webkit-outer-spin-button,\n.rui-number-input-field::-webkit-inner-spin-button { appearance: none; margin: 0; }\n.rui-number-input[data-disabled=\"true\"] {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* ----------------------------------------------------------------------- */\n/* DatePicker */\n/* ----------------------------------------------------------------------- */\n.rui-date-picker { display: flex; flex-direction: column; gap: var(--rui-spacing-xs); }\n.rui-date-picker-label { font-size: 13px; color: var(--rui-color-text); }\n.rui-date-picker-input {\n appearance: none;\n padding: 8px 12px;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-sm);\n background: var(--rui-color-surface);\n color: inherit;\n font: inherit;\n font-size: 13px;\n}\n.rui-date-picker-input:focus {\n outline: none;\n border-color: var(--rui-color-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-primary) 18%, transparent);\n}\n\n/* ----------------------------------------------------------------------- */\n/* FileUpload */\n/* ----------------------------------------------------------------------- */\n.rui-file-upload {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s);\n}\n.rui-file-upload-dropzone {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-m);\n padding: var(--rui-spacing-m) var(--rui-spacing-l);\n border: 1.5px dashed var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-bg-subtle);\n cursor: pointer;\n transition: border-color 120ms ease, background 120ms ease;\n}\n.rui-file-upload-dropzone:hover {\n border-color: var(--rui-color-primary);\n background: color-mix(in srgb, var(--rui-color-primary) 5%, var(--rui-color-bg-subtle));\n}\n.rui-file-upload[data-disabled=\"true\"] { opacity: 0.55; }\n.rui-file-upload[data-disabled=\"true\"] .rui-file-upload-dropzone { cursor: not-allowed; }\n.rui-file-upload-icon {\n flex-shrink: 0;\n width: 32px;\n height: 32px;\n border-radius: 999px;\n display: inline-flex !important;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--rui-color-primary) 14%, transparent);\n color: var(--rui-color-primary);\n font-size: 14px;\n}\n.rui-file-upload-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }\n.rui-file-upload-label { font-weight: 600; font-size: 13px; }\n.rui-file-upload-hint { font-size: 12px; color: var(--rui-color-text-muted); }\n.rui-file-upload-input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n.rui-file-upload-preview {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-xs, 4px);\n padding: var(--rui-spacing-s) var(--rui-spacing-m);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n background: var(--rui-color-surface, var(--rui-color-bg-subtle));\n}\n.rui-file-upload-preview-item {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n}\n.rui-file-upload-thumbnail {\n width: 56px;\n height: 56px;\n object-fit: cover;\n border-radius: var(--rui-radius-sm);\n border: 1px solid var(--rui-color-border);\n flex-shrink: 0;\n}\n.rui-file-upload-filename {\n font-size: 12.5px;\n color: var(--rui-color-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n/* ----------------------------------------------------------------------- */\n/* Combobox */\n/* ----------------------------------------------------------------------- */\n.rui-combobox {\n position: relative;\n display: inline-flex;\n flex-direction: column;\n min-width: 200px;\n}\n.rui-combobox[data-disabled=\"true\"] { opacity: 0.55; }\n.rui-combobox-trigger {\n appearance: none;\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--rui-spacing-s);\n padding: 8px 12px;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-sm);\n color: inherit;\n font: inherit;\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n}\n.rui-combobox-trigger:focus-visible,\n.rui-combobox[data-open=\"true\"] .rui-combobox-trigger {\n outline: none;\n border-color: var(--rui-color-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-primary) 18%, transparent);\n}\n.rui-combobox-value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.rui-combobox-value[data-placeholder=\"true\"] { color: var(--rui-color-text-muted); }\n.rui-combobox-chevron { color: var(--rui-color-text-muted); font-size: 11px; }\n.rui-combobox-panel {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n right: 0;\n z-index: 40;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n box-shadow: var(--rui-shadow-md);\n display: none;\n flex-direction: column;\n padding: 6px;\n gap: 4px;\n max-height: 280px;\n}\n.rui-combobox[data-open=\"true\"] .rui-combobox-panel { display: flex; }\n.rui-combobox-filter {\n appearance: none;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-sm);\n padding: 6px 10px;\n font: inherit;\n font-size: 13px;\n background: var(--rui-color-bg-subtle);\n}\n.rui-combobox-filter:focus {\n outline: none;\n border-color: var(--rui-color-primary);\n}\n.rui-combobox-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }\n.rui-combobox-option {\n appearance: none;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: left;\n padding: 6px 10px;\n border-radius: var(--rui-radius-sm);\n cursor: pointer;\n font-size: 13px;\n}\n.rui-combobox-option:hover { background: var(--rui-color-surface-muted); }\n.rui-combobox-option[aria-selected=\"true\"] {\n background: color-mix(in srgb, var(--rui-color-primary) 14%, transparent);\n color: var(--rui-color-primary);\n font-weight: 600;\n}\n.rui-combobox-empty {\n padding: 12px;\n color: var(--rui-color-text-muted);\n font-size: 12px;\n text-align: center;\n}\n\n/* ----------------------------------------------------------------------- */\n/* Tree / TreeNode */\n/* ----------------------------------------------------------------------- */\n.rui-tree {\n display: flex;\n flex-direction: column;\n gap: 2px;\n font-size: 13px;\n}\n.rui-tree-node {\n display: flex;\n flex-direction: column;\n}\n.rui-tree-node-summary {\n list-style: none;\n cursor: pointer;\n display: block;\n}\n.rui-tree-node-summary::-webkit-details-marker { display: none; }\n.rui-tree-node-row {\n appearance: none;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-xs);\n width: 100%;\n padding: 4px 6px;\n border-radius: var(--rui-radius-sm);\n cursor: pointer;\n text-align: left;\n}\n.rui-tree-node-row:hover { background: var(--rui-color-surface-muted); }\n.rui-tree-node-row[data-active=\"true\"] {\n background: color-mix(in srgb, var(--rui-color-primary) 14%, transparent);\n color: var(--rui-color-primary);\n font-weight: 600;\n}\n.rui-tree-node-chevron {\n font-size: 10px;\n color: var(--rui-color-text-muted);\n width: 14px;\n display: inline-flex;\n justify-content: center;\n transition: transform 150ms ease;\n}\n.rui-tree-node[open] > .rui-tree-node-summary .rui-tree-node-chevron {\n transform: rotate(90deg);\n}\n.rui-tree-node-chevron-spacer { width: 14px; }\n.rui-tree-node-icon { color: var(--rui-color-text-muted); font-size: 12px; }\n.rui-tree-node-row[data-active=\"true\"] .rui-tree-node-icon { color: var(--rui-color-primary); }\n.rui-tree-node-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.rui-tree-node-badge {\n background: var(--rui-color-surface-muted);\n color: var(--rui-color-text-muted);\n border-radius: 999px;\n padding: 1px 8px;\n font-size: 11px;\n font-weight: 600;\n}\n.rui-tree-node-children {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding-left: 16px;\n border-left: 1px solid var(--rui-color-border-subtle);\n margin-left: 8px;\n margin-top: 2px;\n}\n\n/* ----------------------------------------------------------------------- */\n/* Navbar / NavbarItem */\n/* ----------------------------------------------------------------------- */\n.rui-navbar {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-l);\n padding: var(--rui-spacing-s) var(--rui-spacing-l);\n background: var(--rui-color-surface);\n border-bottom: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md) var(--rui-radius-md) 0 0;\n}\n.rui-navbar[data-sticky=\"true\"] {\n position: sticky;\n top: 0;\n z-index: 30;\n backdrop-filter: blur(8px);\n background: color-mix(in srgb, var(--rui-color-surface) 92%, transparent);\n}\n.rui-navbar[data-variant=\"transparent\"] {\n background: transparent;\n border-bottom-color: transparent;\n}\n.rui-navbar-brand {\n font-weight: 700;\n font-size: 15px;\n color: var(--rui-color-text);\n display: inline-flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n}\n.rui-navbar-items {\n display: flex;\n align-items: center;\n gap: 2px;\n flex: 1;\n flex-wrap: wrap;\n}\n.rui-navbar-actions {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s);\n margin-left: auto;\n}\n.rui-navbar-item {\n appearance: none;\n border: none;\n background: transparent;\n color: var(--rui-color-text);\n font: inherit;\n font-size: 13px;\n font-weight: 500;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: var(--rui-radius-sm);\n text-decoration: none;\n cursor: pointer;\n transition: background 150ms ease, color 150ms ease;\n}\n.rui-navbar-item:hover { background: var(--rui-color-surface-muted); }\n.rui-navbar-item[data-active=\"true\"] {\n background: color-mix(in srgb, var(--rui-color-primary) 14%, transparent);\n color: var(--rui-color-primary);\n}\n.rui-navbar-item-icon { display: inline-flex; }\n\n/* Compact layout shifts for narrow viewports */\n@media (max-width: 640px) {\n .rui-navbar { flex-wrap: wrap; gap: var(--rui-spacing-s); }\n .rui-navbar-items { width: 100%; }\n}\n\n/* ------------------------------------------------------------------------- *\n * New / refined component styles — wave introduced by components_suggestions.md\n * ------------------------------------------------------------------------- */\n\n/* Spinner --------------------------------------------------------------- */\n.rui-spinner {\n display: inline-flex;\n align-items: center;\n gap: var(--rui-spacing-xs, 4px);\n vertical-align: middle;\n}\n.rui-spinner-ring {\n width: 16px;\n height: 16px;\n border-radius: 999px;\n border: 2px solid color-mix(in srgb, var(--rui-color-primary) 25%, transparent);\n border-top-color: var(--rui-color-primary);\n animation: rui-spinner-rotate 0.8s linear infinite;\n}\n.rui-spinner[data-size=\"xs\"] .rui-spinner-ring { width: 10px; height: 10px; border-width: 1.5px; }\n.rui-spinner[data-size=\"sm\"] .rui-spinner-ring { width: 14px; height: 14px; }\n.rui-spinner[data-size=\"md\"] .rui-spinner-ring { width: 16px; height: 16px; }\n.rui-spinner[data-size=\"lg\"] .rui-spinner-ring { width: 22px; height: 22px; border-width: 2.5px; }\n.rui-spinner[data-size=\"xl\"] .rui-spinner-ring { width: 32px; height: 32px; border-width: 3px; }\n.rui-spinner[data-tone=\"success\"] .rui-spinner-ring { border-top-color: var(--rui-color-success); border-color: color-mix(in srgb, var(--rui-color-success) 25%, transparent); border-top-color: var(--rui-color-success); }\n.rui-spinner[data-tone=\"warning\"] .rui-spinner-ring { border-color: color-mix(in srgb, var(--rui-color-warning) 25%, transparent); border-top-color: var(--rui-color-warning); }\n.rui-spinner[data-tone=\"danger\"] .rui-spinner-ring { border-color: color-mix(in srgb, var(--rui-color-danger) 25%, transparent); border-top-color: var(--rui-color-danger); }\n.rui-spinner[data-tone=\"info\"] .rui-spinner-ring { border-color: color-mix(in srgb, var(--rui-color-info) 25%, transparent); border-top-color: var(--rui-color-info); }\n.rui-spinner-label { font-size: 0.875rem; color: var(--rui-color-text-muted); }\n@keyframes rui-spinner-rotate { to { transform: rotate(360deg); } }\n@media (prefers-reduced-motion: reduce) {\n .rui-spinner-ring { animation-duration: 2s; }\n}\n\n/* Sparkline ------------------------------------------------------------ */\n.rui-sparkline {\n display: inline-block;\n vertical-align: middle;\n color: var(--rui-color-primary);\n}\n.rui-sparkline-line {\n stroke: currentColor;\n stroke-width: 1.5;\n stroke-linecap: round;\n stroke-linejoin: round;\n fill: none;\n}\n.rui-sparkline-area {\n fill: color-mix(in srgb, currentColor 16%, transparent);\n}\n.rui-sparkline[data-tone=\"success\"] { color: var(--rui-color-success); }\n.rui-sparkline[data-tone=\"warning\"] { color: var(--rui-color-warning); }\n.rui-sparkline[data-tone=\"danger\"] { color: var(--rui-color-danger); }\n.rui-sparkline[data-tone=\"info\"] { color: var(--rui-color-info); }\n.rui-sparkline-wrap { display: inline-flex; align-items: center; }\n\n.rui-stat-spark { margin-top: var(--rui-spacing-xs, 4px); }\n.rui-stats-value-row {\n display: inline-flex;\n align-items: center;\n gap: var(--rui-spacing-s, 8px);\n}\n.rui-stat-card[data-tone=\"success\"] .rui-stat-value { color: var(--rui-color-success); }\n.rui-stat-card[data-tone=\"warning\"] .rui-stat-value { color: var(--rui-color-warning); }\n.rui-stat-card[data-tone=\"danger\"] .rui-stat-value { color: var(--rui-color-danger); }\n\n/* MultiSelect ---------------------------------------------------------- */\n.rui-multiselect {\n position: relative;\n width: 100%;\n font-size: 0.875rem;\n}\n.rui-multiselect-trigger {\n width: 100%;\n min-height: 40px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--rui-spacing-s, 8px);\n padding: 6px var(--rui-spacing-s, 8px);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface);\n color: var(--rui-color-text);\n cursor: pointer;\n font: inherit;\n text-align: left;\n}\n.rui-multiselect-trigger:focus-visible {\n outline: 2px solid var(--rui-color-primary);\n outline-offset: 1px;\n}\n.rui-multiselect[data-disabled=\"true\"] .rui-multiselect-trigger {\n opacity: 0.6;\n cursor: not-allowed;\n}\n.rui-multiselect-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n flex: 1;\n min-width: 0;\n}\n.rui-multiselect-placeholder { color: var(--rui-color-text-muted); }\n.rui-multiselect-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--rui-color-primary) 14%, transparent);\n color: var(--rui-color-primary);\n border-radius: var(--rui-radius-sm, 6px);\n font-size: 0.8125rem;\n}\n.rui-multiselect-chip-remove {\n border: 0;\n background: transparent;\n color: inherit;\n font-size: 1rem;\n line-height: 1;\n cursor: pointer;\n padding: 0 2px;\n border-radius: 4px;\n}\n.rui-multiselect-chip-remove:hover { background: color-mix(in srgb, currentColor 18%, transparent); }\n.rui-multiselect-chevron {\n flex-shrink: 0;\n color: var(--rui-color-text-muted);\n transition: transform 0.15s ease;\n}\n.rui-multiselect[data-open=\"true\"] .rui-multiselect-chevron { transform: rotate(180deg); }\n.rui-multiselect-panel {\n display: none;\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n z-index: 30;\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n box-shadow: var(--rui-shadow-md);\n padding: var(--rui-spacing-xs, 4px);\n}\n.rui-multiselect[data-open=\"true\"] .rui-multiselect-panel { display: block; }\n.rui-multiselect-filter {\n width: 100%;\n padding: 6px 8px;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-sm, 6px);\n background: var(--rui-color-surface);\n color: var(--rui-color-text);\n font: inherit;\n margin-bottom: 4px;\n}\n.rui-multiselect-list {\n max-height: 220px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n}\n.rui-multiselect-option {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s, 8px);\n padding: 6px var(--rui-spacing-s, 8px);\n background: transparent;\n border: 0;\n cursor: pointer;\n color: var(--rui-color-text);\n font: inherit;\n text-align: left;\n border-radius: var(--rui-radius-sm, 6px);\n}\n.rui-multiselect-option:hover:not(:disabled) { background: var(--rui-color-surface-muted); }\n.rui-multiselect-option[data-selected=\"true\"] {\n color: var(--rui-color-primary);\n font-weight: 600;\n}\n.rui-multiselect-option:disabled { opacity: 0.4; cursor: not-allowed; }\n.rui-multiselect-option-check {\n width: 16px;\n height: 16px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--rui-color-border);\n border-radius: 4px;\n flex-shrink: 0;\n}\n.rui-multiselect-option[data-selected=\"true\"] .rui-multiselect-option-check {\n background: var(--rui-color-primary);\n border-color: var(--rui-color-primary);\n color: var(--rui-color-on-primary, #fff);\n}\n.rui-multiselect-empty {\n padding: 12px;\n color: var(--rui-color-text-muted);\n text-align: center;\n font-size: 0.875rem;\n}\n\n/* DateRangePicker ------------------------------------------------------ */\n.rui-date-range-picker { display: flex; flex-direction: column; gap: 4px; }\n.rui-date-range-picker-label {\n font-size: 0.875rem;\n color: var(--rui-color-text-muted);\n}\n.rui-date-range-picker-row {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s, 8px);\n}\n.rui-date-range-picker-input {\n flex: 1;\n min-width: 0;\n padding: 8px var(--rui-spacing-s, 8px);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface);\n color: var(--rui-color-text);\n font: inherit;\n}\n.rui-date-range-picker-input:focus-visible {\n outline: 2px solid var(--rui-color-primary);\n outline-offset: 1px;\n}\n.rui-date-range-picker-separator { color: var(--rui-color-text-muted); }\n\n/* SegmentedControl ----------------------------------------------------- */\n.rui-segmented-control {\n display: inline-flex;\n background: var(--rui-color-surface-muted);\n padding: 3px;\n border-radius: var(--rui-radius-md, 8px);\n border: 1px solid var(--rui-color-border);\n gap: 2px;\n}\n.rui-segmented-control-option {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px var(--rui-spacing-s, 10px);\n background: transparent;\n border: 0;\n border-radius: var(--rui-radius-sm, 6px);\n color: var(--rui-color-text-muted);\n cursor: pointer;\n font: inherit;\n font-size: 0.8125rem;\n font-weight: 500;\n transition: background 0.15s ease, color 0.15s ease;\n}\n.rui-segmented-control-option:hover { color: var(--rui-color-text); }\n.rui-segmented-control-option[data-active=\"true\"] {\n background: var(--rui-color-surface);\n color: var(--rui-color-text);\n box-shadow: var(--rui-shadow-sm);\n}\n.rui-segmented-control[data-size=\"sm\"] .rui-segmented-control-option { padding: 2px 8px; font-size: 0.75rem; }\n.rui-segmented-control[data-size=\"lg\"] .rui-segmented-control-option { padding: 6px 14px; font-size: 0.9375rem; }\n\n/* Toolbar center slot -------------------------------------------------- */\n.rui-toolbar-center {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: var(--rui-spacing-s, 8px);\n flex: 1;\n flex-wrap: wrap;\n}\n.rui-toolbar[data-has-center=\"true\"] .rui-toolbar-left,\n.rui-toolbar[data-has-center=\"true\"] .rui-toolbar-right { flex: 0 1 auto; }\n\n/* EmptyState multi-action + illustration ------------------------------- */\n.rui-empty-state-actions {\n display: flex;\n gap: var(--rui-spacing-s, 8px);\n margin-top: var(--rui-spacing-m, 12px);\n flex-wrap: wrap;\n justify-content: center;\n}\n.rui-empty-state-illustration {\n max-width: 240px;\n width: 100%;\n height: auto;\n display: block;\n margin: 0 auto var(--rui-spacing-m, 12px);\n}\n\n/* Modal size + footer -------------------------------------------------- */\n.rui-modal[data-size=\"sm\"] { max-width: 360px; }\n.rui-modal[data-size=\"md\"] { max-width: 520px; }\n.rui-modal[data-size=\"lg\"] { max-width: 760px; }\n.rui-modal[data-size=\"xl\"] { max-width: 960px; }\n.rui-modal[data-size=\"full\"] { max-width: 96vw; width: 96vw; }\n.rui-modal-footer {\n display: flex;\n gap: var(--rui-spacing-s, 8px);\n padding: var(--rui-spacing-m, 12px) var(--rui-spacing-l, 16px);\n border-top: 1px solid var(--rui-color-border);\n background: var(--rui-color-surface);\n justify-content: flex-end;\n flex-wrap: wrap;\n}\n\n/* Tabs trigger icon + badge ------------------------------------------- */\n.rui-tab-trigger-icon { display: inline-flex; align-items: center; margin-right: 4px; }\n.rui-tab-trigger-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 6px;\n margin-left: 4px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--rui-color-primary) 18%, transparent);\n color: var(--rui-color-primary);\n font-size: 0.6875rem;\n font-weight: 600;\n}\n.rui-tabs[data-orientation=\"vertical\"] {\n display: flex;\n gap: var(--rui-spacing-m, 12px);\n}\n.rui-tabs[data-orientation=\"vertical\"] .rui-tab-list {\n flex-direction: column;\n border-bottom: 0;\n border-right: 1px solid var(--rui-color-border);\n padding-right: var(--rui-spacing-s, 8px);\n min-width: 140px;\n}\n.rui-tabs[data-orientation=\"vertical\"] .rui-tab-trigger {\n justify-content: flex-start;\n text-align: left;\n}\n.rui-tabs[data-orientation=\"vertical\"] .rui-tab-panels { flex: 1; }\n\n/* Progress segmented + buffered --------------------------------------- */\n.rui-progress-segments {\n display: flex;\n gap: 4px;\n}\n.rui-progress-segment {\n flex: 1;\n height: 8px;\n border-radius: 4px;\n background: var(--rui-color-surface-muted);\n border: 1px solid var(--rui-color-border);\n}\n.rui-progress-segment[data-filled=\"true\"] {\n background: var(--rui-color-primary);\n border-color: var(--rui-color-primary);\n}\n.rui-progress[data-tone=\"success\"] .rui-progress-segment[data-filled=\"true\"] { background: var(--rui-color-success); border-color: var(--rui-color-success); }\n.rui-progress[data-tone=\"warning\"] .rui-progress-segment[data-filled=\"true\"] { background: var(--rui-color-warning); border-color: var(--rui-color-warning); }\n.rui-progress[data-tone=\"danger\"] .rui-progress-segment[data-filled=\"true\"] { background: var(--rui-color-danger); border-color: var(--rui-color-danger); }\n.rui-progress-buffer {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--rui-color-primary) 22%, transparent);\n border-radius: inherit;\n}\n.rui-progress-track { position: relative; overflow: hidden; }\n\n/* CodeBlock copy + line gutter + highlight ----------------------------- */\n.rui-code-block-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--rui-spacing-s, 8px);\n padding: 4px 8px;\n background: var(--rui-color-surface-muted);\n border-bottom: 1px solid var(--rui-color-border);\n border-top-left-radius: var(--rui-radius-md, 8px);\n border-top-right-radius: var(--rui-radius-md, 8px);\n font-size: 0.75rem;\n color: var(--rui-color-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n.rui-code-block-copy {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: transparent;\n border: 1px solid transparent;\n color: var(--rui-color-text-muted);\n padding: 2px 6px;\n border-radius: var(--rui-radius-sm, 6px);\n cursor: pointer;\n font: inherit;\n font-size: 0.75rem;\n text-transform: none;\n letter-spacing: 0;\n}\n.rui-code-block-copy:hover {\n background: var(--rui-color-surface);\n border-color: var(--rui-color-border);\n color: var(--rui-color-text);\n}\n.rui-code-block-pre[data-line-numbers=\"true\"] {\n counter-reset: rui-codeline;\n}\n.rui-code-block-line {\n display: flex;\n gap: var(--rui-spacing-s, 8px);\n padding: 0 var(--rui-spacing-s, 8px);\n}\n.rui-code-block-line[data-highlight=\"true\"] {\n background: color-mix(in srgb, var(--rui-color-primary) 10%, transparent);\n}\n.rui-code-block-gutter {\n flex-shrink: 0;\n color: var(--rui-color-text-muted);\n user-select: none;\n min-width: 2ch;\n text-align: right;\n}\n.rui-code-block-code { white-space: pre; }\n\n/* Skeleton variants ---------------------------------------------------- */\n.rui-skeleton[data-variant=\"card\"],\n.rui-skeleton[data-variant=\"image\"],\n.rui-skeleton[data-variant=\"avatar\"],\n.rui-skeleton[data-variant=\"table-row\"] {\n display: flex;\n flex-direction: column;\n gap: var(--rui-spacing-s, 8px);\n}\n.rui-skeleton-shape {\n background: linear-gradient(90deg, var(--rui-color-surface-muted) 25%, var(--rui-color-surface) 37%, var(--rui-color-surface-muted) 63%);\n background-size: 400% 100%;\n animation: rui-skeleton-shimmer 1.4s ease-in-out infinite;\n}\n.rui-skeleton-shape[data-shape=\"circle\"] { border-radius: 999px; }\n.rui-skeleton-shape[data-shape=\"rect\"] { border-radius: var(--rui-radius-md, 8px); }\n.rui-skeleton-row { display: flex; gap: var(--rui-spacing-s, 8px); }\n@keyframes rui-skeleton-shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }\n@media (prefers-reduced-motion: reduce) {\n .rui-skeleton-shape, .rui-skeleton-line { animation-duration: 3s; }\n}\n\n/* Image fit + placeholder --------------------------------------------- */\n.rui-image[data-fit=\"contain\"] img { object-fit: contain; }\n.rui-image[data-fit=\"cover\"] img { object-fit: cover; }\n.rui-image[data-fit=\"fill\"] img { object-fit: fill; }\n.rui-image[data-fit=\"none\"] img { object-fit: none; }\n.rui-image[data-fit=\"scale-down\"] img { object-fit: scale-down; }\n.rui-image-placeholder {\n width: 100%;\n height: 100%;\n min-height: 80px;\n background: var(--rui-color-surface-muted);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--rui-color-text-muted);\n border-radius: inherit;\n}\n.rui-image-fallback-icon { font-size: 1.5rem; opacity: 0.6; }\n.rui-image-fallback-text { font-size: 0.8125rem; opacity: 0.8; }\n\n/* Table density + sticky ---------------------------------------------- */\n.rui-table-wrapper[data-density=\"compact\"] td,\n.rui-table-wrapper[data-density=\"compact\"] th { padding: 4px 8px; }\n.rui-table-wrapper[data-striped=\"true\"] tbody tr:nth-child(even) td {\n background: var(--rui-color-surface-muted);\n}\n.rui-table-wrapper[data-sticky=\"true\"] {\n position: relative;\n overflow: auto;\n max-height: 60vh;\n}\n.rui-table-wrapper[data-sticky=\"true\"] thead th {\n position: sticky;\n top: 0;\n background: var(--rui-color-surface);\n z-index: 1;\n}\n.rui-table td[data-align=\"center\"], .rui-table th[data-align=\"center\"] { text-align: center; }\n.rui-table td[data-align=\"right\"], .rui-table th[data-align=\"right\"] { text-align: right; }\n.rui-table td[data-align=\"left\"], .rui-table th[data-align=\"left\"] { text-align: left; }\n\n/* Pagination summary + per-page selector ------------------------------ */\n.rui-pagination {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-m, 12px);\n flex-wrap: wrap;\n}\n.rui-pagination-summary {\n color: var(--rui-color-text-muted);\n font-size: 0.875rem;\n}\n.rui-pagination-buttons { display: inline-flex; gap: 2px; align-items: center; flex-wrap: wrap; }\n.rui-pagination-current {\n display: inline-flex;\n align-items: center;\n padding: 0 var(--rui-spacing-s, 8px);\n color: var(--rui-color-text-muted);\n font-size: 0.875rem;\n}\n.rui-pagination-per-page {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 0.875rem;\n color: var(--rui-color-text-muted);\n}\n.rui-pagination-per-page-select {\n padding: 4px 6px;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-sm, 6px);\n background: var(--rui-color-surface);\n color: var(--rui-color-text);\n font: inherit;\n}\n\n/* Markdown rich rendering --------------------------------------------- */\n.rui-markdown h1.rui-markdown-h1,\n.rui-markdown h2.rui-markdown-h2,\n.rui-markdown h3.rui-markdown-h3 {\n margin: 0.6em 0 0.3em;\n font-weight: 600;\n line-height: 1.25;\n}\n.rui-markdown h1.rui-markdown-h1 { font-size: 1.5rem; }\n.rui-markdown h2.rui-markdown-h2 { font-size: 1.25rem; }\n.rui-markdown h3.rui-markdown-h3 { font-size: 1.0625rem; }\n.rui-markdown .rui-markdown-quote {\n border-left: 3px solid var(--rui-color-primary);\n padding: 0 var(--rui-spacing-m, 12px);\n color: var(--rui-color-text-muted);\n font-style: italic;\n margin: var(--rui-spacing-s, 8px) 0;\n}\n.rui-markdown .rui-markdown-code {\n background: var(--rui-color-surface-muted);\n padding: var(--rui-spacing-s, 8px) var(--rui-spacing-m, 12px);\n border-radius: var(--rui-radius-md, 8px);\n overflow-x: auto;\n font-size: 0.8125rem;\n margin: var(--rui-spacing-s, 8px) 0;\n}\n.rui-markdown .rui-markdown-image {\n max-width: 100%;\n height: auto;\n display: block;\n margin: var(--rui-spacing-s, 8px) 0;\n border-radius: var(--rui-radius-md, 8px);\n}\n.rui-markdown ol, .rui-markdown ul { padding-left: 1.5em; margin: 0.25em 0; }\n\n/* Separator with label ------------------------------------------------ */\n.rui-separator-with-label {\n display: flex;\n align-items: center;\n gap: var(--rui-spacing-s, 8px);\n height: auto;\n width: 100%;\n /* The line lives in the inner spans, not on the container. */\n background: transparent;\n}\n.rui-separator-with-label[data-orientation=\"horizontal\"] { height: auto; }\n.rui-separator-with-label .rui-separator-line {\n flex: 1;\n height: 1px;\n background: var(--rui-color-border);\n}\n.rui-separator-with-label .rui-separator-label {\n color: var(--rui-color-text-muted);\n font-size: 0.8125rem;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n flex-shrink: 0;\n}\n\n/* Standalone Toast positioning ---------------------------------------- */\n.rui-toast-standalone {\n position: fixed;\n z-index: 1000;\n max-width: 360px;\n}\n.rui-toast-standalone[data-position=\"top-right\"] { top: 20px; right: 20px; }\n.rui-toast-standalone[data-position=\"top-left\"] { top: 20px; left: 20px; }\n.rui-toast-standalone[data-position=\"top-center\"] { top: 20px; left: 50%; transform: translateX(-50%); }\n.rui-toast-standalone[data-position=\"bottom-right\"] { bottom: 20px; right: 20px; }\n.rui-toast-standalone[data-position=\"bottom-left\"] { bottom: 20px; left: 20px; }\n.rui-toast-standalone[data-position=\"bottom-center\"]{ bottom: 20px; left: 50%; transform: translateX(-50%); }\n\n/* Rating half-step / custom icons ------------------------------------- */\n.rui-rating[data-half-step=\"true\"] .rui-rating-star { cursor: crosshair; }\n.rui-rating-star[data-fill=\"half\"] {\n background: linear-gradient(90deg, var(--rui-color-primary) 50%, var(--rui-color-border) 50%);\n -webkit-background-clip: text;\n background-clip: text;\n}\n\n/* Steps active state -------------------------------------------------- */\n.rui-steps-item[data-active=\"true\"] {\n font-weight: 600;\n}\n.rui-steps-item[data-active=\"true\"]::marker {\n color: var(--rui-color-primary);\n}\n\n/* ====================================================================== */\n/* Advanced components (DataGrid, CalendarView, Carousel, Media, ...) */\n/* ====================================================================== */\n\n/* DataGrid ------------------------------------------------------------ */\n.rui-data-grid {\n display: flex;\n flex-direction: column;\n gap: 12px;\n width: 100%;\n}\n.rui-data-grid-bulk {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n align-items: center;\n padding: 10px 14px;\n background: color-mix(in srgb, var(--rui-color-primary) 8%, var(--rui-color-surface, #fff));\n border: 1px solid color-mix(in srgb, var(--rui-color-primary) 25%, var(--rui-color-border));\n border-radius: var(--rui-radius-md, 8px);\n font-size: 13px;\n}\n.rui-data-grid-bulk-count {\n font-weight: 600;\n color: var(--rui-color-primary);\n}\n.rui-data-grid-bulk-tools {\n margin-left: auto;\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n.rui-data-grid-scroll {\n position: relative;\n overflow: auto;\n max-width: 100%;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface, var(--rui-color-bg));\n}\n.rui-data-grid-table {\n width: 100%;\n border-collapse: separate;\n border-spacing: 0;\n font-size: 14px;\n}\n.rui-data-grid-caption {\n text-align: left;\n caption-side: top;\n padding: 12px 14px 8px;\n font-weight: 600;\n font-size: 14px;\n color: var(--rui-color-text);\n background: var(--rui-color-surface, var(--rui-color-bg));\n}\n.rui-data-grid-table thead th {\n position: sticky;\n top: 0;\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 4%, var(--rui-color-surface, #fff)));\n z-index: 2;\n text-align: left;\n font-weight: 600;\n font-size: 12.5px;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n color: var(--rui-color-text-muted);\n border-bottom: 1px solid var(--rui-color-border);\n padding: 10px 12px;\n white-space: nowrap;\n}\n.rui-data-grid-table thead th[data-align=\"right\"] { text-align: right; }\n.rui-data-grid-table thead th[data-align=\"center\"] { text-align: center; }\n.rui-data-grid-table thead th[data-active=\"true\"] { color: var(--rui-color-primary); }\n.rui-data-grid[data-sticky-first=\"true\"] tbody td:first-child,\n.rui-data-grid[data-sticky-first=\"true\"] thead th:first-child {\n position: sticky;\n left: 0;\n background: var(--rui-color-surface, var(--rui-color-bg));\n z-index: 3;\n box-shadow: 1px 0 0 var(--rui-color-border);\n}\n.rui-data-grid[data-sticky-first=\"true\"] thead th:first-child { z-index: 4; }\n.rui-data-grid[data-sticky-header=\"false\"] thead th { position: static; }\n.rui-data-grid-cell-select {\n width: 36px;\n padding-left: 12px;\n padding-right: 4px;\n}\n.rui-data-grid-checkbox {\n cursor: pointer;\n width: 16px;\n height: 16px;\n accent-color: var(--rui-color-primary);\n}\n.rui-data-grid-table tbody td {\n padding: 10px 12px;\n border-bottom: 1px solid var(--rui-color-border);\n vertical-align: middle;\n color: var(--rui-color-text);\n}\n.rui-data-grid[data-density=\"compact\"] .rui-data-grid-table thead th,\n.rui-data-grid[data-density=\"compact\"] .rui-data-grid-table tbody td { padding: 6px 10px; }\n.rui-data-grid-table tbody td[data-align=\"right\"] { text-align: right; font-variant-numeric: tabular-nums; }\n.rui-data-grid-table tbody td[data-align=\"center\"] { text-align: center; }\n.rui-data-grid-table tbody td[data-format=\"number\"],\n.rui-data-grid-table tbody td[data-format=\"currency\"] { font-variant-numeric: tabular-nums; }\n.rui-data-grid-table tbody tr:last-child td { border-bottom: none; }\n.rui-data-grid[data-striped=\"true\"] tbody tr:nth-child(even) td {\n background: color-mix(in srgb, var(--rui-color-text) 2%, transparent);\n}\n.rui-data-grid-table tbody tr[data-selected=\"true\"] td {\n background: color-mix(in srgb, var(--rui-color-primary) 10%, transparent);\n}\n.rui-data-grid-table tbody tr[data-clickable=\"true\"] { cursor: pointer; }\n.rui-data-grid-table tbody tr[data-clickable=\"true\"]:hover td {\n background: color-mix(in srgb, var(--rui-color-text) 4%, transparent);\n}\n.rui-data-grid-sort {\n background: none;\n border: 0;\n font: inherit;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 0;\n color: inherit;\n text-transform: inherit;\n letter-spacing: inherit;\n}\n.rui-data-grid-sort:hover { color: var(--rui-color-primary); }\n.rui-data-grid-sort-icon {\n font-size: 11px;\n opacity: 0.55;\n}\nth[data-active=\"true\"] .rui-data-grid-sort-icon { opacity: 1; }\n.rui-data-grid-filter-row td {\n padding: 6px 10px 10px;\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 2%, var(--rui-color-surface, #fff)));\n border-bottom: 1px solid var(--rui-color-border);\n}\n.rui-data-grid-filter {\n width: 100%;\n font-size: 12px;\n padding: 5px 10px;\n border: 1px solid var(--rui-color-border);\n border-radius: 999px;\n background: var(--rui-color-surface, var(--rui-color-bg));\n color: inherit;\n outline: none;\n}\n.rui-data-grid-filter:focus { border-color: var(--rui-color-primary); }\n.rui-data-grid-empty {\n text-align: center;\n padding: 36px 16px;\n color: var(--rui-color-text-muted);\n font-size: 14px;\n}\n.rui-data-grid-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n padding: 2px 4px;\n font-size: 13px;\n}\n.rui-data-grid-footer-summary { color: var(--rui-color-text-muted); }\n.rui-data-grid-footer-buttons {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.rui-data-grid-page-button {\n border: 1px solid var(--rui-color-border);\n background: var(--rui-color-surface, var(--rui-color-bg));\n color: inherit;\n padding: 4px 10px;\n border-radius: 6px;\n cursor: pointer;\n font: inherit;\n font-size: 12.5px;\n}\n.rui-data-grid-page-button:hover:not([disabled]) { border-color: var(--rui-color-primary); color: var(--rui-color-primary); }\n.rui-data-grid-page-button[disabled] { opacity: 0.45; cursor: not-allowed; }\n.rui-data-grid-page-current {\n min-width: 56px;\n text-align: center;\n font-variant-numeric: tabular-nums;\n color: var(--rui-color-text-muted);\n}\n\n/* CalendarView -------------------------------------------------------- */\n.rui-calendar {\n display: flex;\n flex-direction: column;\n gap: 10px;\n width: 100%;\n}\n.rui-calendar-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 0 4px;\n}\n.rui-calendar-title {\n font-weight: 700;\n font-size: 15px;\n color: var(--rui-color-text);\n}\n.rui-calendar-weekrow {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 1px;\n padding: 0 1px;\n}\n.rui-calendar-weekday {\n padding: 6px 8px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--rui-color-text-muted);\n text-align: left;\n}\n.rui-calendar-grid {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 1px;\n background: var(--rui-color-border);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n overflow: hidden;\n}\n.rui-calendar[data-view=\"week\"] .rui-calendar-grid { grid-template-rows: minmax(120px, 1fr); }\n.rui-calendar-day {\n background: var(--rui-color-surface, var(--rui-color-bg));\n min-height: 88px;\n padding: 6px;\n text-align: left;\n display: flex;\n flex-direction: column;\n gap: 4px;\n font: inherit;\n cursor: pointer;\n border: 0;\n color: inherit;\n transition: background 120ms ease;\n}\n.rui-calendar-day:hover {\n background: color-mix(in srgb, var(--rui-color-primary) 6%, var(--rui-color-surface, var(--rui-color-bg)));\n}\n.rui-calendar-day[data-in-month=\"false\"] {\n color: var(--rui-color-text-muted);\n background: color-mix(in srgb, var(--rui-color-text) 2%, var(--rui-color-surface, var(--rui-color-bg)));\n}\n.rui-calendar-day[data-today=\"true\"] { box-shadow: inset 0 0 0 2px var(--rui-color-primary); }\n.rui-calendar-day[data-selected=\"true\"] {\n background: color-mix(in srgb, var(--rui-color-primary) 18%, var(--rui-color-surface, var(--rui-color-bg)));\n}\n.rui-calendar-daynumber {\n font-weight: 700;\n font-size: 13px;\n align-self: flex-start;\n}\n.rui-calendar-day-events {\n display: flex;\n flex-direction: column;\n gap: 2px;\n overflow: hidden;\n}\n.rui-calendar-event {\n display: block;\n font-size: 11px;\n padding: 2px 6px;\n border-radius: 4px;\n background: color-mix(in srgb, var(--rui-color-primary) 18%, transparent);\n color: var(--rui-color-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n text-align: left;\n}\n.rui-calendar-event[data-tone=\"success\"] { background: color-mix(in srgb, var(--rui-color-success, #10b981) 18%, transparent); color: var(--rui-color-success, #10b981); }\n.rui-calendar-event[data-tone=\"warning\"] { background: color-mix(in srgb, var(--rui-color-warning, #f59e0b) 18%, transparent); color: var(--rui-color-warning, #f59e0b); }\n.rui-calendar-event[data-tone=\"danger\"] { background: color-mix(in srgb, var(--rui-color-danger, #ef4444) 18%, transparent); color: var(--rui-color-danger, #ef4444); }\n.rui-calendar-event[data-tone=\"info\"] { background: color-mix(in srgb, var(--rui-color-info, #06b6d4) 18%, transparent); color: var(--rui-color-info, #06b6d4); }\n.rui-calendar-event-more { font-size: 11px; color: var(--rui-color-text-muted); padding: 0 2px; }\n\n/* ActivityLog / AuditTrail ------------------------------------------- */\n.rui-activity-log,\n.rui-audit-trail {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.rui-activity-log-item,\n.rui-audit-trail-item {\n display: grid;\n grid-template-columns: 32px 1fr;\n gap: 12px;\n align-items: flex-start;\n position: relative;\n}\n.rui-activity-log-item:not(:last-child)::before,\n.rui-audit-trail-item:not(:last-child)::before {\n content: \"\";\n position: absolute;\n left: 15px;\n top: 32px;\n bottom: -12px;\n width: 2px;\n background: var(--rui-color-border);\n}\n.rui-activity-log-marker,\n.rui-audit-trail-marker {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 5%, var(--rui-color-surface, #fff)));\n border: 1px solid var(--rui-color-border);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--rui-color-text-muted);\n position: relative;\n z-index: 1;\n}\n.rui-activity-log-item[data-tone=\"primary\"] .rui-activity-log-marker,\n.rui-audit-trail-item[data-tone=\"primary\"] .rui-audit-trail-marker { color: var(--rui-color-primary); border-color: color-mix(in srgb, var(--rui-color-primary) 35%, var(--rui-color-border)); }\n.rui-activity-log-item[data-tone=\"success\"] .rui-activity-log-marker,\n.rui-audit-trail-item[data-tone=\"success\"] .rui-audit-trail-marker { color: var(--rui-color-success, #10b981); border-color: color-mix(in srgb, var(--rui-color-success, #10b981) 35%, var(--rui-color-border)); }\n.rui-activity-log-item[data-tone=\"warning\"] .rui-activity-log-marker,\n.rui-audit-trail-item[data-tone=\"warning\"] .rui-audit-trail-marker { color: var(--rui-color-warning, #f59e0b); border-color: color-mix(in srgb, var(--rui-color-warning, #f59e0b) 35%, var(--rui-color-border)); }\n.rui-activity-log-item[data-tone=\"danger\"] .rui-activity-log-marker,\n.rui-audit-trail-item[data-tone=\"danger\"] .rui-audit-trail-marker { color: var(--rui-color-danger, #ef4444); border-color: color-mix(in srgb, var(--rui-color-danger, #ef4444) 35%, var(--rui-color-border)); }\n.rui-activity-log-body,\n.rui-audit-trail-body {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding-top: 4px;\n}\n.rui-activity-log-head,\n.rui-audit-trail-head {\n display: flex;\n gap: 6px;\n align-items: baseline;\n flex-wrap: wrap;\n}\n.rui-activity-log-actor,\n.rui-audit-trail-actor {\n font-weight: 600;\n color: var(--rui-color-text);\n}\n.rui-activity-log-title,\n.rui-audit-trail-title {\n color: var(--rui-color-text);\n}\n.rui-activity-log-time,\n.rui-audit-trail-time {\n color: var(--rui-color-text-muted);\n font-size: 12px;\n margin-left: auto;\n white-space: nowrap;\n}\n.rui-activity-log-description,\n.rui-audit-trail-description {\n font-size: 13px;\n color: var(--rui-color-text-muted);\n margin: 0;\n}\n.rui-audit-trail-meta {\n font-family: var(--rui-font-family-mono, ui-monospace, SFMono-Regular, monospace);\n font-size: 11.5px;\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 5%, var(--rui-color-surface, #fff)));\n padding: 3px 6px;\n border-radius: 4px;\n display: inline-block;\n color: var(--rui-color-text-muted);\n align-self: flex-start;\n}\n\n/* ComparisonTable ---------------------------------------------------- */\n.rui-comparison-table {\n width: 100%;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n overflow: hidden;\n background: var(--rui-color-surface, var(--rui-color-bg));\n}\n.rui-comparison-table table {\n width: 100%;\n border-collapse: separate;\n border-spacing: 0;\n font-size: 14px;\n}\n.rui-comparison-table th,\n.rui-comparison-table td {\n padding: 12px 14px;\n text-align: left;\n border-bottom: 1px solid var(--rui-color-border);\n vertical-align: middle;\n}\n.rui-comparison-table tr:last-child td { border-bottom: none; }\n.rui-comparison-table thead th {\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 4%, var(--rui-color-surface, #fff)));\n font-weight: 700;\n color: var(--rui-color-text);\n}\n.rui-comparison-table thead th[data-highlight=\"true\"] {\n background: color-mix(in srgb, var(--rui-color-primary) 14%, var(--rui-color-surface, #fff));\n color: var(--rui-color-primary);\n}\n.rui-comparison-table tbody td[data-highlight=\"true\"] {\n background: color-mix(in srgb, var(--rui-color-primary) 6%, var(--rui-color-surface, #fff));\n}\n.rui-comparison-table-feature {\n font-weight: 600;\n width: 36%;\n color: var(--rui-color-text);\n}\n.rui-comparison-table-feature-label { font-weight: 600; }\n.rui-comparison-table-feature-hint {\n display: block;\n font-size: 12px;\n color: var(--rui-color-text-muted);\n margin-top: 2px;\n font-weight: 400;\n}\n.rui-comparison-table-group td {\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 5%, var(--rui-color-surface, #fff)));\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-size: 12px;\n color: var(--rui-color-text-muted);\n}\n.rui-comparison-yes { color: var(--rui-color-success, #10b981); font-size: 18px; }\n.rui-comparison-no { color: var(--rui-color-text-muted); font-size: 18px; }\n\n/* InfiniteList ------------------------------------------------------- */\n.rui-infinite-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.rui-infinite-list-body {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.rui-infinite-list-sentinel {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 6px;\n padding: 16px;\n color: var(--rui-color-text-muted);\n font-size: 13px;\n}\n.rui-infinite-list-spin {\n animation: rui-spin 0.9s linear infinite;\n}\n@keyframes rui-spin { to { transform: rotate(360deg); } }\n.rui-infinite-list-load-more {\n background: var(--rui-color-surface, var(--rui-color-bg));\n border: 1px solid var(--rui-color-border);\n color: inherit;\n padding: 6px 14px;\n border-radius: 999px;\n cursor: pointer;\n font: inherit;\n font-size: 13px;\n}\n.rui-infinite-list-load-more:hover { border-color: var(--rui-color-primary); color: var(--rui-color-primary); }\n\n/* Media: Video / Audio ---------------------------------------------- */\n.rui-video-player {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 0;\n}\n.rui-video-player-frame {\n position: relative;\n width: 100%;\n border-radius: var(--rui-radius-md, 8px);\n overflow: hidden;\n background: #000;\n}\n.rui-video-player-video {\n display: block;\n width: 100%;\n height: 100%;\n outline: none;\n}\n.rui-video-player-caption {\n margin: 0;\n font-size: 13px;\n color: var(--rui-color-text-muted);\n}\n.rui-audio-player {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 12px 14px;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface, var(--rui-color-bg));\n}\n.rui-audio-player-meta {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n flex-shrink: 0;\n}\n.rui-audio-player-icon {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--rui-color-primary) 12%, transparent);\n color: var(--rui-color-primary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n}\n.rui-audio-player-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.rui-audio-player-title {\n font-weight: 600;\n font-size: 14px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.rui-audio-player-artist {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n}\n.rui-audio-player-audio {\n flex: 1;\n min-width: 0;\n height: 36px;\n}\n\n/* Carousel / Gallery / Lightbox ------------------------------------- */\n.rui-carousel {\n position: relative;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.rui-carousel-frame {\n position: relative;\n width: 100%;\n overflow: hidden;\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 5%, var(--rui-color-surface, #fff)));\n}\n.rui-carousel-track {\n display: flex;\n width: 100%;\n height: 100%;\n transition: transform 0.4s ease;\n will-change: transform;\n}\n.rui-carousel-slide {\n flex: 0 0 100%;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n position: relative;\n}\n.rui-carousel-slide img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n.rui-carousel-figure {\n margin: 0;\n width: 100%;\n height: 100%;\n position: relative;\n overflow: hidden;\n}\n.rui-carousel-figure img,\n.rui-carousel-image {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n.rui-carousel-caption {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n padding: 14px 18px;\n font-size: 14px;\n color: #fff;\n background: linear-gradient(180deg, transparent 0%, rgba(0,0,0,0.6) 100%);\n margin: 0;\n}\n.rui-carousel-arrow {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: 0;\n background: rgba(0, 0, 0, 0.55);\n color: #fff;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n z-index: 1;\n}\n.rui-carousel-arrow:hover { background: rgba(0, 0, 0, 0.75); }\n.rui-carousel-arrow[data-direction=\"prev\"] { left: 12px; }\n.rui-carousel-arrow[data-direction=\"next\"] { right: 12px; }\n.rui-carousel-dots {\n display: flex;\n justify-content: center;\n gap: 6px;\n}\n.rui-carousel-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--rui-color-border);\n border: 0;\n cursor: pointer;\n padding: 0;\n transition: background 120ms ease, transform 120ms ease;\n}\n.rui-carousel-dot[data-active=\"true\"] {\n background: var(--rui-color-primary);\n transform: scale(1.3);\n}\n\n.rui-gallery {\n display: grid;\n grid-template-columns: repeat(var(--rui-gallery-columns, 4), minmax(0, 1fr));\n gap: 8px;\n}\n.rui-gallery[data-columns=\"1\"] { --rui-gallery-columns: 1; }\n.rui-gallery[data-columns=\"2\"] { --rui-gallery-columns: 2; }\n.rui-gallery[data-columns=\"3\"] { --rui-gallery-columns: 3; }\n.rui-gallery[data-columns=\"4\"] { --rui-gallery-columns: 4; }\n.rui-gallery[data-columns=\"5\"] { --rui-gallery-columns: 5; }\n.rui-gallery[data-columns=\"6\"] { --rui-gallery-columns: 6; }\n@media (max-width: 720px) {\n .rui-gallery { grid-template-columns: repeat(min(var(--rui-gallery-columns, 3), 2), 1fr); }\n}\n.rui-gallery-tile {\n position: relative;\n overflow: hidden;\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 5%, var(--rui-color-surface, #fff)));\n border: 1px solid var(--rui-color-border);\n padding: 0;\n margin: 0;\n cursor: pointer;\n font: inherit;\n color: inherit;\n transition: transform 160ms ease, border-color 160ms ease;\n}\n.rui-gallery-tile:hover { transform: scale(1.02); border-color: var(--rui-color-primary); }\n.rui-gallery-tile img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n}\n.rui-gallery-placeholder {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 28px;\n color: var(--rui-color-text-muted);\n}\n.rui-gallery-caption {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));\n color: #fff;\n font-size: 12px;\n padding: 16px 10px 8px;\n text-align: left;\n pointer-events: none;\n}\n\n.rui-lightbox-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.85);\n z-index: 9999;\n display: none;\n align-items: center;\n justify-content: center;\n padding: 32px;\n backdrop-filter: blur(4px);\n}\n.rui-lightbox-overlay[data-open=\"true\"] { display: flex; }\n.rui-lightbox {\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n}\n.rui-lightbox-image-wrap {\n display: flex;\n align-items: center;\n justify-content: center;\n max-width: 90vw;\n max-height: 75vh;\n}\n.rui-lightbox-image-wrap img {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n border-radius: 6px;\n}\n.rui-lightbox-arrow,\n.rui-lightbox-close {\n position: absolute;\n background: rgba(255, 255, 255, 0.15);\n color: #fff;\n border: 0;\n border-radius: 50%;\n width: 44px;\n height: 44px;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n transition: background 120ms ease;\n}\n.rui-lightbox-arrow:hover,\n.rui-lightbox-close:hover { background: rgba(255, 255, 255, 0.3); }\n.rui-lightbox-arrow[data-direction=\"prev\"] { left: 24px; top: 50%; transform: translateY(-50%); }\n.rui-lightbox-arrow[data-direction=\"next\"] { right: 24px; top: 50%; transform: translateY(-50%); }\n.rui-lightbox-close { right: 24px; top: 24px; }\n.rui-lightbox-caption {\n color: #fff;\n text-align: center;\n font-size: 14px;\n}\n.rui-lightbox-counter {\n color: rgba(255, 255, 255, 0.7);\n font-size: 12px;\n font-variant-numeric: tabular-nums;\n}\n\n/* Map --------------------------------------------------------------- */\n.rui-map {\n display: flex;\n flex-direction: column;\n gap: 10px;\n margin: 0;\n}\n.rui-map-frame {\n width: 100%;\n border-radius: var(--rui-radius-md, 8px);\n overflow: hidden;\n border: 1px solid var(--rui-color-border);\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 5%, var(--rui-color-surface, #fff)));\n position: relative;\n}\n.rui-map-iframe {\n display: block;\n width: 100%;\n height: 100%;\n border: 0;\n}\n.rui-map-empty {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--rui-color-text-muted);\n font-size: 13px;\n}\n.rui-map-markers {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n.rui-map-marker {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border: 1px solid var(--rui-color-border);\n border-radius: 999px;\n background: var(--rui-color-surface, var(--rui-color-bg));\n font-size: 12px;\n}\n.rui-map-marker-icon { color: var(--rui-color-primary); }\n.rui-map-caption {\n margin: 0;\n font-size: 12.5px;\n color: var(--rui-color-text-muted);\n}\n\n/* Editors: RichTextEditor / CodeEditor ----------------------------- */\n.rui-rich-text {\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n overflow: hidden;\n background: var(--rui-color-surface, var(--rui-color-bg));\n display: flex;\n flex-direction: column;\n}\n.rui-rich-text[data-disabled=\"true\"] { opacity: 0.6; }\n.rui-rich-text-toolbar {\n display: flex;\n flex-wrap: wrap;\n gap: 2px;\n padding: 6px 8px;\n border-bottom: 1px solid var(--rui-color-border);\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 4%, var(--rui-color-surface, #fff)));\n}\n.rui-rich-text-tool {\n background: transparent;\n border: 0;\n border-radius: 4px;\n width: 30px;\n height: 30px;\n cursor: pointer;\n color: var(--rui-color-text-muted);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 13px;\n transition: background 120ms ease, color 120ms ease;\n}\n.rui-rich-text-tool:hover { background: color-mix(in srgb, var(--rui-color-text) 8%, transparent); color: var(--rui-color-text); }\n.rui-rich-text-content {\n padding: 14px 16px;\n outline: 0;\n font: inherit;\n color: inherit;\n overflow-y: auto;\n position: relative;\n}\n.rui-rich-text-content[data-empty=\"true\"]::before {\n content: attr(data-placeholder);\n color: var(--rui-color-text-muted);\n pointer-events: none;\n position: absolute;\n top: 14px;\n left: 16px;\n}\n.rui-rich-text-content > :first-child { margin-top: 0; }\n.rui-rich-text-content > :last-child { margin-bottom: 0; }\n.rui-rich-text-content :is(h1,h2,h3) { margin: 0.6em 0 0.4em; line-height: 1.25; }\n.rui-rich-text-content h2 { font-size: 18px; font-weight: 700; }\n.rui-rich-text-content h3 { font-size: 16px; font-weight: 700; }\n.rui-rich-text-content p { margin: 0 0 0.6em; line-height: 1.55; }\n.rui-rich-text-content blockquote {\n border-left: 3px solid var(--rui-color-border);\n margin: 0.5em 0;\n padding-left: 12px;\n color: var(--rui-color-text-muted);\n}\n.rui-rich-text-content :is(ul, ol) { padding-left: 20px; margin: 0 0 0.6em; }\n\n.rui-code-editor {\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n overflow: hidden;\n background: var(--rui-color-surface, var(--rui-color-bg));\n font-family: var(--rui-font-family-mono, ui-monospace, SFMono-Regular, monospace);\n font-size: 13px;\n display: flex;\n flex-direction: column;\n}\n.rui-code-editor-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 12px;\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 4%, var(--rui-color-surface, #fff)));\n border-bottom: 1px solid var(--rui-color-border);\n}\n.rui-code-editor-language {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--rui-color-text-muted);\n}\n.rui-code-editor-body {\n display: grid;\n grid-template-columns: auto 1fr;\n}\n.rui-code-editor[data-gutter=\"false\"] .rui-code-editor-body { grid-template-columns: 1fr; }\n.rui-code-editor-gutter {\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 3%, var(--rui-color-surface, #fff)));\n color: var(--rui-color-text-muted);\n padding: 12px 10px;\n text-align: right;\n user-select: none;\n border-right: 1px solid var(--rui-color-border);\n line-height: 1.6;\n font-size: 12px;\n display: flex;\n flex-direction: column;\n}\n.rui-code-editor-line { display: block; min-width: 24px; }\n.rui-code-editor-textarea {\n padding: 12px 14px;\n border: 0;\n outline: 0;\n resize: vertical;\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1.6;\n white-space: pre;\n overflow-x: auto;\n}\n\n/* ContextMenu / ColorPicker / PinInput etc ------------------------ */\n.rui-context-menu {\n position: relative;\n display: inline-block;\n width: 100%;\n}\n.rui-context-menu-target {\n display: block;\n width: 100%;\n}\n.rui-context-menu-pop {\n position: absolute;\n z-index: 50;\n min-width: 200px;\n background: var(--rui-color-surface, var(--rui-color-bg));\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n box-shadow: var(--rui-shadow-md, 0 12px 32px rgba(0, 0, 0, 0.18));\n padding: 4px;\n display: none;\n flex-direction: column;\n gap: 1px;\n}\n.rui-context-menu-pop[data-open=\"true\"] { display: flex; }\n.rui-context-menu-pop .rui-menu-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 10px;\n border-radius: 6px;\n background: transparent;\n border: 0;\n color: inherit;\n font: inherit;\n cursor: pointer;\n text-align: left;\n width: 100%;\n}\n.rui-context-menu-pop .rui-menu-item:hover { background: color-mix(in srgb, var(--rui-color-text) 6%, transparent); }\n.rui-context-menu-pop .rui-menu-item[data-variant=\"danger\"] { color: var(--rui-color-danger, #ef4444); }\n.rui-context-menu-pop .rui-menu-item[disabled] { opacity: 0.5; cursor: not-allowed; }\n.rui-context-menu-pop .rui-menu-item-icon { color: var(--rui-color-text-muted); width: 16px; text-align: center; }\n.rui-context-menu-pop .rui-menu-item-shortcut {\n margin-left: auto;\n font-size: 11px;\n color: var(--rui-color-text-muted);\n font-family: var(--rui-font-family-mono, monospace);\n}\n.rui-context-menu-pop .rui-menu-separator {\n height: 1px;\n background: var(--rui-color-border);\n margin: 4px 0;\n}\n\n.rui-color-picker {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.rui-color-picker[data-disabled=\"true\"] { opacity: 0.6; }\n.rui-color-picker-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--rui-color-text);\n}\n.rui-color-picker-row {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.rui-color-picker-color {\n width: 40px;\n height: 36px;\n border: 1px solid var(--rui-color-border);\n border-radius: 8px;\n padding: 2px;\n cursor: pointer;\n background: var(--rui-color-surface, var(--rui-color-bg));\n}\n.rui-color-picker-hex {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n font-family: var(--rui-font-family-mono, monospace);\n font-size: 13px;\n background: var(--rui-color-surface, var(--rui-color-bg));\n color: inherit;\n}\n.rui-color-picker-hex:focus { outline: none; border-color: var(--rui-color-primary); }\n.rui-color-picker-swatches {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n.rui-color-picker-swatch {\n width: 24px;\n height: 24px;\n border-radius: 50%;\n border: 2px solid var(--rui-color-border);\n cursor: pointer;\n padding: 0;\n transition: transform 120ms ease, border-color 120ms ease;\n}\n.rui-color-picker-swatch:hover { transform: scale(1.1); }\n.rui-color-picker-swatch[data-active=\"true\"] { border-color: var(--rui-color-text); transform: scale(1.15); }\n\n.rui-pin-input {\n display: inline-flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n.rui-pin-input[data-disabled=\"true\"] { opacity: 0.6; }\n.rui-pin-input-slot {\n width: 44px;\n height: 52px;\n text-align: center;\n font-size: 20px;\n font-weight: 600;\n font-family: var(--rui-font-family-mono, monospace);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface, var(--rui-color-bg));\n color: inherit;\n outline: none;\n transition: border-color 120ms ease, box-shadow 120ms ease;\n}\n.rui-pin-input-slot:focus {\n border-color: var(--rui-color-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--rui-color-primary) 22%, transparent);\n}\n\n.rui-password-input {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.rui-password-input[data-disabled=\"true\"] { opacity: 0.6; }\n.rui-password-input-row {\n position: relative;\n}\n.rui-password-input-field {\n width: 100%;\n padding: 8px 40px 8px 12px;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface, var(--rui-color-bg));\n color: inherit;\n font: inherit;\n font-size: 14px;\n outline: none;\n}\n.rui-password-input-field:focus { border-color: var(--rui-color-primary); }\n.rui-password-input-toggle {\n position: absolute;\n right: 6px;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: 0;\n cursor: pointer;\n color: var(--rui-color-text-muted);\n width: 30px;\n height: 30px;\n border-radius: 6px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n.rui-password-input-toggle:hover { color: var(--rui-color-text); }\n.rui-password-input-strength-row {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.rui-password-input-strength {\n display: flex;\n gap: 4px;\n flex: 1;\n}\n.rui-password-input-strength-bar {\n flex: 1;\n height: 4px;\n background: var(--rui-color-border);\n border-radius: 2px;\n}\n.rui-password-input-strength[data-score=\"1\"] .rui-password-input-strength-bar[data-filled=\"true\"] { background: var(--rui-color-danger, #ef4444); }\n.rui-password-input-strength[data-score=\"2\"] .rui-password-input-strength-bar[data-filled=\"true\"] { background: var(--rui-color-warning, #f59e0b); }\n.rui-password-input-strength[data-score=\"3\"] .rui-password-input-strength-bar[data-filled=\"true\"] { background: color-mix(in srgb, var(--rui-color-success, #10b981) 70%, var(--rui-color-warning, #f59e0b)); }\n.rui-password-input-strength[data-score=\"4\"] .rui-password-input-strength-bar[data-filled=\"true\"] { background: var(--rui-color-success, #10b981); }\n.rui-password-input-strength-label {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n min-width: 60px;\n text-align: right;\n}\n\n.rui-tag-input {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px;\n padding: 6px 8px;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface, var(--rui-color-bg));\n min-height: 40px;\n}\n.rui-tag-input[data-disabled=\"true\"] { opacity: 0.6; }\n.rui-tag-input:focus-within { border-color: var(--rui-color-primary); }\n.rui-tag-input-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: color-mix(in srgb, var(--rui-color-primary) 12%, transparent);\n color: var(--rui-color-primary);\n padding: 3px 4px 3px 10px;\n border-radius: 999px;\n font-size: 13px;\n font-weight: 500;\n}\n.rui-tag-input-remove {\n border: 0;\n background: transparent;\n cursor: pointer;\n color: inherit;\n font-size: 14px;\n padding: 0;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n.rui-tag-input-remove:hover { background: color-mix(in srgb, currentColor 20%, transparent); }\n.rui-tag-input-field {\n flex: 1;\n min-width: 100px;\n border: 0;\n outline: 0;\n font: inherit;\n background: transparent;\n color: inherit;\n padding: 4px 6px;\n}\n\n.rui-mention-input {\n position: relative;\n display: flex;\n flex-direction: column;\n}\n.rui-mention-input[data-disabled=\"true\"] { opacity: 0.6; }\n.rui-mention-input-field {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface, var(--rui-color-bg));\n color: inherit;\n font: inherit;\n font-size: 14px;\n resize: vertical;\n outline: none;\n}\n.rui-mention-input-field:focus { border-color: var(--rui-color-primary); }\n.rui-mention-input-suggestions {\n position: absolute;\n z-index: 50;\n left: 0;\n right: 0;\n top: 100%;\n margin-top: 4px;\n min-width: 220px;\n background: var(--rui-color-surface, var(--rui-color-bg));\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n box-shadow: var(--rui-shadow-md, 0 12px 32px rgba(0, 0, 0, 0.18));\n padding: 4px;\n display: none;\n flex-direction: column;\n gap: 1px;\n max-height: 220px;\n overflow: auto;\n}\n.rui-mention-input-suggestions[data-open=\"true\"] { display: flex; }\n.rui-mention-input-option {\n background: transparent;\n border: 0;\n text-align: left;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n color: inherit;\n font: inherit;\n font-size: 13px;\n}\n.rui-mention-input-option:hover { background: color-mix(in srgb, var(--rui-color-text) 6%, transparent); }\n\n/* Time / DateTime / Masked input ---------------------------------- */\n.rui-time-picker,\n.rui-datetime-picker {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.rui-time-picker-label,\n.rui-datetime-picker-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--rui-color-text);\n}\n.rui-time-picker-input,\n.rui-datetime-picker-input,\n.rui-masked-input {\n width: 100%;\n padding: 8px 12px;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface, var(--rui-color-bg));\n color: inherit;\n font: inherit;\n font-size: 14px;\n outline: none;\n}\n.rui-time-picker-input:focus,\n.rui-datetime-picker-input:focus,\n.rui-masked-input:focus { border-color: var(--rui-color-primary); }\n\n/* FormSection / FieldSet / ValidationSummary --------------------- */\n.rui-form-section {\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.rui-form-section-header {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.rui-form-section-label {\n font-weight: 700;\n font-size: 15px;\n margin: 0;\n color: var(--rui-color-text);\n}\n.rui-form-section-helper {\n font-size: 13px;\n color: var(--rui-color-text-muted);\n margin: 0;\n}\n.rui-form-section-body {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n.rui-fieldset {\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n padding: 12px 16px 16px;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 12px;\n background: var(--rui-color-surface, var(--rui-color-bg));\n}\n.rui-fieldset-legend {\n font-weight: 700;\n padding: 0 6px;\n font-size: 13px;\n color: var(--rui-color-text);\n}\n.rui-fieldset-helper {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n margin: 0;\n}\n.rui-validation-summary {\n padding: 14px 16px;\n border: 1px solid color-mix(in srgb, var(--rui-color-danger, #ef4444) 30%, var(--rui-color-border));\n border-radius: var(--rui-radius-md, 8px);\n background: color-mix(in srgb, var(--rui-color-danger, #ef4444) 8%, var(--rui-color-surface, var(--rui-color-bg)));\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.rui-validation-summary[data-tone=\"warning\"] {\n border-color: color-mix(in srgb, var(--rui-color-warning, #f59e0b) 30%, var(--rui-color-border));\n background: color-mix(in srgb, var(--rui-color-warning, #f59e0b) 8%, var(--rui-color-surface, var(--rui-color-bg)));\n}\n.rui-validation-summary-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 700;\n font-size: 14px;\n color: var(--rui-color-danger, #ef4444);\n}\n.rui-validation-summary[data-tone=\"warning\"] .rui-validation-summary-title { color: var(--rui-color-warning, #f59e0b); }\n.rui-validation-summary-icon { font-size: 16px; }\n.rui-validation-summary-list {\n margin: 0;\n padding-left: 22px;\n color: var(--rui-color-text);\n font-size: 13.5px;\n display: flex;\n flex-direction: column;\n gap: 3px;\n}\n\n/* MultiStepForm ------------------------------------------------ */\n.rui-multi-step-form {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n.rui-multi-step-form-steps {\n display: flex;\n gap: 0;\n list-style: none;\n margin: 0;\n padding: 0;\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 3%, var(--rui-color-surface, #fff)));\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n overflow: hidden;\n}\n.rui-multi-step-form-steps .rui-steps-item {\n flex: 1;\n padding: 12px 16px 12px 52px;\n border-right: 1px solid var(--rui-color-border);\n position: relative;\n color: var(--rui-color-text-muted);\n font-size: 13px;\n}\n.rui-multi-step-form-steps .rui-steps-item:last-child { border-right: none; }\n.rui-multi-step-form-steps .rui-steps-item::before {\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--rui-color-text) 12%, transparent);\n color: var(--rui-color-text-muted);\n}\n.rui-multi-step-form-steps .rui-steps-item[data-active=\"true\"]::before {\n background: var(--rui-color-primary);\n color: var(--rui-color-primary-text, #fff);\n}\n.rui-multi-step-form-steps .rui-steps-item[data-complete=\"true\"]::before {\n background: var(--rui-color-success, #10b981);\n color: #fff;\n}\n.rui-multi-step-form-steps .rui-steps-item .rui-steps-title {\n font-weight: 700;\n color: inherit;\n margin: 0;\n line-height: 1.2;\n}\n.rui-multi-step-form-steps .rui-steps-item .rui-steps-details {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n margin-top: 2px;\n}\n.rui-multi-step-form-steps .rui-steps-item[data-active=\"true\"] {\n background: var(--rui-color-surface, var(--rui-color-bg));\n color: var(--rui-color-primary);\n}\n.rui-multi-step-form-steps .rui-steps-item[data-complete=\"true\"] {\n color: var(--rui-color-success, #10b981);\n}\n.rui-multi-step-form-steps .rui-steps-item[data-complete=\"true\"] .rui-steps-title::before {\n content: \"✓ \";\n margin-right: 2px;\n}\n.rui-multi-step-form-body {\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.rui-multi-step-form-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n padding-top: 8px;\n border-top: 1px solid var(--rui-color-border);\n}\n.rui-multi-step-form-progress {\n color: var(--rui-color-text-muted);\n font-size: 13px;\n font-variant-numeric: tabular-nums;\n}\n\n/* Advanced charts (Area/Gauge/Heatmap/Radar/Scatter/Histogram) -- */\n.rui-chart { display: flex; flex-direction: column; gap: 10px; width: 100%; }\n.rui-chart-title { font-size: 13px; font-weight: 600; color: var(--rui-color-text); }\n.rui-chart-svg { display: block; width: 100%; height: auto; }\n.rui-chart-label { font-size: 11px; fill: var(--rui-color-text-muted, #64748b); }\n.rui-chart-tick { font-size: 10.5px; fill: var(--rui-color-text-muted, #64748b); }\n.rui-chart-empty {\n padding: 24px;\n text-align: center;\n color: var(--rui-color-text-muted);\n font-size: 13px;\n}\n.rui-chart-legend {\n display: flex;\n gap: 14px;\n flex-wrap: wrap;\n font-size: 12.5px;\n color: var(--rui-color-text-muted);\n}\n.rui-chart-legend-item {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.rui-chart-legend-swatch {\n width: 10px;\n height: 10px;\n border-radius: 2px;\n display: inline-block;\n}\n\n.rui-area-chart,\n.rui-radar-chart,\n.rui-scatter-chart,\n.rui-histogram { width: 100%; }\n\n.rui-gauge {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: column;\n gap: 4px;\n}\n.rui-gauge[data-size=\"sm\"] svg { max-width: 140px; }\n.rui-gauge[data-size=\"md\"] svg { max-width: 180px; }\n.rui-gauge[data-size=\"lg\"] svg { max-width: 220px; }\n.rui-gauge-arc {\n transition: stroke-dasharray 400ms ease;\n}\n.rui-gauge-value {\n font-size: 22px;\n font-weight: 700;\n color: var(--rui-color-text);\n margin-top: -6px;\n}\n.rui-gauge[data-tone=\"primary\"] .rui-gauge-value { color: var(--rui-color-primary); }\n.rui-gauge[data-tone=\"success\"] .rui-gauge-value { color: var(--rui-color-success, #10b981); }\n.rui-gauge[data-tone=\"warning\"] .rui-gauge-value { color: var(--rui-color-warning, #f59e0b); }\n.rui-gauge[data-tone=\"danger\"] .rui-gauge-value { color: var(--rui-color-danger, #ef4444); }\n.rui-gauge[data-tone=\"info\"] .rui-gauge-value { color: var(--rui-color-info, #06b6d4); }\n.rui-gauge-caption {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n}\n\n.rui-heatmap { display: flex; flex-direction: column; gap: 8px; width: 100%; }\n.rui-heatmap-table {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.rui-heatmap-row {\n display: grid;\n grid-template-columns: 56px repeat(var(--rui-heatmap-cols, 7), minmax(0, 1fr));\n gap: 4px;\n}\n.rui-heatmap-row-header { font-size: 11px; color: var(--rui-color-text-muted); }\n.rui-heatmap-cell {\n padding: 8px 6px;\n border-radius: 4px;\n text-align: center;\n font-size: 12px;\n font-weight: 600;\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 3%, var(--rui-color-surface, #fff)));\n color: var(--rui-color-text);\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.rui-heatmap-xlabel,\n.rui-heatmap-ylabel {\n background: transparent;\n color: var(--rui-color-text-muted);\n font-weight: 500;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n.rui-heatmap-ylabel { justify-content: flex-start; padding-left: 0; }\n.rui-heatmap-corner { background: transparent; }\n\n/* Patterns: state cards, tour/spotlight, inbox, onboarding ----- */\n.rui-loading-state,\n.rui-error-state,\n.rui-success-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n gap: 12px;\n padding: 40px 24px;\n background: var(--rui-color-surface, var(--rui-color-bg));\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n}\n.rui-loading-state .rui-spinner { font-size: 32px; }\n.rui-error-state-icon { color: var(--rui-color-danger, #ef4444); font-size: 36px; }\n.rui-success-state-icon { color: var(--rui-color-success, #10b981); font-size: 36px; }\n.rui-loading-state-title,\n.rui-error-state-title,\n.rui-success-state-title { font-size: 18px; font-weight: 700; margin: 0; color: var(--rui-color-text); }\n.rui-loading-state-description,\n.rui-error-state-description,\n.rui-success-state-description { color: var(--rui-color-text-muted); margin: 0; max-width: 36em; line-height: 1.55; }\n.rui-loading-state-actions,\n.rui-error-state-actions,\n.rui-success-state-actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }\n\n.rui-onboarding-checklist {\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.rui-onboarding-checklist-header {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.rui-onboarding-checklist-title {\n font-size: 15px;\n font-weight: 700;\n margin: 0;\n color: var(--rui-color-text);\n}\n.rui-onboarding-checklist-subtitle {\n margin: 0;\n font-size: 13px;\n color: var(--rui-color-text-muted);\n}\n.rui-onboarding-checklist-progress {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-top: 4px;\n}\n.rui-onboarding-checklist-bar {\n flex: 1;\n height: 6px;\n background: var(--rui-color-border);\n border-radius: 999px;\n overflow: hidden;\n}\n.rui-onboarding-checklist-fill {\n height: 100%;\n background: var(--rui-color-primary);\n transition: width 240ms ease;\n}\n.rui-onboarding-checklist-meta {\n font-size: 12px;\n color: var(--rui-color-text-muted);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n}\n.rui-onboarding-checklist-list {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.rui-onboarding-checklist-item {\n display: grid;\n grid-template-columns: 28px 1fr auto;\n align-items: center;\n gap: 12px;\n padding: 12px 14px;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n background: var(--rui-color-surface, var(--rui-color-bg));\n transition: border-color 120ms ease;\n}\n.rui-onboarding-checklist-item:hover { border-color: color-mix(in srgb, var(--rui-color-primary) 30%, var(--rui-color-border)); }\n.rui-onboarding-checklist-item[data-done=\"true\"] .rui-onboarding-checklist-item-title {\n text-decoration: line-through;\n color: var(--rui-color-text-muted);\n}\n.rui-onboarding-checklist-marker {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 5%, var(--rui-color-surface, #fff)));\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--rui-color-text-muted);\n font-size: 14px;\n}\n.rui-onboarding-checklist-item[data-done=\"true\"] .rui-onboarding-checklist-marker {\n background: var(--rui-color-success, #10b981);\n color: #fff;\n}\n.rui-onboarding-checklist-marker-icon { font-size: 14px; }\n.rui-onboarding-checklist-body {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n.rui-onboarding-checklist-item-title { font-weight: 600; font-size: 14px; color: var(--rui-color-text); }\n.rui-onboarding-checklist-item-description { font-size: 12.5px; color: var(--rui-color-text-muted); margin: 0; }\n\n.rui-inbox-panel {\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.rui-inbox-panel-toolbar {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n}\n.rui-inbox-panel-mark-all {\n background: transparent;\n border: 0;\n cursor: pointer;\n color: var(--rui-color-primary);\n font: inherit;\n font-size: 13px;\n padding: 0;\n}\n.rui-inbox-panel-mark-all:hover { text-decoration: underline; }\n.rui-inbox-panel-empty {\n padding: 28px;\n text-align: center;\n color: var(--rui-color-text-muted);\n font-size: 13px;\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 3%, var(--rui-color-surface, #fff)));\n border-radius: var(--rui-radius-md, 8px);\n}\n.rui-inbox-panel-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.rui-inbox-panel-group-head {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--rui-color-text-muted);\n}\n.rui-inbox-panel-group-count {\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 5%, var(--rui-color-surface, #fff)));\n padding: 1px 8px;\n border-radius: 999px;\n font-variant-numeric: tabular-nums;\n}\n\n/* Tour overlay + Spotlight overlay -------------------------------- */\n.rui-tour {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.55);\n z-index: 9100;\n display: none;\n align-items: center;\n justify-content: center;\n padding: 24px;\n}\n.rui-tour[data-open=\"true\"] { display: flex; }\n.rui-tour-card {\n background: var(--rui-color-surface, var(--rui-color-bg));\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n padding: 24px;\n box-shadow: var(--rui-shadow-md, 0 16px 40px rgba(0, 0, 0, 0.28));\n display: flex;\n flex-direction: column;\n gap: 10px;\n max-width: 460px;\n width: 100%;\n}\n.rui-tour-step {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--rui-color-primary);\n}\n.rui-tour-title {\n font-size: 18px;\n font-weight: 700;\n margin: 0;\n color: var(--rui-color-text);\n}\n.rui-tour-description {\n font-size: 14px;\n color: var(--rui-color-text-muted);\n line-height: 1.55;\n margin: 0;\n}\n.rui-tour-target {\n font-family: var(--rui-font-family-mono, monospace);\n font-size: 12px;\n padding: 6px 10px;\n background: var(--rui-color-surface-muted, color-mix(in srgb, var(--rui-color-text) 4%, var(--rui-color-surface, #fff)));\n border-radius: 6px;\n color: var(--rui-color-text-muted);\n align-self: flex-start;\n}\n.rui-tour-footer {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n margin-top: 8px;\n padding-top: 12px;\n border-top: 1px solid var(--rui-color-border);\n}\n.rui-tour-footer > .rui-button:first-child { margin-right: auto; }\n\n.rui-spotlight {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 9000;\n display: none;\n align-items: center;\n justify-content: center;\n padding: 24px;\n}\n.rui-spotlight[data-open=\"true\"] { display: flex; }\n.rui-spotlight-card {\n background: var(--rui-color-surface, var(--rui-color-bg));\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n padding: 22px 24px;\n box-shadow: var(--rui-shadow-md, 0 16px 40px rgba(0, 0, 0, 0.28));\n display: flex;\n flex-direction: column;\n gap: 8px;\n max-width: 420px;\n width: 100%;\n}\n.rui-spotlight-title { font-size: 16px; font-weight: 700; margin: 0; color: var(--rui-color-text); }\n.rui-spotlight-description { font-size: 13.5px; color: var(--rui-color-text-muted); margin: 0; line-height: 1.55; }\n.rui-spotlight-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 6px; }\n\n/* Sticky / ResizablePanels / MasonryGrid / TopBar -------------- */\n.rui-sticky {\n background: var(--rui-color-surface, var(--rui-color-bg));\n}\n.rui-resizable-panels {\n display: grid;\n grid-template-columns: var(--rui-resizable-primary, 40%) 6px 1fr;\n gap: 0;\n min-height: 280px;\n width: 100%;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n overflow: hidden;\n background: var(--rui-color-surface, var(--rui-color-bg));\n}\n.rui-resizable-panel {\n overflow: auto;\n min-width: var(--rui-resizable-min, 240px);\n padding: 12px;\n}\n.rui-resizable-panel-secondary {\n border-left: 0;\n}\n.rui-resizable-divider {\n cursor: col-resize;\n background: var(--rui-color-border);\n width: 6px;\n position: relative;\n transition: background 120ms ease;\n}\n.rui-resizable-divider::after {\n content: \"\";\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 2px;\n height: 32px;\n border-radius: 2px;\n background: var(--rui-color-text-muted);\n opacity: 0.5;\n}\n.rui-resizable-divider:hover,\n.rui-resizable-divider:focus-visible { background: var(--rui-color-primary); outline: none; }\n\n.rui-masonry-grid {\n column-count: var(--rui-masonry-columns, 3);\n column-gap: 12px;\n}\n.rui-masonry-grid[data-columns=\"1\"] { --rui-masonry-columns: 1; }\n.rui-masonry-grid[data-columns=\"2\"] { --rui-masonry-columns: 2; }\n.rui-masonry-grid[data-columns=\"3\"] { --rui-masonry-columns: 3; }\n.rui-masonry-grid[data-columns=\"4\"] { --rui-masonry-columns: 4; }\n.rui-masonry-grid[data-columns=\"5\"] { --rui-masonry-columns: 5; }\n.rui-masonry-grid[data-columns=\"6\"] { --rui-masonry-columns: 6; }\n.rui-masonry-grid[data-gap=\"xs\"] { column-gap: 4px; }\n.rui-masonry-grid[data-gap=\"s\"] { column-gap: 8px; }\n.rui-masonry-grid[data-gap=\"m\"] { column-gap: 12px; }\n.rui-masonry-grid[data-gap=\"l\"] { column-gap: 16px; }\n.rui-masonry-grid[data-gap=\"xl\"] { column-gap: 24px; }\n.rui-masonry-grid > * {\n display: inline-block;\n width: 100%;\n break-inside: avoid;\n margin-bottom: 12px;\n}\n@media (max-width: 720px) {\n .rui-masonry-grid { column-count: min(var(--rui-masonry-columns, 3), 2); }\n}\n\n.rui-topbar {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 12px 16px;\n background: var(--rui-color-surface, var(--rui-color-bg));\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n flex-wrap: wrap;\n}\n.rui-topbar[data-sticky=\"true\"] { position: sticky; top: 0; z-index: 30; border-radius: 0; border-left: 0; border-right: 0; }\n.rui-topbar-side { display: flex; align-items: center; gap: 10px; min-width: 0; }\n.rui-topbar-title-block { display: flex; flex-direction: column; gap: 2px; }\n.rui-topbar-title { margin: 0; font-size: 16px; font-weight: 700; color: var(--rui-color-text); }\n.rui-topbar-subtitle { margin: 0; font-size: 12px; color: var(--rui-color-text-muted); }\n.rui-topbar-center { flex: 1; min-width: 200px; justify-content: center; }\n.rui-topbar-right { margin-left: auto; }\n\n/* AppShell collapsible / mobile drawer ------------------------ */\n.rui-app-shell-scrim {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.45);\n z-index: 40;\n display: none;\n}\n.rui-app-shell-toggle {\n background: transparent;\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md, 8px);\n padding: 4px 10px;\n cursor: pointer;\n color: inherit;\n display: none;\n align-items: center;\n justify-content: center;\n}\n@media (max-width: 720px) {\n .rui-app-shell[data-collapsible=\"true\"] .rui-app-shell-sidebar {\n position: fixed;\n inset: 0 auto 0 0;\n z-index: 50;\n transform: translateX(-100%);\n transition: transform 0.25s ease;\n }\n .rui-app-shell[data-collapsible=\"true\"][data-sidebar-open=\"true\"] .rui-app-shell-sidebar {\n transform: translateX(0);\n }\n .rui-app-shell[data-collapsible=\"true\"][data-sidebar-open=\"true\"] .rui-app-shell-scrim {\n display: block;\n }\n .rui-app-shell[data-collapsible=\"true\"] .rui-app-shell-toggle {\n display: inline-flex;\n }\n}\n\n/* Collapsed Sidebar (icon rail) ------------------------------ */\n.rui-sidebar[data-collapsed=\"true\"] { width: 64px; }\n.rui-sidebar[data-collapsed=\"true\"] .rui-sidebar-tagline,\n.rui-sidebar[data-collapsed=\"true\"] .rui-sidebar-section-label,\n.rui-sidebar[data-collapsed=\"true\"] .rui-sidebar-item-label,\n.rui-sidebar[data-collapsed=\"true\"] .rui-sidebar-item-badge { display: none; }\n.rui-sidebar[data-collapsed=\"true\"] .rui-sidebar-item { justify-content: center; }\n\n/* New components (Tier 1–3) ----------------------------------- */\n.rui-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: var(--rui-border-width) solid transparent;\n border-radius: var(--rui-radius-button);\n background: transparent;\n color: var(--rui-color-text);\n cursor: pointer;\n padding: 6px;\n}\n.rui-icon-button:hover:not(:disabled) { background: var(--rui-color-surface-muted); }\n.rui-icon-button:disabled { opacity: 0.5; cursor: not-allowed; }\n.rui-icon-button[data-variant=\"primary\"] { background: var(--rui-color-primary); color: var(--rui-color-primary-text); }\n.rui-icon-button[data-size=\"sm\"] { padding: 4px; }\n.rui-icon-button[data-size=\"lg\"] { padding: 10px; }\n\n.rui-command-palette[data-open=\"false\"] { display: none; }\n.rui-command-palette-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.45);\n z-index: 80;\n}\n.rui-command-palette-panel {\n position: fixed;\n top: 12%;\n left: 50%;\n transform: translateX(-50%);\n width: min(560px, calc(100vw - 32px));\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n box-shadow: var(--rui-shadow-md);\n z-index: 81;\n overflow: hidden;\n}\n.rui-command-palette-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n border-bottom: 1px solid var(--rui-color-border);\n}\n.rui-command-palette-input { flex: 1; border: 0; background: transparent; font: inherit; outline: none; }\n.rui-command-palette-shortcut { font-size: 12px; color: var(--rui-color-text-muted); }\n.rui-command-palette-list { max-height: 320px; overflow: auto; padding: 6px; }\n.rui-command-palette-group {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--rui-color-text-muted);\n padding: 8px 8px 4px;\n}\n.rui-command-palette-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n border: 0;\n background: transparent;\n border-radius: var(--rui-radius-sm);\n padding: 8px 10px;\n text-align: left;\n cursor: pointer;\n color: inherit;\n font: inherit;\n}\n.rui-command-palette-item:hover { background: var(--rui-color-surface-muted); }\n.rui-command-palette-item-kbd { font-size: 11px; color: var(--rui-color-text-muted); }\n.rui-command-palette-empty { padding: 16px; text-align: center; color: var(--rui-color-text-muted); }\n\n.rui-filter-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }\n.rui-filter-chips-row { display: flex; flex-wrap: wrap; gap: 6px; }\n.rui-filter-chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--rui-color-primary) 12%, transparent);\n border: 1px solid var(--rui-color-border);\n font-size: 13px;\n}\n.rui-filter-chip-remove {\n border: 0;\n background: transparent;\n cursor: pointer;\n padding: 0 2px;\n color: var(--rui-color-text-muted);\n}\n.rui-filter-chips-clear {\n border: 0;\n background: transparent;\n color: var(--rui-color-primary);\n cursor: pointer;\n font-size: 13px;\n}\n\n.rui-field-repeater { display: flex; flex-direction: column; gap: 12px; }\n.rui-field-repeater-row {\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n padding: 12px;\n background: var(--rui-color-surface);\n}\n.rui-field-repeater-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 10px;\n}\n.rui-field-repeater-label { display: block; font-size: 12px; color: var(--rui-color-text-muted); margin-bottom: 4px; }\n.rui-field-repeater-remove { margin-top: 8px; }\n\n.rui-virtual-list-scroller { position: relative; overflow: auto; border: 1px solid var(--rui-color-border); border-radius: var(--rui-radius-md); }\n.rui-virtual-list-item {\n display: flex;\n align-items: center;\n padding: 0 12px;\n border-bottom: 1px solid var(--rui-color-border);\n box-sizing: border-box;\n}\n\n.rui-query-builder { display: flex; flex-direction: column; gap: 8px; }\n.rui-query-builder-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }\n.rui-query-builder-remove,\n.rui-query-builder-add {\n border: 1px solid var(--rui-color-border);\n background: var(--rui-color-surface);\n border-radius: var(--rui-radius-sm);\n padding: 6px 10px;\n cursor: pointer;\n}\n\n.rui-diff-viewer { border: 1px solid var(--rui-color-border); border-radius: var(--rui-radius-md); overflow: hidden; font-family: var(--rui-font-family-mono, monospace); font-size: 12px; }\n.rui-diff-viewer-panes { display: grid; grid-template-columns: 1fr 1fr; }\n.rui-diff-viewer-pane { margin: 0; padding: 12px; overflow: auto; max-height: 320px; }\n.rui-diff-viewer-left { border-right: 1px solid var(--rui-color-border); background: color-mix(in srgb, var(--rui-color-danger) 6%, var(--rui-color-surface)); }\n.rui-diff-viewer-right { background: color-mix(in srgb, var(--rui-color-success) 6%, var(--rui-color-surface)); }\n.rui-diff-viewer-unified { margin: 0; padding: 12px; max-height: 320px; overflow: auto; }\n.rui-diff-line-add { background: color-mix(in srgb, var(--rui-color-success) 12%, transparent); }\n.rui-diff-line-remove { background: color-mix(in srgb, var(--rui-color-danger) 12%, transparent); }\n\n.rui-json-tree { font-family: var(--rui-font-family-mono, monospace); font-size: 12px; }\n.rui-json-tree-toggle {\n border: 0;\n background: transparent;\n cursor: pointer;\n font: inherit;\n color: var(--rui-color-text);\n padding: 2px 0;\n}\n.rui-json-tree-children[data-open=\"false\"] { display: none; }\n.rui-json-tree-row { padding-left: 12px; }\n.rui-json-tree-key { color: var(--rui-color-primary); }\n.rui-json-tree-leaf { color: var(--rui-color-text-muted); }\n\n.rui-gantt { border: 1px solid var(--rui-color-border); border-radius: var(--rui-radius-md); overflow: hidden; }\n.rui-gantt-row { display: grid; grid-template-columns: 140px 1fr; gap: 8px; align-items: center; padding: 8px 12px; border-bottom: 1px solid var(--rui-color-border); }\n.rui-gantt-label { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.rui-gantt-bars { position: relative; height: 24px; background: var(--rui-color-surface-muted); border-radius: var(--rui-radius-sm); }\n.rui-gantt-bar {\n position: absolute;\n top: 4px;\n height: 16px;\n border-radius: var(--rui-radius-sm);\n background: var(--rui-color-primary);\n overflow: hidden;\n}\n.rui-gantt-bar-progress { height: 100%; background: color-mix(in srgb, #000 25%, var(--rui-color-primary)); }\n\n.rui-truncate-text { margin: 0; }\n.rui-truncate-toggle {\n border: 0;\n background: transparent;\n color: var(--rui-color-primary);\n cursor: pointer;\n padding: 4px 0;\n font-size: 13px;\n}\n\n.rui-inline-edit { display: inline-flex; flex-direction: column; gap: 4px; }\n.rui-inline-edit-display {\n border: 1px dashed var(--rui-color-border);\n background: transparent;\n border-radius: var(--rui-radius-sm);\n padding: 4px 8px;\n cursor: text;\n font: inherit;\n color: inherit;\n text-align: left;\n}\n.rui-inline-edit-input { display: none; }\n.rui-inline-edit[data-editing=\"true\"] .rui-inline-edit-display { display: none; }\n.rui-inline-edit[data-editing=\"true\"] .rui-inline-edit-input { display: block; }\n\n.rui-notification-bell { position: relative; display: inline-block; width: 30px; }\n.rui-notification-bell-trigger {\n position: relative;\n border: 0;\n background: transparent;\n cursor: pointer;\n padding: 6px;\n color: inherit;\n}\n.rui-notification-bell-badge {\n position: absolute;\n top: 0;\n right: 0;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 999px;\n background: var(--rui-color-danger);\n color: #fff;\n font-size: 10px;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.rui-notification-bell-panel {\n display: none;\n position: absolute;\n top: calc(100% + 6px);\n right: 0;\n width: min(320px, 80vw);\n background: var(--rui-color-surface);\n border: 1px solid var(--rui-color-border);\n border-radius: var(--rui-radius-md);\n box-shadow: var(--rui-shadow-md);\n z-index: 40;\n max-height: 360px;\n overflow: auto;\n}\n.rui-notification-bell[data-open=\"true\"] .rui-notification-bell-panel { display: block; }\n.rui-notification-bell-item {\n padding: 10px 12px;\n border-bottom: 1px solid var(--rui-color-border);\n}\n.rui-notification-bell-item-title { font-weight: 600; font-size: 13px; }\n.rui-notification-bell-item-message,\n.rui-notification-bell-item-time { font-size: 12px; color: var(--rui-color-text-muted); }\n.rui-notification-bell-empty { padding: 16px; text-align: center; color: var(--rui-color-text-muted); }\n.rui-select-searchable { width: 100%; }\n\n/* Lightbox thumbnail ------------------------------------------------- */\n.rui-lightbox-thumb {\n display: inline-block;\n padding: 0;\n border: 1px solid var(--rui-color-border);\n background: var(--rui-color-surface);\n border-radius: var(--rui-radius-md, 8px);\n overflow: hidden;\n cursor: zoom-in;\n max-width: 240px;\n}\n.rui-lightbox-thumb img { display: block; width: 100%; height: auto; }\n.rui-lightbox-thumb:hover { border-color: var(--rui-color-primary); }\n`;\n","/**\n * `<aktion-app>` custom element.\n *\n * Public surface:\n * - Attributes:\n * `theme` — \"light\" | \"dark\" | JSON token map\n * `streaming` — \"true\" while text is still arriving from the LLM\n * `response` — Aktion program (string)\n * `showerrors` — \"true\" to render parse errors in the UI\n * (defaults to off; the `error` event still fires)\n * - Properties:\n * `response: string` — current Aktion text\n * `streaming: boolean` — reflects the `streaming` attribute\n * `showErrors: boolean` — reflects the `showerrors` attribute\n * - Methods:\n * `setResponse(text)` — replace the current program\n * `appendChunk(text)` — append a streaming chunk and re-render\n * `setTheme(theme)` — apply a theme by name or token map\n * `registerComponents(...)` — extend the built-in library\n * `registerHttpInterceptors(...)` — install `onRequest`/`onResponse`/`onError`\n * hooks for the Aktion HTTP layer\n * `getSystemPrompt(opts)` — build a system prompt for the current library\n * `clear()` — reset state and clear the rendered output\n *\n * Events:\n * - `assistant-message` — fired when an action handler calls\n * `helpers.sendToAssistant(\"...\")`. `event.detail.message` carries the text.\n * - `error` — fired with `event.detail.errors` for parse failures.\n * - `route-change` — fired when the active hash route changes.\n * - Custom events emitted via `emit \"name\" { detail }` inside\n * `effect` / `action` bodies dispatch with the provided name and detail.\n */\n\nimport { parse } from \"./parser/index.js\";\nimport { applyDelta, type DeltaOp } from \"./tooling/index.js\";\nimport {\n StateStore,\n Router,\n createContext,\n createLocalStorageAdapter,\n planProgram,\n isThemeNode,\n type RouteChangeDetail,\n} from \"./runtime/index.js\";\nimport { HttpRuntime } from \"./runtime/http.js\";\nimport { I18nRuntime } from \"./runtime/i18n.js\";\nimport { EffectRunner, ActionDeclRunner, createInlineJsExecutor } from \"./runtime/effects.js\";\nimport type { EvaluationContext } from \"./runtime/evaluator.js\";\nimport type { ComponentLibrary, ComponentSpec } from \"./library/types.js\";\nimport { defaultLibrary, validateProgramSchema } from \"./library/index.js\";\nimport { mergeLibraries } from \"./library/registry.js\";\nimport { Renderer } from \"./renderer/renderer.js\";\nimport { morphChildren } from \"./renderer/morph.js\";\nimport {\n generatePrompt,\n type PromptOptions,\n} from \"./prompt/generator.js\";\nimport {\n applyTheme,\n applyPartialTheme,\n clearTokenOverrides,\n resolveTheme,\n sanitiseThemeTokens,\n type ThemeInput,\n type ThemeTokens,\n} from \"./theme/index.js\";\nimport { componentStyles } from \"./theme/styles.js\";\nimport { ensureFontAwesomeLoaded } from \"./icons/index.js\";\n\nconst ATTRIBUTE_THEME = \"theme\";\nconst ATTRIBUTE_STREAMING = \"streaming\";\nconst ATTRIBUTE_RESPONSE = \"response\";\nconst ATTRIBUTE_SHOW_ERRORS = \"showerrors\";\n\n// Re-exported from `runtime/http.ts` so consumers can import them from\n// `./element.js` (the legacy public surface) without reaching into the\n// runtime internals.\nimport type {\n HttpInterceptors,\n HttpRequest,\n HttpResponse,\n} from \"./runtime/http.js\";\nexport type { HttpInterceptors, HttpRequest, HttpResponse };\n/**\n * Internal state slot the router writes to so dependent renders can\n * subscribe to URL changes. Authors do NOT read this slot directly —\n * use the `_route_` identifier instead, which is bound to the same\n * underlying state and additionally exposes `navigate(path)`.\n */\nconst STATE_ROUTE = \"route\";\n\n/**\n * Build the reactive `_route_` payload from the router's current state.\n * Returns a plain object with `path`, `params`, `pattern`, `query`, an\n * imperative `navigate(path)` method, plus a `toString()` so template\n * literals like `${_route_}` coerce to the path.\n */\nfunction buildRouteObject(router: Router): Record<string, unknown> {\n const path = router.getPath();\n const params = { ...router.getParams() };\n const pattern = router.getActivePattern();\n const query: Record<string, string> = {};\n if (typeof window !== \"undefined\" && window.location) {\n const search = window.location.search || \"\";\n if (search) {\n const params = new URLSearchParams(search.startsWith(\"?\") ? search.slice(1) : search);\n for (const [k, v] of params) query[k] = v;\n }\n }\n return {\n path,\n params,\n pattern,\n query,\n navigate(target: unknown): void {\n if (typeof target !== \"string\" || !target) return;\n router.navigate(target);\n },\n toString() {\n return path;\n },\n };\n}\n\n/**\n * Compare two `_route_` payloads field-by-field. The route store writes a\n * fresh object on every render — without a content-aware equality check\n * the reference-only test in `StateStore.set` would treat every replan as\n * a change and schedule a redundant follow-up render. That cascade also\n * breaks per-component closures that capture freshly-rendered DOM nodes:\n * the second render copies new handlers onto the morphed DOM but their\n * closures still point at the (now-detached) fragment from this tick.\n */\nfunction routesEqual(a: unknown, b: unknown): boolean {\n if (!a || !b || typeof a !== \"object\" || typeof b !== \"object\") return false;\n const left = a as { path?: unknown; pattern?: unknown; params?: Record<string, unknown>; query?: Record<string, unknown> };\n const right = b as typeof left;\n if (left.path !== right.path) return false;\n if (left.pattern !== right.pattern) return false;\n return (\n shallowEqualObject(left.params ?? {}, right.params ?? {}) &&\n shallowEqualObject(left.query ?? {}, right.query ?? {})\n );\n}\n\nfunction shallowEqualObject(a: Record<string, unknown>, b: Record<string, unknown>): boolean {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (a[key] !== b[key]) return false;\n }\n return true;\n}\n\n/**\n * Lazily-built `CSSStyleSheet` shared across every instance via\n * `adoptedStyleSheets`. The browser parses the source once and reuses the\n * compiled rules for every shadow root that adopts it, which keeps memory\n * and startup time flat as the number of `<aktion-app>` elements\n * grows. The boolean tracks whether the platform actually supports the\n * adoption API — older runtimes fall back to per-instance `<style>` tags.\n */\nlet sharedStyleSheet: CSSStyleSheet | null = null;\nlet sharedStyleSheetSupported: boolean | null = null;\n\nfunction getSharedStyleSheet(): CSSStyleSheet | null {\n if (sharedStyleSheetSupported === false) return null;\n if (sharedStyleSheet) return sharedStyleSheet;\n try {\n if (\n typeof CSSStyleSheet === \"undefined\" ||\n !(\"replaceSync\" in CSSStyleSheet.prototype) ||\n // Some test environments (happy-dom) expose `CSSStyleSheet` but its\n // `replaceSync` is a no-op that doesn't propagate to adoption — keep\n // the fallback so the rendered DOM still has styles.\n typeof document === \"undefined\" ||\n !(\"adoptedStyleSheets\" in Document.prototype)\n ) {\n sharedStyleSheetSupported = false;\n return null;\n }\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(componentStyles);\n sharedStyleSheet = sheet;\n sharedStyleSheetSupported = true;\n return sheet;\n } catch {\n sharedStyleSheetSupported = false;\n return null;\n }\n}\n\nexport class AktionElement extends HTMLElement {\n static readonly tagName = \"aktion-app\";\n\n static get observedAttributes(): string[] {\n return [\n ATTRIBUTE_THEME,\n ATTRIBUTE_STREAMING,\n ATTRIBUTE_RESPONSE,\n ATTRIBUTE_SHOW_ERRORS,\n ];\n }\n\n private readonly state = new StateStore();\n private readonly router = new Router();\n private library: ComponentLibrary = defaultLibrary;\n private readonly http = new HttpRuntime();\n private readonly i18n = new I18nRuntime();\n private readonly effectRunner: EffectRunner;\n private readonly actionDeclRunner: ActionDeclRunner;\n /**\n * Host-registered async tools, exposed to `js{}` blocks (effects + action\n * bodies) as `ctx.tools.<name>(args)`. The runtime never inspects the\n * registry — it just forwards calls — so each handler is responsible for\n * its own validation, auth, and error handling.\n */\n private readonly tools: Record<string, (...args: unknown[]) => unknown> = {};\n private renderer: Renderer;\n private context: EvaluationContext;\n private root: ShadowRoot;\n private rootEl: HTMLElement;\n private errorEl: HTMLElement;\n private currentResponse = \"\";\n private renderScheduled = false;\n /** True when the program text changed and the runtime needs a re-plan. */\n private programDirty = true;\n private parseErrors: string[] = [];\n /**\n * Token keys most recently applied by an in-script `Theme({...})`\n * declaration. We remember them so the next render can clear stale\n * overrides — otherwise switching from a `Theme(...)` block to the\n * base theme would leave the previous tokens stuck on the host.\n */\n private scriptThemeKeys: ReadonlyArray<keyof ThemeTokens> = [];\n\n constructor() {\n super();\n this.root = this.attachShadow({ mode: \"open\" });\n this.errorEl = document.createElement(\"div\");\n this.errorEl.className = \"rui-error-banner\";\n this.errorEl.hidden = true;\n this.rootEl = document.createElement(\"div\");\n this.rootEl.className = \"rui-root\";\n\n // Adopt the shared, pre-parsed stylesheet when the platform supports\n // it — every instance reuses the same compiled rules instead of\n // parsing a 4k-line CSS string per shadow root. Fall back to an inline\n // `<style>` tag when the constructable-stylesheet API is unavailable\n // (older browsers, some headless DOMs).\n const sheet = getSharedStyleSheet();\n if (sheet) {\n try {\n // `as CSSStyleSheet[]` keeps the typing predictable across DOM lib\n // versions where `adoptedStyleSheets` is typed as readonly.\n (this.root as ShadowRoot & { adoptedStyleSheets: CSSStyleSheet[] }).adoptedStyleSheets = [sheet];\n this.root.append(this.errorEl, this.rootEl);\n } catch {\n this.root.append(this.buildInlineStyle(), this.errorEl, this.rootEl);\n }\n } else {\n this.root.append(this.buildInlineStyle(), this.errorEl, this.rootEl);\n }\n\n const dispatchAssistantMessage = (message: string): void => {\n this.dispatchEvent(new CustomEvent(\"assistant-message\", {\n detail: { message },\n bubbles: true,\n composed: true,\n }));\n };\n\n const emit = (eventName: string, detail: unknown): void => {\n this.dispatchEvent(new CustomEvent(eventName, {\n detail,\n bubbles: true,\n composed: true,\n }));\n };\n this.effectRunner = new EffectRunner({\n state: this.state,\n notify: () => this.scheduleRender(),\n onEmit: emit,\n host: this,\n tools: this.tools,\n });\n this.actionDeclRunner = new ActionDeclRunner({\n state: this.state,\n notify: () => this.scheduleRender(),\n onEmit: emit,\n onAssistantMessage: dispatchAssistantMessage,\n host: this,\n tools: this.tools,\n });\n\n this.context = createContext(this.state, {\n router: this.router,\n library: this.library,\n http: this.http,\n i18n: this.i18n,\n actionRunner: this.actionDeclRunner,\n notify: () => this.scheduleRender(),\n jsBlockExecutor: createInlineJsExecutor({\n state: this.state,\n host: this,\n tools: this.tools,\n }),\n });\n this.renderer = new Renderer({\n library: this.library,\n state: this.state,\n router: this.router,\n onAssistantMessage: dispatchAssistantMessage,\n // Expose the evaluation context so the renderer can expand\n // user-declared `component Foo() { ... }` calls (per-instance\n // state, §7). We pass a getter rather than the live ref because\n // `this.context` is rebuilt on every `replan()`.\n evaluationContext: () => this.context,\n });\n\n this.state.subscribe(() => this.scheduleRender());\n this.router.subscribe((detail) => this.handleRouteChange(detail));\n }\n\n connectedCallback(): void {\n ensureFontAwesomeLoaded(this.root);\n this.applyThemeFromAttribute();\n this.startRouter();\n this.attachPersistenceAdapter();\n const responseAttr = this.getAttribute(ATTRIBUTE_RESPONSE);\n if (responseAttr !== null && responseAttr !== \"\" && responseAttr !== this.currentResponse) {\n this.setResponse(responseAttr);\n return;\n }\n if (!this.currentResponse) {\n const fallback = (this.textContent ?? \"\").trim();\n if (fallback) {\n this.setResponse(fallback);\n return;\n }\n }\n // Reconnect path: effects were torn down in `disconnectedCallback`, so we\n // always re-render to give the program a fresh effect-runner mount cycle.\n if (this.currentResponse) {\n this.programDirty = true;\n this.scheduleRender();\n }\n }\n\n disconnectedCallback(): void {\n this.effectRunner.reset();\n this.router.stop();\n }\n\n attributeChangedCallback(name: string, _old: string | null, value: string | null): void {\n if (name === ATTRIBUTE_THEME) this.applyThemeFromAttribute();\n if (name === ATTRIBUTE_STREAMING) {\n // Refresh the error banner: it is suppressed while streaming so partial\n // mid-line content does not flash transient parse errors to the user.\n this.updateErrorBanner();\n this.scheduleRender();\n }\n if (name === ATTRIBUTE_SHOW_ERRORS) {\n this.updateErrorBanner();\n }\n if (name === ATTRIBUTE_RESPONSE) {\n const next = value ?? \"\";\n if (next !== this.currentResponse) this.setResponse(next);\n }\n }\n\n /**\n * Register HTTP interceptors used by the Aktion 0.5 HTTP layer (§22.1 of\n * the spec). Interceptors are invoked by the HTTP runtime around every\n * `query`/`mutation`/`subscription` request. Multiple calls merge\n * incrementally — passing `{ onRequest }` only does not clear an\n * existing `onResponse`.\n */\n registerHttpInterceptors(interceptors: HttpInterceptors): void {\n this.http.registerInterceptors(interceptors);\n }\n\n /** Replace the current program with `text` and re-render from scratch. */\n setResponse(text: string): void {\n if (text === this.currentResponse) return;\n this.currentResponse = text;\n this.programDirty = true;\n this.state.rebind([]);\n // Drop persisted component-local UI state — stale slots from the\n // previous program could otherwise leak into structurally-similar\n // components rendered at the same tree position.\n this.renderer.reset();\n this.parseErrors = [];\n this.scheduleRender();\n }\n\n /**\n * Aktion 0.5 §26 — serialise the host's current state as\n * a plain JSON-friendly object. Combine with `programText` to round-\n * trip the entire app between turns, between tabs, or between\n * server-rendered HTML and client hydration.\n */\n serializeState(): Record<string, unknown> {\n return this.state.snapshot();\n }\n\n /**\n * Apply a snapshot to the live state store. Values land in `values`\n * immediately, so any subsequent `$state x = default` declaration\n * preserves the hydrated value (the planner only writes defaults for\n * names that do not yet exist).\n *\n * If a render is in flight, this call schedules a follow-up render so\n * the new values surface in the next paint.\n */\n hydrateState(snapshot: Readonly<Record<string, unknown>>): void {\n this.state.hydrate(snapshot);\n this.scheduleRender();\n }\n\n /**\n * Aktion 0.5 §14 — Delta Protocol. Apply a structured\n * sequence of operations to the current program; the runtime mounts\n * the patched program with the user's `$state` preserved across the\n * diff.\n *\n * Op shapes (see `src/tooling/delta.ts` for the full reference):\n *\n * - `{ kind: \"patch\", target: \"name\", value: any }`\n * - `{ kind: \"replace\", binding: \"name\", source: \"Expr\" }`\n * - `{ kind: \"append\", binding: \"name\", item: \"Expr\" }`\n * - `{ kind: \"new\", source: \"binding = Expr // or full decl\" }`\n * - `{ kind: \"delete\", binding: \"name\" }`\n *\n * Returns the advisory warnings raised by the delta (e.g. for ops\n * that targeted a missing binding). The host can surface them as a\n * banner or ignore them — partial deltas always still mount the\n * remaining patched program.\n */\n applyDelta(ops: readonly DeltaOp[]): string[] {\n const snapshot = this.state.snapshot();\n const result = applyDelta(this.currentResponse, ops);\n // Apply patch ops on top of the current snapshot, so `applyDelta`\n // is a single atomic step: state survives the structural diff\n // *and* picks up the explicit patches.\n Object.assign(snapshot, result.stateUpdates);\n this.loadSnapshot({ programText: result.programText, state: snapshot });\n return result.warnings;\n }\n\n /**\n * Aktion 0.5 §26 — atomic load of a serialised payload.\n * Sets the program text *and* the state in one shot so the next\n * render plans the program with the hydrated values already in\n * place. Use this for SSR hydration, conversational continuity\n * across turns, and URL-deep-link restoration.\n */\n loadSnapshot(payload: { programText: string; state: Record<string, unknown> }): void {\n this.currentResponse = payload.programText;\n this.programDirty = true;\n // Clear *defaults* and any leftover values from the previous program\n // before seeding from the snapshot — without this, atoms declared\n // by the previous program would keep their old defaults after the\n // new program plans them with new initial expressions.\n this.state.rebind([]);\n this.renderer.reset();\n this.parseErrors = [];\n // Seed values BEFORE the next render plans the new program. Declare\n // only writes defaults when `has(name) === false`, so the planner\n // will leave our hydrated values intact.\n this.state.hydrate(payload.state);\n this.scheduleRender();\n }\n\n /** Append a streaming chunk and re-render. */\n appendChunk(chunk: string): void {\n // Coerce defensively so callers can forward e.g. `decoder.decode(...)`\n // results without checking emptiness, and so a stray non-string never\n // corrupts the buffer with `\"undefined\"`-style concatenation.\n if (chunk === null || chunk === undefined) return;\n const text = typeof chunk === \"string\" ? chunk : String(chunk);\n if (text === \"\") return;\n this.currentResponse += text;\n this.programDirty = true;\n this.scheduleRender();\n }\n\n setTheme(theme: ThemeInput): void {\n applyTheme(this, resolveTheme(theme));\n // Setting a new base theme wipes every token CSS variable, so the\n // tracker for in-script overrides starts fresh — the next render will\n // reapply any `Theme({...})` from the active program on top of the\n // freshly-painted base.\n this.scriptThemeKeys = [];\n this.scheduleRender();\n }\n\n registerComponents(components: ComponentSpec[], rootName?: string): void {\n this.library = mergeLibraries(this.library, { components, root: rootName });\n // Swap the library on the existing renderer so per-instance state slots\n // (Tabs active pane, Popover open/closed, …) carry over to the next\n // render. Recreating the renderer would have dropped that state.\n this.renderer.setLibrary(this.library);\n this.scheduleRender();\n }\n\n /**\n * Build a system prompt for the active library. Pass `{ mode: \"chat\" }`\n * for the compact chat-focused prompt; omit `mode` (or pass `\"full\"`)\n * for the complete prompt.\n */\n getSystemPrompt(options?: PromptOptions): string {\n return generatePrompt(this.library, options ?? {});\n }\n\n /** Programmatic navigation API. */\n navigate(path: string): void {\n this.router.navigate(path);\n }\n\n /**\n * Register host-supplied async tools exposed to `js{}` blocks as\n * `ctx.tools.<name>(args)`. Replaces any previously-registered tools\n * with the same name.\n */\n setTools(tools: Record<string, (...args: unknown[]) => unknown>): void {\n for (const key of Object.keys(this.tools)) delete this.tools[key];\n for (const [name, fn] of Object.entries(tools ?? {})) {\n if (typeof fn === \"function\") this.tools[name] = fn;\n }\n }\n\n /** Current route path (`/`, `/about`, …). */\n get route(): string {\n return this.router.getPath();\n }\n\n clear(): void {\n this.currentResponse = \"\";\n this.state.rebind([]);\n this.effectRunner.reset();\n // Drop component-local UI state (Tabs active pane, Popover open flag,\n // …). Without this, a fresh program would inherit slot values from\n // the previous program and snap stateful primitives into the wrong\n // initial UI.\n this.renderer.reset();\n this.programDirty = true;\n this.parseErrors = [];\n this.errorEl.hidden = true;\n this.errorEl.replaceChildren();\n this.rootEl.replaceChildren();\n // Drop any cached active match — the next render will recompute from\n // the current path against whatever routes the new program declares.\n this.router.setActiveMatch(null, {});\n }\n\n // ----- Property accessors -----\n\n get response(): string {\n return this.currentResponse;\n }\n\n set response(value: string) {\n this.setResponse(value);\n }\n\n get streaming(): boolean {\n return parseBooleanAttribute(this.getAttribute(ATTRIBUTE_STREAMING));\n }\n\n set streaming(value: boolean) {\n if (value) this.setAttribute(ATTRIBUTE_STREAMING, \"true\");\n else this.removeAttribute(ATTRIBUTE_STREAMING);\n }\n\n get showErrors(): boolean {\n return parseBooleanAttribute(this.getAttribute(ATTRIBUTE_SHOW_ERRORS));\n }\n\n set showErrors(value: boolean) {\n if (value) this.setAttribute(ATTRIBUTE_SHOW_ERRORS, \"true\");\n else this.removeAttribute(ATTRIBUTE_SHOW_ERRORS);\n }\n\n // ----- Internal -----\n\n private buildInlineStyle(): HTMLStyleElement {\n const style = document.createElement(\"style\");\n style.textContent = componentStyles;\n return style;\n }\n\n /**\n * Start the router so the hash listener is attached and `_route_` is\n * seeded with the current URL. Idempotent — safe to call from\n * `connectedCallback`.\n */\n private startRouter(): void {\n this.router.start();\n // Seed `_route_` immediately so the very first render sees the URL\n // hash (instead of the default \"/\").\n this.writeRouteState();\n }\n\n /**\n * Write `_route_` only when its content actually changed. Avoids\n * triggering a redundant render-after-replan cascade — see\n * `routesEqual` for the structural comparison.\n */\n private writeRouteState(): void {\n const next = buildRouteObject(this.router);\n if (routesEqual(this.state.get(STATE_ROUTE), next)) return;\n this.state.set(STATE_ROUTE, next);\n }\n\n /**\n * Wire `$$variable` declarations to a `localStorage`-backed adapter.\n * Persistence is namespaced by the element's `id` (falling back to the\n * tag name when no id is set) so two `<aktion-app>` elements on\n * the same page don't collide. SSR / sandboxed contexts without storage\n * silently degrade to in-memory only — `$$variable` still works, just\n * without survival across reloads.\n */\n private attachPersistenceAdapter(): void {\n const storage = typeof window !== \"undefined\" ? window.localStorage : null;\n const prefix = `rui:${AktionElement.tagName}:${this.id || \"default\"}`;\n const adapter = createLocalStorageAdapter(prefix, storage ?? null);\n this.state.setPersistenceAdapter(adapter);\n }\n\n /**\n * React to any path change: write the new value into the route slot (so\n * `_route_` reads re-evaluate), schedule a re-render, and bubble a\n * `route-change` event so host pages can sync analytics or sidebars.\n */\n private handleRouteChange(detail: RouteChangeDetail): void {\n this.writeRouteState();\n this.dispatchEvent(new CustomEvent(\"route-change\", {\n detail,\n bubbles: true,\n composed: true,\n }));\n this.scheduleRender();\n }\n\n private applyThemeFromAttribute(): void {\n const attr = this.getAttribute(ATTRIBUTE_THEME);\n applyTheme(this, resolveTheme(attr));\n // Reapplying the base theme wipes every token CSS variable, so the\n // tracker for in-script overrides has to start fresh — the variables\n // it was tracking just got rewritten by the base layer.\n this.scriptThemeKeys = [];\n }\n\n /**\n * Look for a `theme = Theme({...})` (or any binding returning a\n * `ThemeNode`) in the active program. If found, write its tokens to the\n * host as CSS custom properties so the in-script declaration layers on\n * top of the attribute / `setTheme()` base. The previous render's keys\n * are cleared first so removing a `Theme(...)` line snaps the renderer\n * back to the underlying theme without a reload.\n */\n private applyScriptThemeOverrides(): void {\n if (this.scriptThemeKeys.length > 0) {\n clearTokenOverrides(this, this.scriptThemeKeys);\n this.scriptThemeKeys = [];\n }\n const themeBinding = this.context.bindings.get(\"theme\");\n if (!themeBinding) return;\n let value: unknown;\n try { value = themeBinding(); } catch { return; }\n if (!isThemeNode(value)) return;\n const tokens = sanitiseThemeTokens(value.tokens);\n if (Object.keys(tokens).length === 0) return;\n this.scriptThemeKeys = applyPartialTheme(this, tokens);\n }\n\n private scheduleRender(): void {\n if (this.renderScheduled) return;\n this.renderScheduled = true;\n queueMicrotask(() => this.renderNow());\n }\n\n private renderNow(): void {\n this.renderScheduled = false;\n if (!this.isConnected) return;\n\n // Re-plan only when the program text changed. This is critical:\n // re-planning tears down and re-mounts effects/actions/endpoint resources,\n // which would re-fire their notifies and cause an infinite render loop\n // if we did it every tick.\n if (this.programDirty) {\n this.replan();\n this.programDirty = false;\n }\n\n // Apply any in-script `Theme({...})` declaration before render so the\n // tokens are in place when components measure themselves or read CSS\n // custom properties (charts that grab `--rui-chart-1`, etc.).\n this.applyScriptThemeOverrides();\n\n // The program's entry-point binding is `_app_`. Older clients that\n // still emit `root = …` keep working: we fall back to it when no\n // `_app_` binding is registered.\n const appBinding = this.context.bindings.get(\"_app_\") ?? this.context.bindings.get(\"root\");\n let rootValue: unknown = null;\n if (appBinding) {\n try {\n rootValue = appBinding();\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\"[aktion] _app_ evaluation error\", err);\n }\n }\n\n // Each tick we re-evaluate the entire tree, but instead of throwing the\n // live DOM away (`replaceChildren`) we hand the freshly-rendered tree\n // to a small reconciler that diffs against the existing DOM. That keeps\n // form inputs, scroll positions, <details>.open, and any other browser-\n // owned state stable across renders — typing into one input no longer\n // resets the active tab three components over. The focus snapshot is\n // still useful as a defensive backstop for the rare case where a node's\n // identity actually changes (different tag, replaced subtree).\n this.renderer.beginRender();\n const focusSnapshot = this.captureFocus();\n const rendered = this.renderer.render(rootValue);\n morphChildren(this.rootEl, rendered);\n this.renderer.endRender();\n this.restoreFocus(focusSnapshot);\n }\n\n private captureFocus(): FocusSnapshot | null {\n const active = this.root.activeElement as HTMLElement | null;\n if (!active || !this.rootEl.contains(active)) return null;\n const id = active.id || null;\n if (!id) return null;\n const snapshot: FocusSnapshot = { id, tagName: active.tagName };\n if (\n active instanceof HTMLInputElement ||\n active instanceof HTMLTextAreaElement\n ) {\n snapshot.selectionStart = active.selectionStart;\n snapshot.selectionEnd = active.selectionEnd;\n snapshot.selectionDirection = active.selectionDirection ?? null;\n }\n return snapshot;\n }\n\n private restoreFocus(snapshot: FocusSnapshot | null): void {\n if (!snapshot) return;\n const target = this.rootEl.querySelector<HTMLElement>(`#${cssEscapeId(snapshot.id)}`);\n if (!target || target.tagName !== snapshot.tagName) return;\n // If the morph reconciler reused the same DOM node, focus and selection\n // were never lost; skip the work to avoid spurious focus/blur events.\n const root = this.root as unknown as { activeElement: Element | null };\n if (root.activeElement === target) return;\n target.focus();\n if (\n (target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement) &&\n snapshot.selectionStart != null &&\n snapshot.selectionEnd != null\n ) {\n applySelectionRange(\n target,\n snapshot.selectionStart,\n snapshot.selectionEnd,\n snapshot.selectionDirection ?? \"none\",\n );\n }\n }\n\n private replan(): void {\n this.effectRunner.reset();\n this.context = createContext(this.state, {\n router: this.router,\n library: this.library,\n http: this.http,\n i18n: this.i18n,\n actionRunner: this.actionDeclRunner,\n notify: () => this.scheduleRender(),\n jsBlockExecutor: createInlineJsExecutor({\n state: this.state,\n host: this,\n tools: this.tools,\n }),\n });\n\n const program = parse(this.currentResponse);\n // Aktion 0.5 — schema validator runs alongside the parser\n // so multi-positional calls, unknown props, enum mismatches, and\n // legacy Theme tokens become fatal errors (mirroring the parser-level\n // migration errors for syntactic legacy forms). The banner surfaces\n // them together so authors see one unified list.\n const schemaErrors = validateProgramSchema(program, this.library);\n if (schemaErrors.length > 0) {\n program.errors = [...program.errors, ...schemaErrors];\n }\n planProgram(program, this.context);\n\n // Mount any `effect [ ...deps ] { … }` declarations declared in the\n // program. The runner manages their lifecycle (mount, re-run on state\n // changes, teardown).\n const effectDecls = [...this.context.effectDecls.values()];\n if (effectDecls.length > 0) {\n this.effectRunner.syncEffects(effectDecls, () => this.context);\n }\n\n // Seed `_route_` so user expressions like `_route_.path == \"/about\"`\n // resolve even before the first hashchange fires.\n this.writeRouteState();\n\n this.parseErrors = [\n ...program.errors.map((e) => `Line ${e.line}: ${e.message}`),\n ...this.effectRunner.getErrors(),\n ];\n this.updateErrorBanner();\n\n // While streaming, the in-flight chunk is almost always mid-token, so\n // errors are expected and transient. Defer dispatch until streaming ends.\n if (program.errors.length > 0 && !this.streaming) {\n this.dispatchEvent(new CustomEvent(\"error\", {\n detail: { errors: program.errors },\n bubbles: true,\n composed: true,\n }));\n }\n }\n\n private updateErrorBanner(): void {\n // The banner is additional attributes via the `showerrors` attribute. While the response\n // is still streaming, the in-flight last line is almost always mid-token\n // and will fail to parse, so we also suppress the banner during streaming\n // even when errors are explicitly enabled. Errors are still dispatched via\n // the `error` event for host apps that want to observe them programmatically.\n if (\n !this.showErrors ||\n this.streaming ||\n this.parseErrors.length === 0\n ) {\n this.errorEl.hidden = true;\n this.errorEl.replaceChildren();\n return;\n }\n this.errorEl.hidden = false;\n const title = document.createElement(\"div\");\n title.textContent = `${this.parseErrors.length} parse issue${this.parseErrors.length === 1 ? \"\" : \"s\"} (rendered partial UI):`;\n const list = document.createElement(\"ul\");\n for (const message of this.parseErrors.slice(0, 5)) {\n const li = document.createElement(\"li\");\n li.textContent = message;\n list.append(li);\n }\n this.errorEl.replaceChildren(title, list);\n }\n}\n\ninterface FocusSnapshot {\n id: string;\n tagName: string;\n selectionStart?: number | null;\n selectionEnd?: number | null;\n selectionDirection?: \"forward\" | \"backward\" | \"none\" | null;\n}\n\n/**\n * Escape an id for use in `document.querySelector('#...')`. CSS.escape exists\n * in all modern browsers and happy-dom; we fall back to a tiny shim for older\n * environments so the renderer never blows up while restoring focus.\n */\nfunction cssEscapeId(id: string): string {\n if (typeof CSS !== \"undefined\" && typeof CSS.escape === \"function\") {\n return CSS.escape(id);\n }\n return id.replace(/([^A-Za-z0-9_-])/g, \"\\\\$1\");\n}\n\n/**\n * Input types that do not support `setSelectionRange` per the WHATWG spec\n * — calling it throws `InvalidStateError`. We round-trip through\n * `type=\"text\"` so we can still restore the caret, then flip the type back.\n * This is the same workaround major frameworks (and morphdom) use.\n */\nconst SELECTION_UNSUPPORTED_TYPES = new Set([\n \"email\",\n \"number\",\n \"tel\",\n \"url\",\n \"date\",\n \"datetime-local\",\n \"month\",\n \"week\",\n \"time\",\n \"color\",\n]);\n\nfunction applySelectionRange(\n target: HTMLInputElement | HTMLTextAreaElement,\n start: number,\n end: number,\n direction: \"forward\" | \"backward\" | \"none\",\n): void {\n if (target instanceof HTMLInputElement && SELECTION_UNSUPPORTED_TYPES.has(target.type)) {\n const previousType = target.type;\n try {\n // Flip to `text` so the platform honours setSelectionRange, then\n // restore the declared type. This preserves both caret position and\n // type-specific validation / UI on the element.\n target.type = \"text\";\n target.setSelectionRange(start, end, direction);\n } catch {\n // Last-resort: at least keep focus; modern browsers will park the\n // caret at the end of the field on focus().\n } finally {\n target.type = previousType;\n }\n return;\n }\n try {\n target.setSelectionRange(start, end, direction);\n } catch {\n // Defensive: some headless DOM implementations throw even for text\n // inputs in edge cases. Focus alone is good enough.\n }\n}\n\n/**\n * HTML boolean-ish attribute parser: treat empty strings, \"true\", \"1\", or\n * the attribute name itself as `true`. Anything else (including missing) is\n * `false`. This matches how `<input disabled>` and friends are usually read.\n */\nfunction parseBooleanAttribute(value: string | null): boolean {\n if (value === null) return false;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"\" || normalized === \"true\" || normalized === \"1\") {\n return true;\n }\n if (normalized === ATTRIBUTE_SHOW_ERRORS) return true;\n return false;\n}\n\nexport function defineElement(): void {\n if (!customElements.get(AktionElement.tagName)) {\n customElements.define(AktionElement.tagName, AktionElement);\n }\n}\n","/**\n * Pure-data grammar description for Aktion.\n *\n * The grammar lives here as plain JSON-style data and a minimal stream\n * tokenizer factory. The stream tokenizer returned by\n * `createStreamTokenizer` matches the shape of CodeMirror 6's `StreamParser`\n * (`token`, `startState`, `copyState`), but it does NOT import CodeMirror or\n * any DOM API — so the same data drives Monaco, a VS Code TextMate grammar,\n * or any other editor.\n *\n * Token kinds are reported as semantic strings. Consumers map them to their\n * own highlight tags (CodeMirror's `tags`, Monaco's `TokenType`, etc.).\n */\n\nexport type GrammarTokenKind =\n | \"comment\" // // line and /* block */\n | \"string\" // \"double\" 'single' `backtick`\n | \"number\" // 12, -3.14\n | \"atom\" // true / false / null\n | \"builtin\" // @Each, @Sum, @Filter, @Format, …\n | \"state\" // $variable\n | \"component\" // Capitalised identifier in call position\n | \"identifier\" // lowercase identifier\n | \"operator\" // +, -, *, /, ==, &&, …\n | \"punctuation\" // ( ) [ ] { } , : ?\n | \"loopvar\" // first segment of `row.name` / `params.id`\n | \"property\"; // segment after `.`\n\nexport interface GrammarSpec {\n name: \"aktion\";\n /** No keywords reserved beyond literal atoms. */\n atoms: readonly string[];\n /** Operators (longest-match first when tokenising). */\n operators: readonly string[];\n /** Two-character operators that must be matched before single chars. */\n operatorsLong: readonly string[];\n /** Brackets that must be balanced; useful for editor bracket matching. */\n brackets: ReadonlyArray<{ open: string; close: string }>;\n comments: {\n /** Primary line-comment introducer (used by editors for Ctrl+/ toggle). */\n line: string;\n /**\n * Additional line-comment introducers. Tokenizers strip these the same\n * way as `line`; editors that expose a single comment-toggle keystroke\n * should still use `line` as the canonical form.\n */\n extraLine: readonly string[];\n blockStart: string;\n blockEnd: string;\n };\n strings: {\n /** Quote characters allowed for single-line escape-supporting strings. */\n singleLineQuotes: readonly string[];\n /** Quote character for multi-line raw strings (no escaping needed). */\n multiLineQuote: string;\n };\n identifier: {\n start: RegExp;\n part: RegExp;\n };\n /** Sigils that mark non-identifier categories. */\n sigils: {\n builtin: string;\n state: string;\n };\n}\n\nexport const grammarSpec: GrammarSpec = {\n name: \"aktion\",\n atoms: [\"true\", \"false\", \"null\"],\n operators: [\"+\", \"-\", \"*\", \"/\", \"%\", \"!\", \"=\", \"<\", \">\", \"?\", \":\", \".\", \",\"],\n // Long operators include `??` and `?.` (nullish coalescing + optional chain)\n // and `...` (spread). Order matters: longest match wins.\n operatorsLong: [\"...\", \"==\", \"!=\", \">=\", \"<=\", \"&&\", \"||\", \"??\", \"?.\"],\n brackets: [\n { open: \"(\", close: \")\" },\n { open: \"[\", close: \"]\" },\n { open: \"{\", close: \"}\" },\n ],\n comments: { line: \"//\", extraLine: [\"#\"], blockStart: \"/*\", blockEnd: \"*/\" },\n strings: {\n singleLineQuotes: ['\"', \"'\"],\n multiLineQuote: \"`\",\n },\n identifier: {\n start: /[A-Za-z_]/,\n part: /[A-Za-z0-9_]/,\n },\n sigils: { builtin: \"@\", state: \"$\" },\n};\n\n/**\n * Mutable state carried by the stream tokenizer between calls. We track the\n * unclosed multi-line constructs (backtick strings, block comments).\n */\nexport interface StreamState {\n inBacktick: boolean;\n inBlockComment: boolean;\n}\n\nexport interface StreamLike {\n /** True at column 0 of a line (CodeMirror exposes `stream.sol()`). */\n sol(): boolean;\n /** Returns next char without consuming. */\n peek(): string | null | undefined;\n /** Consume and return the next char, advancing the stream. */\n next(): string | undefined;\n /** Consume while the predicate matches. */\n eatWhile(test: RegExp | ((ch: string) => boolean)): boolean;\n /** Consume one char if it matches; returns whether it consumed. */\n eat(test: string | RegExp | ((ch: string) => boolean)): string | undefined;\n /**\n * Consume everything up to (and optionally including) the given string or\n * regex. CodeMirror's `skipTo` matches the string in the rest of the line.\n * We rely only on `match(string, consume?)` which is available in CM6.\n */\n match(pattern: string | RegExp, consume?: boolean): boolean | RegExpMatchArray | null;\n /** Skip to end of line. */\n skipToEnd(): void;\n /** True at end of line. */\n eol(): boolean;\n}\n\nexport interface StreamTokenizer {\n startState(): StreamState;\n copyState(state: StreamState): StreamState;\n token(stream: StreamLike, state: StreamState): GrammarTokenKind | null;\n /**\n * Language metadata that CodeMirror's `StreamLanguage.define(...)` will pick\n * up — comment style and bracket pairs for auto-pairing.\n */\n languageData: {\n commentTokens: { line: string; block: { open: string; close: string } };\n closeBrackets: { brackets: readonly string[] };\n indentOnInput: RegExp;\n };\n}\n\n/**\n * Lookahead tokenizer driven by `grammarSpec`. Suitable for\n * `StreamLanguage.define(...)` in CodeMirror 6, but framework-agnostic.\n */\nexport function createStreamTokenizer(spec: GrammarSpec = grammarSpec): StreamTokenizer {\n const startState = (): StreamState => ({ inBacktick: false, inBlockComment: false });\n const copyState = (state: StreamState): StreamState => ({ ...state });\n\n const atomSet = new Set(spec.atoms);\n const componentCallRe = /^[A-Z][A-Za-z0-9_]*/;\n const lowerIdentRe = /^[a-z_][A-Za-z0-9_]*/;\n const numberRe = /^-?\\d+(?:\\.\\d+)?/;\n const operatorChars = new Set([...spec.operators.join(\"\"), ...\"=<>!&|\"]);\n\n const consumeStringBody = (stream: StreamLike, quote: string): void => {\n while (!stream.eol()) {\n const ch = stream.next();\n if (!ch) return;\n if (ch === \"\\\\\") {\n stream.next();\n continue;\n }\n if (ch === quote) return;\n }\n };\n\n const token = (stream: StreamLike, state: StreamState): GrammarTokenKind | null => {\n // Resume open multi-line constructs.\n if (state.inBacktick) {\n while (!stream.eol()) {\n const ch = stream.next();\n if (ch === \"\\\\\") { stream.next(); continue; }\n if (ch === \"`\") { state.inBacktick = false; return \"string\"; }\n }\n return \"string\";\n }\n if (state.inBlockComment) {\n while (!stream.eol()) {\n if (stream.match(spec.comments.blockEnd, true)) {\n state.inBlockComment = false;\n return \"comment\";\n }\n stream.next();\n }\n return \"comment\";\n }\n\n // Skip whitespace.\n if (stream.eatWhile(/[ \\t]/)) return null;\n\n // Comments. `line` is the primary introducer (used by editors for the\n // Ctrl+/ toggle); `extraLine` lists alternative single-line introducers\n // such as `#` for shell-style remarks.\n if (stream.match(spec.comments.line, true)) {\n stream.skipToEnd();\n return \"comment\";\n }\n for (const alt of spec.comments.extraLine) {\n if (stream.match(alt, true)) {\n stream.skipToEnd();\n return \"comment\";\n }\n }\n if (stream.match(spec.comments.blockStart, true)) {\n state.inBlockComment = true;\n while (!stream.eol()) {\n if (stream.match(spec.comments.blockEnd, true)) {\n state.inBlockComment = false;\n return \"comment\";\n }\n stream.next();\n }\n return \"comment\";\n }\n\n const next = stream.peek();\n if (next === null || next === undefined) return null;\n\n // Strings.\n if (spec.strings.singleLineQuotes.includes(next)) {\n const quote = next;\n stream.next();\n consumeStringBody(stream, quote);\n return \"string\";\n }\n if (next === spec.strings.multiLineQuote) {\n stream.next();\n while (!stream.eol()) {\n const ch = stream.next();\n if (ch === \"\\\\\") { stream.next(); continue; }\n if (ch === \"`\") return \"string\";\n }\n state.inBacktick = true;\n return \"string\";\n }\n\n // Numbers (also matches `-1`, `-3.14`).\n if (next >= \"0\" && next <= \"9\") {\n if (stream.match(numberRe, true)) return \"number\";\n }\n if (next === \"-\" && stream.match(/^-\\d+(?:\\.\\d+)?/, false)) {\n if (stream.match(numberRe, true)) return \"number\";\n }\n\n // Sigil-prefixed identifiers.\n if (next === spec.sigils.builtin) {\n stream.next();\n stream.eatWhile(spec.identifier.part);\n return \"builtin\";\n }\n if (next === spec.sigils.state) {\n stream.next();\n // Legacy `$$name` is a hard error in Aktion 0.5; the\n // tokenizer still highlights both `$`s as one `state` token so the\n // user sees a single red squiggle pointing at the migration site\n // instead of two unrelated tokens.\n if (stream.peek() === spec.sigils.state) stream.next();\n stream.eatWhile(spec.identifier.part);\n return \"state\";\n }\n\n // Identifiers + atoms + component calls + property access.\n if (spec.identifier.start.test(next)) {\n const upper = stream.match(componentCallRe, true);\n if (upper) {\n return \"component\";\n }\n const lower = stream.match(lowerIdentRe, true);\n if (lower) {\n const text = (lower as RegExpMatchArray)[0];\n if (atomSet.has(text)) return \"atom\";\n // Heuristic: `row.field` highlights `row` as a loop variable. We\n // detect this by the next non-whitespace char being `.`.\n const ahead = stream.peek();\n if (ahead === \".\") return \"loopvar\";\n return \"identifier\";\n }\n }\n\n // Multi-char operators.\n for (const op of spec.operatorsLong) {\n if (stream.match(op, true)) return \"operator\";\n }\n\n // Property access: `.name`.\n if (next === \".\") {\n stream.next();\n if (stream.peek() && spec.identifier.start.test(stream.peek() as string)) {\n stream.eatWhile(spec.identifier.part);\n return \"property\";\n }\n return \"punctuation\";\n }\n\n // Brackets / commas / colons / question.\n if (\"()[]{},:?\".includes(next)) {\n stream.next();\n return \"punctuation\";\n }\n\n // Single-char operators.\n if (operatorChars.has(next)) {\n stream.next();\n return \"operator\";\n }\n\n stream.next();\n return null;\n };\n\n return {\n startState,\n copyState,\n token,\n languageData: {\n commentTokens: { line: spec.comments.line, block: { open: spec.comments.blockStart, close: spec.comments.blockEnd } },\n closeBrackets: { brackets: [\"(\", \"[\", \"{\", '\"', \"'\", \"`\"] },\n indentOnInput: /^\\s*[)\\]}]$/,\n },\n };\n}\n\n/**\n * Default mapping from grammar token kinds to CodeMirror highlight tag names.\n *\n * Returned as plain strings so consumers can resolve them to whatever their\n * highlighter understands. We keep `tagName: string | null` so consumers may\n * skip a kind entirely (e.g. punctuation is often left unhighlighted).\n */\nexport const defaultTagMap: Record<GrammarTokenKind, string | null> = {\n comment: \"comment\",\n string: \"string\",\n number: \"number\",\n atom: \"atom\",\n builtin: \"keyword\",\n state: \"variableName.special\",\n component: \"typeName\",\n identifier: \"variableName\",\n loopvar: \"variableName.local\",\n property: \"propertyName\",\n operator: \"operator\",\n punctuation: null,\n};\n","/**\n * Component catalog derived from the runtime library.\n *\n * We project `ComponentSpec` (which carries a DOM-flavoured `render` fn) into\n * a flat, JSON-serialisable shape that any editor or tool can consume without\n * pulling in the renderer or the DOM.\n */\n\nimport type { ComponentLibrary, ComponentSpec, PropSpec } from \"../library/types.js\";\nimport { defaultLibrary } from \"../library/index.js\";\n\nexport interface ComponentParam {\n name: string;\n type: string;\n required: boolean;\n description?: string;\n enumValues?: readonly string[];\n}\n\nexport interface ComponentEntry {\n name: string;\n group: string;\n description: string;\n params: ComponentParam[];\n /** Short positional signature, e.g. `Card(children, variant?)`. */\n signature: string;\n}\n\nconst projectParam = (prop: PropSpec): ComponentParam => {\n const param: ComponentParam = {\n name: prop.name,\n type: prop.type,\n required: !prop.optional,\n };\n if (prop.description) param.description = prop.description;\n if (prop.enum && prop.enum.length > 0) param.enumValues = prop.enum;\n return param;\n};\n\nconst buildSignature = (spec: ComponentSpec): string => {\n const parts = spec.props.map((p) => (p.optional ? `${p.name}?` : p.name));\n return `${spec.name}(${parts.join(\", \")})`;\n};\n\nconst buildGroupIndex = (library: ComponentLibrary): Map<string, string> => {\n const index = new Map<string, string>();\n for (const group of library.componentGroups ?? []) {\n for (const name of group.components) index.set(name, group.name);\n }\n return index;\n};\n\n/**\n * Project a library's component specs into a flat catalog. Defaults to the\n * built-in `defaultLibrary`, but accepts a custom library so consumers that\n * register extra components via `registerComponents()` get the right autocomplete\n * data.\n */\nexport function getComponentCatalog(library: ComponentLibrary = defaultLibrary): ComponentEntry[] {\n const groupOf = buildGroupIndex(library);\n return library.components.map((spec) => ({\n name: spec.name,\n group: groupOf.get(spec.name) ?? \"Other\",\n description: spec.description,\n params: spec.props.map(projectParam),\n signature: buildSignature(spec),\n }));\n}\n\n/**\n * Returns an index of component name → entry for O(1) lookup. Convenient\n * inside editor extensions that need to render details on hover.\n */\nexport function indexCatalog(entries: ComponentEntry[]): Record<string, ComponentEntry> {\n const out: Record<string, ComponentEntry> = {};\n for (const entry of entries) out[entry.name] = entry;\n return out;\n}\n","/**\n * Snippet templates for common Aktion composites.\n *\n * Placeholders use `${1:label}` syntax. CodeMirror's `snippet()` from\n * `@codemirror/autocomplete` parses this format natively. Monaco and VS\n * Code do too (it matches the LSP snippet format).\n */\n\nexport interface SnippetEntry {\n /** Snippet key — used as the autocomplete completion label. */\n name: string;\n /** Human-readable description shown in the autocomplete popup. */\n description: string;\n /** The template body with `${n:label}` placeholders. */\n template: string;\n}\n\nexport const snippetCatalog: readonly SnippetEntry[] = [\n {\n name: \"App\",\n description: \"Top-level `_app_` binding — every program needs one.\",\n template:\n '_app_ = Stack([\\n' +\n ' ${1:Card([CardHeader(\"${2:Hello}\")])}\\n' +\n '])',\n },\n {\n name: \"Card\",\n description: \"Card with header + body block.\",\n template:\n 'card${1} = Card([\\n' +\n ' CardHeader(\"${2:Title}\", subtitle: \"${3:Subtitle}\"),\\n' +\n ' Stack([\\n' +\n ' Text(\"${4:Body copy goes here.}\")\\n' +\n ' ])\\n' +\n '])',\n },\n {\n name: \"Hero\",\n description: \"Landing-page hero with eyebrow, title, subtitle, and a CTA.\",\n template:\n 'action ${4:Start}() { _route_.navigate(\"/start\") }\\n' +\n 'action ${5:OpenDemo}() { _route_.navigate(\"/demo\") }\\n' +\n 'hero${1} = Hero(\\n' +\n ' \"${2:Ship faster}\",\\n' +\n ' subtitle: \"${3:From idea to production in minutes.}\",\\n' +\n ' primary: Button(\"${6:Get started}\", action: ${4:Start}, variant: \"primary\"),\\n' +\n ' secondary: Button(\"${7:Live demo}\", action: ${5:OpenDemo}, variant: \"ghost\"),\\n' +\n ' eyebrow: \"${8:v2 launch}\"\\n' +\n ')',\n },\n {\n name: \"PageHeader\",\n description: \"Dashboard page header with breadcrumbs and actions.\",\n template:\n 'action ${6:RunAction}() { /* TODO: implement */ }\\n' +\n 'header${1} = PageHeader(\\n' +\n ' \"${2:Page title}\",\\n' +\n ' subtitle: \"${3:Subtitle / meta line}\",\\n' +\n ' breadcrumbs: [\"${4:Workspace}\", \"${5:Section}\"],\\n' +\n ' actions: [Button(\"${7:Action}\", action: ${6:RunAction}, variant: \"primary\")],\\n' +\n ' status: Badge(\"${8:On track}\", variant: \"success\")\\n' +\n ')',\n },\n {\n name: \"Stats\",\n description: \"Responsive KPI strip with four StatCards.\",\n template:\n 'metrics${1} = Stats([\\n' +\n ' StatCard(\"${2:Active}\", value: \"${3:12}\", trend: \"flat\"),\\n' +\n ' StatCard(\"${4:At risk}\", value: \"${5:4}\", trend: \"up\", delta: \"+2\"),\\n' +\n ' StatCard(\"${6:Shipped}\", value: \"${7:8}\", trend: \"up\", delta: \"+3\"),\\n' +\n ' StatCard(\"${8:On-time}\", value: \"${9:87%}\", trend: \"down\", delta: \"-3%\")\\n' +\n '])',\n },\n {\n name: \"GridLayout\",\n description: \"12-column sidebar layout with named GridItem spans.\",\n template:\n 'sidebar${1} = Card([CardHeader(\"${2:Sidebar}\")])\\n' +\n 'main${1} = Card([CardHeader(\"${3:Main}\")])\\n' +\n '_app_ = Grid([\\n' +\n ' GridItem(sidebar${1}, span: \"1/4\"),\\n' +\n ' GridItem(main${1}, span: \"3/4\")\\n' +\n '], columns: 12, gap: \"l\")',\n },\n {\n name: \"KanbanBoard\",\n description: \"Three-column kanban board with sample cards.\",\n template:\n 'board${1} = KanbanBoard([\\n' +\n ' KanbanColumn(\"To do\", items: [\\n' +\n ' KanbanCard(\"${2:Migrate auth}\", description: \"${3:Roll out the new SDK.}\", tags: [\"auth\"], assignee: \"${4:Asha}\")\\n' +\n ' ]),\\n' +\n ' KanbanColumn(\"Doing\", items: [\\n' +\n ' KanbanCard(\"${5:Streaming UI v2}\", description: \"${6:Ship 20 new components.}\", tags: [\"frontend\"], assignee: \"${7:Alex}\", tone: \"primary\")\\n' +\n ' ]),\\n' +\n ' KanbanColumn(\"Done\", items: [\\n' +\n ' KanbanCard(\"${8:Activity timeline}\", description: \"${9:Shipped to 100%.}\", tags: [\"shipped\"], assignee: \"${10:Mira}\", tone: \"success\")\\n' +\n ' ])\\n' +\n '])',\n },\n {\n name: \"FollowUpBlock\",\n description: \"Chat follow-up prompts.\",\n template:\n 'follow${1} = FollowUpBlock([\\n' +\n ' FollowUpItem(\"${2:Show me a chart}\"),\\n' +\n ' FollowUpItem(\"${3:Add a filter}\"),\\n' +\n ' FollowUpItem(\"${4:Export as CSV}\")\\n' +\n '])',\n },\n {\n name: \"Router\",\n description: \"Multi-page router via _router_({…}) with NavLink sidebar.\",\n template:\n 'pages = _router_({\\n' +\n ' \"/\": homePage(),\\n' +\n ' \"/dashboard\": dashboardPage(),\\n' +\n ' \"/users/:id\": userPage(id: params.id),\\n' +\n ' \"/docs/*\": docsPage(rest: params._),\\n' +\n ' default: notFoundPage()\\n' +\n '})\\n\\n' +\n 'component homePage() {\\n' +\n ' return Card([CardHeader(\"Welcome\")])\\n' +\n '}\\n' +\n 'component dashboardPage() {\\n' +\n ' return Card([CardHeader(\"Dashboard\")])\\n' +\n '}\\n' +\n 'component userPage(id) {\\n' +\n ' return Card([CardHeader(`User ${id}`)])\\n' +\n '}\\n' +\n 'component docsPage(rest) {\\n' +\n ' return Card([CardHeader(`Docs · ${rest}`)])\\n' +\n '}\\n' +\n 'component notFoundPage() {\\n' +\n ' return Callout(\"Not found\", variant: \"warning\", description: `We couldn\\'t find ${_route_.path}.`)\\n' +\n '}\\n\\n' +\n 'nav${1} = Stack([\\n' +\n ' NavLink(\"Home\", to: \"/\", variant: \"ghost\", exact: true),\\n' +\n ' NavLink(\"Dashboard\", to: \"/dashboard\", variant: \"ghost\"),\\n' +\n ' NavLink(\"Users\", to: \"/users\", variant: \"ghost\")\\n' +\n '], direction: \"row\", gap: \"s\")',\n },\n {\n name: \"Effect\",\n description: \"Lifecycle-managed effect (clock/interval) with cleanup.\",\n template:\n '$${3:now} = \"\"\\n\\n' +\n 'effect [on:mount] {\\n' +\n ' let id = js{ setInterval(() => helpers.setState(\"${3:now}\", new Date().toISOString()), 1000) }\\n' +\n ' cleanup { js{ clearInterval(id) } }\\n' +\n '}\\n\\n' +\n 'body = Text($${3:now})',\n },\n {\n name: \"Action\",\n description: \"Action declaration that POSTs through the http() builtin.\",\n template:\n '$${1:items} = []\\n\\n' +\n 'action Add(text) {\\n' +\n ' $${1:items} = [...$${1:items}, { id: $${1:items}.length + 1, text: text }]\\n' +\n ' $response = http({ url: \"/api/save\", method: \"POST\", body: { item: { text: text } } })\\n' +\n '}',\n },\n {\n name: \"Each\",\n description: \"Iterate over an array using the expression-form `for` loop.\",\n template:\n 'list${1} = for item in $items {\\n' +\n ' Card([Text(item.${2:name})])\\n' +\n '}',\n },\n {\n name: \"FormReactive\",\n description: \"Two-way bound input with submit action.\",\n template:\n '$draft = \"\"\\n' +\n '$items = []\\n\\n' +\n 'action Add() {\\n' +\n ' $items = [...$items, { id: $items.length + 1, text: $draft }]\\n' +\n ' $draft = \"\"\\n' +\n '}\\n\\n' +\n 'form${1} = Stack([\\n' +\n ' Input(\"${2:draft}\", placeholder: \"What needs doing?\", type: \"text\", bind:value: $draft),\\n' +\n ' Button(\"Add\", action: Add, variant: \"primary\")\\n' +\n '])',\n },\n {\n name: \"Theme\",\n description: \"Brand-style theme override applied on top of the base theme.\",\n template:\n 'theme = Theme({\\n' +\n ' name: \"${1:brand}\",\\n' +\n ' colors: {\\n' +\n ' primary: \"${2:#0969da}\",\\n' +\n ' primaryHover: \"${3:#0860c4}\",\\n' +\n ' bg: \"${4:#ffffff}\",\\n' +\n ' text: \"${5:#1f2328}\"\\n' +\n ' },\\n' +\n ' radius: { button: \"${6:6px}\", input: \"${7:6px}\" },\\n' +\n ' font: {\\n' +\n ' family: \"${8:-apple-system, BlinkMacSystemFont, sans-serif}\",\\n' +\n ' heading: \"${9:-apple-system, BlinkMacSystemFont, sans-serif}\"\\n' +\n ' }\\n' +\n '})',\n },\n {\n name: \"Component\",\n description: \"Reusable component declaration — components MUST `return`.\",\n template:\n 'component ${1:UserCard}(${2:user}) {\\n' +\n ' return Card([\\n' +\n ' Avatar(${2:user}.name),\\n' +\n ' Text(${2:user}.role)\\n' +\n ' ])\\n' +\n '}\\n\\n' +\n 'list = for u in $users { ${1:UserCard}(u) }',\n },\n {\n name: \"If\",\n description: \"Expression-form `if`.\",\n template:\n 'body${1} = if ${2:condition} {\\n' +\n ' ${3:trueBranch}\\n' +\n '} else {\\n' +\n ' ${4:falseBranch}\\n' +\n '}',\n },\n {\n name: \"Match\",\n description: \"Pattern match on a value with arms.\",\n template:\n 'panel${1} = match ${2:$tab} {\\n' +\n ' \"overview\" : overviewPanel\\n' +\n ' \"billing\" : billingPanel\\n' +\n ' \"security\" : securityPanel\\n' +\n ' default : overviewPanel\\n' +\n '}',\n },\n {\n name: \"TemplateLiteral\",\n description: \"Template literal with `${}` interpolation.\",\n template: 'greeting${1} = `Hello ${${2:$user.name}}, you have ${${3:$messages.length}} messages`',\n },\n {\n name: \"Http\",\n description: \"Fire an http() request and bind the reactive resource bag.\",\n template:\n '$${1:response} = http({\\n' +\n ' url: \"${2:/api/items}\",\\n' +\n ' method: \"${3:GET}\",\\n' +\n ' headers: { \"Content-Type\": \"application/json\" }\\n' +\n '})',\n },\n {\n name: \"State\",\n description: \"Reactive state atom — declared with `$name = value`.\",\n template: '$${1:name} = ${2:\"default\"}',\n },\n {\n name: \"ResponsiveGrid\",\n description: \"Grid with a responsive column map per breakpoint.\",\n template: 'cards${1} = Grid(${2:items}, columns: {sm: 1, md: 2, lg: 4}, gap: \"${3:l}\")',\n },\n];\n\nexport function getSnippets(): readonly SnippetEntry[] {\n return snippetCatalog;\n}\n","/**\n * Reusable language-support module for Aktion.\n *\n * Framework-agnostic: this module ships pure data (grammar tokens, the\n * component catalog, builtins, snippets, theme names, severity tokens) plus\n * a lightweight stream tokenizer factory. It does not import CodeMirror,\n * Monaco, or any DOM API at the top level, so the same metadata can drive a\n * VS Code extension, a Monaco editor, a CodeMirror 6 instance, or pure-CLI\n * linting.\n *\n * Consume via `getLanguageSpec(library?)` — see `./README.md` for example\n * wiring against CodeMirror, Monaco, and VS Code.\n */\n\nimport type { ComponentLibrary } from \"../library/types.js\";\nimport { defaultLibrary } from \"../library/index.js\";\nimport { builtInThemes } from \"../theme/index.js\";\n\nimport {\n grammarSpec,\n createStreamTokenizer,\n defaultTagMap,\n type GrammarSpec,\n type GrammarTokenKind,\n type StreamTokenizer,\n} from \"./grammar.js\";\nimport {\n getComponentCatalog,\n indexCatalog,\n type ComponentEntry,\n type ComponentParam,\n} from \"./components.js\";\nimport {\n getBuiltinCatalog,\n indexBuiltins,\n type BuiltinEntry,\n type BuiltinParam,\n} from \"./builtins.js\";\nimport { getSnippets, type SnippetEntry } from \"./snippets.js\";\n\nexport type {\n GrammarSpec,\n GrammarTokenKind,\n StreamTokenizer,\n ComponentEntry,\n ComponentParam,\n BuiltinEntry,\n BuiltinParam,\n SnippetEntry,\n};\n\nexport {\n grammarSpec,\n createStreamTokenizer,\n defaultTagMap,\n getComponentCatalog,\n indexCatalog,\n getBuiltinCatalog,\n indexBuiltins,\n getSnippets,\n};\n\n/**\n * Diagnostic severity buckets that map to common editor lint levels.\n * Editors typically map: `error` → red squiggle, `warning` → yellow,\n * `info` → blue, `hint` → grey.\n */\nexport type DiagnosticSeverity = \"error\" | \"warning\" | \"info\" | \"hint\";\n\nexport interface LanguageSpec {\n grammar: GrammarSpec;\n /** Build a fresh tokenizer instance suitable for CodeMirror StreamLanguage. */\n tokenizer: StreamTokenizer;\n /** Map from grammar token kind → CodeMirror highlight tag name. */\n tagMap: Record<GrammarTokenKind, string | null>;\n components: ComponentEntry[];\n componentsByName: Record<string, ComponentEntry>;\n builtins: BuiltinEntry[];\n builtinsByName: Record<string, BuiltinEntry>;\n snippets: readonly SnippetEntry[];\n /** Built-in theme names; useful for theme-picker autocomplete. */\n themeNames: readonly string[];\n /** Default severity for the parser's ParseError stream. */\n severityTokenMap: Record<\"parse-error\", DiagnosticSeverity>;\n /**\n * Font Awesome icon aliases used by components that accept `icon: string`.\n * Editors can use these to power icon-name autocomplete.\n */\n iconAliases: readonly string[];\n}\n\n/**\n * Build a complete language spec ready for editor consumption. Pass a custom\n * `ComponentLibrary` if your host has registered extra components via\n * `<aktion-app>.registerComponents([...])` — the returned spec will\n * include them in autocomplete and inspection tooltips.\n */\nexport function getLanguageSpec(library: ComponentLibrary = defaultLibrary): LanguageSpec {\n const components = getComponentCatalog(library);\n const builtins = getBuiltinCatalog();\n return {\n grammar: grammarSpec,\n tokenizer: createStreamTokenizer(grammarSpec),\n tagMap: defaultTagMap,\n components,\n componentsByName: indexCatalog(components),\n builtins,\n builtinsByName: indexBuiltins(builtins),\n snippets: getSnippets(),\n themeNames: Object.keys(builtInThemes),\n severityTokenMap: { \"parse-error\": \"error\" },\n iconAliases: COMMON_ICON_ALIASES,\n };\n}\n\n/**\n * A pragmatic shortlist of Font Awesome icon names that the design system\n * uses in templates. Editors get a useful autocomplete without us shipping\n * the full FA dictionary (which is ~2 MB).\n */\nconst COMMON_ICON_ALIASES: readonly string[] = [\n \"house\", \"user\", \"users\", \"gear\", \"bell\", \"envelope\", \"magnifying-glass\",\n \"plus\", \"minus\", \"pen\", \"trash\", \"check\", \"xmark\", \"arrow-right\", \"arrow-left\",\n \"arrow-up\", \"arrow-down\", \"chevron-right\", \"chevron-left\", \"chevron-down\",\n \"chevron-up\", \"ellipsis\", \"ellipsis-vertical\", \"star\", \"heart\", \"bookmark\",\n \"calendar\", \"clock\", \"file\", \"folder\", \"image\", \"video\", \"music\",\n \"chart-line\", \"chart-bar\", \"chart-pie\", \"gauge\", \"table\",\n \"circle-info\", \"circle-check\", \"circle-exclamation\", \"circle-question\",\n \"triangle-exclamation\", \"shield\", \"lock\", \"unlock\", \"key\", \"rocket\",\n \"bolt\", \"fire\", \"snowflake\", \"sun\", \"moon\", \"cloud\", \"code\", \"terminal\",\n \"database\", \"server\", \"globe\", \"link\", \"share\", \"download\", \"upload\",\n \"filter\", \"sort\", \"list\", \"grid\", \"columns\", \"sidebar\", \"bars\",\n \"tag\", \"tags\", \"flag\", \"trophy\", \"medal\", \"gift\", \"cart-shopping\",\n \"credit-card\", \"money-bill\", \"receipt\", \"wallet\", \"comment\", \"comments\",\n \"paper-plane\", \"inbox\", \"paper-clip\", \"phone\", \"video-camera\",\n \"play\", \"pause\", \"stop\", \"forward\", \"backward\", \"expand\", \"compress\",\n \"eye\", \"eye-slash\", \"thumbs-up\", \"thumbs-down\", \"thumbtack\",\n];\n","/**\n * Public entry point.\n *\n * Importing this file (or loading the bundled script) registers the\n * `<aktion-app>` custom element. All public types and helpers are\n * also re-exported so consumers can use them programmatically.\n */\n\nimport { AktionElement, defineElement } from \"./element.js\";\n\nexport { AktionElement, defineElement };\n\nexport * from \"./parser/index.js\";\nexport * from \"./runtime/index.js\";\nexport * from \"./library/index.js\";\nexport * from \"./renderer/index.js\";\nexport * from \"./prompt/index.js\";\nexport * from \"./theme/index.js\";\nexport * from \"./language/index.js\";\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"aktion-app\": AktionElement;\n }\n}\n\ndefineElement();\n\n// Build script also writes the system prompt to dist/system_prompt.txt; this\n// constant lets consumers read the same text at runtime without an HTTP call.\nimport { generatePrompt } from \"./prompt/generator.js\";\nimport { defaultLibrary } from \"./library/index.js\";\n\nexport const SYSTEM_PROMPT_TEXT = generatePrompt(defaultLibrary);\n"],"names":["KEYWORDS_AKTION","SINGLE_CHAR_PUNCT","KEYWORDS","tokenize","source","tokens","i","line","column","peek","offset","push","type","value","startLine","startCol","advance","ch","quote","escaped","parts","chunk","sawExpr","exprLine","exprCol","depth","source2","next","q","lastToken","allowSignedNumber","isDigit","raw","sawDot","name","isIdentifierChar","err","isIdentifierStart","lookahead","s","body","keyword","two","parse","ctx","ParserContext","statements","errors","stmt","parseStatement","error","_topLevel","head","parseComponentDecl","parseEffectDecl","parseActionDecl","parseEmit","parseCleanup","parseAwait","parseReturn","saved","couldStartAssignment","parseAssignment","parseExpressionStatement","start","expression","parseExpression","nameTok","params","slots","parseComponentSignature","parseBlock","tok","slotTok","defaultValue","triggers","rateLimit","parseEffectDependency","rl","decl","setRateLimit","lifecycle","arg","kind","consumeLegacyUsesClause","optimistic","firstArg","detail","props","parseObjectProps","callback","argument","__publicField","index","identifier","isState","savedIndex","parsedParams","ok","eq","parseTernary","test","parseLogicalOr","consequent","alternate","left","parseLogicalAnd","op","right","parseEquality","parseComparison","parseAdditive","parseMultiplicative","parseUnary","parsePostfix","expr","parsePrimary","propTok","after","args","parseCallArgs","computed","parseIfExpression","parseMatchExpression","parseForExpression","nxt","quasis","expressions","pendingChunk","hasPendingChunk","flushChunk","part","firstStmt","elements","properties","lambda","tryParseLambdaFromParenList","opts","allowNamed","parseCallArgItem","parseArgItem","target","discriminant","arms","pattern","item","destructure","fields","iterable","param","parseAssignmentLikeExpression","keyTok","key","computeFrontier","program","buildFrontier","errorLines","e","committed","drafting","stmtLine","committedSource","draftingSource","firstErrorLine","split","splitSourceAtLine","splitIndex","bindingNameOf","n","isQuiescent","frontier","deps","current","applyDelta","ops","warnings","stateUpdates","programText","result","applyStructural","sub","snippet","sep","idx","findBindingIndex","spliceLines","itemStmt","rebuilt","stringifyExpression","bindingName","replacement","lines","endLine","before","p","obj","indexCache","getIndex","library","spec","mergeLibraries","base","extra","map","c","findComponent","findPositionalIndex","explicit","findPositionalProp","assertOnePositionalMax","specs","positional","names","mapPositionalArgs","out","prop","validateProgram","schemaErrors","validateProgramSchema","walkStatement","walkExpression","inner","validateCall","validateBuiltinCall","arm","LEGACY_V1_CALLS","legacy","validateThemeCall","propNames","alias","positionalArgs","positionalName","namedNames","a","extras","hints","v","STRUCTURED_THEME_GROUPS","THEME_METADATA_KEYS","suggestion","suggestStructuredKey","message","LEGACY_V1_BUILTINS","flatKey","groups","prefix","group","tail","toNumber","toArray","compare","b","haystack","needle","getField","field","cursor","filterByField","arr","isObject","toDate","d","MONTHS_SHORT","MONTHS_LONG","DAYS_SHORT","DAYS_LONG","formatDateTokens","date","pad","w","hours","hour12","re","formatRelative","now","diff","abs","future","minute","hour","day","week","month","year","unit","recase","input","cap","dataBuiltins","acc","direction","av","bv","decimals","factor","end","seen","step","keys","k","mode","opt","currency","locale","days","singular","plural","text","search","min","max","isThemeNode","StateStore","adapter","initial","stored","snapshot","dirty","fallback","declarations","subscriber","changes","createLocalStorageAdapter","keyPrefix","storage","fullKey","HttpRuntime","defaults","interceptors","url","req","exec","controller","timeoutMs","timeoutId","fetchFn","init","encodeBody","response","headers","contentType","retryCfg","maxRetries","backoffMode","execWithRetry","lastErr","attempt","sleep","computeBackoff","retried","retry","ms","resolve","buildRequestFromConfig","config","cfg","method","finalUrl","qs","createHttpResource","resource","run","inFlight","notify","normalisePath","queryAt","matchRoute","path","normPattern","normPath","patternSegments","pathSegments","wildcard","patternSegment","rest","pathSegment","Router","options","sync","hashPath","listener","shallowEqual","previousPath","aKeys","bKeys","safeRun","fn","serialise","deserialise","createWebStorageNamespace","getBackend","backend","getLocalBackend","getSessionBackend","getDocument","formatExpires","parsed","buildCookieAttributes","expires","readAllCookies","doc","pair","trimmed","cookies","encodedKey","encodedValue","all","local","session","METHODS","getNativeConsole","forward","native","consoleNs","GLOBAL_NAMESPACES","storageGlobal","consoleGlobal","isComponentNode","isUserComponentNode","createContext","state","paramArgs","callArgs","resolveStateAlias","aliased","planProgram","evaluateLiteral","evaluate","installStatementBinding","evaluateRouterCall","loc","readRoutePath","wildcardArm","runRouterArm","prev","had","buildRouteState","binding","action","makeActionCallable","resolved","element","computedMemberAccess","memberAccess","evaluateBinary","evaluateComponentCall","evaluateMethodCall","evaluateBuiltinCall","evaluateTemplate","evaluateIf","evaluateMatch","evaluateFor","evaluateBlock","lambdaParams","lambdaBody","capturedAliases","frame","capturedLoopVars","restoreLoopVars","restoreAliases","restore","slot","iterableValue","itemHad","itemPrev","idxName","idxHad","idxPrev","destructurePrev","row","entry","block","introduced","stringify","leftExpr","rightExpr","r","named","hasNamed","callee","componentDecl","invokeComponentDecl","actionDecl","evaluated","invokeActionDecl","optsArg","localHelper","tokensArg","collectThemeTokens","configArg","explicitKey","propArgs","argMeta","resolveLibraryCallArgs","slotByName","positionalIndex","positionals","positionalExprs","explicitKeyExpr","flatPositional","evaluatedNamed","evaluateUserComponent","node","instanceKey","childrenValue","slotsValue","slotName","aliasFrame","instanceName","evaluateSyntheticAssign","evaluateSyntheticPostfix","sourceArg","varNameArg","templateArg","sourceValue","varName","destructuring","parseDestructureNames","snapshots","condArg","thenArg","elseArg","valueArg","casesArg","defaultArg","keyArg","varsArg","vars","applyAssignOp","divisor","targetExpr","valueExpr","opExpr","rhs","delta","f","braceIdx","scalar","closeIdx","router","query","usp","toArrayIndex","length","property","innerKey","innerValue","capitalise","stringifyTokenValue","ownToString","str","I18nRuntime","sanitiseMessages","readPath","interpolate","messages","segment","template","_","EffectRunner","decls","getCtx","incoming","mounted","runBody","wrapRateLimit","logCleanupError","runEffectBody","hasMountTrigger","hasUnmountTrigger","hasEveryTrigger","trigger","id","targetName","unsub","changed","t","timer","cancel","lastFired","pending","elapsed","runStatement","cb","executeJsBlock","createInlineJsExecutor","ownerName","blockCtx","ActionDeclRunner","snapshotState","lastValue","restoreState","unwrapPromise","FONT_AWESOME_CDN_URL","FONT_AWESOME_VERSION","LINK_MARKER_ATTR","SUPPORTED_VARIANTS","DEFAULT_VARIANT","ensureFontAwesomeLoaded","shadow","injectLink","root","isHappyDomEnvironment","link","resolveIconClasses","sanitized","stripInvisibleModifiers","isAsciiIconName","variant","splitVariant","INVISIBLE_MODIFIER_RE","ICON_SIZES","el","tag","attrs","children","child","asArray","asString","asBoolean","asNumber","RESPONSIVE_BREAKPOINTS","readResponsiveProp","entries","values","matched","CSS_URL_FORBIDDEN","sanitiseCssUrl","CSS_LENGTH_ALLOWED","sanitiseCssLength","SAFE_HREF_SCHEMES","sanitiseHref","cleaned","schemeMatch","scheme","SAFE_IMAGE_SCHEMES","sanitiseImageSrc","renderIcon","classes","wrapperClass","GRID_COLUMNS","FLEX_ALIGN","FLEX_JUSTIFY","mapFlexAlign","token","mapFlexJustify","applyDirectionWithReverse","reverse","emitResponsiveSpacingVars","styleParts","cssPrefix","bp","emitResponsiveFlexVars","mapper","applyResponsiveEnumProp","isComponentNamed","stackBaseDirection","StackItem","_node","helpers","basis","alignSelf","order","minWidth","maxWidth","Stack","gap","padding","uniformDefault","uniform","dir","alignContent","Card","CardHeader","subtitle","CardFooter","Separator","orientation","decorative","label","renderStepLi","title","details","active","Steps","data","TabItem","wrapper","Tabs","items","tablist","panels","fallbackValue","first","activeSlot","setActive","originBtn","liveRoot","isActive","tabNode","badge","icon","button","iconNode","renderIconForTab","event","origin","horizontal","isNext","isPrev","liveList","currentIdx","nextIdx","nextValue","panel","iconName","AccordionItem","summary","Accordion","clampGridColumns","resolveSpan","span","numPart","denPart","num","den","gridMinChildWidth","width","GridItem","baseSpan","spanAt","Box","margin","mar","Grid","hasGridItems","columns","rowGap","columnGap","twelveColMode","explicitNonTwelve","requested","cols","minChild","alignItems","justifyItems","AspectRatio","ratio","parseRatio","h","ScrollArea","Modal","size","closable","overlay","dialog","header","stateName","closeModal","closeBtn","footer","footRow","ICON_VARIANTS","SIZE_ENUM","TONE_ENUM","normaliseSize","Icon","composed","TEXT_VARIANTS","sanitiseInlineStyle","TEXT_PROPS","renderText","tone","style","Text","TextContent","Image","parseImageRatio","safeSrc","placeholder","Link","external","safeHref","BADGE_VARIANTS","Badge","BadgeList","pill","Callout","compact","defaultCalloutIcon","desc","CodeBlock","language","code","showLineNumbers","highlights","parseLineRanges","showCopy","copyBtn","copyIcon","clipboard","original","pre","codeEl","lineText","lineNumber","Skeleton","shape","renderShapeSkeleton","renderVariantSkeleton","rawLines","rawHeight","lineHeight","heightInput","height","cells","Markdown","html","renderMarkdown","Container","Spacer","flex","Spinner","Quote","cite","escape","listMode","inQuote","inCode","codeLang","codeBuf","closeList","closeQuote","flushCode","lang","rawLine","fenceMatch","heading","level","inline","quoteMatch","ulMatch","olMatch","_match","alt","rawSrc","src","escapeAttr","rawHref","sanitizeMarkdownHref","renderAvatar","img","ev","initialsFor","DISMISS_REGISTRY","installDismissListeners","onDismiss","existing","host","disposed","onOutside","handle","onKey","ownerDoc","observer","observeRoot","disposeDismissListeners","ICON_KEYWORD_RULES","pickIconForLabel","rule","TONE_ICONS","pickIconForTone","dicebearUrlFor","seed","extractComboboxItems","BUTTON_VARIANTS","BUTTON_SIZES","INPUT_TYPES","normaliseButtonSize","Button","loading","iconOnly","iconPosition","labelText","labelSpan","adornment","Buttons","Input","bindToStateAtArg","applyValidations","TextArea","textarea","SelectItem","Select","renderSearchableSelect","select","Checkbox","isChecked","CheckBoxItem","itemName","description","CheckBoxGroup","groupName","valueObject","defaultChecked","rootEl","Radio","itemRoot","FormControl","fieldEl","hint","SearchBar","iconWrap","shortcut","btn","Form","form","actions","Slider","showValue","valueEl","NumberInput","hasMin","hasMax","disabled","decBtn","incBtn","adjust","live","clampNumber","DatePicker","FileUpload","dropZone","isImageFile","file","accept","fileInput","uploadRoot","files","preview","objectUrl","Combobox","currentValue","currentLabel","emptyLabel","initialOpen","openSlot","filterSlot","isOpen","triggerBtn","chevron","filterInput","list","renderList","filter","lower","matches","option","selectComboboxValue","firstOption","MultiSelect","selected","selectedSet","chipRow","writeSelection","chip","removeBtn","isSelected","atCap","checkbox","checkIcon","DateRangePicker","fromId","toId","fromInput","toInput","fromState","toState","meta","argIndex","validations","SURFACE_TONES","renderActionsRow","HERO_EYEBROW_RULES","deriveHeroEyebrow","Hero","layout","heroTitle","heroSubtitle","eyebrow","safeImageSrc","safeHeight","caption","ctaItems","ctas","cta","heroImageSrc","tags","media","PageHeader","crumbs","crumbWrap","titleRow","titleBlock","titleLine","EmptyState","illustration","wrap","TimelineItem","li","marker","time","Timeline","FeatureItem","FeatureGrid","Testimonial","rating","stars","filled","avatarSrc","role","ProfileCard","bio","tagRow","Comment","Banner","msg","KanbanCard","titleEl","assignee","KanbanColumn","KanbanBoard","SectionHeader","Toolbar","center","centerWrap","SidebarItem","SidebarSection","Sidebar","collapsed","brand","tagline","footerItems","AppShell","collapsible","sidebarOpen","sidebarHost","scrim","main","topbar","bar","toggle","content","SplitView","primary","DescriptionItem","labelWrap","DescriptionList","StatusDot","PricingCard","featured","priceRow","period","features","check","PricingTable","tier","MediaCard","parseMediaRatio","imageSrc","badgeWrap","renderInlineSparkline","svgNS","svg","range","linePath","x","y","areaPath","area","Stats","hasComponentItems","gridNode","align","valueRow","sparkValues","Tile","isClickable","Notification","PersonChip","avatarSize","avatarWrap","status","COL_ALIGN","Col","Table","density","striped","sticky","table","aligns","col","thead","headRow","th","tbody","columnValues","formats","rowCount","tr","cell","format","td","formatCell","emptyRow","ListItem","List","StatCard","labelRow","trend","trendArrow","spark","sparkWrap","Sparkline","TreeNode","hasChildren","expanded","childList","Tree","PALETTE","colorAt","Series","readSeries","BarChart","labels","l","series","labelPlan","planLabels","innerWidth","innerHeight","createSvg","drawAxes","groupCount","groupWidth","seriesCount","barWidth","sIdx","gIdx","barHeight","rect","svgEl","drawXAxisLabels","legend","LineChart","rows","derivedLabels","seriesByKey","stacked","pointCount","stackedValues","denominator","stepX","xForPoint","baseline","points","baselinePoints","last","PieChart","total","cx","cy","angle","slice","large","x1","y1","x2","y2","APPROX_CHAR_PX","MIN_ROTATED_SLOT_PX","longest","maxChars","truncateLabel","_innerWidth","plan","xFor","baseY","display","SectionBlock","ListBlock","FollowUpBlock","buildFollowUpButton","extractFollowUp","FollowUpItem","ActionLink","AVATAR_SIZES","Avatar","explicitSrc","generated","AvatarGroup","visible","overflow","Progress","indeterminate","percent","segments","buffered","trackRoot","track","bufferedPercent","Switch","ToggleGroup","extractToggleItem","isOn","itemIconNode","Tooltip","HoverCard","card","RATING_ICONS","Rating","interactive","halfStep","iconChoice","resolveRatingIcons","fill","iconClasses","star","fullValue","halfValue","evt","count","ProgressRing","px","stroke","circumference","rawLabel","labelIcon","ChatBubble","from","renderAvatarFallback","bubble","Kbd","Popover","triggerWrap","titleText","setPopoverOpen","installPopoverDismiss","Toast","position","defaultToastIcon","actionWrap","dismissedSlot","timerSlot","liveToast","cancelTimer","removalTimerSlot","dismiss","duration","BreadcrumbItem","Breadcrumb","separator","isLast","PER_PAGE_OPTIONS","Pagination","siblings","setPage","clamped","totalRecords","perPageValue","buttonsWrap","pageNumbers","computePageNumbers","perPageState","perPageWrap","optEl","pages","to","totalNumbers","leftSibling","rightSibling","NavbarItem","tagName","Navbar","brandWrap","MENU_SIDES","MENU_ALIGNS","MENU_VARIANTS","setDropdownOpen","installOutsideClickClose","isMenuChild","DropdownMenu","MenuItem","MenuSeparator","MenuLabel","readDataGridCols","compareCells","ta","tb","formatCellValue","DataGrid","rowIds","idFor","rowIdx","sortState","sortKey","sortDir","selectedIds","selectable","stickyHeader","stickyFirst","filters","indices","keep","term","sortCol","cmp","totalAfterFilter","perPage","totalPages","rawPage","page","sortStateName","selectedStateName","pageStateName","toolbarChildren","tools","tableWrap","allSelected","dirIcon","dirNode","nextDir","filterRow","liveTbody","requestRebody","renderBody","cellTd","cellValue","liveOverride","localFilters","filtered","pageRows","startIdx","endIdx","buttons","readCalendarEvents","startOfWeek","weekStartsOn","formatIsoDate","m","CalendarView","view","events","valueRaw","monthRaw","today","refDate","valueIso","eventsByDate","onSelectState","monthLabel","weekRow","dayLabels","anchor","firstOfMonth","lastOfMonth","gridStart","totalDays","grid","todayIso","iso","isToday","cellEvents","dayBtn","evts","visibleEvents","readFeedEntries","renderFeed","klass","ActivityLog","ComparisonTable","highlightIdx","currentGroup","groupRow","labelCell","InfiniteList","hasMore","sentinel","spin","SAFE_MEDIA_SCHEMES","sanitiseMediaSrc","VideoPlayer","playerWrap","showControls","video","sources","AudioPlayer","artist","audio","renderCarouselSlide","captionText","Carousel","defaultIdx","showDots","showArrows","slide","rendered","move","liveTrack","dot","prevIcon","nextIcon","dots","_item","Gallery","extractGalleryItem","clickable","tile","Lightbox","indexStateName","openStateName","internalOpen","internalIndex","rawIndex","setOpen","setIndex","close","thumb","safeThumb","imageWrap","parseLatLng","lat","lng","Map","frameWrap","zoom","iframe","markers","pin","pinIcon","DEFAULT_RTE_TOOLS","RichTextEditor","toolbar","tool","editor","isEmpty","refreshEmpty","CodeEditor","showGutter","tabSize","readonly","minHeight","gutter","liveGutter","indent","extractContextItem","ContextMenu","menu","closeAll","open","clientX","clientY","liveMenu","DEFAULT_SWATCHES","normaliseHex","hex","ColorPicker","colorInput","textInput","swatchRow","swatches","palette","swatch","safeHex","Gauge","pct","half","startX","startY","endX","endY","autoLabel","formatGaugeValue","Heatmap","xLabels","yLabels","valueRows","headerRow","rIdx","rowEl","cIdx","intensity","RadarChart","axes","rings","radius","j","labelX","labelY","readScatterSeries","ScatterChart","xs","ys","minX","maxX","minY","maxY","xRange","yRange","drawHorizontalGrid","pt","circle","seriesData","Histogram","bins","binCount","counts","formatBinLabel","bin","PIN_TYPES","renderPin","mask","onChange","inputs","getLiveSlots","pinRoot","collectLive","liveSlots","chars","lastFilled","PinInput","passwordStrength","score","PasswordInput","visibleSlot","toggleBtn","toggleIcon","liveInput","strength","meter","TagInput","setTags","remove","readMentionItems","MentionInput","people","suggestions","renderSuggestions","insertMention","caret","triggerIdx","insert","match","TimePicker","DateTimePicker","applyMask","MaskedInput","FormSection","helper","FieldSet","ValidationSummary","titleNode","readSteps","MultiStepForm","steps","stepsEl","prevBtn","isFinal","nextLabel","nextBtn","readInboxEntries","InboxPanel","unread","read","renderGroup","groupHead","readChecklistItems","OnboardingChecklist","completed","renderStateCard","LoadingState","spinner","ErrorState","SuccessState","Tour","skip","Spotlight","Sticky","side","z","styles","ResizablePanels","divider","secondary","onMove","moveEvent","onUp","upEvent","MasonryGrid","Drawer","footerRow","TopBar","Theme","NavLink","exact","currentPath","readChipList","readPlainObjects","readCommandItems","readFields","readGanttTasks","parseIsoDate","diffLines","la","lb","jsonPreview","appendJsonChildren","container","val","buildJsonTree","isArray","liveToggle","liveChildren","IconButton","CommandPalette","propProvided","propOpen","backdrop","shell","paintList","lastGroup","liveHost","liveShell","FilterChips","chips","xIcon","clear","FieldRepeater","add","VirtualList","itemHeight","rawItems","viewport","scrollEl","spacer","windowEl","renderSlice","startIndex","viewHeight","QueryBuilder","rules","stateRef","paint","fieldSelect","opSelect","valueInput","DiffViewer","panes","leftPane","rightPane","JsonTree","Gantt","tasks","starts","ends","rangeStart","rangeEnd","task","barWrap","startPct","widthPct","Truncate","maxLines","expandedSlot","clampStyle","liveBody","InlineEdit","editingSlot","draftSlot","resolveLive","commit","draft","kev","NotificationBell","bell","liveTrigger","renderChild","isResourceShape","components","mount","loader","errorWrapper","componentGroups","defaultLibrary","ROOT_PATH","Renderer","disposers","dispose","alive","sepIdx","instancePath","fragment","ctxRef","keyPart","keySuffix","childCounter","childValue","callable","safeUrl","opener","propKey","getter","initialValue","storageKey","cleanup","bucket","prior","EVENT_PROPS","morphChildren","newRoot","newChildren","reconcileChildren","morphNode","oldNode","newNode","replaceNode","oldEl","newEl","patchElement","syncAttributes","syncEventHandlers","syncFormState","oldAttrs","attr","newAttrs","fresh","syncInput","syncTextArea","isFocused","desired","parent","keyedOld","keyFor","cursorIndex","newChild","newKey","liveKey","surplus","dataKey","DATA_DESCRIPTIONS","ITERATION_ENTRIES","buildSignature","finalize","getBuiltinCatalog","indexBuiltins","ROOT_NAME","generatePrompt","buildChatPrompt","buildFullPrompt","describeComponentSpec","formatComponentSignature","hasTools","flags","sections","fullHeader","fullMentalModel","fullSyntax","fullReactiveState","fullComponentsAndLambdas","fullActions","fullEffects","fullHttp","fullControlFlow","fullRouting","fullTwoWayBinding","fullJsEscape","fullBuiltins","fullHelpers","fullGlobals","fullI18n","fullTheming","fullIcons","fullComponentLibrary","fullInlineMode","fullEditMode","toolsListSection","examplesSection","examples","fullDefaultExamples","rulesSection","fullStreaming","fullOutputRules","fullFinalVerification","chatHeader","chatSyntax","chatComponentLibrary","chatIcons","chatBuiltins","chatStreaming","chatToolsList","chatDefaultExamples","chatImportantRules","chatFinalVerification","preamble","formatBuiltinCatalog","allGroups","byName","componentName","note","grouped","g","ungrouped","CHAT_COMPONENT_ALLOWLIST","catalog","iter","dataLines","formatBuiltinEntry","iterLines","typePart","positionalTag","example","argsLine","lightTheme","darkTheme","neonTheme","pastelTheme","glassTheme","brutalistTheme","skylineTheme","builtInThemes","TOKEN_TO_CSS","resolveTheme","mergeTheme","applyTheme","theme","cssVar","applyPartialTheme","partial","applied","clearTokenOverrides","sanitiseThemeTokens","componentStyles","ATTRIBUTE_THEME","ATTRIBUTE_STREAMING","ATTRIBUTE_RESPONSE","ATTRIBUTE_SHOW_ERRORS","STATE_ROUTE","buildRouteObject","routesEqual","shallowEqualObject","sharedStyleSheet","sharedStyleSheetSupported","getSharedStyleSheet","sheet","_AktionElement","dispatchAssistantMessage","emit","eventName","responseAttr","_old","payload","rootName","parseBooleanAttribute","themeBinding","appBinding","rootValue","focusSnapshot","cssEscapeId","applySelectionRange","effectDecls","AktionElement","SELECTION_UNSUPPORTED_TYPES","previousType","normalized","defineElement","grammarSpec","createStreamTokenizer","startState","copyState","atomSet","componentCallRe","lowerIdentRe","numberRe","operatorChars","consumeStringBody","stream","defaultTagMap","projectParam","buildGroupIndex","getComponentCatalog","groupOf","indexCatalog","snippetCatalog","getSnippets","getLanguageSpec","builtins","COMMON_ICON_ALIASES","SYSTEM_PROMPT_TEXT"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}