{
  "version": 1.1,
  "globalAttributes": [
    {
      "name": "state",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Declares reactive state. Value is a JS object literal.\n\n```html\n<div state=\"{ count: 0, name: 'World' }\">\n```\n\n**Companions:** `persist`, `persist-key`, `persist-fields`, `persist-schema`"
      }
    },
    {
      "name": "store",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Declares a named global store.\n\n```html\n<div store=\"cart\" value=\"{ items: [], total: 0 }\">\n```\n\n**Companion:** `value`"
      }
    },
    {
      "name": "computed",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Declares a computed property.\n\n```html\n<div computed=\"fullName\" expr=\"firstName + ' ' + lastName\">\n```\n\n**Companion:** `expr`"
      }
    },
    {
      "name": "watch",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Watches an expression for changes.\n\n```html\n<div watch=\"count\" on:change=\"console.log($old, $new)\">\n```\n\n**Companion:** `on:change`\n\n**Limitation:** On form controls, avoid combining with `on:change` — both claim the change event."
      }
    },
    {
      "name": "get",
      "description": {
        "kind": "markdown",
        "value": "No.JS: HTTP GET request.\n\n```html\n<div get=\"/api/users\" as=\"users\" loading=\"spinner-tpl\">\n```\n\n**Companions:** `as`, `loading`, `error`, `empty`, `success`, `then`, `redirect`, `confirm`, `refresh`, `cached`, `body`, `headers`, `var`, `into`, `retry`, `retry-delay`, `params`, `debounce`"
      }
    },
    {
      "name": "post",
      "description": {
        "kind": "markdown",
        "value": "No.JS: HTTP POST request. Same companions as `get`.\n\n```html\n<form post=\"/api/users\" body=\"{ name: name }\" as=\"result\">\n```"
      }
    },
    {
      "name": "put",
      "description": {
        "kind": "markdown",
        "value": "No.JS: HTTP PUT request. Same companions as `get`."
      }
    },
    {
      "name": "patch",
      "description": {
        "kind": "markdown",
        "value": "No.JS: HTTP PATCH request. Same companions as `get`."
      }
    },
    {
      "name": "delete",
      "description": {
        "kind": "markdown",
        "value": "No.JS: HTTP DELETE request. Same companions as `get`."
      }
    },
    {
      "name": "query",
      "description": {
        "kind": "markdown",
        "value": "No.JS: HTTP QUERY request (RFC 10008) — a safe, idempotent, cacheable method that carries a request body. Behaves like `get` on non-form elements (auto-fires, trigger modes) and intercepts submit on `<form>`. Companions include `query-trigger`, `query-trigger-label`, `query-threshold`.\n\n```html\n<form query=\"/orders\" body=\"{ status, minTotal }\" as=\"result\">\n```"
      }
    },
    {
      "name": "bind",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Binds element text content to a JS expression.\n\n```html\n<span bind=\"user.name\">\n```\n\n**Limitation:** Do not use with `t` on the same element — both write text content."
      }
    },
    {
      "name": "bind-html",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Binds element innerHTML to a JS expression.\n\n```html\n<div bind-html=\"richContent\">\n```"
      }
    },
    {
      "name": "model",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Two-way data binding for form elements (INPUT, SELECT, TEXTAREA).\n\n```html\n<input model=\"username\">\n```\n\n**Limitation:** Do not use with `bind-value` on the same element — duplicate two-way bindings."
      }
    },
    {
      "name": "if",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Conditionally renders element. Removes from DOM when false.\n\n```html\n<div if=\"isLoggedIn\">Welcome!</div>\n<div else>Please log in</div>\n```\n\n**Companions:** `then`, `else`, `animate-enter`, `animate-leave`, `transition`, `animate-duration`\n\n**Limitation:** Do not place `if` and a loop on the same element. Use the loop's `filter` attribute or a wrapper element."
      }
    },
    {
      "name": "else-if",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Conditional branch after `if`.\n\n```html\n<div else-if=\"isAdmin\">Admin panel</div>\n```\n\n**Companion:** `then`"
      }
    },
    {
      "name": "else",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Fallback branch after `if`/`else-if`. No value needed.\n\n**After conditional:**\n```html\n<div if=\"isLoggedIn\">Welcome!</div>\n<div else>Please log in</div>\n```\n\n**On loop elements** (`each`/`foreach`/`for`), `else=\"templateId\"` is the empty-state companion — the referenced template (bare id or `#id`) renders when the list is empty, null/undefined, or not an array.\n\nA bare `else` with no preceding `if`/`else-if` sibling is invalid — No.JS logs a console warning.\n\n**Companion:** `then`"
      },
      "valueSet": "v"
    },
    {
      "name": "show",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Toggles element visibility via CSS `display`. Element stays in DOM.\n\n```html\n<div show=\"isVisible\">Visible content</div>\n```\n\n**Companions:** `animate-enter`, `animate-leave`, `transition`, `animate-duration`"
      }
    },
    {
      "name": "hide",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Opposite of `show`. Hides element via CSS `display: none`.\n\n```html\n<div hide=\"isLoading\">Content</div>\n```\n\n**Companions:** `animate-enter`, `animate-leave`, `transition`, `animate-duration`"
      }
    },
    {
      "name": "switch",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Switch statement. Children use `case`, `default`, `then`.\n\n```html\n<div switch=\"role\">\n  <p case=\"admin\">Admin panel</p>\n  <p case=\"user\">User dashboard</p>\n  <p default>Guest view</p>\n</div>\n```"
      }
    },
    {
      "name": "each",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Self-repeating loop — the element with `each` IS the template that gets cloned for each item. Syntax: `\"item in list\"`.\n\n```html\n<ul>\n  <li each=\"user in users\" bind=\"user.name\"></li>\n</ul>\n```\n\n**Empty list fallback:**\n```html\n<li each=\"user in users\" else=\"noUsersTpl\" bind=\"user.name\"></li>\n<template id=\"noUsersTpl\"><li>No users found</li></template>\n```\nThe `else` template (bare id or `#id`) renders when the list is empty (`[]`) or null/undefined/not an array.\n\nLoop context: `$index`, `$count`, `$first`, `$last`, `$even`, `$odd`\n\n**Companions:** `template`, `else` (template ID), `key`, `animate-enter`, `animate-leave`, `animate-stagger`, `animate-duration`"
      }
    },
    {
      "name": "foreach",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Primary self-repeating loop — the element with `foreach` IS the template that gets cloned for each item. Syntax: `\"item in list\"`. Aliases: `each`, `for`.\n\n**Self-repeating (recommended):**\n```html\n<ul>\n  <li foreach=\"user in users\" bind=\"user.name\"></li>\n</ul>\n```\n\n**Empty list fallback:**\n```html\n<li foreach=\"user in users\" else=\"noUsersTpl\" bind=\"user.name\"></li>\n<template id=\"noUsersTpl\"><li>No users found</li></template>\n```\nThe `else` template (bare id or `#id`) renders when the list is empty (`[]`) or null/undefined/not an array.\n\n**External template:**\n```html\n<li foreach=\"item in products\" template=\"item-tpl\"></li>\n```\n\nLoop context: `$index`, `$count`, `$first`, `$last`, `$even`, `$odd`\n\n**Companions:** `index`, `else` (template ID), `filter`, `sort`, `limit`, `offset`, `template` (optional), `key`, animation attrs"
      }
    },
    {
      "name": "for",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Alias of `foreach`. Self-repeating loop — the element with `for` IS the template that gets cloned for each item. Syntax: `\"item in list\"`.\n\n```html\n<ul>\n  <li for=\"user in users\" bind=\"user.name\"></li>\n</ul>\n```\n\n**Empty list fallback:**\n```html\n<li for=\"user in users\" else=\"noUsersTpl\" bind=\"user.name\"></li>\n<template id=\"noUsersTpl\"><li>No users found</li></template>\n```\nThe `else` template (bare id or `#id`) renders when the list is empty (`[]`) or null/undefined/not an array.\n\nLoop context: `$index`, `$count`, `$first`, `$last`, `$even`, `$odd`\n\n**Companions:** `index`, `else` (template ID), `filter`, `sort`, `limit`, `offset`, `template`, `key`, animation attrs"
      }
    },
    {
      "name": "trigger",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Dispatches a custom event.\n\n```html\n<button on:click=\"count++\" trigger=\"countChanged\" trigger-data=\"count\">\n```\n\n**Companion:** `trigger-data`"
      }
    },
    {
      "name": "ref",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Declares a reference to this element, accessible via `$refs`.\n\n```html\n<input ref=\"emailInput\">\n<!-- Access via $refs.emailInput -->\n```\n\n**Limitation:** On a looped element, `$refs` will point to the last clone only."
      }
    },
    {
      "name": "use",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Inserts a `<template>` by ID.\n\n```html\n<template id=\"user-card\">\n  <div bind=\"name\"></div>\n</template>\n<div use=\"user-card\" var-name=\"user.name\">\n```\n\n**Companions:** `var-*` (slot parameters)"
      }
    },
    {
      "name": "call",
      "description": {
        "kind": "markdown",
        "value": "No.JS: HTTP call triggered by user action (e.g., button click).\n\n```html\n<button call=\"/api/delete/1\" method=\"delete\" confirm=\"Are you sure?\" loading=\"spinner-tpl\">\n```\n\n**Companions:** `method`, `as`, `loading`, `into`, `success`, `error`, `then`, `redirect`, `confirm`, `body`, `headers`"
      }
    },
    {
      "name": "validate",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Form validation with pristine-aware errors. **Requires `@no-js-dev/nojs-elements` plugin since v1.13.0.**\n\n```html\n<form validate=\"\" error-class=\"is-invalid\" validate-on=\"input blur\">\n  <input name=\"email\" validate=\"required|email\" error-required=\"Email is required\" />\n</form>\n```\n\nBuilt-in validators: `required`, `email`, `url`, `min`, `max`, `custom`\n\n**Companions:** `error`, `error-*`, `error-class`, `validate-on`, `validate-if`, `as`, `success`"
      }
    },
    {
      "name": "error-class",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class(es) applied to invalid fields after interaction. **Requires `@no-js-dev/nojs-elements` plugin since v1.13.0.**\n\n```html\n<form validate=\"\" error-class=\"is-invalid\">\n  <input name=\"email\" validate=\"required\" error-class=\"field-error\" />\n</form>\n```\n\nCan be set on the form (applies to all fields) or on individual fields."
      }
    },
    {
      "name": "validate-on",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Validation trigger events (space-separated). **Requires `@no-js-dev/nojs-elements` plugin since v1.13.0.**\n\n```html\n<form validate=\"\" validate-on=\"input blur\">\n<input validate=\"required\" validate-on=\"blur\" />\n```\n\n**Values:** `input`, `blur`, `focusout`, `submit`\n\nDefaults to `input focusout` if not specified."
      }
    },
    {
      "name": "validate-if",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Conditional validation expression. Field is only validated when expression is truthy. **Requires `@no-js-dev/nojs-elements` plugin since v1.13.0.**\n\n```html\n<input name=\"company\" validate=\"required\" validate-if=\"isBusinessAccount\" />\n```"
      }
    },
    {
      "name": "error-boundary",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Wraps content with error handling. Value is the fallback template ID.\n\n```html\n<div error-boundary=\"error-tpl\"\n     on:error=\"console.log($event.detail.message)\">\n  ...\n</div>\n```\n\nWhen an error is caught, dispatches a `nojs:error` CustomEvent on the boundary element. `$event.detail` contains: `message` (string), `error` (original Error).\n\n**Companion:** `on:error`"
      }
    },
    {
      "name": "t",
      "description": {
        "kind": "markdown",
        "value": "No.JS: i18n translation. Value is the translation key.\n\n```html\n<span t=\"greeting\" t-name=\"World\">\n```\n\n**Expression proxy:** Use `$i18n.[path]` in expressions to access translations as reactive dot-notation properties — e.g. `bind=\"$i18n.labels.email\"`. Fully reactive: locale switches update bindings in real-time.\n\n**Companions:** `t-*` (interpolation params), `t-html`\n\n**Limitation:** Do not use with `bind` on the same element — both write text content."
      }
    },
    {
      "name": "i18n-ns",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Sets i18n namespace for child elements. When used without a value on `route-view`, the namespace is auto-detected from the template name.\n\n```html\n<div i18n-ns=\"dashboard\">\n  <span t=\"title\"><!-- dashboard.title --></span>\n</div>\n\n<!-- Auto-detect from route -->\n<main route-view src=\"templates/\" i18n-ns></main>\n```"
      }
    },
    {
      "name": "drag",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Makes element draggable. **Requires `@no-js-dev/nojs-elements` plugin since v1.13.0.**\n\n```html\n<div drag=\"item\" drag-type=\"card\" drag-class=\"dragging\">\n```\n\n**Companions:** `drag-type`, `drag-effect`, `drag-handle`, `drag-image`, `drag-image-offset`, `drag-disabled`, `drag-class`, `drag-ghost-class`, `drag-group`"
      }
    },
    {
      "name": "drop",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Makes element a drop target. **Requires `@no-js-dev/nojs-elements` plugin since v1.13.0.**\n\n```html\n<div drop=\"items.push($drag)\" drop-accept=\"card\" drop-class=\"over\">\n```\n\n**Companions:** `drop-accept`, `drop-effect`, `drop-class`, `drop-reject-class`, `drop-disabled`, `drop-max`, `drop-sort`, `drop-placeholder`, `drop-placeholder-class`\n\n**Handler vars:** `$drag`, `$dragType`, `$dragEffect`, `$dropIndex`, `$source`, `$target`, `$el`"
      }
    },
    {
      "name": "drag-list",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Sortable list with drag and drop. **Requires `@no-js-dev/nojs-elements` plugin since v1.13.0.**\n\n```html\n<ul drag-list=\"items\" template=\"item-tpl\" drag-type=\"card\">\n```\n\n**Companions:** `template`, `drag-list-key`, `drag-list-item`, `drop-sort`, `drag-type`, `drop-accept`, `drag-list-copy`, `drag-list-remove`, and more"
      }
    },
    {
      "name": "drag-multiple",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Enables multi-select drag on `drag` elements. **Requires `@no-js-dev/nojs-elements` plugin since v1.13.0.**\n\n```html\n<div drag=\"item\" drag-multiple drag-group=\"cards\">\n```\n\n**Companions:** `drag-group` (required), `drag-multiple-class`"
      },
      "valueSet": "v"
    },
    {
      "name": "base",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Sets the base URL for all descendant fetch directives (`get`, `post`, `put`, `patch`, `delete`, `call`).\n\n```html\n<div base=\"https://api.example.com/v1\">\n  <div get=\"/users\" as=\"users\"></div>\n</div>\n```"
      }
    },
    {
      "name": "persist",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `state`. Persists state to localStorage.\n\n```html\n<div state=\"{ count: 0 }\" persist>\n```"
      },
      "valueSet": "v"
    },
    {
      "name": "persist-key",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `state`. Custom localStorage key.\n\n```html\n<div state=\"{ count: 0 }\" persist persist-key=\"myState\">\n```"
      }
    },
    {
      "name": "expr",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `computed`. The expression to evaluate.\n\n```html\n<div computed=\"total\" expr=\"price * quantity\">\n```"
      }
    },
    {
      "name": "as",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives (`get`, `post`, etc.), `call`, and `sse`. Names the response/event data variable. Defaults to `\"data\"` for `call` and `sse`.\n\n```html\n<div get=\"/api/users\" as=\"users\">\n<div sse=\"/events\" as=\"notification\">\n```"
      }
    },
    {
      "name": "loading",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives and `call`. Template ID to show while loading.\n\n```html\n<div get=\"/api/data\" as=\"data\" loading=\"spinner-tpl\">\n```"
      }
    },
    {
      "name": "empty",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives. Template ID to show when response is empty."
      }
    },
    {
      "name": "success",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives and `call`. Template ID to show on success."
      }
    },
    {
      "name": "then",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion attribute. For HTTP directives: expression to run on success. For `sse`: expression to run on each event (`$event` = parsed message data). For `if`/`else`/`else-if`: template ID to render.\n\n```html\n<div if=\"isAdmin\" then=\"admin-panel\">\n<div get=\"/api\" as=\"d\" then=\"console.log(d)\">\n<div sse=\"/events\" as=\"msg\" then=\"count++\">\n```"
      }
    },
    {
      "name": "redirect",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives, `call`, and router. Path to redirect to after success."
      }
    },
    {
      "name": "confirm",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives and `call`. Shows confirmation dialog before executing.\n\n```html\n<button call=\"/api/delete/1\" confirm=\"Are you sure?\">\n```"
      }
    },
    {
      "name": "refresh",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives. Auto-refresh interval in milliseconds.\n\n```html\n<div get=\"/api/notifications\" as=\"notifs\" refresh=\"30000\">\n```"
      }
    },
    {
      "name": "cached",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives. Enables response caching."
      },
      "valueSet": "v"
    },
    {
      "name": "body",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives and `call`. Request body expression.\n\n```html\n<form post=\"/api/users\" body=\"{ name: name, email: email }\">\n```"
      }
    },
    {
      "name": "headers",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives and `call`. Custom request headers object.\n\n```html\n<div get=\"/api/data\" headers=\"{ 'X-Custom': 'value' }\">\n<button call=\"/api/action\" headers=\"{ 'Authorization': token }\">\n```"
      }
    },
    {
      "name": "var",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives. Variable name to store additional data."
      }
    },
    {
      "name": "into",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives, `call`, and `sse`. Store name to dual-write response/event data into.\n\n```html\n<button call=\"/api/cart\" into=\"cart\">\n<div sse=\"/events\" as=\"data\" into=\"live\">\n```"
      }
    },
    {
      "name": "retry",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives. Number of retry attempts on failure.\n\n```html\n<div get=\"/api/data\" retry=\"3\" retry-delay=\"1000\">\n```"
      }
    },
    {
      "name": "retry-delay",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives. Delay between retries in milliseconds."
      }
    },
    {
      "name": "params",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives. Query parameters object.\n\n```html\n<div get=\"/api/search\" params=\"{ q: query, page: page }\">\n```"
      }
    },
    {
      "name": "debounce",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives. Debounce delay in milliseconds before making request."
      }
    },
    {
      "name": "from",
      "description": {
        "kind": "markdown",
        "value": "**Deprecated.** No.JS: Companion for `foreach`. Use `\"item in list\"` syntax instead.\n\n```html\n<!-- Deprecated -->\n<li foreach=\"item\" from=\"items\">\n\n<!-- Use instead -->\n<li foreach=\"item in items\">\n```\n\nCore emits a console warning when `from` is used."
      }
    },
    {
      "name": "index",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `foreach`. Custom name for the index variable.\n\n```html\n<li foreach=\"item\" from=\"items\" index=\"i\">\n```"
      }
    },
    {
      "name": "filter",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `foreach`. Filter expression for list items."
      }
    },
    {
      "name": "sort",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `foreach`. Property name to sort by."
      }
    },
    {
      "name": "limit",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `foreach`. Maximum number of items to display."
      }
    },
    {
      "name": "offset",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `foreach`. Number of items to skip."
      }
    },
    {
      "name": "template",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `each`, `foreach`, `drag-list`. Template ID to use for rendering items.\n\n```html\n<ul each=\"item in items\" template=\"item-tpl\">\n```"
      }
    },
    {
      "name": "key",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `each`. Expression for unique item key to optimize DOM updates.\n\n```html\n<li each=\"user in users\" key=\"user.id\">\n```"
      }
    },
    {
      "name": "method",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `call`. HTTP method to use.\n\n```html\n<button call=\"/api/item/1\" method=\"delete\">\n```"
      },
      "valueSet": "httpMethods"
    },
    {
      "name": "trigger-data",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `trigger`. Expression for event detail data.\n\n```html\n<button trigger=\"notify\" trigger-data=\"{ message: 'Hello' }\">\n```"
      }
    },
    {
      "name": "case",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Child attribute for `switch`. Value to match against.\n\n```html\n<div switch=\"status\">\n  <p case=\"active\">Active</p>\n</div>\n```\n\n**Limitation:** Do not combine `case` with a loop directive on the same element — switch logic becomes inert."
      }
    },
    {
      "name": "default",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Child attribute for `switch`. Fallback when no `case` matches.\n\n```html\n<p default>Unknown status</p>\n```\n\n**Limitation:** Do not combine `default` with a loop directive on the same element — switch logic becomes inert."
      },
      "valueSet": "v"
    },
    {
      "name": "t-html",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `t`. Renders the translation value as sanitized HTML (via `_sanitizeHtml()`) instead of plain text.\n\n```html\n<div t=\"legal.notice\" t-html></div>\n```"
      },
      "valueSet": "v"
    },
    {
      "name": "animate",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Animation name for element enter/appear.\n\n```html\n<div if=\"show\" animate=\"fadeIn\">\n```"
      },
      "valueSet": "animations"
    },
    {
      "name": "animate-enter",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Animation name for element entering (alias for `animate`).\n\n```html\n<div if=\"show\" animate-enter=\"fadeIn\" animate-leave=\"fadeOut\">\n```"
      },
      "valueSet": "animations"
    },
    {
      "name": "animate-leave",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Animation name for element leaving.\n\n```html\n<div if=\"show\" animate-leave=\"fadeOut\">\n```"
      },
      "valueSet": "animations"
    },
    {
      "name": "animate-duration",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Animation duration in milliseconds.\n\n```html\n<div if=\"show\" animate=\"fadeIn\" animate-duration=\"500\">\n```"
      }
    },
    {
      "name": "animate-stagger",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Incremental delay between animated list items in milliseconds.\n\n```html\n<li each=\"item in items\" animate=\"fadeInUp\" animate-stagger=\"50\">\n```"
      }
    },
    {
      "name": "transition",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS transition name. Uses class convention: `{name}-enter`, `{name}-enter-active`, `{name}-enter-to`, `{name}-leave`, `{name}-leave-active`, `{name}-leave-to`.\n\n```html\n<div if=\"show\" transition=\"fade\">\n```"
      }
    },
    {
      "name": "route-view",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Router outlet container. Renders matched route templates.\n\n```html\n<div route-view src=\"./pages/\" transition=\"fade\">\n```"
      }
    },
    {
      "name": "route",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Route path declaration on `<template>` or navigation on `<a>`. Use `\"*\"` as a catch-all wildcard for 404 pages.\n\n```html\n<template route=\"/users/:id\">...</template>\n<a route=\"/home\">Home</a>\n<template route=\"*\">404 — Not Found</template>\n```"
      }
    },
    {
      "name": "route-active",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class applied when element's route is active.\n\n```html\n<a route=\"/home\" route-active=\"active\">Home</a>\n```"
      }
    },
    {
      "name": "route-active-exact",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class applied only on exact route match.\n\n```html\n<a route=\"/home\" route-active-exact=\"exact-active\">Home</a>\n```"
      }
    },
    {
      "name": "route-index",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Index page name for `route-view`. Default: `\"index\"`."
      }
    },
    {
      "name": "outlet",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Named outlet for `<template>`. Default: `\"default\"`.\n\n```html\n<template route=\"/dashboard\" outlet=\"sidebar\">...</template>\n```"
      }
    },
    {
      "name": "guard",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Route guard expression. Evaluated before entering route.\n\n```html\n<template route=\"/admin\" guard=\"isAuthenticated\">\n```"
      }
    },
    {
      "name": "src",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Template source URL for `route-view` or `<template>`.\n\n```html\n<div route-view src=\"./pages/\">\n<template src=\"./components/header.tpl\">\n```"
      }
    },
    {
      "name": "ext",
      "description": {
        "kind": "markdown",
        "value": "No.JS: File extension for `route-view` templates. Default from config."
      }
    },
    {
      "name": "lazy",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Loading strategy for templates.\n\n```html\n<template src=\"./heavy.tpl\" lazy=\"ondemand\">\n```"
      },
      "valueSet": "lazyModes"
    },
    {
      "name": "drag-type",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Type identifier for the dragged item. Used with `drop-accept` for filtering. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drag-effect",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Drag effect cursor indicator. Requires `@no-js-dev/nojs-elements` plugin."
      },
      "valueSet": "dragEffects"
    },
    {
      "name": "drag-handle",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS selector for the drag handle element. Requires `@no-js-dev/nojs-elements` plugin.\n\n```html\n<div drag=\"item\" drag-handle=\".handle\">\n```"
      }
    },
    {
      "name": "drag-image",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS selector for custom drag image element. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drag-image-offset",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Offset for custom drag image as `\"x,y\"`. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drag-disabled",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Expression to disable dragging conditionally. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drag-class",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class applied to element while being dragged. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drag-ghost-class",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class applied to the ghost element left behind while dragging. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drag-group",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Group name for `drag-multiple` multi-selection. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drag-multiple-class",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class applied to multi-selected drag items. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drop-accept",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Comma-separated list of accepted `drag-type` values. Requires `@no-js-dev/nojs-elements` plugin.\n\n```html\n<div drop=\"handleDrop()\" drop-accept=\"card,task\">\n```"
      }
    },
    {
      "name": "drop-effect",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Drop effect cursor indicator. Requires `@no-js-dev/nojs-elements` plugin."
      },
      "valueSet": "dropEffects"
    },
    {
      "name": "drop-class",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class applied when a valid drag item is over the drop target. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drop-reject-class",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class applied when an invalid drag item is over the drop target. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drop-disabled",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Expression to disable dropping conditionally. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drop-max",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Maximum number of items the drop target accepts. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drop-sort",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Sort direction for drop targets. Value: `\"vertical\"` (default), `\"horizontal\"`, or `\"grid\"`. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drop-placeholder",
      "description": {
        "kind": "markdown",
        "value": "No.JS: HTML string or tag name for the placeholder element shown during drag. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drop-placeholder-class",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class for the drop placeholder element. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drag-list-key",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Unique key property for `drag-list` items. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drag-list-item",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Variable name for current item in `drag-list` template. Requires `@no-js-dev/nojs-elements` plugin."
      }
    },
    {
      "name": "drag-list-copy",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Copy items instead of moving when dragging from this `drag-list`. Requires `@no-js-dev/nojs-elements` plugin."
      },
      "valueSet": "v"
    },
    {
      "name": "drag-list-remove",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Remove items from source list after dragging. Requires `@no-js-dev/nojs-elements` plugin."
      },
      "valueSet": "v"
    },
    {
      "name": "drop-settle-class",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class applied during the settle animation after a drop in `drag-list`."
      }
    },
    {
      "name": "drop-empty-class",
      "description": {
        "kind": "markdown",
        "value": "No.JS: CSS class applied to `drag-list` when it has no items."
      }
    },
    {
      "name": "value",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `store`. Initial store data as a JS object literal.\n\n```html\n<div store=\"cart\" value=\"{ items: [], total: 0 }\">\n```"
      }
    },
    {
      "name": "error",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for HTTP directives, `call`, and `sse`. Template ID shown on error or when the SSE connection closes."
      }
    },
    {
      "name": "include",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Synchronously clones an inline template into the current position. Used on `<template>` elements.\n\n```html\n<template id=\"header\"><h1>My App</h1></template>\n<template include=\"header\"></template>\n```"
      }
    },
    {
      "name": "persist-fields",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `state` + `persist`. Comma-separated list of fields to persist selectively. Unlisted fields use their initial values on page load.\n\n```html\n<div state=\"{ theme: 'dark', sidebar: true, tempData: null }\"\n     persist=\"localStorage\"\n     persist-key=\"prefs\"\n     persist-fields=\"theme,sidebar\">\n```"
      }
    },
    {
      "name": "page-title",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Reactively sets the document `<title>`. Place on a `<div hidden>` element.\n\n```html\n<div hidden page-title=\"product.name + ' | My Store'\"></div>\n<div hidden page-title=\"'About Us | My Store'\"></div>\n```\n\nWatches the expression and updates `<title>` whenever the reactive context changes."
      }
    },
    {
      "name": "page-description",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Reactively sets `<meta name=\"description\">` in `<head>`. Creates the tag if it doesn't exist.\n\n```html\n<div hidden page-description=\"product.description\"></div>\n```\n\nWatches the expression and updates the meta content whenever the reactive context changes."
      }
    },
    {
      "name": "page-canonical",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Reactively sets `<link rel=\"canonical\">` in `<head>`. Creates the tag if it doesn't exist.\n\n```html\n<div hidden page-canonical=\"'/products/' + product.slug\"></div>\n```\n\nWatches the expression and updates the canonical URL whenever the reactive context changes."
      }
    },
    {
      "name": "page-jsonld",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Reactively sets `<script type=\"application/ld+json\" data-nojs>` in `<head>`. Value is either a No.JS expression evaluating to an object, or a JSON string with `{interpolation}` placeholders.\n\n```html\n<div hidden page-jsonld>\n  { \"@type\": \"Product\", \"name\": \"{product.name}\" }\n</div>\n```\n\nThe `data-nojs` marker distinguishes it from hand-written JSON-LD so they can coexist."
      }
    },
    {
      "name": "get-trigger",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Controls when the GET request fires for pagination. Companion for `get`.\n\n```html\n<div get=\"/api/items\" as=\"items\" get-trigger=\"scroll\">\n```\n\n**Values:** `load`, `visible`, `hover`, `none`, `scroll`, `button`"
      },
      "valueSet": "getTriggerModes"
    },
    {
      "name": "get-trigger-label",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Label text for the auto-generated Load More button when `get-trigger=\"button\"`. Companion for `get`.\n\n```html\n<div get=\"/api/items\" as=\"items\" get-trigger=\"button\" get-trigger-label=\"Show More\">\n```\n\nDefault: `\"Load More\"`"
      }
    },
    {
      "name": "get-insert",
      "description": {
        "kind": "markdown",
        "value": "No.JS: How fetched content is inserted into the container during pagination. Companion for `get`.\n\n```html\n<div get=\"/api/items\" as=\"items\" get-trigger=\"scroll\" get-insert=\"append\">\n```\n\n**Values:** `append`, `prepend`"
      },
      "valueSet": "getInsertModes"
    },
    {
      "name": "get-page",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Initial page number for offset-based pagination (auto-increments on each fetch). Companion for `get`. Mutually exclusive with `get-cursor`.\n\n```html\n<div get=\"/api/items?page={$page}\" as=\"items\" get-page=\"1\" get-trigger=\"scroll\">\n```"
      }
    },
    {
      "name": "get-cursor",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Enables cursor-based pagination. Companion for `get`. Mutually exclusive with `get-page`.\n\n```html\n<div get=\"/api/items\" as=\"items\" get-cursor get-cursor-field=\"meta.nextCursor\" get-trigger=\"scroll\">\n```"
      },
      "valueSet": "v"
    },
    {
      "name": "get-cursor-field",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Dot-notation path to the cursor value in the JSON response. Companion for `get` + `get-cursor`.\n\n```html\n<div get=\"/api/items\" as=\"items\" get-cursor get-cursor-field=\"meta.nextCursor\">\n```\n\nIf omitted, the framework auto-detects the cursor from the response."
      }
    },
    {
      "name": "get-threshold",
      "description": {
        "kind": "markdown",
        "value": "No.JS: IntersectionObserver `rootMargin` for `scroll`/`visible` triggers. Companion for `get`.\n\n```html\n<div get=\"/api/items\" as=\"items\" get-trigger=\"scroll\" get-threshold=\"200px\">\n```\n\nDefault: `200px` for scroll trigger, `0px` for visible trigger."
      }
    },
    {
      "name": "skeleton",
      "description": {
        "kind": "markdown",
        "value": "No.JS: ID (without `#`) of a DOM element to hide while loading and restore on response. Prevents CLS — element must start visible in HTML. Companion for `get`.\n\n```html\n<div id=\"user-skeleton\">Loading...</div>\n<div get=\"/api/user\" as=\"user\" skeleton=\"user-skeleton\">\n  <h1 bind=\"user.name\"></h1>\n</div>\n```"
      }
    },
    {
      "name": "sse",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Opens a Server-Sent Events (EventSource) connection. Value is a URL (supports `{expr}` interpolation). Incoming events are parsed as JSON (raw-string fallback) and stored in the context variable named by `as`.\n\n```html\n<div sse=\"/events/notifications\" as=\"notification\">\n  <p bind=\"notification.message\"></p>\n  <span show=\"$sse.connecting\">Connecting...</span>\n</div>\n```\n\n**Context key:** `$sse` — `{ connecting, open, error }` booleans.\n\n**Companions:** `as`, `sse-event`, `sse-insert`, `sse-limit`, `sse-credentials`, `into`, `error`, `then`"
      }
    },
    {
      "name": "sse-event",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `sse`. Named SSE event type to listen for. Defaults to `\"message\"` (the standard EventSource event).\n\n```html\n<div sse=\"/events\" as=\"data\" sse-event=\"status-update\">\n```"
      }
    },
    {
      "name": "sse-insert",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `sse`. Controls how incoming events are stored.\n\n- `replace` (default) — overwrites the variable with each new event\n- `append` — pushes to the end of an array\n- `prepend` — unshifts to the beginning of an array\n\n```html\n<ul sse=\"/events/feed\" as=\"items\" sse-insert=\"append\" sse-limit=\"50\">\n  <li each=\"item in items\" bind=\"item.text\"></li>\n</ul>\n```"
      },
      "valueSet": "sseInsertModes"
    },
    {
      "name": "sse-limit",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `sse`. Maximum number of items to keep in the array when using `sse-insert=\"append\"` or `sse-insert=\"prepend\"`. Prevents unbounded memory growth on long-lived streams. Has no effect with `sse-insert=\"replace\"` (the default).\n\n```html\n<div sse=\"/events/log\" as=\"entries\" sse-insert=\"append\" sse-limit=\"100\">\n```"
      }
    },
    {
      "name": "sse-credentials",
      "description": {
        "kind": "markdown",
        "value": "No.JS: Companion for `sse`. Boolean attribute — when present, the EventSource connection is opened with `withCredentials: true`, sending cookies and HTTP auth headers cross-origin.\n\n```html\n<div sse=\"https://api.example.com/events\" as=\"data\" sse-credentials>\n```"
      },
      "valueSet": "v"
    }
  ],
  "valueSets": [
    {
      "name": "animations",
      "values": [
        {
          "name": "fadeIn",
          "description": "No.JS: Fade in from transparent"
        },
        {
          "name": "fadeOut",
          "description": "No.JS: Fade out to transparent"
        },
        {
          "name": "fadeInUp",
          "description": "No.JS: Fade in while sliding up"
        },
        {
          "name": "fadeInDown",
          "description": "No.JS: Fade in while sliding down"
        },
        {
          "name": "fadeOutUp",
          "description": "No.JS: Fade out while sliding up"
        },
        {
          "name": "fadeOutDown",
          "description": "No.JS: Fade out while sliding down"
        },
        {
          "name": "slideInLeft",
          "description": "No.JS: Slide in from the left"
        },
        {
          "name": "slideInRight",
          "description": "No.JS: Slide in from the right"
        },
        {
          "name": "slideOutLeft",
          "description": "No.JS: Slide out to the left"
        },
        {
          "name": "slideOutRight",
          "description": "No.JS: Slide out to the right"
        },
        {
          "name": "zoomIn",
          "description": "No.JS: Zoom in from small"
        },
        {
          "name": "zoomOut",
          "description": "No.JS: Zoom out to small"
        },
        {
          "name": "bounceIn",
          "description": "No.JS: Bounce in with elastic effect"
        },
        {
          "name": "bounceOut",
          "description": "No.JS: Bounce out with elastic effect"
        },
        {
          "name": "slideInUp",
          "description": "No.JS: Slide in from below"
        },
        {
          "name": "slideInDown",
          "description": "No.JS: Slide in from above"
        },
        {
          "name": "slideOutUp",
          "description": "No.JS: Slide out upward"
        },
        {
          "name": "slideOutDown",
          "description": "No.JS: Slide out downward"
        },
        {
          "name": "flipIn",
          "description": "No.JS: Flip in with 3D rotation"
        }
      ]
    },
    {
      "name": "httpMethods",
      "values": [
        {
          "name": "get",
          "description": "No.JS: HTTP GET"
        },
        {
          "name": "post",
          "description": "No.JS: HTTP POST"
        },
        {
          "name": "put",
          "description": "No.JS: HTTP PUT"
        },
        {
          "name": "patch",
          "description": "No.JS: HTTP PATCH"
        },
        {
          "name": "delete",
          "description": "No.JS: HTTP DELETE"
        },
        {
          "name": "query",
          "description": "No.JS: HTTP QUERY (safe, cacheable, carries a body)"
        }
      ]
    },
    {
      "name": "lazyModes",
      "values": [
        {
          "name": "priority",
          "description": "No.JS: Load with priority (prefetch)"
        },
        {
          "name": "ondemand",
          "description": "No.JS: Load only when needed"
        }
      ]
    },
    {
      "name": "dragEffects",
      "values": [
        {
          "name": "copy",
          "description": "No.JS: Copy the dragged item"
        },
        {
          "name": "move",
          "description": "No.JS: Move the dragged item"
        },
        {
          "name": "link",
          "description": "No.JS: Link to the dragged item"
        },
        {
          "name": "none",
          "description": "No.JS: No drag effect"
        }
      ]
    },
    {
      "name": "dropEffects",
      "values": [
        {
          "name": "copy",
          "description": "No.JS: Copy into drop target"
        },
        {
          "name": "move",
          "description": "No.JS: Move into drop target"
        },
        {
          "name": "link",
          "description": "No.JS: Link in drop target"
        },
        {
          "name": "none",
          "description": "No.JS: No drop effect"
        }
      ]
    },
    {
      "name": "getTriggerModes",
      "values": [
        {
          "name": "load",
          "description": "No.JS: Fetch on page load (default)"
        },
        {
          "name": "visible",
          "description": "No.JS: Fetch when element becomes visible"
        },
        {
          "name": "hover",
          "description": "No.JS: Fetch on hover"
        },
        {
          "name": "none",
          "description": "No.JS: Do not auto-fetch"
        },
        {
          "name": "scroll",
          "description": "No.JS: Fetch when scrolled near (infinite scroll)"
        },
        {
          "name": "button",
          "description": "No.JS: Fetch on Load More button click"
        }
      ]
    },
    {
      "name": "getInsertModes",
      "values": [
        {
          "name": "append",
          "description": "No.JS: Append new items after existing content"
        },
        {
          "name": "prepend",
          "description": "No.JS: Prepend new items before existing content"
        }
      ]
    },
    {
      "name": "sseInsertModes",
      "values": [
        {
          "name": "replace",
          "description": "No.JS: Overwrite variable with each new event (default)"
        },
        {
          "name": "append",
          "description": "No.JS: Push each event to the end of an array"
        },
        {
          "name": "prepend",
          "description": "No.JS: Unshift each event to the beginning of an array"
        }
      ]
    }
  ]
}
