
{
    "version": "2.50.0",
    "build": "dev-develop",
    "build_ref": "0c6cade5da267eb57e1240005575b884008d9367",
    "released_version": "2.50.0",
    "generated_at": "2026-09-14T06:29:51+00:00",
    "components": [
        {
            "name": "checkbox",
            "tag": "\u003Cx-wirekit::checkbox\u003E",
            "category": "Form",
            "description": "Checkbox input with label, hint, and error support",
            "docs_url": "https://docs.wirekit.app/components/checkbox",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method this component should call, when it should show the new value before the server has agreed to it. Null leaves the component exactly as it has always rendered. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hideLabel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Render the label sr-only (kept as the control's accessible name) — for a checkbox in a table column whose header already names it, so the visible label is redundant. Mirrors input / select / textarea / combobox `hideLabel`.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "indeterminate",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.checkbox.size', 'md')",
                    "default_normalized": "config('wirekit.components.checkbox.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "variant",
                    "default": "config('wirekit.components.checkbox.variant', 'default')",
                    "default_normalized": "config('wirekit.components.checkbox.variant', 'default')",
                    "type_hint": null,
                    "comment": "'default' (inline control + label) or 'card' (the whole bordered card is the clickable target and highlights when checked — the selectable-option pattern).",
                    "examples": [],
                    "values": [
                        "default",
                        "card"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "color-picker",
            "tag": "\u003Cx-wirekit::color-picker\u003E",
            "category": "Form",
            "description": "Native color picker with preview swatch",
            "docs_url": "https://docs.wirekit.app/components/color-picker",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method to call once a color is settled — a released drag, a swatch, an arrow-key nudge. A refusal KEEPS the color and says it was not saved: the hex field is typed, and a rollback may never delete what the reader wrote. See the note at the top of this file. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "id",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`error` and `hint` were undeclared on the one Form-category CONTROL that never got them, so `:error=\"$errors-\u003Efirst('brand_color')\"` landed in the attribute bag and rendered as `error=\"…\"` on the native `\u003Cinput type=\"color\"\u003E` — invalid HTML carrying a validation message the reader is never shown. The same class was closed once for the four controls that take a `label`; this one takes a `name` instead and fell outside that reading of it. No `label` prop comes with them, deliberately. The accessible name here is the DEFAULT SLOT (rendered `sr-only` beside the swatch, documented on the component page and sanctioned in the accessibility rules), and a second naming path would give the component two ways to be named with nothing deciding between them.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Whether the error paragraph announces itself. Same precedence chain as every sibling control: explicit prop \u003E the enclosing form's @aware value \u003E config.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "'#000000'",
                    "default_normalized": "'#000000'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.color-picker.size', 'md')",
                    "default_normalized": "config('wirekit.components.color-picker.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "showValue",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "popover",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Popover mode — a from-scratch HSV picker (SV plane + hue + alpha + format input + swatches + eyedropper + copy + recents). Default false keeps the native \u003Cinput type=\"color\"\u003E render byte-identical. Boolean flag (not a `mode` prop) per the prop-naming convention — same call the date-picker `range` made.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "format",
                    "default": "config('wirekit.components.color-picker.format', 'hex')",
                    "default_normalized": "config('wirekit.components.color-picker.format', 'hex')",
                    "type_hint": null,
                    "comment": "hex | rgb | hsl | oklch",
                    "examples": [],
                    "values": [
                        "hex",
                        "rgb",
                        "hsl",
                        "oklch"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "nativeOnMobile",
                    "default": "config('wirekit.components.color-picker.native-on-mobile', false)",
                    "default_normalized": "config('wirekit.components.color-picker.native-on-mobile', false)",
                    "type_hint": null,
                    "comment": "Popover mode only: on touch-primary devices (pointer: coarse) open the platform's native color sheet instead of the custom panel — the same dialog the default (non-popover) variant gets for free. Opt-in; desktop pointers always get the popover.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "withAlpha",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "withEyedropper",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "withClear",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Popover mode only: render a \"clear\" (no color) button that empties the bound form value. The native \u003Cinput type=\"color\"\u003E cannot represent an empty value (HTML coerces it to #000000), so this is popover-only. Off by default — \"no color\" is rarely a valid state on a color control.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "withRecents",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "presets",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "recentsKey",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "trigger",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "combobox",
            "tag": "\u003Cx-wirekit::combobox\u003E",
            "category": "Form",
            "description": "Autocomplete select with search filtering",
            "docs_url": "https://docs.wirekit.app/components/combobox",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "Livewire method to call optimistically. The choice appears immediately and is put back if the call fails. Absent -\u003E this component renders exactly as it did before, down to the byte. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "id",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "options",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.combobox.size', 'md')",
                    "default_normalized": "config('wirekit.components.combobox.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "placement",
                    "default": "config('wirekit.components.combobox.placement', 'bottom-start')",
                    "default_normalized": "config('wirekit.components.combobox.placement', 'bottom-start')",
                    "type_hint": null,
                    "comment": "Where the options panel opens against the field: any placement `dropdown` takes. The panel still flips to the other side when the chosen one has no room.",
                    "examples": [],
                    "values": [
                        "bottom-start",
                        "bottom",
                        "bottom-end",
                        "top-start",
                        "top",
                        "top-end",
                        "left-start",
                        "left",
                        "left-end",
                        "right-start",
                        "right",
                        "right-end"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "panelWidth",
                    "default": "config('wirekit.components.combobox.panel-width', 'trigger')",
                    "default_normalized": "config('wirekit.components.combobox.panel-width', 'trigger')",
                    "type_hint": null,
                    "comment": "How wide the panel is. `trigger` matches the field. `auto` takes the width of the widest option, and a CSS length sets one. Those two are never narrower than the field and never wider than the room the placement leaves.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "searchable",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "`false` renders a select-only combobox: a focusable trigger instead of a text field, for a short list nobody needs to search, with the keyboard of the WAI-ARIA select-only pattern.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "placeholder",
                    "default": "config('wirekit.components.combobox.placeholder') ?? __('wirekit::Select…')",
                    "default_normalized": "config('wirekit.components.combobox.placeholder') ?? __('wirekit::Select…')",
                    "type_hint": null,
                    "comment": "`??` rather than a `config(…, 'Select…')` fallback, and the difference is the whole point: a config default holds ONE string for every locale, so the literal that used to sit in that second argument was unreachable to a translated app — its only escape was publishing the config, which freezes the wording again. The seam survives (an app may still pin its own word), and an untouched default now resolves through the catalog, exactly as the sibling multi-select already does.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`hint` — the one Form control with both `label` and `error` that did not have it. A caller writing `hint=\"Start typing to search\"` got the string on the wrapper div as a stray HTML attribute: never displayed, never announced, and never reported, because Blade folds an undeclared prop into the attribute bag without complaint. Every sibling control has carried it for releases.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the combobox. Mirrors select / multi-select: a visible `label` renders an associated x-wirekit::label (for={comboId}); `hideLabel` keeps it in the DOM for assistive tech but visually hidden (compact toolbar / header fields); `ariaLabel` sets aria-label directly on the role=\"combobox\" input for the label-less case. All default to today's behavior (no label at all), so existing comboboxes render byte-identically.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hideLabel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "ariaLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "date-picker",
            "tag": "\u003Cx-wirekit::date-picker\u003E",
            "category": "Form",
            "description": "Calendar-based date input",
            "docs_url": "https://docs.wirekit.app/components/date-picker",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "Livewire method to call optimistically. The date appears immediately and is put back if the call fails. Single-date mode only — see the note above. Absent -\u003E this component renders exactly as it did before, down to the byte. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "id",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "range",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "false (default) renders one native date input. true renders a linked start + end pair (two native inputs) — see the range parsing below.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "min",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "max",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.date-picker.size', 'md')",
                    "default_normalized": "config('wirekit.components.date-picker.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "placeholder",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "editor",
            "tag": "\u003Cx-wirekit::editor\u003E",
            "category": "Form",
            "description": "Rich-text editor (ProseMirror-based peer-dependency adapter; Tiptap recommended) with toolbar + hidden-input form binding",
            "docs_url": "https://docs.wirekit.app/components/editor",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk. StrictnessGate did not complain either, because `required` is in its HTML passthrough list — so it looked like a legitimate attribute all the way down. The result was a required field that submits empty, in the same form as a plain input that behaves correctly.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method to call when you leave the editor. A refusal KEEPS what you wrote — see the note above. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "id",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "format",
                    "default": "config('wirekit.components.editor.format', 'html')",
                    "default_normalized": "config('wirekit.components.editor.format', 'html')",
                    "type_hint": null,
                    "comment": "html | json",
                    "examples": [],
                    "values": [
                        "html",
                        "json"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "extensions",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "array of editor extension NAMES (hint for window.wirekitEditor)",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "toolbar",
                    "default": "config('wirekit.components.editor.toolbar', 'basic')",
                    "default_normalized": "config('wirekit.components.editor.toolbar', 'basic')",
                    "type_hint": null,
                    "comment": "false | 'basic' | 'full' | 'custom'",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "placeholder",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "maxLength",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "editable",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.editor.size', 'md')",
                    "default_normalized": "config('wirekit.components.editor.size', 'md')",
                    "type_hint": null,
                    "comment": "sm | md | lg",
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "maxHeight",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Cap the editable area's height (any CSS length, e.g. '20rem' / '50vh'). The content host already scrolls (overflow-y-auto); maxHeight gives it a CEILING so a long document scrolls INSIDE the field instead of growing the page downward. null = grow with content (the size's min-height is the only bound). Width is set the normal way — the editor is w-full, so constrain it with a class/style on the component (e.g. style=\"max-width: 40rem\" or a max-w-* class).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "autofocus",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "bottomBar",
                    "required": false
                }
            ],
            "sub_components": [
                {
                    "name": "editor.toolbar",
                    "tag": "\u003Cx-wirekit::editor.toolbar\u003E",
                    "props": [
                        {
                            "name": "commands",
                            "default": "['bold', 'italic', 'strike', 'link', '|', 'bullet-list', 'ordered-list']",
                            "default_normalized": "['bold', 'italic', 'strike', 'link', '|', 'bullet-list', 'ordered-list']",
                            "type_hint": null,
                            "comment": "Command vocabulary to render. '|' is a visual separator. Commands the active extension set doesn't support simply no-op (Tiptap's chain ignores them).",
                            "examples": [],
                            "values": null,
                            "value_type": "array"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "field",
            "tag": "\u003Cx-wirekit::field\u003E",
            "category": "Form",
            "description": "Form field wrapper with label, hint, and error",
            "docs_url": "https://docs.wirekit.app/components/field",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "When true (default), the error message renders as an ARIA live region (aria-live=\"polite\") so a validation error that appears dynamically — e.g. after a Livewire round-trip — is announced by screen readers without the focus having to return to the field. Set false when the surrounding page runs its own live region for form errors (avoids a double announcement). The aria-describedby link to the field is unaffected either way.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "for",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "orientation",
                    "default": "'vertical'",
                    "default_normalized": "'vertical'",
                    "type_hint": null,
                    "comment": "vertical (label above) | horizontal (label beside)",
                    "examples": [],
                    "values": [
                        "vertical",
                        "horizontal"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "field.legend",
                    "tag": "\u003Cx-wirekit::field.legend\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "field.set",
                    "tag": "\u003Cx-wirekit::field.set\u003E",
                    "props": [
                        {
                            "name": "legend",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "hint",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "field.spacer",
                    "tag": "\u003Cx-wirekit::field.spacer\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "file-upload",
            "tag": "\u003Cx-wirekit::file-upload\u003E",
            "category": "Form",
            "description": "Drag-and-drop file upload area",
            "docs_url": "https://docs.wirekit.app/components/file-upload",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk. StrictnessGate did not complain either, because `required` is in its HTML passthrough list — so it looked like a legitimate attribute all the way down. The result was a required field that submits empty, in the same form as a plain input that behaves correctly.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "id",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "multiple",
                    "default": "config('wirekit.components.file-upload.multiple', false)",
                    "default_normalized": "config('wirekit.components.file-upload.multiple', false)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "accept",
                    "default": "config('wirekit.components.file-upload.accept', null)",
                    "default_normalized": "config('wirekit.components.file-upload.accept', null)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "capture",
                    "default": "config('wirekit.components.file-upload.capture', null)",
                    "default_normalized": "config('wirekit.components.file-upload.capture', null)",
                    "type_hint": null,
                    "comment": "`capture` is its OWN attribute, not a token inside `accept`. The docs table used to sell camera capture as `accept=\"image/*;capture=camera\"`, which is a legacy Android spelling that no current browser reads and which sets a MIME filter no file matches. It could not have worked from the caller's side either: this input takes named attributes and `wire:model*` only, never the whole bag, so a developer passing `capture` themselves got nothing on the element.",
                    "examples": [],
                    "values": [
                        "user",
                        "environment"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.file-upload.size', 'md')",
                    "default_normalized": "config('wirekit.components.file-upload.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "variant",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": "Shape, not chrome. `default` is the full drop AREA — a block-level dashed rectangle that fills its container, which is right for a field in a form. `compact` is the same control at button height, shrink-to-fit, for a dense row beside badges and `size=\"sm\"` buttons where a full-width area would push every neighbor onto its own line. Both keep the native input, the click-to-browse path and the drop handlers — only the shape differs.",
                    "examples": [],
                    "values": [
                        "default",
                        "compact"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Null rather than the sentence itself, so the component can tell \"the caller said nothing\" from \"the caller chose this text\". The shipped default is written for a large area; in `compact` it would make the control wider than the row it exists to fit, so there it names the control without painting. Resolved below — a null default also keeps TranslatableDefaultsGuardTest satisfied, which is what a hard literal here would fail.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "removeLabel",
                    "default": "__('wirekit::Remove :name')",
                    "default_normalized": "__('wirekit::Remove :name')",
                    "type_hint": null,
                    "comment": "Accessible name for each file's remove button. The `:name` placeholder is replaced with the file name at runtime, so translators control word order (some languages put the object before the verb). Overridable per call site.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "filter-builder",
            "tag": "\u003Cx-wirekit::filter-builder\u003E",
            "category": "Form",
            "description": "Active-filter chip bar with a typed add/edit popover (field/operator/value)",
            "docs_url": "https://docs.wirekit.app/components/filter-builder",
            "props": [
                {
                    "name": "fields",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "[{key,label,type,operators?,options?}]; type: text|number|select|date|bool",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "value",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "active filters [{field,op,value}] (two-way via wire:model bridge)",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "hidden-input name for plain-form submission",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "searchable",
                    "default": "config('wirekit.components.filter-builder.searchable', false)",
                    "default_normalized": "config('wirekit.components.filter-builder.searchable', false)",
                    "type_hint": null,
                    "comment": "free-text search box",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "searchDebounce",
                    "default": "config('wirekit.components.filter-builder.search-debounce', 300)",
                    "default_normalized": "config('wirekit.components.filter-builder.search-debounce', 300)",
                    "type_hint": null,
                    "comment": "Milliseconds to wait after the last keystroke before announcing `search-change`. Same reasoning, same default and same escape as data-table's `searchDebounce`: this input dispatches straight to whatever the host wired the event to, and the documented wiring is a Livewire round trip. Without the wait that is one request per CHARACTER, and every answer but the last is discarded. 0 disables it.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "searchPlaceholder",
                    "default": "config('wirekit.components.filter-builder.search-placeholder') ?? __('wirekit::Search…')",
                    "default_normalized": "config('wirekit.components.filter-builder.search-placeholder') ?? __('wirekit::Search…')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "addLabel",
                    "default": "config('wirekit.components.filter-builder.add-label') ?? __('wirekit::Add filter')",
                    "default_normalized": "config('wirekit.components.filter-builder.add-label') ?? __('wirekit::Add filter')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "status",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "form",
            "tag": "\u003Cx-wirekit::form\u003E",
            "category": "Form",
            "description": "Form wrapper that inherits an error-announcement policy to every control inside",
            "docs_url": "https://docs.wirekit.app/components/form",
            "props": [
                {
                    "name": "announceErrors",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Error-announcement policy inherited by every WireKit form control nested inside this form. null  — inherit the global wirekit.a11y.announce_error config (the default) false — turn the per-control aria-live error region OFF for all controls inside. Use this when THIS form renders its OWN error summary — a role=\"alert\" list that announces every message and pulls focus (the WCAG 3.3.1 pattern) — so the per-field live regions would otherwise double-announce. true  — force it ON for all controls inside. A per-control :announce-error still overrides this for that one control.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "input",
            "tag": "\u003Cx-wirekit::input\u003E",
            "category": "Form",
            "description": "Text input with prefix/suffix support",
            "docs_url": "https://docs.wirekit.app/components/input",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method this component should call, when it should show the new value before the server has agreed to it. A refusal keeps your value — see the note above. Null leaves the component exactly as it has always rendered. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hideLabel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "render the label sr-only (kept for assistive tech) — for compact toolbar / header fields",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "reserveMessage",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Keep the message line's height whether or not there is a message. Wasted space in a stacked form, and the difference between a working toolbar and one that jumps in a horizontal row: an appearing error grows this element, and every sibling in the row re-anchors to the new bottom edge. Aligning the row does not fix it — `items-end` follows the growth, and `items-start` lines things up with the label rather than the control.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "When true (default), the error message renders as an ARIA live region (aria-live=\"polite\") so a validation error that appears dynamically — e.g. after a Livewire round-trip — is announced by screen readers without the focus having to return to the field. Set false when the surrounding page runs its own live region for form errors (avoids a double announcement). The aria-describedby link on the input is unaffected either way.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "success",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Success / valid state. Pass a string to show a green confirmation message below the field (e.g. \"Username available\"), or `true` for just the green border with no message. `error` always wins when both are set.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.input.size', 'md')",
                    "default_normalized": "config('wirekit.components.input.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md-compact",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "type",
                    "default": "'text'",
                    "default_normalized": "'text'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "mono",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Monospace the field value — for SKUs, measurements, codes, hashes. Swaps the input font to --font-wk-mono; off by default (byte-identical). The \u003Cx-slot:leading\u003E / \u003Cx-slot:trailing\u003E named slots put an icon or addon INSIDE the field frame (a search glyph, a unit) — distinct from the text-only `prefix`/`suffix` props.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "prefix",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "suffix",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "clearable",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Optional trailing affordances (opt-in; default off for byte-identical back-compat). `clearable` shows an X button that empties the field, refocuses it, and dispatches input/change so wire:model / x-model sync. `copyable` shows a copy-to-clipboard button with a brief \"Copied\" state. Both route the field through the flex wrapper and add a tiny inline Alpine island; when neither is set the input renders exactly as before.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "copyable",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "HTML5 form-state props — surface in the schema so AI / IDE tools know about them, while preserving the pre-existing attribute-bag passthrough so the plain HTML-attribute form (required, disabled, readonly as bare attributes) keeps working byte-identically.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "readonly",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "autocomplete",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "placeholder",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "leading",
                    "required": false
                },
                {
                    "name": "trailing",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "label",
            "tag": "\u003Cx-wirekit::label\u003E",
            "category": "Form",
            "description": "Form label with required indicator",
            "docs_url": "https://docs.wirekit.app/components/label",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "multi-select",
            "tag": "\u003Cx-wirekit::multi-select\u003E",
            "category": "Form",
            "description": "Multi-value select with tag display",
            "docs_url": "https://docs.wirekit.app/components/multi-select",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk. StrictnessGate did not complain either, because `required` is in its HTML passthrough list — so it looked like a legitimate attribute all the way down. The result was a required field that submits empty, in the same form as a plain input that behaves correctly.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "Livewire method to call optimistically. It receives the FULL new selection as an array. The pill appears immediately and is removed again if the call fails. Absent -\u003E this component renders exactly as before. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "options",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "value",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "option keys to pre-select on load (array or comma-separated string)",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "placeholder",
                    "default": "config('wirekit.components.multi-select.placeholder') ?? __('wirekit::Select…')",
                    "default_normalized": "config('wirekit.components.multi-select.placeholder') ?? __('wirekit::Select…')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "placement",
                    "default": "config('wirekit.components.multi-select.placement', 'bottom-start')",
                    "default_normalized": "config('wirekit.components.multi-select.placement', 'bottom-start')",
                    "type_hint": null,
                    "comment": "Where the options panel opens against the field: any placement `dropdown` takes. The panel still flips to the other side when the chosen one has no room.",
                    "examples": [],
                    "values": [
                        "bottom-start",
                        "bottom",
                        "bottom-end",
                        "top-start",
                        "top",
                        "top-end",
                        "left-start",
                        "left",
                        "left-end",
                        "right-start",
                        "right",
                        "right-end"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "panelWidth",
                    "default": "config('wirekit.components.multi-select.panel-width', 'trigger')",
                    "default_normalized": "config('wirekit.components.multi-select.panel-width', 'trigger')",
                    "type_hint": null,
                    "comment": "How wide the panel is. `trigger` matches the field. `auto` takes the width of the widest option, and a CSS length sets one. Those two are never narrower than the field and never wider than the room the placement leaves.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "ariaLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "number-input",
            "tag": "\u003Cx-wirekit::number-input\u003E",
            "category": "Form",
            "description": "Numeric input with stepper buttons",
            "docs_url": "https://docs.wirekit.app/components/number-input",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method to call when the value should be shown before the server has agreed to it. A refusal KEEPS what is there — see the note above for why that holds for the steppers too. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hideLabel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Render the label sr-only (kept as the field's accessible name) — for a compact stepper in a toolbar or a table cell, where the stacked visible label costs a second line the layout does not have. The real \u003Clabel for=\"…\"\u003E stays in the DOM, so the name survives. Mirrors input / select / textarea / combobox.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.number-input.size', 'md')",
                    "default_normalized": "config('wirekit.components.number-input.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "min",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "max",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "step",
                    "default": "config('wirekit.components.number-input.step', 1)",
                    "default_normalized": "config('wirekit.components.number-input.step', 1)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "prefix",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "suffix",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "otp-input",
            "tag": "\u003Cx-wirekit::otp-input\u003E",
            "category": "Form",
            "description": "One-time password input with auto-focus",
            "docs_url": "https://docs.wirekit.app/components/otp-input",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk. StrictnessGate did not complain either, because `required` is in its HTML passthrough list — so it looked like a legitimate attribute all the way down. The result was a required field that submits empty, in the same form as a plain input that behaves correctly.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method to call when the code is COMPLETE — not per keystroke. A refusal keeps what was entered; see the note above. Null leaves the component exactly as it has always rendered. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "length",
                    "default": "config('wirekit.components.otp-input.length', 6)",
                    "default_normalized": "config('wirekit.components.otp-input.length', 6)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "masked",
                    "default": "config('wirekit.components.otp-input.masked', false)",
                    "default_normalized": "config('wirekit.components.otp-input.masked', false)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "alphabet",
                    "default": "'0123456789'",
                    "default_normalized": "'0123456789'",
                    "type_hint": null,
                    "comment": "Which characters a box accepts. Defaults to digits, so a call site that passes nothing keeps exactly the previous behavior. \"OTP\" does not mean \"numeric\": an ambiguity-free alphabet like ABCDEFGHJKMNPQRSTUVWXYZ23456789 (no I/1, no O/0) is chosen deliberately — it carries far more entropy per character and survives being read aloud. Before this prop existed, such a code could not be entered here at all: every keystroke was discarded and the boxes stayed empty with no message.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "autofocus",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Focus the first box on load. A one-time-code screen is single-purpose: the reader arrived from a redirect whose status region has already said the code was sent, and the boxes are the only thing on the page they came to operate. Every sibling screen in that flow focuses its field; this one could not, because an `autofocus` written at the call site landed in the attribute bag and was dropped with it — measured as `document.activeElement === body`, one extra Tab for a keyboard reader and a pre-filled email field read out first for a screen-reader reader. Default false, because an OTP field is not always alone on its page and moving focus on a page somebody is already reading takes them somewhere they did not ask to go. WCAG forbids neither; the call site knows which of the two screens it is building.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Disable the whole control: native `disabled` on every digit box and on the hidden input that carries the combined value, plus `aria-disabled` on the group so a reader who lands there before reaching a box hears it too. It was DOCUMENTED — a props-table row and a `--opacity-wk-disabled` theming row — while undeclared here, so the flag landed in the attribute bag, and the bag never reaches the digit boxes: the only reads are `-\u003Eonly('class')` on the wrapper, `-\u003EwhereStartsWith('wire:model')` on the hidden input and `-\u003Eget('aria-label')`. Nothing was emitted anywhere. A one-time-code field written `disabled` stayed fully typeable, pasteable and submittable, announced as editable, and the `disabled:` variants below could never fire. Same defect, same shape, as the one range-slider carries a note about.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "password-input",
            "tag": "\u003Cx-wirekit::password-input\u003E",
            "category": "Form",
            "description": "Password input with visibility toggle and strength meter",
            "docs_url": "https://docs.wirekit.app/components/password-input",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method to call when the field should show the new value before the server has agreed to it. A refusal KEEPS what was typed — see the note above. Null leaves the component exactly as it has always rendered. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hideLabel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Render the label sr-only (kept as the field's accessible name) — for a compact field in a toolbar or header, where the stacked visible label costs a second line the layout does not have. The real \u003Clabel for=\"…\"\u003E stays in the DOM, so the name survives. Mirrors input / select / textarea / combobox.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.password-input.size', 'md')",
                    "default_normalized": "config('wirekit.components.password-input.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "toggle",
                    "default": "config('wirekit.components.password-input.toggle', true)",
                    "default_normalized": "config('wirekit.components.password-input.toggle', true)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "strengthMeter",
                    "default": "config('wirekit.components.password-input.strength-meter', false)",
                    "default_normalized": "config('wirekit.components.password-input.strength-meter', false)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "autocomplete",
                    "default": "'current-password'",
                    "default_normalized": "'current-password'",
                    "type_hint": null,
                    "comment": "WCAG 1.3.5 (Identify Input Purpose): a password field has to say WHICH password it is, or a password manager and an autofill heuristic have to guess — and they guess wrong on a change-password form, where three fields look identical and only one is the new one. The default is the sign-in case, which is the overwhelming majority of uses. A registration or change form passes `autocomplete=\"new-password\"`, and `false` opts out entirely for a field that is not a credential at all.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "radial-progress",
            "tag": "\u003Cx-wirekit::radial-progress\u003E",
            "category": "Display",
            "description": "Radial progress ring — determinate, token-driven, with threshold coloring",
            "docs_url": "https://docs.wirekit.app/components/radial-progress",
            "props": [
                {
                    "name": "value",
                    "default": "0",
                    "default_normalized": "0",
                    "type_hint": null,
                    "comment": "Current value. Determinate only — a ring that cannot say how far along it is has nothing to draw; use the spinner for unknown-duration work.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "max",
                    "default": "100",
                    "default_normalized": "100",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name. REQUIRED: a progressbar with no name announces a number and never says what the number is about.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "valueText",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "What assistive tech should read instead of the bare percentage. Use it when the percentage is not the point (\"18.2 GB of 25 GB used\").",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.radial-progress.size', 'md')",
                    "default_normalized": "config('wirekit.components.radial-progress.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "md",
                        "sm",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "intent",
                    "default": "config('wirekit.components.radial-progress.intent', 'primary')",
                    "default_normalized": "config('wirekit.components.radial-progress.intent', 'primary')",
                    "type_hint": null,
                    "comment": "Color axis. Ignored once a threshold is crossed — see below.",
                    "examples": [],
                    "values": [
                        "primary",
                        "accent",
                        "success",
                        "warning",
                        "danger",
                        "info",
                        "neutral"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "warn",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Fraction of max at which the ring turns warning / danger, mirroring usage-meter so a dashboard reads the same in both shapes. null disables.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "danger",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "animate",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Sweep the fill from empty to its value on first paint, and animate later value changes instead of snapping. Purely additive polish: gated by prefers-reduced-motion, and the ring is complete without it (the on-load sweep is above-baseline progressive enhancement — see dist/wirekit.css).",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "radio",
            "tag": "\u003Cx-wirekit::radio\u003E",
            "category": "Form",
            "description": "Radio button with label and hint",
            "docs_url": "https://docs.wirekit.app/components/radio",
            "props": [
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.radio.size', 'md')",
                    "default_normalized": "config('wirekit.components.radio.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "variant",
                    "default": "config('wirekit.components.radio.variant', 'default')",
                    "default_normalized": "config('wirekit.components.radio.variant', 'default')",
                    "type_hint": null,
                    "comment": "'default' (inline control + label) or 'card' (the whole bordered card is the clickable target and highlights when selected — the pricing-tier pattern).",
                    "examples": [],
                    "values": [
                        "default",
                        "card"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "range-slider",
            "tag": "\u003Cx-wirekit::range-slider\u003E",
            "category": "Form",
            "description": "Dual-thumb range slider",
            "docs_url": "https://docs.wirekit.app/components/range-slider",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk. StrictnessGate did not complain either, because `required` is in its HTML passthrough list — so it looked like a legitimate attribute all the way down. The result was a required field that submits empty, in the same form as a plain input that behaves correctly.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "Livewire method to call optimistically. It receives the full range as [min, max]. Absent -\u003E this component renders exactly as it did before, down to the byte. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`error` was undeclared while `label` was not, so `:error` on this control landed in the attribute bag and rendered as a stray HTML attribute — a validation message the developer wrote, silently not shown, on a control that is part of forms.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out — an app that runs its OWN error summary would otherwise double-announce here.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "min",
                    "default": "config('wirekit.components.range-slider.min', 0)",
                    "default_normalized": "config('wirekit.components.range-slider.min', 0)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "max",
                    "default": "config('wirekit.components.range-slider.max', 100)",
                    "default_normalized": "config('wirekit.components.range-slider.max', 100)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "step",
                    "default": "config('wirekit.components.range-slider.step', 1)",
                    "default_normalized": "config('wirekit.components.range-slider.step', 1)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "minValue",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "maxValue",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "showValues",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "valueTextMap",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Spoken value per stop, e.g. [0 =\u003E 'Free', 100 =\u003E 'Enterprise']. Each thumb announces its OWN value through it — the dual-handle equivalent of the same prop on the single-value slider component. (Written without the tag syntax on purpose: Blade compiles component tags even inside comments.) Without it a screen reader reads the bare number, which is right for a price and wrong for a tier.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Disable the whole control: `aria-disabled` on both thumbs, native `disabled` on the two hidden inputs (so a submitted form carries no range), no pointer or keyboard handlers, and the group dims via --opacity-wk-disabled. It was DOCUMENTED — a props-table row and an accessibility bullet — while undeclared here, so the flag landed in the attribute bag and rendered on the wrapper `\u003Cdiv\u003E`, where `disabled` means nothing: the control looked untouched and stayed fully operable by pointer AND keyboard.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "rating",
            "tag": "\u003Cx-wirekit::rating\u003E",
            "category": "Form",
            "description": "Star rating input",
            "docs_url": "https://docs.wirekit.app/components/rating",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk. StrictnessGate did not complain either, because `required` is in its HTML passthrough list — so it looked like a legitimate attribute all the way down. The result was a required field that submits empty, in the same form as a plain input that behaves correctly.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method this rating should call, when it should show the new score before the server has agreed to it. Null (the default) leaves this component byte-identical to what it has always rendered. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`error` was undeclared while `label` was not, so `:error` on a rating landed in the attribute bag and rendered as a stray HTML attribute — a validation message the developer wrote, silently not shown, on a control that IS part of forms.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out — an app that runs its OWN error summary would otherwise double-announce here.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "0",
                    "default_normalized": "0",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "max",
                    "default": "config('wirekit.components.rating.max', 5)",
                    "default_normalized": "config('wirekit.components.rating.max', 5)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "icon",
                    "default": "'star'",
                    "default_normalized": "'star'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "clearable",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Let the reader take the score back. This control implements the ARIA radiogroup model, and a radiogroup has no way back to \"nothing chosen\" — a native radio cannot be deselected from the keyboard either. By that measure the old behavior was correct, which is why this is a prop and not a fix: lowering the floor for everybody would change a documented model for every existing call site. It is opt-in because the two places a rating is most often used are not radiogroups in spirit. A filter facet and an optional form field both need \"no opinion\" to survive a mis-click; without it the server receives a score nobody meant to give, and the zero state this component renders and documents is reachable only until the first interaction. The gesture is picking the chosen star again, plus stepping down past the first one. A separate clear control was the alternative and was not taken: it puts a permanent extra element and an extra tab stop on every rating on the page — including the majority that never clear — and it needs a label and a position that only the call site knows.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "readonly",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.rating.size', 'md')",
                    "default_normalized": "config('wirekit.components.rating.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "inline-edit",
            "tag": "\u003Cx-wirekit::inline-edit\u003E",
            "category": "Form",
            "description": "Edit a value in place, with an explicit confirm step",
            "docs_url": "https://docs.wirekit.app/components/inline-edit",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "context",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Names the RECORD as well as the field. \"Edit: Title\" is useless in a list of twenty rows — a screen reader then reads twenty identical entries and the user cannot tell which one they are on.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "trigger",
                    "default": "'always'",
                    "default_normalized": "'always'",
                    "type_hint": null,
                    "comment": "What the reader SEES. There is deliberately no `none`: plain text is not focusable, so a value with no button is unreachable by keyboard entirely (WCAG 2.1.1). `focus-only` gives the quiet look without that defect.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "openOnValueClick",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Whether clicking the VALUE opens the editor. Separate axis from `trigger` — one is what you see, the other is what acts.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "exclusive",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "control",
                    "default": "'text'",
                    "default_normalized": "'text'",
                    "type_hint": null,
                    "comment": "Which control the editor renders.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "options",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "Options for control=\"select\" — key =\u003E label.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "displayValue",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "What READ MODE shows when the stored value is not the readable one: a select stores a key, an amount stores 1299, a date stores an ISO string. Defaults to the value, and resolves itself for a select.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "emptyText",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Read-mode text when there is no value. Deliberately NOT called `placeholder`: on input, textarea and select that name already means the HTML attribute, and a second `placeholder` meaning something else would damage the prop vocabulary rather than extend it.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "commitOn",
                    "default": "'explicit'",
                    "default_normalized": "'explicit'",
                    "type_hint": null,
                    "comment": "`explicit` — only the confirm control commits. `blur` additionally commits when the control loses focus. Forced to explicit for a select, see below.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "actions",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "size",
                    "default": "'md'",
                    "default_normalized": "'md'",
                    "type_hint": null,
                    "comment": "sm / md / lg only. Measured against all four control components rather than assumed: `md-compact` exists on input and select but NOT on textarea or number-input, so offering it here would throw for two of the four.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "width",
                    "default": "'full'",
                    "default_normalized": "'full'",
                    "type_hint": null,
                    "comment": "Cross-axis behavior. `auto` measures the content, so the width DOES jump when the editor opens and that is the honest choice for a short value in running text. `full` takes the container width, and then read and edit boxes are the same width — which is the half of layout stability that can actually be promised.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "loading",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "loadingTarget",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "NOTE: `loadingTarget`, not `target` — the same distinction the button draws, so a page using both does not have to remember two spellings.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "rows",
                    "default": "'auto'",
                    "default_normalized": "'auto'",
                    "type_hint": null,
                    "comment": "Textarea height, forwarded to the textarea's own `rows`. `auto` is its content-sizing mode: the editor opens as tall as the text it replaces and grows while typing. A row count pins a fixed height instead — which is what shipped, and it meant a four-line value opened into a three-row box the reader had to scroll to see their own text in. Ignored for every control except `textarea`.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "saveTimeout",
                    "default": "10000",
                    "default_normalized": "10000",
                    "type_hint": null,
                    "comment": "How long to wait for the developer's `wirekit:inline-edit-saved` / `-failed` answer before giving up, in milliseconds. 0 disables the bound and lets the editor stay busy indefinitely — only sensible when the answer is genuinely guaranteed.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "unknownMessage",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "What the reader is told when that bound is reached. It exists because the alternative shipped: the timeout path wrote `config.unknownMessage ?? ''` and nothing ever supplied the value, so the component set the live region to the EMPTY STRING and abandoned the save in silence. A field that announced itself busy and then says nothing at all is the worst of the three possible outcomes — a screen-reader user is left with no way to know whether the edit was kept, and sighted readers only see a spinner stop.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "editor",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "select",
            "tag": "\u003Cx-wirekit::select\u003E",
            "category": "Form",
            "description": "Native select dropdown",
            "docs_url": "https://docs.wirekit.app/components/select",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method this component should call, when it should show the new value before the server has agreed to it. Null leaves the component exactly as it has always rendered. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hideLabel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "render the label sr-only (kept for assistive tech) — for compact toolbar / header fields",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "reserveMessage",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Keep the message line's height whether or not there is a message. Wasted space in a stacked form, and the difference between a working toolbar and one that jumps in a horizontal row: an appearing error grows this element, and every sibling in the row re-anchors to the new bottom edge. Aligning the row does not fix it — `items-end` follows the growth, and `items-start` lines things up with the label rather than the control.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "success",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Success / valid state — string shows a green confirmation below, `true` shows just the green border. `error` always wins when both are set.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.select.size', 'md')",
                    "default_normalized": "config('wirekit.components.select.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md-compact",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "placeholder",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "options",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The pre-selected option. It has to be a declared prop: `\u003Cselect\u003E` has no `value` content attribute, so an undeclared one fell into the attribute bag and rendered onto the element, where HTML ignores it. `value=\"pro\"` then selected nothing and the browser fell back to the first option — the field showed one choice while everything reading the component believed another.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "slider",
            "tag": "\u003Cx-wirekit::slider\u003E",
            "category": "Form",
            "description": "Single-thumb slider with value display",
            "docs_url": "https://docs.wirekit.app/components/slider",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk. StrictnessGate did not complain either, because `required` is in its HTML passthrough list — so it looked like a legitimate attribute all the way down. The result was a required field that submits empty, in the same form as a plain input that behaves correctly.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method to call when the slider should show the new value before the server has agreed to it. The value is sent when the gesture ends — see the note above. Null leaves the component exactly as it has always rendered. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "id",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`error` was undeclared while `label` was not, so `:error` on this control landed in the attribute bag and rendered as a stray HTML attribute — a validation message the developer wrote, silently not shown, on a control that is part of forms.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out — an app that runs its OWN error summary would otherwise double-announce here.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "min",
                    "default": "config('wirekit.components.slider.min', 0)",
                    "default_normalized": "config('wirekit.components.slider.min', 0)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "max",
                    "default": "config('wirekit.components.slider.max', 100)",
                    "default_normalized": "config('wirekit.components.slider.max', 100)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "step",
                    "default": "config('wirekit.components.slider.step', 1)",
                    "default_normalized": "config('wirekit.components.slider.step', 1)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.slider.size', 'md')",
                    "default_normalized": "config('wirekit.components.slider.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "showValue",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "marks",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "Step marks: a list of values (`[0, 25, 50, 75, 100]`) for plain ticks, or a value =\u003E label map (`[0 =\u003E 'Low', 100 =\u003E 'High']`) for labeled ticks.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "valueTextMap",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Decouple the announced aria-valuetext from the visual tick labels: an explicit value =\u003E spoken-text map lets you show NUMERIC ticks but announce semantic meaning (e.g. [1 =\u003E 'Low', 5 =\u003E 'High']). Falls back to the `marks` labels.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "tooltip",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Show a value bubble above the thumb that follows it as the user drags.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "tags-input",
            "tag": "\u003Cx-wirekit::tags-input\u003E",
            "category": "Form",
            "description": "Tag entry input with add/remove",
            "docs_url": "https://docs.wirekit.app/components/tags-input",
            "props": [
                {
                    "name": "required",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`required` — DECLARED rather than left to the attribute bag. Undeclared, Blade folded it into the bag and it landed on a wrapper div, where it is invalid HTML that nothing reads: no native constraint, no aria-required, no asterisk. StrictnessGate did not complain either, because `required` is in its HTML passthrough list — so it looked like a legitimate attribute all the way down. The result was a required field that submits empty, in the same form as a plain input that behaves correctly.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method to call when the set changes. A refusal KEEPS the change and says it was not saved — see the note above. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "maxTags",
                    "default": "config('wirekit.components.tags-input.max-tags')",
                    "default_normalized": "config('wirekit.components.tags-input.max-tags')",
                    "type_hint": null,
                    "comment": "Both resolve through config, because the docs page has told developers to override them in `config/wirekit.php` since it shipped and nothing here ever read it — an instruction that fails silently, with no error to search for. The catalog default stays behind a `??` rather than moving into the config stub: a literal in the stub would freeze one language for every locale.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "placeholder",
                    "default": "config('wirekit.components.tags-input.placeholder') ?? __('wirekit::Add a tag…')",
                    "default_normalized": "config('wirekit.components.tags-input.placeholder') ?? __('wirekit::Add a tag…')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Documented as part of this control's API since it shipped, and until now it was documentation only: the attribute bag never reached the text input, so a call site asking for a disabled field got a fully working one.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "textarea",
            "tag": "\u003Cx-wirekit::textarea\u003E",
            "category": "Form",
            "description": "Multi-line text input with resize control",
            "docs_url": "https://docs.wirekit.app/components/textarea",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method this component should call, when it should show the new value before the server has agreed to it. A refusal keeps your text — see the note above. Null leaves the component exactly as it has always rendered. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hideLabel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "render the label sr-only (kept for assistive tech) — for compact toolbar / header fields",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "reserveMessage",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Keep the message line's height whether or not there is a message. Wasted space in a stacked form, and the difference between a working toolbar and one that jumps in a horizontal row: an appearing error grows this element, and every sibling in the row re-anchors to the new bottom edge. Aligning the row does not fix it — `items-end` follows the growth, and `items-start` lines things up with the label rather than the control.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "success",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Success / valid state — string shows a green confirmation below, `true` shows just the green border. `error` always wins when both are set.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.textarea.size', 'md')",
                    "default_normalized": "config('wirekit.components.textarea.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "rows",
                    "default": "config('wirekit.components.textarea.rows', 3)",
                    "default_normalized": "config('wirekit.components.textarea.rows', 3)",
                    "type_hint": null,
                    "comment": "Number of rows, OR 'auto' to grow with content via CSS field-sizing: content — a property ABOVE the browser baseline, which this line called safe to assume for thirteen releases. Auto mode falls back to a 2-row minimum where the property is unsupported; the degradation is spelled out at $autosize.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "resize",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "time-picker",
            "tag": "\u003Cx-wirekit::time-picker\u003E",
            "category": "Form",
            "description": "Time selection input",
            "docs_url": "https://docs.wirekit.app/components/time-picker",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method this component should call, when it should show the new value before the server has agreed to it. Null leaves the component exactly as it has always rendered. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "format",
                    "default": "'24h'",
                    "default_normalized": "'24h'",
                    "type_hint": null,
                    "comment": "24h | 12h",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "step",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The native `step` attribute, in SECONDS, exactly as HTML defines it: 900 is a quarter of an hour, 60 is one minute, null leaves the browser's own default. It read as MINUTES here for a quick-pick list that was computed on every render and never emitted, and the value never reached the control at all — so a caller writing the documented `step=\"900\"` got a field that still accepted 09:07, and the arrow keys still stepped by one.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.time-picker.size', 'md')",
                    "default_normalized": "config('wirekit.components.time-picker.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "toggle",
            "tag": "\u003Cx-wirekit::toggle\u003E",
            "category": "Form",
            "description": "Toggle switch with label and hint",
            "docs_url": "https://docs.wirekit.app/components/toggle",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method this toggle should call, when it should show the new state before the server has agreed to it. Null (the default) is today's behavior exactly: the developer's own wire:model / wire:click, untouched. It is a METHOD NAME rather than a boolean because the component cannot know the action otherwise — WireKit passes server actions through the attribute bag, so a component never sees the developer's wire:click. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hideLabel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Render the label sr-only (kept as the control's accessible name) — for a toggle in a table column or a toolbar whose surrounding chrome already names it. The \u003Clabel\u003E WRAPS the control, so the name is associated with the element rather than with the visible text and survives being taken off the screen. Mirrors input / select / textarea / combobox / checkbox `hideLabel`.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.toggle.size', 'md')",
                    "default_normalized": "config('wirekit.components.toggle.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "toggle-button",
            "tag": "\u003Cx-wirekit::toggle-button\u003E",
            "category": "Display",
            "description": "Single two-state button that stays pressed (aria-pressed) — the bold/italic/mute shape",
            "docs_url": "https://docs.wirekit.app/components/toggle-button",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method to call when the button should show its new pressed state before the server has agreed to it. A refusal puts the old state back — see the note above about the wrapper this adds. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "pressed",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "The two-state truth. In the controlled default, bind it to your own state — the pressed state of a formatting control lives in the document, not in the button. It also seeds the initial state in self-toggle mode.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "selfToggle",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Uncontrolled convenience. When true the button flips its OWN aria-pressed on click (Alpine), so it works standalone — a formatting toolbar, a docs demo — with no Livewire wiring. Default is controlled: a bare click must NOT flip it locally and drift from the document's truth.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "size",
                    "default": "'md'",
                    "default_normalized": "'md'",
                    "type_hint": null,
                    "comment": "Visual weight, forwarded to the underlying button.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "icon",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "One glyph, the same in both states. The pressed surface carries the state, as it always has.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "onIcon",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A glyph per state, swapped as the state changes. Both are needed: one alone would swap with nothing. The same alias works in every icon preset, where an outline and a filled variant of one glyph would not, so a second alias is how a state gets its own shape.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "offIcon",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "tooltip",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A hint shown on hover and focus. On a toggle with no visible label it is ALSO the accessible name, because a glyph is not a name and a hover never happens on a touch screen.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "activeIntent",
                    "default": "'accent'",
                    "default_normalized": "'accent'",
                    "type_hint": null,
                    "comment": "The color of the icon while pressed, from the canonical intents. Color is never the state on its own here: the surface changes either way.",
                    "examples": [],
                    "values": [
                        "accent",
                        "success",
                        "warning",
                        "danger",
                        "info"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "onLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A label per state, such as \"Sound on\" and \"Sound off\". A button whose label says its state is not a toggle in the ARIA sense, so it renders WITHOUT aria-pressed: announcing \"Sound on, pressed\" would say the state twice, and the APG button pattern rules the pairing out.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "offLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "tool-call",
            "tag": "\u003Cx-wirekit::tool-call\u003E",
            "category": "Display",
            "description": "One tool invocation an assistant made — name, status, arguments as JSON, and the result behind a disclosure",
            "docs_url": "https://docs.wirekit.app/components/tool-call",
            "props": [
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "What was called. This is the name a reader recognizes — `search_docs`, `get_weather` — and it is also the accessible name of the whole block, so it is required in practice: a tool call nobody can name is a spinner with extra steps.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "status",
                    "default": "'pending'",
                    "default_normalized": "'pending'",
                    "type_hint": null,
                    "comment": "Where the call stands: pending — queued, nothing has happened yet running — in flight (the block is aria-busy and the label shimmers) done    — returned, the result is in the slot failed  — returned an error, and the slot holds it",
                    "examples": [],
                    "values": [
                        "pending",
                        "running",
                        "done",
                        "failed"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "arguments",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The arguments the model passed, shown as JSON. An array is encoded here; a string is printed as given, so an application that already has the provider's raw JSON does not pay a decode/encode round trip to display it.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "seconds",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Seconds the call took, for the settled label. The APPLICATION owns this number — it knows when the call started, and a stopwatch in the browser would disagree with it the moment the page re-renders from the server. Null keeps the plain status word.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "open",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Whether the result opens closed. A finished call's result is reference material, so it is collapsed by default; a failure opens, because an error nobody sees is not reported.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "app-rail",
            "tag": "\u003Cx-wirekit::app-rail\u003E",
            "category": "Navigation",
            "description": "Full-height module rail with tooltip, below (captions under the icons), or inline labels",
            "docs_url": "https://docs.wirekit.app/components/app-rail",
            "props": [
                {
                    "name": "labels",
                    "default": "'tooltip'",
                    "default_normalized": "'tooltip'",
                    "type_hint": null,
                    "comment": "How an item names itself. tooltip — icon only; the label is the link's accessible name and appears on hover/focus in a tooltip. The narrowest form, and the default. below   — a caption under the icon. Wider, and it removes the hover dependency, which matters on touch where hover does not exist. inline  — the label beside the icon, in a wide rail. This is the shape a single-column application wants when the rail IS the navigation.",
                    "examples": [],
                    "values": [
                        "tooltip",
                        "below",
                        "inline"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "expandable",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Adds a toggle that widens the rail to `inline` labels and back, persisting the choice. Orthogonal to `labels`: the toggle switches between the width `labels` selects and the expanded width, so `labels=\"below\"` plus `expandable` gives captions that become full labels.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "expanded",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Initial state on a first visit, before storage answers. Left unset, the cookie driver below is allowed to answer it instead — which is the whole point of that driver, so an explicit value here wins and turns the seeding off.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "persist",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Storage key. Null keeps the choice for the session only.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "persistDriver",
                    "default": "'local'",
                    "default_normalized": "'local'",
                    "type_hint": null,
                    "comment": "WHERE the choice is remembered: 'local' (default) or 'cookie'. No server can read localStorage, so a rail that remembers being expanded renders collapsed and widens itself after the first paint. An adopting application measured that at 0.1097 CLS against a budget of 0.1 — the content column moving 187px, 53ms in. Reported again on 2026-09-01 from several production applications, as the navigation being briefly collapsed and then snapping open. A small nonced script after the column closes that gap now — it reads the stored flag while the parser is still working and swaps the width class before anything is painted. This comment used to end here saying the usual fix is an inline script \"which a strict `script-src 'self'` policy without a nonce simply blocks\", and that was an argument against an UNNONCED script: `fonts.blade.php` had already answered the same objection for its inline \u003Cstyle\u003E by emitting `WireKit::cspNonce()`. Where a policy refuses it anyway, the column falls back to exactly the behavior described above. A cookie is the only store Blade and Alpine both read, so this driver mirrors the flag there and the first render is already right. Opt-in on purpose: writing a cookie where a developer asked for localStorage is a behavior change, and a cookie is something an application has to be able to account for.",
                    "examples": [],
                    "values": [
                        "local",
                        "cookie"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "tone",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": "The surface. Each tone re-points the `--color-wk-rail-*` roles in dist/wirekit.css; every class below reads only those, so a tone is a change of variables rather than a parallel set of utilities. Override the roles in your own CSS to reskin one tone, or the `:root` defaults to reskin them all.",
                    "examples": [],
                    "values": [
                        "default",
                        "muted",
                        "inverse",
                        "accent"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "variant",
                    "default": "'flush'",
                    "default_normalized": "'flush'",
                    "type_hint": null,
                    "comment": "Shape. `flush` is the edge-to-edge chrome column with a single inline-end edge. `panel` is the floating rounded strip that sits ON the page with a gap around it — the shape that pairs with the app-shell's own `panel` prop. (The component tag is deliberately NOT written here. Blade is a text preprocessor and does not know it is inside a PHP comment: an `x-wirekit::` tag in one gets COMPILED, and the compiled component construct lands in the middle of this array. The failure reads \"unexpected token\" at a line that has nothing to do with it.)",
                    "examples": [],
                    "values": [
                        "flush",
                        "panel"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "indicator",
                    "default": "'pill'",
                    "default_normalized": "'pill'",
                    "type_hint": null,
                    "comment": "How the current module is marked. `pill` fills the item's own box. `edge` draws a bar on the inline-end edge of the rail, pointing at the column it selects — which reads better when the rail is very narrow and a filled box would dominate.",
                    "examples": [],
                    "values": [
                        "pill",
                        "edge"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "label",
                    "default": "__('wirekit::Modules')",
                    "default_normalized": "__('wirekit::Modules')",
                    "type_hint": null,
                    "comment": "Accessible name for the navigation landmark. A console shell has TWO \u003Cnav\u003E landmarks side by side, and a screen-reader user moving between landmarks cannot tell them apart unless each says what it is. Passing aria-label or aria-labelledby directly wins over this default and suppresses it, so the element never carries two conflicting names.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "brand",
                    "required": false
                },
                {
                    "name": "footer",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "app-rail.brand",
                    "tag": "\u003Cx-wirekit::app-rail.brand\u003E",
                    "props": [
                        {
                            "name": "name",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "The workspace's name. Drawn only where the rail is wide enough to read it; it stays the mark's accessible name in every mode regardless, so a narrow rail is not an unlabeled circle to a screen reader.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "description",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "A second, quieter line under the name — the plan, the environment, the role. Drawn only beside the name, never on its own: a subline without its subject says nothing.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "href",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Makes the whole block a link. Leave it out for a switcher — wrap the component in a dropdown trigger instead, so the control is a button and announces itself as one.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "app-rail.group",
                    "tag": "\u003Cx-wirekit::app-rail.group\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "An optional heading. It is drawn only where the rail draws labels at all — in the icon-only rail there is no room for it, and a section title that does not fit is worse than none — the labels themselves never truncate, so a heading there would wrap to three or four lines and push the modules off the screen. It stays the group's accessible name in every mode regardless, which is what lets a screen-reader user tell two clusters of icons apart.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "separated",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": "A separator line above the group. The rails these come from cluster modules with a rule rather than a heading — a heading costs a row of height that a narrow column does not have. Off for the first group, which needs no line above it.",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "app-rail.item",
                    "tag": "\u003Cx-wirekit::app-rail.item\u003E",
                    "props": [
                        {
                            "name": "href",
                            "default": "'#'",
                            "default_normalized": "'#'",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "as",
                            "default": "'a'",
                            "default_normalized": "'a'",
                            "type_hint": null,
                            "comment": "`a` or `button`. A rail module is a destination, so a link is the default and stays the default — this exists for the OTHER thing a rail entry legitimately is: the trigger of a dropdown, which our own console-shell blueprint builds out of one. As a link that trigger is subtly broken. A link activates on Enter and NOT on Space, measured against the blueprint's own pattern: Enter opened the menu and moved focus to the first entry, Escape closed it and returned focus, and Space did nothing — `aria-expanded` stayed \"false\". In a `viewport` shell Space is not even scrolling, so the key simply has no effect anywhere. On top of that every click on an `href=\"#\"` pushes a history entry and writes `…#` into the address bar, and a modified click opens a dead duplicate tab. Additive on purpose: switching automatically when `href` is \"#\" would have been the tidier API and would have changed the rendered element under every existing caller, including their CSS.",
                            "examples": [],
                            "values": [
                                "a",
                                "button"
                            ],
                            "value_type": "string"
                        },
                        {
                            "name": "active",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "The module's icon. A bare name string (\"chart-bar\") resolves through the WireKit icon system; a \u003Cx-slot:icon\u003E or inline markup renders verbatim. Consistent with sidebar.item / dropdown.item / command-palette.item.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "label",
                            "default": "''",
                            "default_normalized": "''",
                            "type_hint": null,
                            "comment": "The module's name. REQUIRED, and not merely by convention: in the rail's default mode nothing of it is drawn, so this string is the link's ONLY accessible name. Leave it out and a screen reader announces \"link\" — the failure that makes icon rails inaccessible in practice, and the reason this is a prop rather than the default slot (a slot cannot also be a tooltip's text without rendering twice).",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "badge",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "A trailing counter. Digits where a label is visible, a dot where it is not — the digits have no room in a 3.5rem rail, but an unread signal must not simply vanish where it matters most. The count stays in the accessible name in BOTH states.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "placement",
                            "default": "'right'",
                            "default_normalized": "'right'",
                            "type_hint": null,
                            "comment": "Where the tooltip opens. `right` is correct for a rail on the inline-start edge; a right-hand rail wants `left`.",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "app-shell",
            "tag": "\u003Cx-wirekit::app-shell\u003E",
            "category": "Layout",
            "description": "App shell with header, sidebar, and main content",
            "docs_url": "https://docs.wirekit.app/components/app-shell",
            "props": [
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "viewport",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Viewport-fixer mode. Default (false) keeps `min-h-screen` — the shell grows with its content and the PAGE scrolls as a document. When true, the root is pinned to the viewport (`h-dvh overflow-hidden`) so the inner sidebar + main regions scroll INTERNALLY (brand pinned top, account menu pinned bottom) — the classic fixed-height admin-shell case. `dvh` (not `vh`) so the mobile browser toolbar collapse is handled.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "sidebarInset",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Whether the in-flow sidebar column keeps its top and inline-start inset. True (default) is the card layout: the sidebar sits as a panel inside a padded column. False is the full-bleed navigation column — the sidebar meets the top and the inline-start edge of the shell with nothing between. A prop because the two utilities that produce the inset were literals on the \u003Caside\u003E, and the attribute bag lands on the ROOT element — so they were unreachable from a call site by any means except a CSS rule targeting the vendor's own marker class and out-specifying Tailwind by emission order. Pair it with the sidebar's own `variant=\"flush\"`: this removes the gap around the column, that removes the card inside it. (Named without its tag on purpose — a component tag written inside this comment block is compiled by Blade, not ignored, and takes the whole component down with a 500.)",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "headerPlacement",
                    "default": "'shell'",
                    "default_normalized": "'shell'",
                    "type_hint": null,
                    "comment": "Where the header slot renders. `shell` (default) spans the full width above the sidebar row. `content` puts it INSIDE the content column, so the sidebar runs the full height and the topbar begins beside it — the other common admin layout, and previously reachable only by hiding the header slot at lg and hand-placing a topbar in the default slot, which cost the header slot on desktop entirely and cost every developer the same discovery. A `sticky` HEADER STOPS WORKING IN THIS MODE, and the reason is structural rather than a bug to fix here. `position: sticky` sticks to the nearest scrolling ancestor; in `content` mode the header's nearest one is the content column, which carries `overflow-hidden` (see the comment on that element below) and therefore never scrolls. Nothing sticks to a container that does not move. In `shell` mode the header is outside that column, so its scrolling ancestor is the page and sticky behaves as written. With `viewport` the question dissolves rather than being answered: the main region becomes the scroller and the header sits above it without moving at all, so it needs no sticky. Reaching for `sticky` there is harmless and does nothing. (The component tag for that region is deliberately NOT written here. Blade is a text preprocessor and does not know it is inside a PHP comment — an `x-wirekit::` tag in one gets COMPILED, and the compiled component construct lands in the middle of this array. The failure is \"Undefined variable $component\", which points at the render rather than at the sentence that caused it.)",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "panel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "The content column as an INSET rounded surface, floating on the shell's own background rather than meeting it edge to edge. The shape three of the reference consoles use: the chrome (rail, second column, top rule) is one surface and the content sits on it like a sheet, its inline-start corners rounded. lg only, and that is not a shortcut. Below the breakpoint the navigation is an off-canvas drawer and the content is the whole viewport — a rounded inset there would spend horizontal room a phone does not have on a decoration nothing is beside.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "tone",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": "The shell's own chrome surface. `default` leaves the shell on --color-wk-bg, which is every existing app-shell and stays byte-identical. The other tones point the root at the same `--color-wk-rail-*` roles the rail and a toned sidebar read, so a shell, its rail and its second column become one continuous chrome surface with the content panel sitting on top of it. A flush sidebar inside a toned shell follows automatically — it paints nothing of its own, so the chrome IS its surface, and its contents are remapped with it. It is the same token set on purpose: three components that must agree about a color should not each own a copy of it.",
                    "examples": [],
                    "values": [
                        "default",
                        "muted",
                        "inverse"
                    ],
                    "value_type": "string"
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "rail",
                    "required": false
                },
                {
                    "name": "sidebar",
                    "required": false
                },
                {
                    "name": "header",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "aspect-ratio",
            "tag": "\u003Cx-wirekit::aspect-ratio\u003E",
            "category": "Layout",
            "description": "Constrained aspect ratio wrapper",
            "docs_url": "https://docs.wirekit.app/components/aspect-ratio",
            "props": [
                {
                    "name": "ratio",
                    "default": "'16/9'",
                    "default_normalized": "'16/9'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "center",
            "tag": "\u003Cx-wirekit::center\u003E",
            "category": "Layout",
            "description": "Center content horizontally and vertically",
            "docs_url": "https://docs.wirekit.app/components/center",
            "props": [
                {
                    "name": "inline",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "as",
                    "default": "'div'",
                    "default_normalized": "'div'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "container",
            "tag": "\u003Cx-wirekit::container\u003E",
            "category": "Layout",
            "description": "Max-width content container with optional padding",
            "docs_url": "https://docs.wirekit.app/components/container",
            "props": [
                {
                    "name": "max",
                    "default": "config('wirekit.components.container.max', 'xl')",
                    "default_normalized": "config('wirekit.components.container.max', 'xl')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl",
                        "full"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "padding",
                    "default": "config('wirekit.components.container.padding', 'md')",
                    "default_normalized": "config('wirekit.components.container.padding', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "none",
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "center",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "as",
                    "default": "'div'",
                    "default_normalized": "'div'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "divider",
            "tag": "\u003Cx-wirekit::divider\u003E",
            "category": "Layout",
            "description": "Horizontal or vertical divider with optional label",
            "docs_url": "https://docs.wirekit.app/components/divider",
            "props": [
                {
                    "name": "orientation",
                    "default": "'horizontal'",
                    "default_normalized": "'horizontal'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "horizontal",
                        "vertical"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "variant",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "default",
                        "subtle",
                        "bold"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "grid",
            "tag": "\u003Cx-wirekit::grid\u003E",
            "category": "Layout",
            "description": "CSS grid with responsive column syntax",
            "docs_url": "https://docs.wirekit.app/components/grid",
            "props": [
                {
                    "name": "cols",
                    "default": "config('wirekit.components.grid.cols', 1)",
                    "default_normalized": "config('wirekit.components.grid.cols', 1)",
                    "type_hint": null,
                    "comment": "@example \"1 md:2 lg:4\" @example \"1 sm:2 md:3 lg:4 xl:6\"",
                    "examples": [
                        "1 md:2 lg:4",
                        "1 sm:2 md:3 lg:4 xl:6"
                    ],
                    "values": [
                        "1",
                        "2",
                        "3",
                        "4",
                        "5",
                        "6",
                        "7",
                        "8",
                        "9",
                        "10",
                        "11",
                        "12",
                        "sm:1",
                        "sm:2",
                        "sm:3",
                        "sm:4",
                        "sm:5",
                        "sm:6",
                        "sm:7",
                        "sm:8",
                        "sm:9",
                        "sm:10",
                        "sm:11",
                        "sm:12",
                        "md:1",
                        "md:2",
                        "md:3",
                        "md:4",
                        "md:5",
                        "md:6",
                        "md:7",
                        "md:8",
                        "md:9",
                        "md:10",
                        "md:11",
                        "md:12",
                        "lg:1",
                        "lg:2",
                        "lg:3",
                        "lg:4",
                        "lg:5",
                        "lg:6",
                        "lg:7",
                        "lg:8",
                        "lg:9",
                        "lg:10",
                        "lg:11",
                        "lg:12",
                        "xl:1",
                        "xl:2",
                        "xl:3",
                        "xl:4",
                        "xl:5",
                        "xl:6",
                        "xl:7",
                        "xl:8",
                        "xl:9",
                        "xl:10",
                        "xl:11",
                        "xl:12",
                        "2xl:1",
                        "2xl:2",
                        "2xl:3",
                        "2xl:4",
                        "2xl:5",
                        "2xl:6",
                        "2xl:7",
                        "2xl:8",
                        "2xl:9",
                        "2xl:10",
                        "2xl:11",
                        "2xl:12"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "min",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "@example \"14rem\" @example \"20ch\"",
                    "examples": [
                        "14rem",
                        "20ch"
                    ],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "template",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "@example \"14rem 1fr 18rem\" @example \"4.5rem repeat(7, minmax(0, 1fr))\"",
                    "examples": [
                        "14rem 1fr 18rem",
                        "4.5rem repeat(7, minmax(0, 1fr))"
                    ],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "gap",
                    "default": "config('wirekit.components.grid.gap', 'md')",
                    "default_normalized": "config('wirekit.components.grid.gap', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "none",
                        "xs",
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scale",
                    "default": "'space'",
                    "default_normalized": "'space'",
                    "type_hint": null,
                    "comment": "Which spacing ladder `gap` names a rung on: `space`, what this prop has always read, or `gap`, the tighter ladder WireKit's own components use inside themselves. The two share the rung names `xs`…`2xl` and differ from `md` up, so a card grid written against `--gap-wk-md` could not become this component without every gap growing by a third. `row` and `stack` have had the same prop since it was first reported for them; the grids were left behind only because that report came from a repository using those two.",
                    "examples": [],
                    "values": [
                        "space",
                        "gap"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "align",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "start",
                        "center",
                        "end",
                        "stretch"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "as",
                    "default": "'div'",
                    "default_normalized": "'div'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "header",
            "tag": "\u003Cx-wirekit::header\u003E",
            "category": "Layout",
            "description": "Sticky page header for app-shell layouts",
            "docs_url": "https://docs.wirekit.app/components/header",
            "props": [
                {
                    "name": "sticky",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "container",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "logo-cloud",
            "tag": "\u003Cx-wirekit::logo-cloud\u003E",
            "category": "Marketing",
            "description": "Partner / customer logo wall, exposed as a labeled list",
            "docs_url": "https://docs.wirekit.app/components/logo-cloud",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional lead-in (\"Trusted by teams at\"). Rendered as real text above the wall, so the claim is readable rather than implied by layout alone.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "ariaLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the list itself. Falls back to the label.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "muted",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Drain the color out of the logos so a row of clashing brand colors does not compete with the page's own. They return to full color on hover. The word for that filter is deliberately not written here: Tailwind scans this file including its comments, and a bare utility name in prose makes it emit a class nothing uses. The treatment itself lives in dist/wirekit.css. Purely visual: every logo still carries its own alt text, so nothing about the company's identity depends on seeing the color.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "main",
            "tag": "\u003Cx-wirekit::main\u003E",
            "category": "Layout",
            "description": "Primary content area in app-shell layouts",
            "docs_url": "https://docs.wirekit.app/components/main",
            "props": [
                {
                    "name": "container",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "padding",
                    "default": "config('wirekit.components.main.padding', 'lg')",
                    "default_normalized": "config('wirekit.components.main.padding', 'lg')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "none",
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "max",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "cap the content width by default so dashboards don't stretch edge-to-edge on 1900px+ monitors. Default '2xl' matches the container component's '2xl' tier — most full-page layouts already wrap the slot in a container with that cap, so adopting the same default here unifies the two surfaces. Opt out with max=\"none\" to preserve the pre-2.3.0 unbounded behavior. Reads from config to allow per-app overrides.",
                    "examples": [],
                    "values": [
                        "none",
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl",
                        "full"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "id",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "First-class id prop — pairs with the wirekit::skip-link helper. When set, the main element also becomes programmatically focusable (tabindex=\"-1\") so the skip-link's fragment navigation moves keyboard focus INTO the landmark (browser default would only scroll).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "resizable",
            "tag": "\u003Cx-wirekit::resizable\u003E",
            "category": "Layout",
            "description": "Resizable panel layout",
            "docs_url": "https://docs.wirekit.app/components/resizable",
            "props": [
                {
                    "name": "direction",
                    "default": "'horizontal'",
                    "default_normalized": "'horizontal'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "resizable.handle",
                    "tag": "\u003Cx-wirekit::resizable.handle\u003E",
                    "props": [
                        {
                            "name": "index",
                            "default": "0",
                            "default_normalized": "0",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Accessible name for the separator. It needs one: the Alpine plugin gives this element `role=\"separator\"` and `tabindex=\"0\"`, so a reader tabs onto it and hears \"splitter, 50%\" with nothing saying WHICH split it moves — and a three-panel layout has two of them, announced identically. The APG's Window Splitter names it after the pane it sizes, so pass the pane's name when you have one, or point `aria-labelledby` at that pane's visible heading; the default is only a floor.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "resizable.panel",
                    "tag": "\u003Cx-wirekit::resizable.panel\u003E",
                    "props": [
                        {
                            "name": "defaultSize",
                            "default": "50",
                            "default_normalized": "50",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "minSize",
                            "default": "10",
                            "default_normalized": "10",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "maxSize",
                            "default": "90",
                            "default_normalized": "90",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "band",
            "tag": "\u003Cx-wirekit::band\u003E",
            "category": "Layout",
            "description": "Edge-to-edge strip with padding and one rule",
            "docs_url": "https://docs.wirekit.app/components/band",
            "props": [
                {
                    "name": "edge",
                    "default": "'bottom'",
                    "default_normalized": "'bottom'",
                    "type_hint": null,
                    "comment": "Which edge carries the rule. ⚠️ There is no majority to default to, and the number is worth recording so nobody later \"corrects\" this on a hunch: across the 24 hand-rolled bands in the blueprint catalog the split is exactly 12 top and 12 bottom. `bottom` is chosen because a band under a header is the mental model most callers arrive with, not because it is more common. State it at the call site.",
                    "examples": [],
                    "values": [
                        "none",
                        "top",
                        "bottom",
                        "both"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "padding",
                    "default": "'sm'",
                    "default_normalized": "'sm'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "none",
                        "xs",
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "surface",
                    "default": "'none'",
                    "default_normalized": "'none'",
                    "type_hint": null,
                    "comment": "The occasional band that is not on the page background. Measured: 5 of the 24.",
                    "examples": [],
                    "values": [
                        "none",
                        "subtle",
                        "muted"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "as",
                    "default": "'div'",
                    "default_normalized": "'div'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "row",
            "tag": "\u003Cx-wirekit::row\u003E",
            "category": "Layout",
            "description": "Horizontal flex container",
            "docs_url": "https://docs.wirekit.app/components/row",
            "props": [
                {
                    "name": "gap",
                    "default": "config('wirekit.components.row.gap', 'md')",
                    "default_normalized": "config('wirekit.components.row.gap', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "none",
                        "xs",
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "align",
                    "default": "'center'",
                    "default_normalized": "'center'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "start",
                        "center",
                        "end",
                        "stretch",
                        "baseline"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "alignFields",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Line the CONTROLS up when this row holds form fields. A labeled field is taller than an unlabeled one and a field with a hint is taller still, so any single `align` value lines up the wrong edge for some mix of them. Measured across six combinations: `center` leaves the controls 13.5px apart, `end` fixes that and then breaks by 25.5px as soon as one field carries a hint, and `start`/`stretch`/`baseline` are worse than either. With this on, the row becomes a three-row grid — labels, controls, messages — that every field shares, so a control sits on the control row whatever its neighbors carry. Children that are not fields (a submit button) sit on the control row too. Opt-in, and it has to be: it changes the row's display model and asks the fields inside it to render placeholder parts. Nothing renders differently until asked.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "justify",
                    "default": "'start'",
                    "default_normalized": "'start'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "start",
                        "center",
                        "end",
                        "between",
                        "around",
                        "evenly"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scale",
                    "default": "'space'",
                    "default_normalized": "'space'",
                    "type_hint": null,
                    "comment": "Which spacing ladder `gap` names a rung on. WireKit defines two, they share the rung names `xs`…`2xl`, and from `md` up they are different numbers — `--gap-wk-md` is 0.75rem against `--space-wk-md`'s 1rem. This prop read only `--space-wk-*`, while the kit's own components read `--gap-wk-*` in dozens of places. So a repository that followed WireKit's example and wrote `gap-[var(--gap-wk-md)]` could never turn that container into a `row` without re-spacing it, and kept the raw utility instead — reported by three separate developers, blocking a conversion sweep each time. Default `space`, which is what this prop has always meant. The rung names are unchanged too, so `gap=\"md\"` still resolves exactly as before and only `scale=\"gap\"` moves anything. The two maps below are written out rather than derived. Tailwind emits an arbitrary utility only when it can see the class as a literal string in a scanned file, so a token name assembled at runtime produces a class that never gets generated — a gap that silently does nothing.",
                    "examples": [],
                    "values": [
                        "space",
                        "gap"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "wrap",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "as",
                    "default": "'div'",
                    "default_normalized": "'div'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "section",
            "tag": "\u003Cx-wirekit::section\u003E",
            "category": "Layout",
            "description": "Full-width page section with background and padding",
            "docs_url": "https://docs.wirekit.app/components/section",
            "props": [
                {
                    "name": "padding",
                    "default": "config('wirekit.components.section.padding', 'xl')",
                    "default_normalized": "config('wirekit.components.section.padding', 'xl')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "none",
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "background",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "default",
                        "muted",
                        "subtle",
                        "inverse",
                        "accent"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "divider",
                    "default": "'none'",
                    "default_normalized": "'none'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "none",
                        "top",
                        "bottom",
                        "both"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "as",
                    "default": "'section'",
                    "default_normalized": "'section'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "spacer",
            "tag": "\u003Cx-wirekit::spacer\u003E",
            "category": "Layout",
            "description": "Flexible space filler in flex layouts",
            "docs_url": "https://docs.wirekit.app/components/spacer",
            "props": [
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "stack",
            "tag": "\u003Cx-wirekit::stack\u003E",
            "category": "Layout",
            "description": "Vertical flex container",
            "docs_url": "https://docs.wirekit.app/components/stack",
            "props": [
                {
                    "name": "gap",
                    "default": "config('wirekit.components.stack.gap', 'md')",
                    "default_normalized": "config('wirekit.components.stack.gap', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "none",
                        "xs",
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "align",
                    "default": "'stretch'",
                    "default_normalized": "'stretch'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "start",
                        "center",
                        "end",
                        "stretch",
                        "baseline"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "justify",
                    "default": "'start'",
                    "default_normalized": "'start'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "start",
                        "center",
                        "end",
                        "between",
                        "around",
                        "evenly"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scale",
                    "default": "'space'",
                    "default_normalized": "'space'",
                    "type_hint": null,
                    "comment": "Which spacing ladder `gap` names a rung on. See `row` for the full reasoning; the two components share this axis because they share the prop, and a difference between them would be the worse of the two outcomes — a developer who learned it on one would be wrong on the other. Short form: WireKit defines two ladders with the same rung names and different values from `md` up (`--gap-wk-md` 0.75rem against `--space-wk-md` 1rem), and only one of them was reachable here. Default `space` keeps every existing call site exactly where it is. Both maps are written out rather than derived: Tailwind emits an arbitrary utility only when it can see the class as a literal in a scanned file.",
                    "examples": [],
                    "values": [
                        "space",
                        "gap"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "wrap",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "as",
                    "default": "'div'",
                    "default_normalized": "'div'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "sticky-panel",
            "tag": "\u003Cx-wirekit::sticky-panel\u003E",
            "category": "Layout",
            "description": "Sticky companion column (header / scrollable body / footer) pinned beside an article",
            "docs_url": "https://docs.wirekit.app/components/sticky-panel",
            "props": [
                {
                    "name": "offset",
                    "default": "'2rem'",
                    "default_normalized": "'2rem'",
                    "type_hint": null,
                    "comment": "Distance from the viewport top when pinned (any CSS length). Also drives the default max-height: calc(100dvh - 2*offset), leaving the offset above + below.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "maxHeight",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Explicit max-height override (CSS length); null = the calc above.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "width",
                    "default": "'20rem'",
                    "default_normalized": "'20rem'",
                    "type_hint": null,
                    "comment": "The panel's width CEILING, not a fixed width. It fills the column it is given and stops growing here — so a two-column desktop layout gets exactly this, and a stacked mobile layout gets the full width instead of a narrow card floating in a wide space. It used to be applied as `width: \u003Cthis\u003E; max-width: 100%`, which caps the wrong end: the ceiling only bites when the container is NARROWER, and the case that actually happens is the container being wider. Measured at 393px with the layout stacked, the summary came out 214px beside a 301px sibling.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "hideBelow",
                    "default": "'md'",
                    "default_normalized": "'md'",
                    "type_hint": null,
                    "comment": "Tailwind breakpoint at/above which the panel sticks. Below it, mobileBehavior applies.",
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "mobileBehavior",
                    "default": "'inline'",
                    "default_normalized": "'inline'",
                    "type_hint": null,
                    "comment": "Below the breakpoint: 'inline' (un-stick, render in flow) or 'hide' (display:none).",
                    "examples": [],
                    "values": [
                        "inline",
                        "hide"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the panel AND for its scrollable body — and the switch that makes that body a LANDMARK. It fell back to \"Panel content\", so two panels on one page were two rotor entries with the same name (axe: `landmark-unique`). Unnamed, the body keeps `tabindex=\"0\"` and no role: reachable per WCAG 2.1.1, deliberately not a destination.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scrollShadow",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Show top/bottom overflow shadows on the body. They render as OVERLAYS above the content (.wk-scroll-shadow-top/-bottom + an IntersectionObserver over edge sentinels), so hovered rows/buttons never cover them. For a plain-CSS variant on your own containers, the .wk-scroll-shadow utility still exists.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "header",
                    "required": false
                },
                {
                    "name": "footer",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "skip-link",
            "tag": "\u003Cx-wirekit::skip-link\u003E",
            "category": "Layout",
            "description": "WCAG 2.4.1 skip-link to main landmark (keyboard bypass)",
            "docs_url": "https://docs.wirekit.app/components/skip-link",
            "props": [
                {
                    "name": "target",
                    "default": "'main-content'",
                    "default_normalized": "'main-content'",
                    "type_hint": null,
                    "comment": "The id (without leading \"#\") of the landmark this link jumps to. Defaults to \"main-content\" to match the id the docs tell you to set on the main component via its `id` prop (id=\"main-content\"). Note that `id` is opt-in — the main component leaves it null by default — so you set it explicitly to wire the pair. (No literal component tag in this comment: Blade's tag compiler scans even PHP comments.)",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "label",
                    "default": "__('wirekit::Skip to main content')",
                    "default_normalized": "__('wirekit::Skip to main content')",
                    "type_hint": null,
                    "comment": "Label rendered inside the link when keyboard focus reveals it.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "visually-hidden",
            "tag": "\u003Cx-wirekit::visually-hidden\u003E",
            "category": "Layout",
            "description": "Screen-reader-only content wrapper",
            "docs_url": "https://docs.wirekit.app/components/visually-hidden",
            "props": [
                {
                    "name": "as",
                    "default": "'span'",
                    "default_normalized": "'span'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "blockquote",
            "tag": "\u003Cx-wirekit::blockquote\u003E",
            "category": "Typography",
            "description": "Styled blockquote with optional citation",
            "docs_url": "https://docs.wirekit.app/components/blockquote",
            "props": [
                {
                    "name": "cite",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "variant",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "default",
                        "accent"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "code",
            "tag": "\u003Cx-wirekit::code\u003E",
            "category": "Typography",
            "description": "Inline code with monospace font",
            "docs_url": "https://docs.wirekit.app/components/code",
            "props": [
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "code-block",
            "tag": "\u003Cx-wirekit::code-block\u003E",
            "category": "Typography",
            "description": "Multi-line code block with copy button",
            "docs_url": "https://docs.wirekit.app/components/code-block",
            "props": [
                {
                    "name": "language",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "filename",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "copy",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The name of the scroll region, and the switch that makes it a LANDMARK at all. `role=\"region\"` plus a name is a landmark, and twenty landmarks called \"PHP code\" are twenty indistinguishable entries in a screen reader's rotor — axe reports it as `landmark-unique`. Reported from an audit log rendering one diff per table row, where the language is identical on every row and so cannot tell them apart. The language-derived name used to fill this in, which meant the duplicate-landmark case was the DEFAULT one and naming was the escape. That is now the other way round: with no label the block is `tabindex=\"0\"` and nothing else — still keyboard-reachable (WCAG 2.1.1), deliberately not a destination. Name it after the row, not after the language: \"Change 4471\" locates the block; \"PHP code\" only says what everything on the page already is.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "heading",
            "tag": "\u003Cx-wirekit::heading\u003E",
            "category": "Typography",
            "description": "Semantic heading (h1–h6) with auto-sizing",
            "docs_url": "https://docs.wirekit.app/components/heading",
            "props": [
                {
                    "name": "level",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "base",
                        "lg",
                        "xl",
                        "2xl",
                        "3xl",
                        "4xl",
                        "5xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "accent",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "tracking",
                    "default": "'normal'",
                    "default_normalized": "'normal'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "normal",
                        "tight",
                        "tighter"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "as",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "highlight",
            "tag": "\u003Cx-wirekit::highlight\u003E",
            "category": "Typography",
            "description": "Text with highlighted query matches",
            "docs_url": "https://docs.wirekit.app/components/highlight",
            "props": [
                {
                    "name": "query",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "as",
                    "default": "'span'",
                    "default_normalized": "'span'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "indicator",
            "tag": "\u003Cx-wirekit::indicator\u003E",
            "category": "Display",
            "description": "Anchors a count badge, status dot, or ribbon to any corner of any target — RTL-safe",
            "docs_url": "https://docs.wirekit.app/components/indicator",
            "props": [
                {
                    "name": "position",
                    "default": "'top-end'",
                    "default_normalized": "'top-end'",
                    "type_hint": null,
                    "comment": "Which corner the badge is anchored to. Logical, not physical: \"end\" is the right edge in LTR and the left edge in RTL, so the anchor follows the reading direction with no extra rules.",
                    "examples": [],
                    "values": [
                        "top-end",
                        "top-start",
                        "bottom-end",
                        "bottom-start"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "offset",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Nudge the badge further out (any CSS length). Default centers it on the corner.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "badge",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "kbd",
            "tag": "\u003Cx-wirekit::kbd\u003E",
            "category": "Typography",
            "description": "Keyboard key indicator",
            "docs_url": "https://docs.wirekit.app/components/kbd",
            "props": [
                {
                    "name": "size",
                    "default": "'md'",
                    "default_normalized": "'md'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "link",
            "tag": "\u003Cx-wirekit::link\u003E",
            "category": "Typography",
            "description": "Styled anchor with external link support",
            "docs_url": "https://docs.wirekit.app/components/link",
            "props": [
                {
                    "name": "href",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "variant",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "default",
                        "subtle",
                        "muted"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Font size, in `text`'s vocabulary — `xs`, `sm`, `base`, `lg`, `xl`. `null` inherits, which is what this component has always done and the right default: a link sits inside a sentence far more often than it stands alone, and naming a size here would resize every link that lives in body copy. So the default emits no class at all rather than a `base` that happens to match today. Without the axis, a footer or a preferences row had to hand-build the anchor to get `--text-wk-sm` — reported as six such anchors in one repository that used this component correctly eight times elsewhere, wherever the inherited size happened to fit. Deliberately `text`'s rung names, `base` and not `md`: two vocabularies for one ladder is the near-miss that makes a rename sweep silently re-size a page.",
                    "examples": [],
                    "values": [
                        "xs",
                        "sm",
                        "base",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "external",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "underline",
                    "default": "'always'",
                    "default_normalized": "'always'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "always",
                        "hover",
                        "none"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "as",
                    "default": "'a'",
                    "default_normalized": "'a'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "list",
            "tag": "\u003Cx-wirekit::list\u003E",
            "category": "Typography",
            "description": "Ordered or unordered list with type (disc / decimal / roman / alpha / none) and spacing variants",
            "docs_url": "https://docs.wirekit.app/components/list",
            "props": [
                {
                    "name": "type",
                    "default": "'disc'",
                    "default_normalized": "'disc'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "disc",
                        "decimal",
                        "none",
                        "lower-roman",
                        "upper-roman",
                        "lower-alpha",
                        "upper-alpha"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "spacing",
                    "default": "'sm'",
                    "default_normalized": "'sm'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "none",
                        "sm",
                        "md"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "as",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "list.item",
                    "tag": "\u003Cx-wirekit::list.item\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "mark",
            "tag": "\u003Cx-wirekit::mark\u003E",
            "category": "Typography",
            "description": "Highlighted text mark",
            "docs_url": "https://docs.wirekit.app/components/mark",
            "props": [
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "prose",
            "tag": "\u003Cx-wirekit::prose\u003E",
            "category": "Typography",
            "description": "Typography wrapper for raw HTML content",
            "docs_url": "https://docs.wirekit.app/components/prose",
            "props": [
                {
                    "name": "size",
                    "default": "'md'",
                    "default_normalized": "'md'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "variant",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "default",
                        "muted"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "density",
                    "default": "'comfortable'",
                    "default_normalized": "'comfortable'",
                    "type_hint": null,
                    "comment": "`density` — controls the heading + paragraph block-spacing scale. `comfortable` (default) — long-form-article rhythm: generous `--padding-wk-y-xl` (2.5 rem) top-margin on h2 headings, `--padding-wk-y-md` (0.75 rem) bottom-margin on paragraphs. Optimized for blog posts, docs, news articles where section breaks should breathe. `compact` — marketing/landing-page rhythm: tighter `--padding-wk-y-md` (0.75 rem) top-margin on h2, smaller heading sizes, `--padding-wk-y-sm` (0.5 rem) paragraph bottom-margin. Reaches for the tight rhythm a marketing page wants without forcing the developer to write `.ml h2 { margin: ... }` overrides.",
                    "examples": [],
                    "values": [
                        "comfortable",
                        "compact"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "measure",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": "`measure` — readable line-length clamp (max-width). Long-form prose reads best at ~65 characters per line; without a cap it runs the full container width, which hurts readability on wide screens. `default` (default) — ~65ch via --measure-wk. `wide` — ~78ch via --measure-wk-wide. `none` — no clamp (full container width; the pre-v2.10.0 behavior).",
                    "examples": [],
                    "values": [
                        "default",
                        "wide",
                        "none"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "preset",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`preset` — a readability tuning applied on top of size/density/measure. Kept as its OWN axis (a data-preset attribute + CSS) rather than a bundle of prop defaults, so it composes with the existing props instead of fighting them for precedence — the same shape as `measure`. `null` (default) — no tuning. `chat` — tight leading for a message bubble; the bubble already caps the line length, so the measure clamp would only fight it. `reading` — long-form: roomier leading for sustained reading. `large` — accessibility: bigger body text AND roomier leading, for users who scale text up. Not just a font-size bump: leading has to grow with it or large text reads worse, not better.",
                    "examples": [],
                    "values": [
                        "chat",
                        "reading",
                        "large"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "container",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`container` — opt in to adapting the rhythm to the COLUMN rather than the viewport. Prose in a sidebar, a card or a table cell is narrow on a desktop screen, where every viewport breakpoint says \"wide\" and the heading scale stays built for a full page. With this set, the wrapper becomes a size container and the scale tightens below 30rem of its own width — the `compact` rhythm, without the caller having to know which column the prose landed in. Opt-IN, because `container-type: inline-size` is not free: the element's inline size stops depending on its contents, so a prose inside a shrink-to-fit parent (an `inline-block`, a `max-content` grid track, a floated box) collapses instead of sizing itself. Every prose that is laid out by its parent is unaffected, which is most of them — but not all, and the caller is the one who knows.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "team-section",
            "tag": "\u003Cx-wirekit::team-section\u003E",
            "category": "Marketing",
            "description": "Team roster grid, exposed as a labeled list",
            "docs_url": "https://docs.wirekit.app/components/team-section",
            "props": [
                {
                    "name": "label",
                    "default": "__('wirekit::Team')",
                    "default_normalized": "__('wirekit::Team')",
                    "type_hint": null,
                    "comment": "Accessible name for the roster, so a screen reader announces how many people are in it rather than reading a run of names with no boundary.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "team-member",
            "tag": "\u003Cx-wirekit::team-member\u003E",
            "category": "Marketing",
            "description": "One person in a team section — avatar, name, role, links",
            "docs_url": null,
            "props": [
                {
                    "name": "name",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": "The person. Without a name there is nobody here.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "role",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Their role (\"Head of Platform\").",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "avatar",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Portrait. Without one, the initials are derived — never an empty disc.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "initials",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "text",
            "tag": "\u003Cx-wirekit::text\u003E",
            "category": "Typography",
            "description": "Body text with size, variant, and weight",
            "docs_url": "https://docs.wirekit.app/components/text",
            "props": [
                {
                    "name": "size",
                    "default": "'base'",
                    "default_normalized": "'base'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "xs",
                        "sm",
                        "base",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "variant",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": "back-compat alias of `intent`",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "intent",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "canonical color axis: default | muted | subtle | accent | success | warning | danger. null → falls back to `variant`",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "weight",
                    "default": "'normal'",
                    "default_normalized": "'normal'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "normal",
                        "medium",
                        "semibold",
                        "bold"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "align",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "left",
                        "center",
                        "right"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "truncate",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "lineClamp",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "1",
                        "2",
                        "3",
                        "4",
                        "5",
                        "6"
                    ],
                    "value_type": "int"
                },
                {
                    "name": "break",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "where an unbroken token may wrap: normal | anywhere | all. null → the default rules, no class",
                    "examples": [],
                    "values": [
                        "normal",
                        "anywhere",
                        "all"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "as",
                    "default": "'p'",
                    "default_normalized": "'p'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "bento-grid",
            "tag": "\u003Cx-wirekit::bento-grid\u003E",
            "category": "Layout",
            "description": "Asymmetric feature showcase — cells claim different amounts of space",
            "docs_url": "https://docs.wirekit.app/components/bento-grid",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the showcase. A bento is a set of related feature claims, so a screen reader should get a boundary and a name for it rather than a wall of loose headings.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "gap",
                    "default": "config('wirekit.components.bento-grid.gap', 'md')",
                    "default_normalized": "config('wirekit.components.bento-grid.gap', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "md",
                        "none",
                        "xs",
                        "sm",
                        "lg",
                        "xl",
                        "2xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scale",
                    "default": "'space'",
                    "default_normalized": "'space'",
                    "type_hint": null,
                    "comment": "Which spacing ladder `gap` names a rung on: `space` (the default) or the tighter `gap` ladder. The same choice, and the same reason, as on the grid this component extends.",
                    "examples": [],
                    "values": [
                        "space",
                        "gap"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "bento-cell",
            "tag": "\u003Cx-wirekit::bento-cell\u003E",
            "category": "Layout",
            "description": "One cell of a bento grid; claims 1x1, 2x1, 1x2 or 2x2 from md up",
            "docs_url": null,
            "props": [
                {
                    "name": "span",
                    "default": "'1x1'",
                    "default_normalized": "'1x1'",
                    "type_hint": null,
                    "comment": "How much room this cell claims once the grid is wide enough (the '@2xl' container width). In a narrow grid every cell is full width regardless — see below. '1x1' → one column  (the default) '2x1' → two columns wide '1x2' → two rows tall '2x2' → the hero cell",
                    "examples": [],
                    "values": [
                        "1x1",
                        "2x1",
                        "1x2",
                        "2x2"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "emphasis",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Lift this cell visually. A border and a background, never a tint or a gradient: the emphasis has to survive a reader who cannot separate the accent hue from the surface.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "bleed",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Let content run to the cell's edge — for imagery that should bleed rather than sit in a padded box. Turns off the cell's own padding.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "bottom-nav",
            "tag": "\u003Cx-wirekit::bottom-nav\u003E",
            "category": "Navigation",
            "description": "Fixed mobile tab bar — safe-area aware, 44px targets, aria-current",
            "docs_url": "https://docs.wirekit.app/components/bottom-nav",
            "props": [
                {
                    "name": "label",
                    "default": "__('wirekit::Main')",
                    "default_normalized": "__('wirekit::Main')",
                    "type_hint": null,
                    "comment": "What this bar navigates. Every page has more than one nav landmark once you count the header, so an unnamed one is announced as \"navigation\" and the reader has to go in to find out which.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "mobileOnly",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Hide the bar from `md` up, where a sidebar or a header does this job. A bar pinned to the bottom of a 27-inch screen is a long way from the content it belongs to.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "interactive",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Let the bar track the current tab client-side: clicking an item marks it active (Alpine), no page load. Off by default — a real app usually drives `active` from its router. Handy for a self-contained demo. Read by each item via @aware.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "bottom-nav.item",
                    "tag": "\u003Cx-wirekit::bottom-nav.item\u003E",
                    "props": [
                        {
                            "name": "href",
                            "default": "'#'",
                            "default_normalized": "'#'",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "label",
                            "default": "''",
                            "default_normalized": "''",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "active",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": "Which page this is. Marks the item as the current one. In interactive mode it is the INITIAL current tab; clicks then move it client-side.",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Optional icon name — see the icon component.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "badge",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "A small count on the icon (\"3 unread\"). It is announced as part of the item's name, never as bare punctuation.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "brand",
            "tag": "\u003Cx-wirekit::brand\u003E",
            "category": "Navigation",
            "description": "Logo and name combo for header/sidebar",
            "docs_url": "https://docs.wirekit.app/components/brand",
            "props": [
                {
                    "name": "logo",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "mobileLogo",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "darkLogo",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Dark-mode logo. When set, the desktop logo swaps light↔dark by the `.dark` class via the `wk-light-only` / `wk-dark-only` visibility pair in dist/wirekit.css — components never use the Tailwind `dark:` variant (an image-src swap has no design-token mechanism, so the toggle lives in CSS like every other `.dark`-scoped WireKit rule). Composes with `$mobileLogo`: the mobile mark stays mode-neutral below the breakpoint; the light/dark swap applies to the desktop logo at + breakpoint. Null → single-logo behavior (byte-identical back-compat).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "mobileBreakpoint",
                    "default": "'sm'",
                    "default_normalized": "'sm'",
                    "type_hint": null,
                    "comment": "Tailwind breakpoint at which the responsive-logo swap flips back to the full `$logo`. Values: 'sm' / 'md' / 'lg' / 'xl'. Default 'sm' (640px) — wide wordmark logos in a brand-bar typically clear sm+ viewports. When `$mobileLogo` is null, this prop is a no-op.",
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "logoAspect",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Intrinsic aspect ratio of `$logo` / `$darkLogo`, as `'width/height'` — e.g. `'4/1'` for a wide wordmark. Every logo here is `h-8 w-auto`: the height is fixed and the WIDTH is whatever the image turns out to be. Until its bytes arrive there is nothing to derive that width from, so the element is 0 px wide and everything beside it — the product name, the navigation, the whole header row — sits further left than it will a moment later, then jumps. On an uncached view that is a visible shift on the most prominent row of the page, and it happens on every page load rather than once. The ratio is the missing input and the only one: `width`/`height` attributes would say the same thing less directly, since the `h-8 w-auto` this component ships overrides both and leaves the browser using them for their ratio anyway. Unset is not left to shift: the images carry a min-width of one logo height, so the worst case is a square reservation rather than nothing. Almost every wordmark is wider than tall, which makes that a floor rather than an over-reservation.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "mobileLogoAspect",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Same, for `$mobileLogo`. Defaults to `$logoAspect` — a responsive pair is often the same mark at two widths — but a square app icon beside a wide wordmark is exactly the case that needs its own value.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "href",
                    "default": "'/'",
                    "default_normalized": "'/'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "brand-bar",
            "tag": "\u003Cx-wirekit::brand-bar\u003E",
            "category": "Navigation",
            "description": "Page-chrome wrapper for brand + tagline + actions with content-edge padding",
            "docs_url": "https://docs.wirekit.app/components/brand-bar",
            "props": [
                {
                    "name": "as",
                    "default": "'header'",
                    "default_normalized": "'header'",
                    "type_hint": null,
                    "comment": "`as` — the semantic element. Defaults to `header` for page chrome (the brand-bar sits at the top of a section / page and announces the brand). Set to `nav` if the bar IS the primary navigation.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "divider",
                    "default": "'bottom'",
                    "default_normalized": "'bottom'",
                    "type_hint": null,
                    "comment": "`divider` — optional bottom-border treatment. Default `bottom` paints a 1 px line across the bar's bottom edge using `--color-wk-border`. Pass `none` for a borderless variant on backgrounds that already provide separation.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "padding",
                    "default": "'lg'",
                    "default_normalized": "'lg'",
                    "type_hint": null,
                    "comment": "`padding` — inline padding tier from the `--padding-wk-x-*` content-edge spine. Defaults to `lg` to match the main wrapper and header chrome at the same tier — the brand's visible-text edge aligns with the article body and TOC strip below.",
                    "examples": [],
                    "values": [
                        "none",
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "sticky",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`sticky` — when true, pins the bar to the top of the scroll container via `position: sticky; top: 0`. Default false.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "container",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`container` — when true, wraps the inner flex-row in a max-width container so the brand-bar's CHROME (background, border, sticky behavior) stays edge-to-edge while the CONTENT (brand, tagline, actions) aligns with the body's container-wrapped column. Default false preserves the v2.0.0 edge-to-edge content behavior.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "max",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`max` — container max-width tier when `container=true`. One of `sm/md/lg/xl/2xl/full`. Defaults to `xl` (the most common marketing-landing-page content width). Reads the same `--size-wk-container-*` tokens as the container component so brand-bar + body align on the same vertical content-edge spine.",
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl",
                        "full"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "brand",
                    "required": false
                },
                {
                    "name": "tagline",
                    "required": false
                },
                {
                    "name": "actions",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "breadcrumb",
            "tag": "\u003Cx-wirekit::breadcrumb\u003E",
            "category": "Navigation",
            "description": "Breadcrumb trail with separator",
            "docs_url": "https://docs.wirekit.app/components/breadcrumb",
            "props": [
                {
                    "name": "items",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "separator",
                    "default": "config('wirekit.components.breadcrumb.separator', 'chevron')",
                    "default_normalized": "config('wirekit.components.breadcrumb.separator', 'chevron')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "schema",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Emit BreadcrumbList JSON-LD for this trail. Turn it OFF when the page already carries a breadcrumb elsewhere — a shell's top bar and the content body is the common case. A page must carry exactly ONE BreadcrumbList, and two of them compete rather than combine: a crawler shown two trails for one URL picks one, or neither. Defaults ON so nothing about an existing single breadcrumb changes. Same shape and same reasoning as the FAQ component's own `schema` prop, which is the house pattern for a component that emits structured data without being asked. (Its tag is deliberately NOT written here. Blade is a text preprocessor and does not know it is inside a PHP comment: an `x-wirekit::` tag in one gets COMPILED, and the compiled construct lands in the middle of this array. The failure reads \"Undefined variable $component\" and points at the render rather than at the sentence.)",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "actions",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "menubar",
            "tag": "\u003Cx-wirekit::menubar\u003E",
            "category": "Navigation",
            "description": "Horizontal menu bar with dropdowns",
            "docs_url": "https://docs.wirekit.app/components/menubar",
            "props": [
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "menubar.item",
                    "tag": "\u003Cx-wirekit::menubar.item\u003E",
                    "props": [
                        {
                            "name": "href",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "danger",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "disabled",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "shortcut",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "menubar.menu",
                    "tag": "\u003Cx-wirekit::menubar.menu\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "''",
                            "default_normalized": "''",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "menubar.separator",
                    "tag": "\u003Cx-wirekit::menubar.separator\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "menubar.submenu",
                    "tag": "\u003Cx-wirekit::menubar.submenu\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Parent item text (or pass a \u003Cx-slot:label\u003E for rich content)",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Optional leading icon (WireKit icon system)",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "placement",
                            "default": "'right-start'",
                            "default_normalized": "'right-start'",
                            "type_hint": null,
                            "comment": "Floating UI placement of the child panel",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "offset",
                            "default": "0",
                            "default_normalized": "0",
                            "type_hint": null,
                            "comment": "Gap between the parent item and the child panel",
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "disabled",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "navbar",
            "tag": "\u003Cx-wirekit::navbar\u003E",
            "category": "Navigation",
            "description": "Top navigation bar",
            "docs_url": "https://docs.wirekit.app/components/navbar",
            "props": [
                {
                    "name": "variant",
                    "default": "config('wirekit.components.navbar.variant', 'default')",
                    "default_normalized": "config('wirekit.components.navbar.variant', 'default')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "sticky",
                    "default": "config('wirekit.components.navbar.sticky', false)",
                    "default_normalized": "config('wirekit.components.navbar.sticky', false)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "forceMobile",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "When true the navbar skips the `md:` viewport-breakpoint classes and renders the mobile layout unconditionally (hamburger button visible, desktop item row hidden). Useful for (a) previewing the mobile state in docs without resizing the browser, (b) dedicated mobile app views, and (c) embedding the navbar inside a container that is narrower than the 768px breakpoint. Defaults to `false` so existing developers keep the responsive behavior.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "container",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`container` — when true, wraps the inner flex-row in a max-width container so the navbar's CHROME (background, border, sticky behavior) stays edge-to-edge while the CONTENT (brand, nav items, actions) aligns with the body's container-wrapped column. Mirrors the brand-bar `container` prop. Default false preserves the prior edge-to-edge content behavior.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "max",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`max` — container max-width tier when `container=true`. One of `sm/md/lg/xl/2xl/full`. Defaults to `xl` (the most common marketing-landing-page content width). Reads the same `--size-wk-container-*` tokens as the container component so navbar + body align on the same vertical content-edge spine.",
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl",
                        "full"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "brand",
                    "required": false
                },
                {
                    "name": "actions",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "navbar.item",
                    "tag": "\u003Cx-wirekit::navbar.item\u003E",
                    "props": [
                        {
                            "name": "href",
                            "default": "'#'",
                            "default_normalized": "'#'",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "active",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "navigation-menu",
            "tag": "\u003Cx-wirekit::navigation-menu\u003E",
            "category": "Navigation",
            "description": "Accessible navigation menu with mega-menu support",
            "docs_url": "https://docs.wirekit.app/components/navigation-menu",
            "props": [
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "navigation-menu.item",
                    "tag": "\u003Cx-wirekit::navigation-menu.item\u003E",
                    "props": [
                        {
                            "name": "trigger",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "href",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "navigation-menu.link",
                    "tag": "\u003Cx-wirekit::navigation-menu.link\u003E",
                    "props": [
                        {
                            "name": "href",
                            "default": "'#'",
                            "default_normalized": "'#'",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "active",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "pagination",
            "tag": "\u003Cx-wirekit::pagination\u003E",
            "category": "Navigation",
            "description": "Page navigation for paginated data",
            "docs_url": "https://docs.wirekit.app/components/pagination",
            "props": [
                {
                    "name": "paginator",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "variant",
                    "default": "config('wirekit.components.pagination.variant', 'full')",
                    "default_normalized": "config('wirekit.components.pagination.variant', 'full')",
                    "type_hint": null,
                    "comment": "full | simple | mini",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "justify",
                    "default": "config('wirekit.components.pagination.justify', 'between')",
                    "default_normalized": "config('wirekit.components.pagination.justify', 'between')",
                    "type_hint": null,
                    "comment": "between | center | end | start",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "previousLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The two direction labels. `Previous`/`Next` are correct for a page-ordered list and MISLEADING on a reverse-chronological one, where \"next\" moves BACKWARD in time — a reader on a changelog or an activity feed is told the opposite of what the button does. There was no way to say otherwise: the strings were baked in, and translating them globally would have changed every paginator in the application. Null keeps today's behavior exactly, including its translation.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "nextLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "profile",
            "tag": "\u003Cx-wirekit::profile\u003E",
            "category": "Navigation",
            "description": "Avatar and name display for headers",
            "docs_url": "https://docs.wirekit.app/components/profile",
            "props": [
                {
                    "name": "avatar",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "interactive",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Interactive mode: when true, the profile becomes a focusable button-like element with role=\"button\" + tabindex=\"0\" plus Enter / Space keyboard handlers that synthesize a click event. Used when a profile sits inside a dropdown trigger (or any other parent that listens for click + needs a focusable child for keyboard-reachability). Default false preserves the pre-existing presentational div byte-for-byte.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "as",
                    "default": "'div'",
                    "default_normalized": "'div'",
                    "type_hint": null,
                    "comment": "The element this renders. `button` is the better answer wherever the profile is the thing being clicked: the browser gives a real button Space activation, Enter activation and the button role for free, where `interactive` synthesizes the first two from Alpine handlers that do not exist until Alpine boots. Same trade `app-rail.item` took in v2.38.0, in the same direction. The default stays `div` so every existing call site keeps the DOM it has — a profile is often a passive summary inside something else that is already the control, and nesting a button inside one would be invalid.",
                    "examples": [],
                    "values": [
                        "div",
                        "button"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "radius",
                    "default": "'sm'",
                    "default_normalized": "'sm'",
                    "type_hint": null,
                    "comment": "Corner rounding, on the control branch — the branch that has a background and a focus ring for a radius to describe. Baked as `sm` before this prop existed, and that is one row's worth of difference in the place this component is most often used: the account trigger at the foot of a sidebar, sitting directly under navigation entries that round on `--radius-wk-nav-item`. One control rounded unlike every neighbor is exactly the mismatch that stops a repository from adopting the component and keeps its hand-built row instead. `nav-item` is on the list for that reason and is not a rung: the shell redefines it per surface (it derives from the panel radius minus the padding), so no fixed rung can stand in for it.",
                    "examples": [],
                    "values": [
                        "none",
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "full",
                        "nav-item"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "gap",
                    "default": "'sm'",
                    "default_normalized": "'sm'",
                    "type_hint": null,
                    "comment": "Space between the avatar and the name. Reads the `--gap-wk-*` ladder — the tighter of the two, and the one this component already stood on.",
                    "examples": [],
                    "values": [
                        "none",
                        "xs",
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "tone",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": "How loud the name is. `default` is the color this component has always emitted; `muted` is what a navigation column asks for. A sidebar's own entries stand muted at rest and go full on hover (`sidebar/item.blade.php`). The account trigger sits directly under them, so a name baked to the full color leaves exactly ONE row in the column permanently brighter than every other — reported from a consuming project, which could only work around it by abandoning the `name` prop for the slot and re-writing the collapse handling by hand. A color on the wrapper does not reach it: the span sets its own and wins.",
                    "examples": [],
                    "values": [
                        "default",
                        "muted"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "padding",
                    "default": "'none'",
                    "default_normalized": "'none'",
                    "type_hint": null,
                    "comment": "Inline padding, on the page-edge spine ladder. `none` keeps the DOM this component has always emitted. It exists for the same place `radius` does — the account trigger at the foot of a sidebar. Without it the hover background hugs the name instead of drawing a row, so the entry that closes a navigation list looks unlike every entry in it. That is reachable from a call site as a class, and being reachable that way is exactly the problem: a component whose most common use needs an incantation gets rebuilt by hand instead of adopted.",
                    "examples": [],
                    "values": [
                        "none",
                        "xs",
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "scroll-to-top",
            "tag": "\u003Cx-wirekit::scroll-to-top\u003E",
            "category": "Navigation",
            "description": "Floating scroll-to-top button",
            "docs_url": "https://docs.wirekit.app/components/scroll-to-top",
            "props": [
                {
                    "name": "threshold",
                    "default": "1.5",
                    "default_normalized": "1.5",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "float"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.scroll-to-top.size', 'md')",
                    "default_normalized": "config('wirekit.components.scroll-to-top.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "position",
                    "default": "'bottom-right'",
                    "default_normalized": "'bottom-right'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "forceVisible",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "shell-bar",
            "tag": "\u003Cx-wirekit::shell-bar\u003E",
            "category": "Layout",
            "description": "Aligned column head that draws an app shell's top rule",
            "docs_url": "https://docs.wirekit.app/components/shell-bar",
            "props": [
                {
                    "name": "rule",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "The border. This is THE horizontal line of a console shell: place one bar at the head of each column and the segments meet, because they are the same component reading the same height token rather than three hand-aligned headers. Set false for a second, stacked bar that should not draw a rule of its own (a tab strip directly under the title bar). `true` draws it BELOW the bar, which is what a head wants. `'top'` draws it above instead, for a bar sitting at the FOOT of a column — an account row at the bottom of a sidebar is the case. Without it such a bar drew its rule along the column's bottom edge, so the only way to get a symmetric column was to leave the foot as a bare row, and a bare row does not match the head it faces.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "padding",
                    "default": "'lg'",
                    "default_normalized": "'lg'",
                    "type_hint": null,
                    "comment": "Inline padding, on the page-edge spine scale. `none` is for the rail head, whose content is a centered mark rather than text on the spine. `xs` is the rung a bar needs to line its content up with the navigation rows of the column it sits in. A sidebar pads itself on the extra-small step, a bleeding foot band cancels that padding so its rule reaches the edge, and a bar inside it therefore starts at zero — while the rows above start at the column's inset. The next rung up overshoots by 4px, which reads as a footer row belonging to a slightly different list than the one it closes.",
                    "examples": [],
                    "values": [
                        "none",
                        "xs",
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "align",
                    "default": "'between'",
                    "default_normalized": "'between'",
                    "type_hint": null,
                    "comment": "Main-axis distribution. `between` (default) pushes the `end` slot to the far edge, which is what a title-plus-actions bar wants; `start` and `center` are for a bar whose content is one cluster.",
                    "examples": [],
                    "values": [
                        "start",
                        "center",
                        "between"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "sticky",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Sticks the bar to the top of its SCROLLING ancestor. Read this before reaching for it: in the console layout the bar sits inside the app-shell's content column, and that column carries `overflow-hidden` and therefore never scrolls — so `sticky` there sticks to something that does not move, which is to say it does nothing. It is not a bug to fix here; it is what `position: sticky` means. The console layout does not need it either, because the main region below is the scroller and the bar already stays put. Where it DOES work: a bar placed in ordinary document flow on a page that scrolls as a document.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "bleed",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Cancels the padding of a host that pads its children, so the bar — and therefore its rule — spans the host's full width and meets its top edge. The case this exists for is a bar placed in a sidebar's `header` zone. A sidebar pads itself uniformly, which is right for navigation items and wrong for a chrome band: the rule ends up inset on three sides and sits 6px below the rule in the columns either side of it. Measured in the browser at exactly that, which is the padding token's value. The bar does not escape: it marks itself `data-wk-bleed`, and the container stands aside. A zone holding a bleeding bar drops its own inset and pulls back the column's, so the head reaches the column's edge FROM THE INSIDE — see dist/wirekit.css. Outside such a container the prop does nothing at all, which is the right no-op.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "An accessible name for the leading cluster. The cluster SCROLLS rather than clipping (see below), and a scroll region has to be keyboard-operable. Where its content is interactive — a tab strip, a breadcrumb of links — Tab reaches each item and the browser scrolls it into view, so nothing more is owed. Where it is not — a long title, a status line — the region needs a name and a tab stop of its own, and that is what passing a label turns on.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "start",
                    "required": false
                },
                {
                    "name": "end",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "scope-switcher",
            "tag": "\u003Cx-wirekit::scope-switcher\u003E",
            "category": "Navigation",
            "description": "Searchable switcher for the team, server or site a page is about",
            "docs_url": "https://docs.wirekit.app/components/scope-switcher",
            "props": [
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Stable id base. REQUIRED, and not by convention: every option's id is built from it, `aria-activedescendant` points at those ids, and a Livewire morph that regenerates them silently breaks the link between the input and the row it claims is active.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": "What is being switched — \"Server\", \"Team\". Names the control, the dialog and the search field, and stands in as the trigger's text when nothing is selected yet.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "items",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "@var list\u003Carray\u003Cstring, mixed\u003E\u003E",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "current",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`key` of the item the page is currently showing, or null.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "create",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "['label' =\u003E …, 'url' =\u003E …, 'icon' =\u003E …] — the footer action. Omit for no footer.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "searchPlaceholder",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "emptyText",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "placement",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "width",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "listMaxHeight",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "sidebar",
            "tag": "\u003Cx-wirekit::sidebar\u003E",
            "category": "Navigation",
            "description": "Vertical sidebar navigation",
            "docs_url": "https://docs.wirekit.app/components/sidebar",
            "props": [
                {
                    "name": "collapsible",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Collapse-to-icon rail. When true, the sidebar can collapse to a narrow icon-only rail: an auto-rendered toggle flips the state, item/group labels become sr-only (accessible names preserved), and only icons stay visible.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "collapsed",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Initial collapsed state (only meaningful with `collapsible`). Left unset, the cookie driver below is allowed to answer it instead — which is the whole point of that driver, so an explicit value here wins and turns the seeding off. Null rather than false so those two cases stay APART. Once the boolean cast has run they are the same value, and a server that cannot tell \"not set\" from \"explicitly collapsed=false\" would override a developer who asked for expanded.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "mode",
                    "default": "'navigation'",
                    "default_normalized": "'navigation'",
                    "type_hint": null,
                    "comment": "Surface shape. `card` (default) is the self-contained panel: background, border on all four sides, rounded, meant to sit inside a padded column. `flush` is the full-bleed navigation COLUMN of the common admin layout — no radius, no surrounding border, the surface inherited from the host, and a single inline-end edge separating it from the content. Two variants rather than a set of booleans, because the halves are not independent: a rounded panel with no border reads as a rendering fault, and a full-bleed column with a radius shows a sliver of the page at each corner. Default stays `card` so no existing sidebar changes. Which ARIA contract this column carries, and the two are not interchangeable. `navigation` (the default, and byte-identical to every sidebar that exists today) is a list of LINKS: each row is in the tab order, Enter follows it, and the row for the page you are on is marked `aria-current`. `selection` is one CONTROL holding many choices: the container is in the tab order once, the arrows move an `aria-activedescendant` marker without moving focus, and the chosen row is marked `aria-selected`. It emits no `aria-current` at all, which is the whole point — announcing a page you are on AND a value you have picked are two different claims, and a column that made both would be lying about one.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "selected",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The chosen value, in `selection` mode. Matched against each row's `value`, so the column can render already-selected on the server rather than waiting for Alpine — a listbox whose selection appears one frame late reads as a flicker.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "variant",
                    "default": "'card'",
                    "default_normalized": "'card'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "tone",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": "The surface tone, on the same `--color-wk-rail-*` roles the module rail reads — minus `accent`, for the reason spelled out where the value is validated. `default` is every sidebar that exists today and is byte-identical to it; the other tones let the second navigation column carry its own color, which is what a console shell needs when its rail is dark chrome and the content is a light sheet. Shared roles rather than a private `--color-wk-sidebar-*` set on purpose: a rail and the column beside it must agree about a color, and two components that must agree should not each own a copy of it.",
                    "examples": [],
                    "values": [
                        "default",
                        "muted",
                        "inverse"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "toggle",
                    "default": "'end'",
                    "default_normalized": "'end'",
                    "type_hint": null,
                    "comment": "Where the auto-rendered collapse toggle sits, or `none` to omit it and supply your own. `none` keeps the state machinery here — a developer who wanted the trigger elsewhere previously had to switch `collapsible` off and rebuild the rail's Alpine state, the persisted flag and the marker the descendant items read, which is vendor mechanics reimplemented in an app. An outside trigger reaches this sidebar through the `wirekit:sidebar:toggle` window event instead; see the docs page.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "side",
                    "default": "'start'",
                    "default_normalized": "'start'",
                    "type_hint": null,
                    "comment": "WHICH SIDE OF THE CONTENT this column stands on: 'start' (default) or 'end'. It decides two things a reader reads as one — where the separator is drawn, and which way the collapse chevron points. Both belong on the edge that FACES the content: a details panel on the trailing side draws its rule on its leading edge and closes to the right, and the mirror image of that is a rule on the page margin and a chevron pointing into the panel it is closing. ⚠️ NOT derivable from `toggle`, which was tried and measured wrong. `toggle` says where the CONTROL sits inside the column, not which side the column is on — the multi-column shell uses `toggle=\"start\"` for a list on the left AND a details panel on the right, so the inference would have broken the list to fix the panel.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "persist",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional storage key — persists the collapsed state across reloads.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "persistDriver",
                    "default": "'local'",
                    "default_normalized": "'local'",
                    "type_hint": null,
                    "comment": "WHERE that choice is remembered: 'local' (default) or 'cookie'. No server can read localStorage, so a column that remembers being collapsed renders at its seed width and corrects itself after the first paint. A nonced script after the column closes that gap — see the partial it includes — but the driver below remains the only way the FIRST render is right without any script at all. An adopting application measured that on the rail next door at 0.1097 CLS against a budget of 0.1 — the content column moving 187px, 53ms in. The usual answer, a blocking inline script in the head, is unavailable under a strict `script-src 'self'` policy without a nonce. A cookie is the only store Blade and Alpine both read, so this driver mirrors the flag there and the first render is already right. Opt-in on purpose: writing a cookie where a developer asked for localStorage is a behavior change, and a cookie is something an application has to be able to account for.",
                    "examples": [],
                    "values": [
                        "local",
                        "cookie"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "label",
                    "default": "__('wirekit::Sidebar')",
                    "default_normalized": "__('wirekit::Sidebar')",
                    "type_hint": null,
                    "comment": "Accessible name for the navigation landmark. Defaults to \"Sidebar\" so assistive tech can tell it apart from the main \u003Cnav\u003E; override it when the page carries more than one navigation landmark. Passing aria-label OR aria-labelledby directly on the component also wins over this default (and suppresses it, so the \u003Cnav\u003E never gets a duplicate/conflicting name).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scrollShadows",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "The edge shadows on the scrolling middle. On by default, because a scrollbar alone is easy to miss on a track that fades when idle. It has to be separable from the zones, and that is the point of the prop: the zones and the shadows arrived as one thing, so a developer with their own edge treatment could only be rid of ours by dropping `header` and `footer` entirely — which also gives up the sticky head and foot, a completely unrelated capability. Two decisions were being made by one answer.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "zoneInset",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "The head and foot zones inset their content to line up with the navigation below them. That is right for a brand row or a plain block, and wrong for a component that already insets itself: a `sidebar.item` placed in a zone carries its own padding and ends up indented twice, sitting visibly right of the items it belongs with. Set `false` when the zone's content brings its own.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "footer",
                    "required": false
                },
                {
                    "name": "header",
                    "required": false
                }
            ],
            "sub_components": [
                {
                    "name": "sidebar.collapsible",
                    "tag": "\u003Cx-wirekit::sidebar.collapsible\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "''",
                            "default_normalized": "''",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "open",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "persist",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Optional localStorage key. When set, the open/closed state survives a reload — same semantics as the sidebar component's own `persist`. Null keeps it ephemeral.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "variant",
                            "default": "'default'",
                            "default_normalized": "'default'",
                            "type_hint": null,
                            "comment": "Trigger styling. 'default' looks like a sidebar.item (nav row). 'heading' makes it a small uppercase tracked section label (matching a collapsible sidebar.group) for designs that treat the group title as a section heading rather than a nav row.",
                            "examples": [],
                            "values": [
                                "default",
                                "heading"
                            ],
                            "value_type": "string"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "sidebar.group",
                    "tag": "\u003Cx-wirekit::sidebar.group\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "collapsible",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": "When set, the group heading becomes a disclosure button that folds its items. `open` is the initial state (default open — a section keeps showing its children until the user folds it), `persist` is an optional localStorage key so the fold state survives a reload (same semantics as the sidebar's own `persist`).",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "open",
                            "default": "true",
                            "default_normalized": "true",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "persist",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "sidebar.item",
                    "tag": "\u003Cx-wirekit::sidebar.item\u003E",
                    "props": [
                        {
                            "name": "href",
                            "default": "'#'",
                            "default_normalized": "'#'",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "active",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "submenu",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "badge",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "A trailing counter/dot (an unread badge) — a count or short string renders a pill AFTER the label, OUTSIDE the label span so a long name can never push it out, and stays visible in the collapsed rail.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "value",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "The identity of this row when the parent sidebar is in `selection` mode. Ignored in the default navigation mode, where `href` is the identity.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "sidebar.toggle",
                    "tag": "\u003Cx-wirekit::sidebar.toggle\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "stepper",
            "tag": "\u003Cx-wirekit::stepper\u003E",
            "category": "Navigation",
            "description": "Step indicator for multi-step flows",
            "docs_url": "https://docs.wirekit.app/components/stepper",
            "props": [
                {
                    "name": "steps",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "current",
                    "default": "1",
                    "default_normalized": "1",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "orientation",
                    "default": "config('wirekit.components.stepper.orientation', 'horizontal')",
                    "default_normalized": "config('wirekit.components.stepper.orientation', 'horizontal')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "wizard",
            "tag": "\u003Cx-wirekit::wizard\u003E",
            "category": "Navigation",
            "description": "Multi-step flow container — holds the step, gates advancing, announces the change",
            "docs_url": "https://docs.wirekit.app/components/wizard",
            "props": [
                {
                    "name": "steps",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "Step names, in order. They drive the indicator and the announcement, so a flow with no names still works — it announces \"Step 2 of 4\" instead of naming the place.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "current",
                    "default": "1",
                    "default_normalized": "1",
                    "type_hint": null,
                    "comment": "Which step shows first, 1-based.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "indicator",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Draw the progress indicator above the panel. `false` when the surrounding page already shows progress its own way — two indicators for one flow is worse than one.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "orientation",
                    "default": "config('wirekit.components.wizard.orientation', 'horizontal')",
                    "default_normalized": "config('wirekit.components.wizard.orientation', 'horizontal')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "controls",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "wizard.step",
                    "tag": "\u003Cx-wirekit::wizard.step\u003E",
                    "props": [
                        {
                            "name": "index",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Which position in the flow this panel is, 1-based. Required — the container finds a step by this number, and guessing it from DOM order would break the moment a step is rendered conditionally.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "complete",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Whether the flow may leave this step. Unset means yes: a wizard whose steps carry no condition is an ordinary next/back flow, and defaulting to blocked would make the simplest use of the component the one that does not work.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "tabs",
            "tag": "\u003Cx-wirekit::tabs\u003E",
            "category": "Navigation",
            "description": "Tabbed content navigation",
            "docs_url": "https://docs.wirekit.app/components/tabs",
            "props": [
                {
                    "name": "items",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "default",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Which tab opens on first paint. Initial only — Alpine reads a seed once, so a later value here never reaches a rendered tablist.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "active",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Which tab is active, as the SERVER sees it. Distinct from `default` on purpose: this one keeps arriving. Set it and the tablist follows the server on every round trip — a tab restored from a URL, a validation error whose field lives in another panel, a permission that just changed. Leave it unset and nothing about the rendered output moves.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "variant",
                    "default": "config('wirekit.components.tabs.variant', 'underline')",
                    "default_normalized": "config('wirekit.components.tabs.variant', 'underline')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "orientation",
                    "default": "'horizontal'",
                    "default_normalized": "'horizontal'",
                    "type_hint": null,
                    "comment": "horizontal (default) | vertical",
                    "examples": [],
                    "values": [
                        "horizontal",
                        "vertical"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "label",
                    "default": "__('wirekit::Tabs')",
                    "default_normalized": "__('wirekit::Tabs')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "findable",
                    "default": "config('wirekit.components.tabs.findable', false)",
                    "default_normalized": "config('wirekit.components.tabs.findable', false)",
                    "type_hint": null,
                    "comment": "Inactive panels become findable by the browser's find in page, which switches to the tab a match lands in. Off by default: an inactive tab is often a view of its own, and a search that changes the reader's view unasked is a surprise. Only where the engine supports it.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": [
                {
                    "name": "tabs.list",
                    "tag": "\u003Cx-wirekit::tabs.list\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Names the bar for assistive technology. A tablist with no accessible name is announced as an unlabeled group, which is worse than no landmark at all when a page carries two of them.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "variant",
                            "default": "'underline'",
                            "default_normalized": "'underline'",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": [
                                "underline",
                                "pills",
                                "bordered"
                            ],
                            "value_type": "string"
                        },
                        {
                            "name": "orientation",
                            "default": "'horizontal'",
                            "default_normalized": "'horizontal'",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": [
                                "horizontal",
                                "vertical"
                            ],
                            "value_type": "string"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "tabs.tab",
                    "tag": "\u003Cx-wirekit::tabs.tab\u003E",
                    "props": [
                        {
                            "name": "selected",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": "Whether the SERVER considers this tab current. Not a default and not initial state: it arrives on every render and is the only thing that decides.",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "disabled",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "badge",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "alert-dialog",
            "tag": "\u003Cx-wirekit::alert-dialog\u003E",
            "category": "Overlay",
            "description": "Confirmation dialog with required action",
            "docs_url": "https://docs.wirekit.app/components/alert-dialog",
            "props": [
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "dismissible",
                    "default": "config('wirekit.components.alert-dialog.dismissible', false)",
                    "default_normalized": "config('wirekit.components.alert-dialog.dismissible', false)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "initialFocus",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "CSS selector, resolved inside the panel, for the control that should hold focus when the dialog opens. Unset, focus goes to Cancel — the least destructive action, per the APG alertdialog pattern.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "focusReturnTo",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "CSS selector for where focus should land when the dialog closes and its own trigger is gone — the normal case for a delete-in-a-list confirmation, whose Livewire re-render removes the very row that held the trigger. Unset, the dialog falls back to the nearest ancestor of the trigger that survived.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "closeOnConfirm",
                    "default": "config('wirekit.components.alert-dialog.close-on-confirm', false)",
                    "default_normalized": "config('wirekit.components.alert-dialog.close-on-confirm', false)",
                    "type_hint": null,
                    "comment": "Close the dialog once the destructive action has fired. ⚠️ DEFAULT FALSE, and that is back-compat rather than a recommendation. Leaving it false is what every dialog shipped before this prop did, and a caller who wants the close today writes `x-on:click=\"close()\"` on their own control — which works, because `close()` is in this component's Alpine scope, and is exactly the line this prop exists to stop everyone from writing. ⚠️ `alert-dialog.confirm` IS NOT THE SAME THING, whatever its name suggests. That component is a PHRASE GUARD: it refuses an activation until the confirmation string is typed. It fires nothing and closes nothing, so swapping a hand-written `x-on:click=\"close()\"` for it removes the close and takes the announcement defect back — on a part whose name promises the opposite.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "confirmationPhrase",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The exact string a developer must type before `alert-dialog.confirm` will fire — the brake in front of an action nobody can undo. Unset (the default), nothing about this component changes: no field renders and the confirm control is never held back. The comparison is documented rather than guessed at, because a brake whose rule is invisible is a brake people learn to resent: surrounding whitespace is trimmed, everything else is compared EXACTLY. Case, punctuation and inner spacing all count. Trimming is the one concession, and only because a trailing space arrives from a copy-paste rather than from a decision.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "An explicit accessible name, for an alert-dialog composed WITHOUT `alert-dialog.title`. Same reasoning as `drawer`: `aria-labelledby` points at an id the title would have bound at runtime, and a caller `aria-label` never reaches the element that carries the role. WCAG 2.1 4.1.2, Level A.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "describedby",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`false` drops `aria-describedby` for an alert-dialog composed without `alert-dialog.description`, where the attribute otherwise ships a permanently unresolvable reference. Default `null` keeps the documented behavior, so nothing that composes the description changes. Read through BooleanProp below, and that is the whole of this prop's history: the check was a bare `!== false`, so only the BOUND spelling `:describedby=\"false\"` worked. `describedby=\"false\"` compiles to the STRING \"false\", which is not `false` and is truthy besides, so the unresolvable reference the prop exists to remove shipped anyway — silently, in the spelling a reader is most likely to write.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "trigger",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "alert-dialog.actions",
                    "tag": "\u003Cx-wirekit::alert-dialog.actions\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "alert-dialog.cancel",
                    "tag": "\u003Cx-wirekit::alert-dialog.cancel\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "alert-dialog.confirm",
                    "tag": "\u003Cx-wirekit::alert-dialog.confirm\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "alert-dialog.confirmation",
                    "tag": "\u003Cx-wirekit::alert-dialog.confirmation\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "alert-dialog.description",
                    "tag": "\u003Cx-wirekit::alert-dialog.description\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "alert-dialog.title",
                    "tag": "\u003Cx-wirekit::alert-dialog.title\u003E",
                    "props": [
                        {
                            "name": "level",
                            "default": "2",
                            "default_normalized": "2",
                            "type_hint": null,
                            "comment": "Heading level for the dialog title (1-6). Defaults to 2 so nothing moves for a caller who never sets it. A dialog's heading is part of the document's outline like any other, so a page whose surrounding levels differ can say so here rather than around it.",
                            "examples": [],
                            "values": [
                                "1",
                                "2",
                                "3",
                                "4",
                                "5",
                                "6"
                            ],
                            "value_type": "int"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "command-palette",
            "tag": "\u003Cx-wirekit::command-palette\u003E",
            "category": "Overlay",
            "description": "Searchable command palette (⌘K)",
            "docs_url": "https://docs.wirekit.app/components/command-palette",
            "props": [
                {
                    "name": "hotkey",
                    "default": "config('wirekit.components.command-palette.hotkey', 'cmd+k')",
                    "default_normalized": "config('wirekit.components.command-palette.hotkey', 'cmd+k')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "placeholder",
                    "default": "config('wirekit.components.command-palette.placeholder') ?? __('wirekit::Search commands…')",
                    "default_normalized": "config('wirekit.components.command-palette.placeholder') ?? __('wirekit::Search commands…')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "teleport",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "When true (default) the overlay teleports out of the document flow so it sits above every other stacking context. Set to false to render the overlay inline inside the parent element — useful for docs previews or when embedding the palette inside a scoped stacking context (wrapper with `contain: layout`, `transform`, etc.) that should contain the fixed overlay instead of letting it escape to the viewport.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "lockScroll",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "When true (default) opening the palette sets `document.body.style.overflow = 'hidden'` so the page behind the overlay can't be scrolled — standard modal behavior. Set to false when the palette is embedded inside a local container (e.g. a docs preview card) where locking global body scroll would be disruptive and where a backdrop scoped via `contain: layout` already confines the overlay.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "empty",
                    "required": false
                },
                {
                    "name": "footer",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "command-palette.empty",
                    "tag": "\u003Cx-wirekit::command-palette.empty\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "command-palette.group",
                    "tag": "\u003Cx-wirekit::command-palette.group\u003E",
                    "props": [
                        {
                            "name": "heading",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "command-palette.item",
                    "tag": "\u003Cx-wirekit::command-palette.item\u003E",
                    "props": [
                        {
                            "name": "href",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "shortcut",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "disabled",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "id",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Stable DOM id for this item. It anchors the combobox's aria-activedescendant, so it must survive a re-render: with server-side search the list is rebuilt on every keystroke, and an id that changes each time keeps moving the screen reader's announcement target and makes Livewire's morph patch every row. Pass one when you have a natural key.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "context-menu",
            "tag": "\u003Cx-wirekit::context-menu\u003E",
            "category": "Overlay",
            "description": "Right-click context menu",
            "docs_url": "https://docs.wirekit.app/components/context-menu",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "When true (default) the panel teleports out of the document flow so it escapes every ancestor stacking context, overflow:hidden, and `contain: layout` container. This is the right default for 99% of production use cases and it mirrors what Modal, Drawer, Alert-Dialog, Tooltip, and Command-Palette already do. Set to false if the panel must stay inside the component root — e.g. when you're embedding the context menu inside a scoped stacking container that should contain the overlay itself (rare, and usually an anti-pattern). Names the panel. A `role=\"menu\"` with no name is announced as an unnamed menu, and the panel TELEPORTS out to the overlay root — so the trigger that opened it is no longer where the reading cursor is, and there is nothing left to identify it by.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "teleport",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "trigger",
                    "required": true
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "context-menu.item",
                    "tag": "\u003Cx-wirekit::context-menu.item\u003E",
                    "props": [
                        {
                            "name": "danger",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "disabled",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "href",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Renders an `\u003Ca\u003E` instead of a `\u003Cbutton\u003E`. The docs promised this prop for a long time while the component declared only the four below and hard-coded `\u003Cbutton\u003E` — so `href` fell into the attribute bag and was emitted onto the button, where HTML ignores it. Left-click did nothing and cmd-click, middle-click, \"open in new tab\" and \"copy link address\" were all dead, with no warning: a declared-looking prop on a real element. The shape mirrors `dropdown.item`, which has carried it all along — including the `target=\"_blank\"` handling, because a menu item that opens a new tab without `rel=\"noopener\"` hands the opened page a reference back to this one.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "context-menu.separator",
                    "tag": "\u003Cx-wirekit::context-menu.separator\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "context-menu.submenu",
                    "tag": "\u003Cx-wirekit::context-menu.submenu\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Parent item text (or pass a \u003Cx-slot:label\u003E for rich content)",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Optional leading icon (WireKit icon system)",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "placement",
                            "default": "'right-start'",
                            "default_normalized": "'right-start'",
                            "type_hint": null,
                            "comment": "Floating UI placement of the child panel",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "offset",
                            "default": "0",
                            "default_normalized": "0",
                            "type_hint": null,
                            "comment": "Gap between the parent item and the child panel",
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "disabled",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "drawer",
            "tag": "\u003Cx-wirekit::drawer\u003E",
            "category": "Overlay",
            "description": "Slide-out panel from screen edge",
            "docs_url": "https://docs.wirekit.app/components/drawer",
            "props": [
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "position",
                    "default": "config('wirekit.components.drawer.position', 'right')",
                    "default_normalized": "config('wirekit.components.drawer.position', 'right')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "left",
                        "right",
                        "top",
                        "bottom"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.drawer.size', 'md')",
                    "default_normalized": "config('wirekit.components.drawer.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "dismissible",
                    "default": "config('wirekit.components.drawer.dismissible', true)",
                    "default_normalized": "config('wirekit.components.drawer.dismissible', true)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "describedby",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "An explicit accessible name, for a drawer composed WITHOUT `drawer.header`. Without it such a drawer announces as a bare \"dialog\": `aria-labelledby` points at an id the header would have bound at runtime, and a caller `aria-label` lands on the outer x-data wrapper — which carries no role — while the element that IS the dialog keeps the unresolvable reference. WCAG 2.1 4.1.2, Level A. A prop rather than server-side detection of the header: the header binds its id through Alpine (`x-bind:id`), so it is not in the rendered slot for the parent to find. This also means the name survives with JavaScript disabled.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "drawer.body",
                    "tag": "\u003Cx-wirekit::drawer.body\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "drawer.close",
                    "tag": "\u003Cx-wirekit::drawer.close\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "drawer.footer",
                    "tag": "\u003Cx-wirekit::drawer.footer\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "drawer.header",
                    "tag": "\u003Cx-wirekit::drawer.header\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "close",
                            "default": "true",
                            "default_normalized": "true",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        }
                    ]
                }
            ]
        },
        {
            "name": "dropdown",
            "tag": "\u003Cx-wirekit::dropdown\u003E",
            "category": "Overlay",
            "description": "Dropdown menu with items",
            "docs_url": "https://docs.wirekit.app/components/dropdown",
            "props": [
                {
                    "name": "placement",
                    "default": "config('wirekit.components.dropdown.placement', 'bottom-start')",
                    "default_normalized": "config('wirekit.components.dropdown.placement', 'bottom-start')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "offset",
                    "default": "config('wirekit.components.dropdown.offset', 8)",
                    "default_normalized": "config('wirekit.components.dropdown.offset', 8)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Pin the panel id across renders. `alert-dialog`, `drawer` and `lightbox` all carry this escape hatch; the dropdown was the one overlay without it, which is why a Livewire round trip could not be made survivable from the call site.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "block",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Fills the row it sits in instead of shrinking to its trigger. The wrapper is shrink-to-fit by default, which is right for a menu button in a toolbar and wrong for the one place a dropdown is the WHOLE row: the account trigger at the foot of a sidebar column. There the trigger's highlight has to span the row like the navigation entries above it, and no width set on the trigger can reach past a wrapper sized to that same trigger. A class from the call site cannot do this either — the wrapper's own `display` would have to be overridden, and two conflicting utilities resolve by stylesheet order rather than by which one the caller wrote.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The menu's accessible name, handed to the panel the quick form composes. That panel is written by this file, not by the caller, so nothing on the call site can reach it except a prop of the parent — without this one, a quick-form menu could not be named at all. In the explicit form the caller writes the panel and gives it `label` there; the note above the panel's @props says why there is no generic fallback.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "trigger",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "dropdown.checkbox-item",
                    "tag": "\u003Cx-wirekit::dropdown.checkbox-item\u003E",
                    "props": [
                        {
                            "name": "optimisticArgs",
                            "default": "[]",
                            "default_normalized": "[]",
                            "type_hint": null,
                            "comment": "The Livewire method to call when the item is toggled, showing the new checked state before the server agrees. A refusal puts the old state back. Adds a `display: contents` wrapper — see the note above for why that is safe inside a menu, and how it was checked. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                            "examples": [],
                            "values": null,
                            "value_type": "array"
                        },
                        {
                            "name": "optimistic",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "checked",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "disabled",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "shortcut",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "keyboard-shortcut hint at the inline-end",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "dropdown.item",
                    "tag": "\u003Cx-wirekit::dropdown.item\u003E",
                    "props": [
                        {
                            "name": "href",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "danger",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "disabled",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "shortcut",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "keyboard-shortcut hint shown at the inline-end (e.g. \"⌘K\")",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "active",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": "\"This is the page you are on.\" A navigation menu's most common state, and until now there was no way to say it — so the only mark on screen was the focus ring the menu puts on its first item when it opens, which reads as a selection to everyone who did not put it there. Deliberately NOT painted as a background. Hover and focus already use the subtle surface, and a third thing that looks like those two would not tell them apart. The current entry is marked by weight and text color, which survives beside either.",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "role",
                            "default": "'menuitem'",
                            "default_normalized": "'menuitem'",
                            "type_hint": null,
                            "comment": "The ARIA role, `menuitem` unless a caller asks for something else. A group of MUTUALLY EXCLUSIVE menu options is `menuitemradio` + `aria-checked` under the APG menu pattern, and no amount of `aria-current` substitutes: `aria-current` says which item is the current one within a set of related items and carries no group membership at all. A reader hears \"System, current\" instead of \"System, radio button, checked, 1 of 3\" — never told that the three are one choice, nor how many there are. Opt-in rather than inferred, because this sub-component cannot see whether its siblings form a set. The caller knows; the item does not.",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "dropdown.panel",
                    "tag": "\u003Cx-wirekit::dropdown.panel\u003E",
                    "props": [
                        {
                            "name": "width",
                            "default": "config('wirekit.components.dropdown.panel.width', 'auto')",
                            "default_normalized": "config('wirekit.components.dropdown.panel.width', 'auto')",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "The menu's accessible name. See the note above @props for why it is a prop, and why an absent one stays absent.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "dropdown.radio-item",
                    "tag": "\u003Cx-wirekit::dropdown.radio-item\u003E",
                    "props": [
                        {
                            "name": "model",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "name of the Alpine variable holding the group's selected value",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "value",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "this option's value",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "disabled",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "shortcut",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "dropdown.separator",
                    "tag": "\u003Cx-wirekit::dropdown.separator\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "dropdown.submenu",
                    "tag": "\u003Cx-wirekit::dropdown.submenu\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Parent item text (or pass a \u003Cx-slot:label\u003E for rich content)",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Optional leading icon (WireKit icon system)",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "placement",
                            "default": "'right-start'",
                            "default_normalized": "'right-start'",
                            "type_hint": null,
                            "comment": "Floating UI placement of the child panel",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "offset",
                            "default": "0",
                            "default_normalized": "0",
                            "type_hint": null,
                            "comment": "Gap between the parent item and the child panel",
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "disabled",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "dropdown.trigger",
                    "tag": "\u003Cx-wirekit::dropdown.trigger\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "ariaLabelFallback",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Optional fallback aria-label used when the trigger has no accessible name (icon-only triggers, responsive layouts that hide the visible label below sm). Defaults to \"Open menu\". Explicit aria-label / aria-labelledby on the inner button or an sr-only span both win over this fallback — see x-init below.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "fab",
            "tag": "\u003Cx-wirekit::fab\u003E",
            "category": "Overlay",
            "description": "Floating action button that fans out into secondary actions",
            "docs_url": "https://docs.wirekit.app/components/fab",
            "props": [
                {
                    "name": "label",
                    "default": "__('wirekit::Actions')",
                    "default_normalized": "__('wirekit::Actions')",
                    "type_hint": null,
                    "comment": "What the trigger does. REQUIRED in spirit: the trigger is an icon, so without this it announces as \"button\" and nothing else.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "position",
                    "default": "config('wirekit.components.fab.position', 'end')",
                    "default_normalized": "config('wirekit.components.fab.position', 'end')",
                    "type_hint": null,
                    "comment": "Where it floats. 'end' is the inline-end corner — it follows the writing direction rather than assuming everyone reads left-to-right.",
                    "examples": [],
                    "values": [
                        "end",
                        "start",
                        "center"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "trigger",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "fab.action",
                    "tag": "\u003Cx-wirekit::fab.action\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "''",
                            "default_normalized": "''",
                            "type_hint": null,
                            "comment": "What this action does. The button is an icon, so this is its whole name.",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "hideLabel",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": "Drop the label from the SCREEN while keeping it as the accessible name — the plain icon-only speed dial. Same meaning the prop carries on checkbox, so the name is reused rather than reinvented.",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "href",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "fab.button",
                    "tag": "\u003Cx-wirekit::fab.button\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "The accessible name when the button carries no words of its own. Null rather than the default string, so the component can tell \"the caller said nothing\" from \"the caller asked for this\" — a distinction the name resolution below needs and could not otherwise make. The default is applied there, so an existing icon-only call renders exactly as before.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "position",
                            "default": "config('wirekit.components.fab.position', 'end')",
                            "default_normalized": "config('wirekit.components.fab.position', 'end')",
                            "type_hint": null,
                            "comment": "Where it floats — the inline corner, following the writing direction.",
                            "examples": [],
                            "values": [
                                "end",
                                "start",
                                "center"
                            ],
                            "value_type": "string"
                        },
                        {
                            "name": "placement",
                            "default": "'block-end'",
                            "default_normalized": "'block-end'",
                            "type_hint": null,
                            "comment": "Which block edge it sits on. `block-end` (the default) is the canonical bottom-corner FAB and is unchanged; `block-start` moves it to the top.",
                            "examples": [],
                            "values": [
                                "block-end",
                                "block-start"
                            ],
                            "value_type": "string"
                        },
                        {
                            "name": "haspopup",
                            "default": "'dialog'",
                            "default_normalized": "'dialog'",
                            "type_hint": null,
                            "comment": "What the button opens, so assistive tech announces it correctly. A single-action FAB is NOT a menu — the default is 'dialog' (the canonical use is a feedback / compose modal). Pass 'menu' / 'true' / 'listbox' / 'grid' / 'tree' as needed, or a falsy value to omit aria-haspopup entirely (a plain action that navigates or fires an event rather than opening a popup).",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "href",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Render an \u003Ca\u003E instead of a \u003Cbutton\u003E when the action is a navigation.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Optional icon name (resolved via the WireKit icon system). A slot overrides it.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "hover-card",
            "tag": "\u003Cx-wirekit::hover-card\u003E",
            "category": "Overlay",
            "description": "Content preview on hover",
            "docs_url": "https://docs.wirekit.app/components/hover-card",
            "props": [
                {
                    "name": "placement",
                    "default": "'bottom'",
                    "default_normalized": "'bottom'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "offset",
                    "default": "8",
                    "default_normalized": "8",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "delayShow",
                    "default": "300",
                    "default_normalized": "300",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "delayHide",
                    "default": "200",
                    "default_normalized": "200",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "trigger",
                    "required": true
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "lightbox",
            "tag": "\u003Cx-wirekit::lightbox\u003E",
            "category": "Overlay",
            "description": "Focus-trapped media viewer for images, video, and embeds — reusable, keyboard-navigable, event-driven",
            "docs_url": "https://docs.wirekit.app/components/lightbox",
            "props": [
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Instance identifier. Any control can open this lightbox by dispatching `wirekit-lightbox-open` with a matching `name` + `index`.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "items",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The slides. Each item is an array: ['src' =\u003E …, 'alt' =\u003E …, 'caption' =\u003E …, 'type' =\u003E 'image'|'video'|'embed'] `type` defaults to 'image'. A plain string is treated as a decorative image src.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "loop",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Whether prev/next wraps around at the ends (true) or stops (false).",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "showCaptions",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Show each item's caption inside the lightbox.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "overlay",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Backdrop color / opacity for THIS instance (any CSS color). Null → the themeable --color-wk-overlay token.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "slideOverlay",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Per-slide overlay render-callback: a closure `fn($slide, $i)` returning markup to lay OVER the media of slide #$i in the viewer (a label, a watermark, a report control), shown only while that slide is. The wrapper is pointer-events-none; interactive controls inside opt back in with `pointer-events-auto`. Return a view or HtmlString for HTML (a plain string is escaped). Null → no overlay.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "mockup",
            "tag": "\u003Cx-wirekit::mockup\u003E",
            "category": "Marketing",
            "description": "Frame chrome for a screenshot or live composition — browser, window, code, phone, tablet",
            "docs_url": "https://docs.wirekit.app/components/mockup",
            "props": [
                {
                    "name": "variant",
                    "default": "'browser'",
                    "default_normalized": "'browser'",
                    "type_hint": null,
                    "comment": "browser — URL bar + traffic lights (a web app screenshot) window  — title bar + traffic lights (a desktop app) code    — filename tab + traffic lights (a snippet, pairs with code-block) phone   — a phone frame tablet  — a tablet frame",
                    "examples": [],
                    "values": [
                        "browser",
                        "window",
                        "code",
                        "phone",
                        "tablet"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "url",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Shown in the browser variant's address bar.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "title",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Shown in the window / code variant's title area.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "modal",
            "tag": "\u003Cx-wirekit::modal\u003E",
            "category": "Overlay",
            "description": "Dialog overlay with backdrop",
            "docs_url": "https://docs.wirekit.app/components/modal",
            "props": [
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.modal.size', 'md')",
                    "default_normalized": "config('wirekit.components.modal.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "dismissible",
                    "default": "config('wirekit.components.modal.dismissible', true)",
                    "default_normalized": "config('wirekit.components.modal.dismissible', true)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "describedby",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "ariaLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Names the dialog when it has no header sub-component. A dialog with no accessible name is announced as just \"dialog\", and the failure is silent — see the aria-labelledby block below for why one had to be added. (No component tag in this comment: Blade compiles tags inside comments too, and one here breaks the @props array it sits in.)",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "trigger",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "modal.body",
                    "tag": "\u003Cx-wirekit::modal.body\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "modal.close",
                    "tag": "\u003Cx-wirekit::modal.close\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "modal.footer",
                    "tag": "\u003Cx-wirekit::modal.footer\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "modal.header",
                    "tag": "\u003Cx-wirekit::modal.header\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "close",
                            "default": "true",
                            "default_normalized": "true",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        }
                    ]
                },
                {
                    "name": "modal.trigger",
                    "tag": "\u003Cx-wirekit::modal.trigger\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "popover",
            "tag": "\u003Cx-wirekit::popover\u003E",
            "category": "Overlay",
            "description": "Contextual content popover",
            "docs_url": "https://docs.wirekit.app/components/popover",
            "props": [
                {
                    "name": "placement",
                    "default": "config('wirekit.components.popover.placement', 'bottom')",
                    "default_normalized": "config('wirekit.components.popover.placement', 'bottom')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "offset",
                    "default": "config('wirekit.components.popover.offset', 8)",
                    "default_normalized": "config('wirekit.components.popover.offset', 8)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The panel's accessible name. It is a `role=\"dialog\"`, so a screen reader announces this on entry — and the default said \"Popover\", which names the mechanism rather than the content. A page with two of them announced the same word twice.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "padded",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Whether the panel pads its own contents. `false` hands the whole surface to the caller, which is what a panel with its own header, scroll region and footer needs: those three have to reach the panel's edges, and padding on the outside puts a gutter between the scrollbar and the border and stops a sticky header from sitting flush.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "trigger",
                    "required": true
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "toast-region",
            "tag": "\u003Cx-wirekit::toast-region\u003E",
            "category": "Overlay",
            "description": "Toast notification container",
            "docs_url": null,
            "props": [
                {
                    "name": "position",
                    "default": "config('wirekit.components.toast-region.position', 'top-right')",
                    "default_normalized": "config('wirekit.components.toast-region.position', 'top-right')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "duration",
                    "default": "config('wirekit.components.toast-region.duration', 5000)",
                    "default_normalized": "config('wirekit.components.toast-region.duration', 5000)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "max",
                    "default": "config('wirekit.components.toast-region.max', 5)",
                    "default_normalized": "config('wirekit.components.toast-region.max', 5)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "scoped name — when set, listens on 'wirekit-toast-{name}' instead of global",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the stack, and the switch that makes it a LANDMARK. `role=\"region\"` plus a name is a landmark, and this component is designed to be mounted several times on one page — one per corner, or one per section through `eventScope`. With a built-in name every one of them was the same rotor entry called \"Notifications\", which is what axe reports as `landmark-unique`: the name meant to tell them apart is exactly what made them identical. So the role waits for a name the CALLER chose, never one the component can invent. Nothing is lost without it — the two live regions below are the announcement path, and they do not depend on the landmark. Name it after the surface (\"Form notifications\").",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "filled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "when true, toast uses full variant background color (like callout)",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "class-personalization scope — passed to WireKit::resolveClasses",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "eventScope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "CSS selector for DOM-containment event filtering",
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "tooltip",
            "tag": "\u003Cx-wirekit::tooltip\u003E",
            "category": "Overlay",
            "description": "Hover tooltip with configurable position",
            "docs_url": "https://docs.wirekit.app/components/tooltip",
            "props": [
                {
                    "name": "text",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "placement",
                    "default": "config('wirekit.components.tooltip.placement', 'top')",
                    "default_normalized": "config('wirekit.components.tooltip.placement', 'top')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "offset",
                    "default": "config('wirekit.components.tooltip.offset', 6)",
                    "default_normalized": "config('wirekit.components.tooltip.offset', 6)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "delayShow",
                    "default": "config('wirekit.components.tooltip.delay-show', 300)",
                    "default_normalized": "config('wirekit.components.tooltip.delay-show', 300)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "delayHide",
                    "default": "config('wirekit.components.tooltip.delay-hide', 100)",
                    "default_normalized": "config('wirekit.components.tooltip.delay-hide', 100)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "focusableTrigger",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Make the trigger keyboard-focusable so the tooltip is reachable by keyboard, not just hover (WCAG 2.1.1). Default true covers the common case of a tooltip on a NON-interactive slot (an icon, a text span). Set false when the slot is already interactive (a button/link) to avoid a double tab-stop — the slot's own focus then bubbles to the trigger and still shows the tooltip.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "describes",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "`false` when the tooltip text is ALSO the trigger's accessible name, as on an icon-only control named by its tooltip. Describing a control with its own name makes a screen reader say it twice (\"Fast mode, button, Fast mode\"), so the pairing is left out.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Switch the tooltip off without removing it. A tooltip on a control that has become inert — a collapsed sidebar item, a disabled action — has to be able to go quiet, and `pointer-events-none` on the root is NOT a way to do that however much it looks like one: `mouseenter` is delivered to every ancestor of the element actually hit, whatever their own pointer-events value, so the handler fires and the panel appears over something that is supposed to be dead. Rendered as an attribute rather than passed into the factory, so a call site can bind it — `x-bind:data-wk-tooltip-disabled=\"collapsed\"` — and get a tooltip that follows live state. The component reads it at trigger time.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "content",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "tour",
            "tag": "\u003Cx-wirekit::tour\u003E",
            "category": "Overlay",
            "description": "Guided product tour with steps",
            "docs_url": "https://docs.wirekit.app/components/tour",
            "props": [
                {
                    "name": "name",
                    "default": "'tour'",
                    "default_normalized": "'tour'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "tour.step",
                    "tag": "\u003Cx-wirekit::tour.step\u003E",
                    "props": [
                        {
                            "name": "target",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "placement",
                            "default": "'bottom'",
                            "default_normalized": "'bottom'",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "index",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "When null (default), the index is auto-assigned via TourStepCounter::next() based on document order under the enclosing tour parent. Explicit :index=\"N\" bypasses the auto-assignment — useful when steps render conditionally and the developer needs control over the numbering.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "level",
                            "default": "3",
                            "default_normalized": "3",
                            "type_hint": null,
                            "comment": "Heading level for the title (1-6). Defaults to 3 — a step's title inside the tour dialog — so nothing moves for a caller who never sets it. Set it to match the surrounding document outline: a component cannot know where in the page it sits, and a guessed level is worse than a chosen one. A skipped level is what `heading-order` reports, and that rule lives in axe's best-practice tag rather than the WCAG tags most suites run — so it is invisible to an axe sweep and visible in Lighthouse.",
                            "examples": [],
                            "values": [
                                "1",
                                "2",
                                "3",
                                "4",
                                "5",
                                "6"
                            ],
                            "value_type": "int"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "announcement-banner",
            "tag": "\u003Cx-wirekit::announcement-banner\u003E",
            "category": "Marketing",
            "description": "Dismissible page-edge announcement bar with persisted dismissal and an optional inline CTA",
            "docs_url": "https://docs.wirekit.app/components/announcement-banner",
            "props": [
                {
                    "name": "position",
                    "default": "'top'",
                    "default_normalized": "'top'",
                    "type_hint": null,
                    "comment": "Where the bar lives. Sticky is opt-in — a bar that follows the reader is a stronger claim on the viewport than most announcements deserve.",
                    "examples": [],
                    "values": [
                        "top",
                        "bottom"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "sticky",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "intent",
                    "default": "'promo'",
                    "default_normalized": "'promo'",
                    "type_hint": null,
                    "comment": "Semantic tint. `promo` is the marketing default (accent), the state intents carry the usual meaning.",
                    "examples": [],
                    "values": [
                        "promo",
                        "info",
                        "success",
                        "warning",
                        "danger"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "dismissKey",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A stable key makes the dismissal STICK across page loads. Without one the bar is not dismissible unless `persist` is explicitly turned off (below) — a close button that silently forgets is worse than no close button, so forgetfulness has to be a deliberate choice, never an accident.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "persist",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Whether a dismissal is remembered across page loads (localStorage). On by default. Turn it OFF for a session-scoped notice that should reappear next visit — and it is what makes a live demo resettable, since a re-mount then brings the bar back instead of reading a stored \"dismissed\" flag.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the region — and the LANDMARK waits for it. ⚠️ THE DEFAULT USED TO BE `__('wirekit::Announcement')`, WHICH MADE EVERY BANNER THE SAME LANDMARK. `position` validates against top AND bottom, so a page with a promo bar above and a notice below is a first-class composition — and it produced two `role=\"region\"` landmarks both called \"Announcement\". Somebody paging through landmarks meets two regions with one name and cannot tell them apart, which is the failure the house rule on named landmarks was written against — a component may not invent the name that turns itself into one. Eight siblings in this catalog already gate the role on `filled()`; this component was the outlier. Null, so the role is gated on the CALLER having supplied a name rather than on this file being able to invent one. The dismiss button still gets a composed name below, because a control needs one whether or not the banner is a landmark.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "action",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "cta",
            "tag": "\u003Cx-wirekit::cta\u003E",
            "category": "Marketing",
            "description": "Call-to-action banner section",
            "docs_url": "https://docs.wirekit.app/components/cta",
            "props": [
                {
                    "name": "variant",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "default",
                        "dark",
                        "accent"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "animateIn",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional reveal animation when the CTA scrolls into view. Null = no animation (default — CTA renders without an entrance reveal).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "'md'",
                    "default_normalized": "'md'",
                    "type_hint": null,
                    "comment": "`size` — vertical-rhythm tier (mirrors hero's prop). One of `sm` / `md` / `lg`. Default `md` (= `--space-wk-section-md` at sm+ viewports). Mobile viewport (\u003C sm breakpoint) drops one tier so the cta never overshoots vertical-padding budget on small screens.",
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "level",
                    "default": "2",
                    "default_normalized": "2",
                    "type_hint": null,
                    "comment": "Heading level for the title (1-6). Defaults to 2 — a call to action, usually a section of its own — so nothing moves for a caller who never sets it. Set it to match the surrounding document outline: a component cannot know where in the page it sits, and a guessed level is worse than a chosen one. A skipped level is what `heading-order` reports, and that rule lives in axe's best-practice tag rather than the WCAG tags most suites run — so it is invisible to an axe sweep and visible in Lighthouse.",
                    "examples": [],
                    "values": [
                        "1",
                        "2",
                        "3",
                        "4",
                        "5",
                        "6"
                    ],
                    "value_type": "int"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "title",
                    "required": false
                },
                {
                    "name": "description",
                    "required": false
                },
                {
                    "name": "actions",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "faq",
            "tag": "\u003Cx-wirekit::faq\u003E",
            "category": "Marketing",
            "description": "FAQ block — accordion of questions that emits FAQPage JSON-LD derived from what it rendered",
            "docs_url": "https://docs.wirekit.app/components/faq",
            "props": [
                {
                    "name": "label",
                    "default": "config('wirekit.components.faq.label') ?? __('wirekit::Frequently asked questions')",
                    "default_normalized": "config('wirekit.components.faq.label') ?? __('wirekit::Frequently asked questions')",
                    "type_hint": null,
                    "comment": "Accessible name for the question list.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "variant",
                    "default": "config('wirekit.components.faq.variant', 'flush')",
                    "default_normalized": "config('wirekit.components.faq.variant', 'flush')",
                    "type_hint": null,
                    "comment": "Visual treatment, passed through to the underlying accordion. 'flush' is the default here (not 'bordered'): an FAQ almost always sits inline in page content, where outer chrome only competes with the section around it.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.faq.size', 'lg')",
                    "default_normalized": "config('wirekit.components.faq.size', 'lg')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "multiple",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Let several answers stand open at once. Default is one at a time, which is how people read an FAQ: they are hunting one answer, not comparing. A boolean rather than the accordion's `mode` string on purpose. `mode` is a forbidden prop name for new components — the house convention froze the shared-axis names, and the handful of components still on `mode` are grandfathered pending a migration. Widening that list for a brand-new component would be the wrong side of a rule that exists to stop exactly this drift. A bare boolean attribute also reads better at the call site than a string enum with two values.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "schema",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Emit FAQPage JSON-LD for the questions rendered here. Turn it OFF when the same questions already appear elsewhere on the page, or when this FAQ is one of several: a page must carry exactly one FAQPage, and two of them compete rather than combine.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "plainText",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Strip markup from the SCHEMA answer text (the visible answer is untouched). Google's FAQPage accepts only a limited HTML subset, so answers containing nested components, data-* attributes or Alpine directives can fail rich-result validation. The schema text stays DERIVED from what is rendered — same content, markup removed — so it cannot drift from the page.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "findable",
                    "default": "config('wirekit.components.accordion.findable', true)",
                    "default_normalized": "config('wirekit.components.accordion.findable', true)",
                    "type_hint": null,
                    "comment": "Passed to the accordion: a question's answer stays findable by the browser's find in page.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "faq-item",
            "tag": "\u003Cx-wirekit::faq-item\u003E",
            "category": "Marketing",
            "description": "One question and answer inside an FAQ; records itself for the FAQPage schema",
            "docs_url": null,
            "props": [
                {
                    "name": "question",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": "The question. Rendered as the accordion trigger AND recorded for the FAQPage schema — one string, both jobs, so they cannot disagree.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "schemaAnswer",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Escape hatch for the rare case where the schema answer must differ from the visible one in CONTENT, not just markup. Prefer `plain-text` on the faq: a hand-written duplicate is copy that can drift away from what the reader sees, which is exactly what deriving the schema from the render prevents.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "id",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "feature",
            "tag": "\u003Cx-wirekit::feature\u003E",
            "category": "Marketing",
            "description": "Individual feature card for feature grids",
            "docs_url": "https://docs.wirekit.app/components/feature",
            "props": [
                {
                    "name": "icon",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "title",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "intent",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The canonical color axis, the one button, badge, progress, alert and callout all spell: primary | neutral | info | success | warning | danger. `tone` below is its back-compat alias and keeps working unchanged.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "tone",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "animateIn",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional reveal animation when the feature card scrolls into view. Null = no animation (default, v1.5.0-identical).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "level",
                    "default": "3",
                    "default_normalized": "3",
                    "type_hint": null,
                    "comment": "Heading level for the title (1-6). Defaults to 3 — a card in a grid of features — so nothing moves for a caller who never sets it. Set it to match the surrounding document outline: a component cannot know where in the page it sits, and a guessed level is worse than a chosen one. A skipped level is what `heading-order` reports, and that rule lives in axe's best-practice tag rather than the WCAG tags most suites run — so it is invisible to an axe sweep and visible in Lighthouse.",
                    "examples": [],
                    "values": [
                        "1",
                        "2",
                        "3",
                        "4",
                        "5",
                        "6"
                    ],
                    "value_type": "int"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "iconSlot",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "feature-grid",
            "tag": "\u003Cx-wirekit::feature-grid\u003E",
            "category": "Marketing",
            "description": "Responsive grid for feature cards",
            "docs_url": "https://docs.wirekit.app/components/feature-grid",
            "props": [
                {
                    "name": "cols",
                    "default": "config('wirekit.components.feature-grid.cols', '1 sm:2 lg:3')",
                    "default_normalized": "config('wirekit.components.feature-grid.cols', '1 sm:2 lg:3')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "1",
                        "2",
                        "3",
                        "4",
                        "5",
                        "6",
                        "sm:1",
                        "sm:2",
                        "sm:3",
                        "sm:4",
                        "sm:5",
                        "sm:6",
                        "md:1",
                        "md:2",
                        "md:3",
                        "md:4",
                        "md:5",
                        "md:6",
                        "lg:1",
                        "lg:2",
                        "lg:3",
                        "lg:4",
                        "lg:5",
                        "lg:6",
                        "xl:1",
                        "xl:2",
                        "xl:3",
                        "xl:4",
                        "xl:5",
                        "xl:6",
                        "2xl:1",
                        "2xl:2",
                        "2xl:3",
                        "2xl:4",
                        "2xl:5",
                        "2xl:6"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "gap",
                    "default": "'lg'",
                    "default_normalized": "'lg'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "none",
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scale",
                    "default": "'space'",
                    "default_normalized": "'space'",
                    "type_hint": null,
                    "comment": "Which spacing ladder `gap` names a rung on: `space` (the default) or the tighter `gap` ladder, as on `grid`. The rungs offered stay the ones this prop has always had.",
                    "examples": [],
                    "values": [
                        "space",
                        "gap"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "stagger",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Cascade entrance animations across direct children. null = no stagger (default — each child animates simultaneously) true = enable with default 75ms step int  = explicit ms step (e.g. 125)",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "footer",
            "tag": "\u003Cx-wirekit::footer\u003E",
            "category": "Layout",
            "description": "Landing page footer with columns and legal",
            "docs_url": "https://docs.wirekit.app/components/footer",
            "props": [
                {
                    "name": "animateIn",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional reveal animation when the footer scrolls into view. Null = no animation (default — footer renders without an entrance reveal).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "max",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`max` — container max-width tier for the inner content wrappers (columns, brand+legal row, default slot). Defaults to `xl` (= 80 rem). Same enum as the container primitive (sm/md/lg/xl/2xl/ full) so the footer aligns with the rest of the page chrome on the same vertical content-edge spine.",
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl",
                        "full"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "columns",
                    "required": false
                },
                {
                    "name": "brand",
                    "required": false
                },
                {
                    "name": "legal",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "hero",
            "tag": "\u003Cx-wirekit::hero\u003E",
            "category": "Marketing",
            "description": "Landing page hero with title, lede, and actions",
            "docs_url": "https://docs.wirekit.app/components/hero",
            "props": [
                {
                    "name": "variant",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "default",
                        "dark",
                        "accent",
                        "muted"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "gradient",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "layout",
                    "default": "'balanced'",
                    "default_normalized": "'balanced'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "balanced",
                        "lead",
                        "centered",
                        "stacked"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "asideWidth",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Only valid when layout=\"balanced\". Tunes the copy:aside ratio from the default 50/50 to one of: 1/3 | 2/5 | 3/5 | 2/3. Under any non-balanced layout this prop throws via validateProp (debug) or is silently ignored (production).",
                    "examples": [],
                    "values": [
                        "1/3",
                        "2/5",
                        "1/2",
                        "3/5",
                        "2/3"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "animateIn",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional reveal animation. Null = no animation (default, v1.5.0-identical).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "'lg'",
                    "default_normalized": "'lg'",
                    "type_hint": null,
                    "comment": "`size` — vertical-rhythm tier. One of `sm` / `md` / `lg`. Default `lg` (= `--space-wk-section-lg` at `sm+` viewports). Mobile viewport (\u003C sm breakpoint) automatically drops one tier — `lg` becomes `md` (= 5rem each side) so the bottom-empty-area-with-gradient class of bug (variant=\"dark\" hero with gradient overlay produces a visually empty dark band below the content on narrow viewports when the section padding is too generous) doesn't recur. Pass `size=\"sm\"` for the tightest spacing across every viewport.",
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "tightOnMobile",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`tightOnMobile` — when true, drop an ADDITIONAL tier on mobile viewports for `size=\"lg\"` heroes. Useful for dark-variant heroes with gradient overlays where even 5 rem of mobile bottom padding reads as a visible dead-zone below the content on 390 px-wide viewports (iPhone 12-class). Opt-in (default `false`) — does NOT change the rendering of any existing hero. For `size=\"sm\"` and `size=\"md\"`, the prop is a no-op (mobile already runs at the tightest tier).",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "level",
                    "default": "1",
                    "default_normalized": "1",
                    "type_hint": null,
                    "comment": "Heading level for the title (1-6). Defaults to 1 — the page's main heading — the level a hero usually carries — so nothing moves for a caller who never sets it. Set it to match the surrounding document outline: a component cannot know where in the page it sits, and a guessed level is worse than a chosen one. A skipped level is what `heading-order` reports, and that rule lives in axe's best-practice tag rather than the WCAG tags most suites run — so it is invisible to an axe sweep and visible in Lighthouse.",
                    "examples": [],
                    "values": [
                        "1",
                        "2",
                        "3",
                        "4",
                        "5",
                        "6"
                    ],
                    "value_type": "int"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "eyebrow",
                    "required": false
                },
                {
                    "name": "title",
                    "required": false
                },
                {
                    "name": "lede",
                    "required": false
                },
                {
                    "name": "actions",
                    "required": false
                },
                {
                    "name": "aside",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "accordion",
            "tag": "\u003Cx-wirekit::accordion\u003E",
            "category": "Display",
            "description": "Collapsible content panels",
            "docs_url": "https://docs.wirekit.app/components/accordion",
            "props": [
                {
                    "name": "mode",
                    "default": "config('wirekit.components.accordion.mode', 'single')",
                    "default_normalized": "config('wirekit.components.accordion.mode', 'single')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "variant",
                    "default": "config('wirekit.components.accordion.variant', 'bordered')",
                    "default_normalized": "config('wirekit.components.accordion.variant', 'bordered')",
                    "type_hint": null,
                    "comment": "Visual treatment of the container + items: - 'bordered'  → outer border + rounded card + row dividers + elevated bg (default; byte-identical to the pre-variant look). - 'flush'     → no outer chrome, just hair-line row dividers — for an FAQ that sits inline in page content. - 'separated' → each item is its own standalone card with a gap between them (the container draws nothing; items carry the chrome).",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.accordion.size', 'md')",
                    "default_normalized": "config('wirekit.components.accordion.size', 'md')",
                    "type_hint": null,
                    "comment": "Row density. 'md' is the default trigger/panel padding; 'lg' is roomier (larger padding + trigger text) for marketing / spacious layouts.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "findable",
                    "default": "config('wirekit.components.accordion.findable', true)",
                    "default_normalized": "config('wirekit.components.accordion.findable', true)",
                    "type_hint": null,
                    "comment": "Closed panels stay findable by the browser's find in page, which opens the one a match lands in. Only where the engine supports it; elsewhere a closed panel is hidden as before. Read by every item through @aware.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "level",
                    "default": "3",
                    "default_normalized": "3",
                    "type_hint": null,
                    "comment": "Heading level each item's trigger is wrapped in (1–6). Defaults to 3, which is what every accordion shipped before this prop existed. The ARIA authoring practices require the level to be \"appropriate for the information architecture of the page\", and that is a property of the PAGE, not of the widget: an accordion sitting directly under the page \u003Ch1\u003E wants level 2, one inside an \u003Ch2\u003E section wants 3, and a fixed \u003Ch3\u003E produces a skipped or flattened outline in every other position. Screen-reader heading navigation is where that shows up, so nothing on screen reports it. Items read this through @aware — the level belongs to the group, not to one row.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "accordion.item",
                    "tag": "\u003Cx-wirekit::accordion.item\u003E",
                    "props": [
                        {
                            "name": "id",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "title",
                            "default": "''",
                            "default_normalized": "''",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "action-bar",
            "tag": "\u003Cx-wirekit::action-bar\u003E",
            "category": "Display",
            "description": "Floating action bar for bulk operations",
            "docs_url": "https://docs.wirekit.app/components/action-bar",
            "props": [
                {
                    "name": "visible",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "mode",
                    "default": "'floating'",
                    "default_normalized": "'floating'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "activity-row",
            "tag": "\u003Cx-wirekit::activity-row\u003E",
            "category": "Display",
            "description": "Activity-feed / timeline row with kind-colored dot, actor, timestamp, and badge slot",
            "docs_url": "https://docs.wirekit.app/components/activity-row",
            "props": [
                {
                    "name": "kind",
                    "default": "'system'",
                    "default_normalized": "'system'",
                    "type_hint": null,
                    "comment": "Activity kind — drives the leading dot color. The built-in set is commit / merge / deploy / comment / system / user; extend or recolor via `config('wirekit.components.activity-row.kinds')`. Unknown kinds fall back to the muted dot (no error — the map is intentionally open).",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "kindLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "What a screen reader hears for the kind, in place of the dot's color. The six built-in kinds are announced from the translation catalog; any other kind is announced by its key unless this names it.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "actor",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional actor name, rendered bold at the start of the line.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "timestamp",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional relative timestamp (\"2 hours ago\"), right-aligned + muted.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "badge",
                    "required": false
                },
                {
                    "name": "detail",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "alert",
            "tag": "\u003Cx-wirekit::alert\u003E",
            "category": "Display",
            "description": "Contextual alert message",
            "docs_url": "https://docs.wirekit.app/components/alert",
            "props": [
                {
                    "name": "variant",
                    "default": "config('wirekit.components.alert.variant', 'info')",
                    "default_normalized": "config('wirekit.components.alert.variant', 'info')",
                    "type_hint": null,
                    "comment": "back-compat alias of `intent`",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "intent",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "canonical color axis: primary | neutral | info | success | warning | danger. null → falls back to `variant`",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "title",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "dismissible",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "icon",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "animateIn",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional reveal animation. Null = no animation (default, v1.5.0-identical).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "iconSlot",
                    "required": false
                },
                {
                    "name": "actions",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "attachment",
            "tag": "\u003Cx-wirekit::attachment\u003E",
            "category": "Display",
            "description": "File/image attachment card with formatted size, type label, upload state, and actions",
            "docs_url": "https://docs.wirekit.app/components/attachment",
            "props": [
                {
                    "name": "name",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": "File name. Also the accessible name of the card.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "bytes",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Raw byte count — formatted for display (\"2.4 MB\"). Pass the raw number; formatting is ours, so developers never hand-roll it.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "type",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "MIME type (e.g. \"application/pdf\"). Rendered as a short label (\"PDF\").",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "thumbnail",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Image source for a visual preview. Given → the media tile shows the thumbnail instead of the file glyph.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "state",
                    "default": "'idle'",
                    "default_normalized": "'idle'",
                    "type_hint": null,
                    "comment": "Lifecycle: idle | uploading | done | error.",
                    "examples": [],
                    "values": [
                        "idle",
                        "uploading",
                        "done",
                        "error"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "progress",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "0–100 while uploading. Drives the progress bar.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "href",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Makes the whole card a link (download / open).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "icon",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Override the media glyph with any icon name from the active preset.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "animate",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Animate the upload progress bar while `state=\"uploading\"` — a shimmer sweep that reads as \"actively uploading\". Opt-in (off by default), gated by prefers-reduced-motion at the CSS layer.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "actions",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "attachment-group",
            "tag": "\u003Cx-wirekit::attachment-group\u003E",
            "category": "Display",
            "description": "Group of attachments — vertical stack or horizontal scroll-snap row",
            "docs_url": null,
            "props": [
                {
                    "name": "label",
                    "default": "config('wirekit.components.attachment-group.label') ?? __('wirekit::Attachments')",
                    "default_normalized": "config('wirekit.components.attachment-group.label') ?? __('wirekit::Attachments')",
                    "type_hint": null,
                    "comment": "Accessible name for the group (e.g. \"3 attachments\").",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "orientation",
                    "default": "'stack'",
                    "default_normalized": "'stack'",
                    "type_hint": null,
                    "comment": "'row' scroll-snaps horizontally (chat bubbles, tight rows); 'stack' lists them vertically (mail, detail panels).",
                    "examples": [],
                    "values": [
                        "row",
                        "stack"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "assistant-message",
            "tag": "\u003Cx-wirekit::assistant-message\u003E",
            "category": "Display",
            "description": "AI assistant turn — roles, streaming body, model chip, reasoning disclosure, and coalesced screen-reader announcements",
            "docs_url": "https://docs.wirekit.app/components/assistant-message",
            "props": [
                {
                    "name": "role",
                    "default": "'assistant'",
                    "default_normalized": "'assistant'",
                    "type_hint": null,
                    "comment": "Who is speaking: assistant (left, avatar + model chip), user (right), system (centered, muted — a configuration/system turn, not a person).",
                    "examples": [],
                    "values": [
                        "assistant",
                        "user",
                        "system"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Display name for the speaker. Null uses the role's own wording.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "avatar",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional avatar image for the speaker.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "model",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Model / engine chip (e.g. \"atlas-2\"). Assistant turns only.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "intent",
                    "default": "'neutral'",
                    "default_normalized": "'neutral'",
                    "type_hint": null,
                    "comment": "Optional state tint on the bubble — for a turn that IS a state: an error answer (danger), a caution (warning), a confirmation (success), a note (info). neutral (default) keeps the plain role surface. Mirrors the message component's intent tint (bg + border at low alpha; the body text stays regular, never a state color).",
                    "examples": [],
                    "values": [
                        "neutral",
                        "info",
                        "success",
                        "warning",
                        "danger"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "streaming",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "True while tokens are still landing. Marks the turn aria-busy and shows the streaming affordance.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "citations",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The sources this answer cites, as numbered chips under the body. Takes whatever the retrieval layer produced: titles, arrays with label/href/snippet, or the application's own models — `CitationList` normalizes all three and drops an entry with no label, because a chip a screen reader announces as nothing is worse than no chip.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "reasoningSeconds",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Seconds the model spent reasoning, for the disclosure's summary once the stream has ended: \"Thought for 12s\". The APPLICATION owns that number — it knows when the stream started, and a stopwatch in the browser would disagree with it the moment the page re-renders from the server. Null keeps the plain label.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announce",
                    "default": "config('wirekit.components.assistant-message.announce', 'sentence')",
                    "default_normalized": "config('wirekit.components.assistant-message.announce', 'sentence')",
                    "type_hint": null,
                    "comment": "How streamed output reaches assistive technology: sentence — flush each finished sentence (default; the readable choice) all      — flush once, when streaming stops off      — never announce (you narrate it yourself)",
                    "examples": [],
                    "values": [
                        "sentence",
                        "all",
                        "off"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "reasoning",
                    "required": false
                },
                {
                    "name": "footer",
                    "required": false
                },
                {
                    "name": "actions",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "avatar",
            "tag": "\u003Cx-wirekit::avatar\u003E",
            "category": "Display",
            "description": "User avatar with image, initials, or status",
            "docs_url": "https://docs.wirekit.app/components/avatar",
            "props": [
                {
                    "name": "src",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "alt",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "initials",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "fromInitials",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "When true (with `initials` set and no `src`), derive a deterministic background color from the initials hash so the same person always gets the same color — replaces per-app crc32-palette helpers. The palette pairs an AA-contrast background with white text and is theme-independent. See Pushery\\WireKit\\Support\\AvatarPalette.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.avatar.size', 'md')",
                    "default_normalized": "config('wirekit.components.avatar.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "xs",
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "shape",
                    "default": "config('wirekit.components.avatar.shape', 'circle')",
                    "default_normalized": "config('wirekit.components.avatar.shape', 'circle')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "circle",
                        "square"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "status",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "statusVariant",
                    "default": "config('wirekit.components.avatar.status-variant', 'dot')",
                    "default_normalized": "config('wirekit.components.avatar.status-variant', 'dot')",
                    "type_hint": null,
                    "comment": "How to visually render the status: 'dot'  — small colored dot in the bottom-right corner (default). 'ring' — full colored ring that surrounds the avatar, separated from the image by a thin gap in the page background color. The more prominent of the two: presence reads at a glance in a dense roster, where a corner dot needs looking for. Ignored when `status` is null.",
                    "examples": [],
                    "values": [
                        "dot",
                        "ring"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": [
                {
                    "name": "avatar.group",
                    "tag": "\u003Cx-wirekit::avatar.group\u003E",
                    "props": [
                        {
                            "name": "remaining",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Optional overflow counter. When set, a trailing \"+N\" chip is rendered after the avatars (e.g. show 3 avatars + `:remaining=\"7\"` → \"+7\"). The developer controls how many avatars they place in the slot.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "size",
                            "default": "config('wirekit.components.avatar.size', 'md')",
                            "default_normalized": "config('wirekit.components.avatar.size', 'md')",
                            "type_hint": null,
                            "comment": "Sizes the overflow chip to match the avatars in the slot — set it to the same size you pass to those avatars.",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Accessible name for the group as a whole (e.g. \"5 collaborators\"). The individual avatars keep their own alt text.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "badge",
            "tag": "\u003Cx-wirekit::badge\u003E",
            "category": "Display",
            "description": "Small status label",
            "docs_url": "https://docs.wirekit.app/components/badge",
            "props": [
                {
                    "name": "intent",
                    "default": "config('wirekit.components.badge.intent', 'neutral')",
                    "default_normalized": "config('wirekit.components.badge.intent', 'neutral')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "primary",
                        "accent",
                        "success",
                        "warning",
                        "danger",
                        "info",
                        "neutral"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.badge.size', 'md')",
                    "default_normalized": "config('wirekit.components.badge.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "surface",
                    "default": "config('wirekit.components.badge.surface', 'soft')",
                    "default_normalized": "config('wirekit.components.badge.surface', 'soft')",
                    "type_hint": null,
                    "comment": "Surface treatment within the chosen intent: 'soft'    — tinted background + intent text (default; back-compat — the lifted chip with the themeable inset ring depth). 'solid'   — filled intent background + on-color foreground text. 'outline' — transparent background + intent ring + intent text.",
                    "examples": [],
                    "values": [
                        "soft",
                        "solid",
                        "outline"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "dot",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "tooltip",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Discoverable tooltip — surfaces the status explanation through WireKit's own tooltip component (hover / focus / touch / keyboard, aria-describedby) instead of the browser's native title attribute. The text is the badge label; the tooltip is the supplementary explanation (e.g. \"Build failed\" on a \"Failed\" badge).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "leadingIcon",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional leading status glyph (icon alias, e.g. 'check' / 'clock' / 'x-circle' / 'shield-check'). Rendered decoratively before the label — the text is the accessible name, so the icon is aria-hidden.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "trailingIcon",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional trailing glyph — mirror of leadingIcon, rendered after the label (e.g. an external-link arrow on a link badge). Also decorative.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "dismissible",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "When true, renders a trailing close button that removes the badge (Alpine x-show) and dispatches a `wirekit:badge-dismissed` event. Keyboard- and screen-reader-operable; label set via dismissLabel. A dismissible badge also emits data-replayable=\"true\" so the docs preview frame offers a \"↻ Replay\" reset (inert in a developer app — no replay-button is injected there).",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "dismissLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Null, not the English word: the fallback is resolved through the catalog in the block below. A literal default here is a label a translated application cannot reach — the dialog cancel button shipped that way, rendering an English control inside a fully translated German dialog while the catalog that would have fixed it was already installed.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "wrap",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Multi-line mode. A badge is a fixed-height single-line pill by default. Set `wrap` for a long label that must break across lines: the fixed height is swapped for `min-h-*` + vertical padding so the pill GROWS with the text instead of the second line spilling below the surface.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "branch-switcher",
            "tag": "\u003Cx-wirekit::branch-switcher\u003E",
            "category": "Display",
            "description": "Steps between several generated answers — prev/next, a live count, and a polite announcement per move",
            "docs_url": "https://docs.wirekit.app/components/branch-switcher",
            "props": [
                {
                    "name": "count",
                    "default": "0",
                    "default_normalized": "0",
                    "type_hint": null,
                    "comment": "How many variants there are. Required in practice: a switcher that does not know its own count cannot say \"2 of 3\", and the count is what the reader navigates by.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "current",
                    "default": "1",
                    "default_normalized": "1",
                    "type_hint": null,
                    "comment": "Which one is showing, 1-based, because that is what the label says and what a caller reasons about. Out of range is clamped rather than refused — a server that regenerates and re-renders can legitimately hand over an index that no longer exists.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Names the group for assistive technology. A switcher with no name is announced as a group of nothing, so an unset label falls back to a translated default.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "loop",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Whether the ends wrap. Off by default: a reader stepping through variants expects the last one to be the last one, and silent wrap-around loses that.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "button",
            "tag": "\u003Cx-wirekit::button\u003E",
            "category": "Display",
            "description": "Action button with variants and loading state",
            "docs_url": "https://docs.wirekit.app/components/button",
            "props": [
                {
                    "name": "intent",
                    "default": "config('wirekit.components.button.intent', 'primary')",
                    "default_normalized": "config('wirekit.components.button.intent', 'primary')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "primary",
                        "neutral",
                        "success",
                        "warning",
                        "danger",
                        "info"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "surface",
                    "default": "config('wirekit.components.button.surface', 'filled')",
                    "default_normalized": "config('wirekit.components.button.surface', 'filled')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "filled",
                        "outline",
                        "soft",
                        "ghost",
                        "link"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.button.size', 'md')",
                    "default_normalized": "config('wirekit.components.button.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "xs",
                        "sm",
                        "md-compact",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "type",
                    "default": "'button'",
                    "default_normalized": "'button'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "wrapLabel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Let a label that a USER typed take a second line. Default false: a label the application wrote belongs on one line, and a button that wraps mid-word is the defect there.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "href",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "loading",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "forceLoading",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "loadingTarget",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Scope the loading spinner + disable to THIS button's own Livewire action, e.g. loading-target=\"redeliver\". The spinner is a child \u003Csvg wire:loading\u003E with no target of its own, so Livewire falls back to hasActionForComponent() and flashes it on EVERY commit — including wire:poll refreshes and unrelated sibling actions. Setting loadingTarget emits wire:target so the spinner only reacts to that action. NOTE: this is `loadingTarget`, NOT `target` — a `target` prop would collide with the HTML target attribute (target=\"_blank\" + the rel tabnabbing auto-inject). Null = today's untargeted behavior (byte-identical); scoping is strictly opt-in.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "disableOnLoading",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Whether the busy state DISABLES the control, or merely announces itself. `disabled` is what this component has always used, and it costs the focus: the browser blurs a control the moment it becomes disabled, so the element the reader just activated stops being focused for the whole in-flight window and focus falls to `\u003Cbody\u003E`. That is WCAG 2.4.3, on every request, and it is why an adopting project set `aria-busy` through the attribute bag by hand rather than use `loading` at all. `false` swaps the attribute for `aria-busy`, which announces the same wait while the element stays focusable and in the tab order. Livewire's `.attr` sets the attribute to `true` — measured in its own `toggleBooleanStateDirective`, not assumed — so this yields a valid `aria-busy=\"true\"` rather than the attribute's own name. The default stays `true`, and the trade is the developer's to make: a control that stays enabled while its action is in flight can be pressed twice.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "iconLeft",
                    "required": false
                },
                {
                    "name": "iconRight",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "button.group",
                    "tag": "\u003Cx-wirekit::button.group\u003E",
                    "props": [
                        {
                            "name": "orientation",
                            "default": "'horizontal'",
                            "default_normalized": "'horizontal'",
                            "type_hint": null,
                            "comment": "'horizontal' (default) joins children left-to-right; 'vertical' stacks them. Literal default (a sub-component, so it does not dotted-read its own config — mirrors avatar.group / accordion.item).",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Accessible name for the group (e.g. \"View mode\"). Recommended when the group acts as a single control (segmented toggle, pagination cluster).",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "button-group",
            "tag": "\u003Cx-wirekit::button-group\u003E",
            "category": "Display",
            "description": "Welds adjacent controls into one unit — collapsed inner radii and a single seam, RTL-safe",
            "docs_url": "https://docs.wirekit.app/components/button-group",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the group (\"Text alignment\", \"Save options\").",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "orientation",
                    "default": "'horizontal'",
                    "default_normalized": "'horizontal'",
                    "type_hint": null,
                    "comment": "horizontal (default) welds left-to-right; vertical welds top-to-bottom.",
                    "examples": [],
                    "values": [
                        "horizontal",
                        "vertical"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "calendar",
            "tag": "\u003Cx-wirekit::calendar\u003E",
            "category": "Display",
            "description": "Calendar date display",
            "docs_url": "https://docs.wirekit.app/components/calendar",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "Livewire method to call optimistically. The date appears selected immediately and is put back if the call fails. Absent -\u003E this component renders exactly as it did before, down to the byte. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "range",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Multi-month display — render N consecutive months side by side (1 = the classic single grid). Clamped 1..4 in the Alpine component. Two-click range selection. `value` then reads and writes `YYYY-MM-DD/YYYY-MM-DD`, the spelling the date-picker's own range flag already uses — a value moved between the two keeps its meaning. Written WITHOUT the component tag on purpose: Blade compiles component tags across the whole file before a PHP comment means anything, so naming one here compiles it, and the failure arrives as `Undefined variable $component` from a line that is not code.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "months",
                    "default": "1",
                    "default_normalized": "1",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "selectableHeader",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Replace the static month label with native month + year \u003Cselect\u003E jump controls for fast navigation. Opt-in; default keeps the label byte-identical.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "weekStartsOn",
                    "default": "config('wirekit.components.calendar.week-starts-on', 1)",
                    "default_normalized": "config('wirekit.components.calendar.week-starts-on', 1)",
                    "type_hint": null,
                    "comment": "First day of the week: 0 (Sun) .. 1 (Mon, default) — matches the house convention + the event-calendar default. Configurable via config/wirekit.php.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "callout",
            "tag": "\u003Cx-wirekit::callout\u003E",
            "category": "Display",
            "description": "Highlighted information callout",
            "docs_url": "https://docs.wirekit.app/components/callout",
            "props": [
                {
                    "name": "variant",
                    "default": "config('wirekit.components.callout.variant', 'info')",
                    "default_normalized": "config('wirekit.components.callout.variant', 'info')",
                    "type_hint": null,
                    "comment": "back-compat alias of `intent`",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "intent",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "canonical color axis: primary | neutral | info | success | warning | danger. null → falls back to `variant`",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "icon",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "bordered",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "stripe",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Opt-in one-sided accent stripe (default OFF). The plain callout is the alert-style 4-sided tinted border; a one-sided colored stripe reads as generic dashboard chrome, so it is no longer the default. Pass `stripe` to restore the accent bar deliberately.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "animateIn",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional reveal animation. Null = no animation (default, v1.5.0-identical).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "iconSlot",
                    "required": false
                },
                {
                    "name": "title",
                    "required": false
                },
                {
                    "name": "actions",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "card",
            "tag": "\u003Cx-wirekit::card\u003E",
            "category": "Display",
            "description": "Content container card with optional link",
            "docs_url": "https://docs.wirekit.app/components/card",
            "props": [
                {
                    "name": "surface",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The canonical surface axis, spelled as on button: outline | elevated | flat. `variant` below is its back-compat alias and keeps working unchanged.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "variant",
                    "default": "config('wirekit.components.card.variant', 'outlined')",
                    "default_normalized": "config('wirekit.components.card.variant', 'outlined')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "as",
                    "default": "'div'",
                    "default_normalized": "'div'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "href",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "animateIn",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional reveal animation when card scrolls into view. One of 11 base presets (or any -in / -out variant). Null = no animation (default, v1.5.0-identical).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "overflow",
                    "default": "'hidden'",
                    "default_normalized": "'hidden'",
                    "type_hint": null,
                    "comment": "What the card does with a child that reaches past its box. The default clips, which is what makes the rounded corners cut the content inside them — but it also clips a badge pinned to a corner, an avatar that scales on hover, or a focus ring that extends past the edge. `visible` releases all of it. A prop rather than an !important utility override on the base class, because that override is not the same thing: it removes the corner clipping for EVERY child, and nothing says so until someone drops a full-bleed image or a table into that card. Reported from a consuming project that was carrying exactly that override, on two elements.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "card.body",
                    "tag": "\u003Cx-wirekit::card.body\u003E",
                    "props": [
                        {
                            "name": "padded",
                            "default": "true",
                            "default_normalized": "true",
                            "type_hint": null,
                            "comment": "Comfortable padding by default. Set padded=false for edge-to-edge content (a flush hero image, a full-bleed table). When false, the body also tags itself so a raw \u003Ctable\u003E dropped inside still gets readable cell padding (see the .wk-card-body[data-wk-padded=\"false\"] rule in dist/wirekit.css).",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "card.footer",
                    "tag": "\u003Cx-wirekit::card.footer\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "card.header",
                    "tag": "\u003Cx-wirekit::card.header\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "carousel",
            "tag": "\u003Cx-wirekit::carousel\u003E",
            "category": "Display",
            "description": "Image/content carousel with autoplay",
            "docs_url": "https://docs.wirekit.app/components/carousel",
            "props": [
                {
                    "name": "autoplay",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "interval",
                    "default": "5000",
                    "default_normalized": "5000",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "loop",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "orientation",
                    "default": "'horizontal'",
                    "default_normalized": "'horizontal'",
                    "type_hint": null,
                    "comment": "horizontal (default) | vertical",
                    "examples": [],
                    "values": [
                        "horizontal",
                        "vertical"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "perView",
                    "default": "1",
                    "default_normalized": "1",
                    "type_hint": null,
                    "comment": "How many slides share the view. '1' is the classic one-up carousel; the rest show neighbors, which is what a product row or a logo rail wants. Only meaningful horizontally — a vertical carousel is one slide tall.",
                    "examples": [],
                    "values": [
                        "1",
                        "2",
                        "3",
                        "4"
                    ],
                    "value_type": "int"
                },
                {
                    "name": "label",
                    "default": "__('wirekit::Carousel')",
                    "default_normalized": "__('wirekit::Carousel')",
                    "type_hint": null,
                    "comment": "What this carousel is FOR. A carousel of testimonials is not an image carousel, and the name is the first thing a screen reader reads.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "carousel.slide",
                    "tag": "\u003Cx-wirekit::carousel.slide\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "The slide's accessible name. `role=\"group\"` conformance does not require one, but `aria-roledescription` is what makes a screen reader say \"slide\" instead of \"group\" — and it is unreliable on an element that has no name at all, so a track of unnamed slides reads as N identical groups with nothing to tell them apart. It is a PROP rather than only an `aria-label` passthrough because a prop is what the props parser, the JSON export and the api-map can see; an attribute that happens to work is not a documented affordance, and the parent's own name for the same idea is `label` too. Deliberately NOT defaulted. There is no honest built-in name here: an anonymous Blade slide has no index of its own, so anything this file could invent would name every slide identically — the same reasoning that gates `role=\"region\"` on a caller-supplied name everywhere else in this library, rather than on a name the component made up.",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "chat-marker",
            "tag": "\u003Cx-wirekit::chat-marker\u003E",
            "category": "Display",
            "description": "In-thread meta row — streaming/tool status, system note, or labeled date break between chat messages",
            "docs_url": "https://docs.wirekit.app/components/chat-marker",
            "props": [
                {
                    "name": "variant",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": "default    — a centered inline status / system note row border     — the same row with a hairline under it (row boundaries) separator  — a centered label flanked by rules (a date break)",
                    "examples": [],
                    "values": [
                        "default",
                        "border",
                        "separator"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "icon",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional leading glyph (decorative — the row text carries the meaning).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "status",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Renders the row as a live region so a text swap inside it is ANNOUNCED. Use for streaming / progress rows (\"Thinking…\", \"Explored 4 files\").",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "shimmer",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Shimmers the label — the \"work is in flight\" affordance. Implies busy.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "intent",
                    "default": "'neutral'",
                    "default_normalized": "'neutral'",
                    "type_hint": null,
                    "comment": "Semantic color for system notes (\"Rate limit reached\").",
                    "examples": [],
                    "values": [
                        "neutral",
                        "info",
                        "success",
                        "warning",
                        "danger"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "clipboard-button",
            "tag": "\u003Cx-wirekit::clipboard-button\u003E",
            "category": "Display",
            "description": "Copy-to-clipboard button",
            "docs_url": "https://docs.wirekit.app/components/clipboard-button",
            "props": [
                {
                    "name": "value",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "copiedText",
                    "default": "__('wirekit::Copied')",
                    "default_normalized": "__('wirekit::Copied')",
                    "type_hint": null,
                    "comment": "`wirekit::Copied`, the key `color-picker` already uses. This asked for `wirekit::Copied!` — a second catalog key for the same visible state, and the only value of 370 carrying an exclamation mark. Two keys for one string means an application translating the kit has to find both, and the two components answer the same event in two registers.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "duration",
                    "default": "2000",
                    "default_normalized": "2000",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "iconOnly",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Bare icon button — no border / bg / label, just the copy glyph (muted, pops green on copy). For compact action rows (a message's copy control). Requires an aria-label (there is no visible text to name it).",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "collapsible",
            "tag": "\u003Cx-wirekit::collapsible\u003E",
            "category": "Display",
            "description": "Single disclosure — one trigger toggles one collapsible region (WAI-ARIA Disclosure)",
            "docs_url": "https://docs.wirekit.app/components/collapsible",
            "props": [
                {
                    "name": "trigger",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Trigger label (string). For rich trigger content, pass a named \"trigger\" slot instead — both surface as the $trigger variable, so the template renders either.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "open",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "findable",
                    "default": "config('wirekit.components.collapsible.findable', true)",
                    "default_normalized": "config('wirekit.components.collapsible.findable', true)",
                    "type_hint": null,
                    "comment": "Closed content stays findable by the browser's find in page, which opens the disclosure a match lands in. Only where the engine supports it; switch it off for a spoiler.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "countdown",
            "tag": "\u003Cx-wirekit::countdown\u003E",
            "category": "Display",
            "description": "Live countdown to an absolute deadline with overdue + urgent states (client-side, no polling)",
            "docs_url": "https://docs.wirekit.app/components/countdown",
            "props": [
                {
                    "name": "until",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The ABSOLUTE target instant — a Carbon, an ISO-8601 string, or a unix timestamp. Absolute, never a duration: a duration drifts the moment the tab sleeps or the page is cached; an absolute instant is recomputed from the real clock on every tick.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "expiredText",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Text shown once the deadline has passed. Null → a translatable default.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "warnThreshold",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Seconds-remaining threshold below which the countdown enters its \"urgent\" (warning-tinted) state. Null → no urgent state.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "units",
                    "default": "'auto'",
                    "default_normalized": "'auto'",
                    "type_hint": null,
                    "comment": "Which units to show. 'auto' (default): the largest meaningful unit down to the smallest, dropping leading zero-units — years appear only once the remaining time actually reaches a year (no more \"26831d\"). Or an explicit ordered subset, e.g. \"days hours minutes\" or \"years days\": the largest listed unit carries all the overflow above it, the smallest truncates.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "showSeconds",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Include seconds in 'auto' mode (ignored when `units` is an explicit list).",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "variant",
                    "default": "'inline'",
                    "default_normalized": "'inline'",
                    "type_hint": null,
                    "comment": "'inline' (default): \"73y 190d 12h 15m 09s\". 'segments': each unit in its own boxed block with a label — the classic dashboard countdown look.",
                    "examples": [],
                    "values": [
                        "inline",
                        "segments"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "separators",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Locale-aware thousands separators on large unit values (like price). Turn off with :separators=\"false\".",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "locale",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "BCP-47 locale for the separators. Null → the app locale.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "animate",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Change animation. For the segments variant, choose the style: true / \"box\"  → the whole box pulses (border + accent flash + scale pop) \"text\"        → only the changing number briefly flashes the accent color false / \"none\" → no motion The inline variant animates with a rise + fade whenever it is on.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "data-list",
            "tag": "\u003Cx-wirekit::data-list\u003E",
            "category": "Display",
            "description": "Key-value data display list",
            "docs_url": "https://docs.wirekit.app/components/data-list",
            "props": [
                {
                    "name": "layout",
                    "default": "config('wirekit.components.data-list.layout', 'horizontal')",
                    "default_normalized": "config('wirekit.components.data-list.layout', 'horizontal')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "data-list.item",
                    "tag": "\u003Cx-wirekit::data-list.item\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "empty-state",
            "tag": "\u003Cx-wirekit::empty-state\u003E",
            "category": "Display",
            "description": "Placeholder for empty content areas",
            "docs_url": "https://docs.wirekit.app/components/empty-state",
            "props": [
                {
                    "name": "icon",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "title",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "description",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "level",
                    "default": "3",
                    "default_normalized": "3",
                    "type_hint": null,
                    "comment": "Heading level for the title (1–6). Defaults to 3 (the v1.5.0-identical \u003Ch3\u003E); set it to match the surrounding document outline so screen-reader heading navigation stays correct (e.g. level=2 directly under a page \u003Ch1\u003E, or level=1 when the empty-state IS the page's main content).",
                    "examples": [],
                    "values": [
                        "1",
                        "2",
                        "3",
                        "4",
                        "5",
                        "6"
                    ],
                    "value_type": "int"
                },
                {
                    "name": "variant",
                    "default": "config('wirekit.components.empty-state.variant', 'default')",
                    "default_normalized": "config('wirekit.components.empty-state.variant', 'default')",
                    "type_hint": null,
                    "comment": "Container chrome: default (no border/bg — v1.5.0-identical) · outline (dashed border, reads as a placeholder drop-zone) · muted (filled muted surface).",
                    "examples": [],
                    "values": [
                        "default",
                        "outline",
                        "muted"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "animateIn",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional reveal animation. Null = no animation (default, v1.5.0-identical).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "iconSlot",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "image",
            "tag": "\u003Cx-wirekit::image\u003E",
            "category": "Display",
            "description": "Content image as a figure with alt text, lazy loading, CLS-safe ratio box, and optional caption",
            "docs_url": "https://docs.wirekit.app/components/image",
            "props": [
                {
                    "name": "src",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Image URL. The component only renders — the developer supplies a ready URL (a signed / ACL-protected download URL works unchanged).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "alt",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name. REQUIRED for a content image; pass an empty string ONLY for a purely decorative image (renders alt=\"\" so screen readers skip it). The default is null rather than '' so the two cases can be told apart. With '' as the default, \"the developer marked this decorative\" and \"the developer forgot\" produced byte-identical markup — and the forgotten one is a content image that announces nothing, which no automated check can see either, because `alt=\"\"` IS valid HTML and IS the correct answer for the other case.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "caption",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional visible caption — renders a \u003Cfigcaption\u003E under the image.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "ratio",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional intrinsic aspect-ratio (\"16/9\", \"4/3\", \"1/1\", or a number). Sizes the box BEFORE the image loads, so the layout never shifts (CLS-safe) even when the natural dimensions are unknown. Null → the image sizes itself.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "fit",
                    "default": "'cover'",
                    "default_normalized": "'cover'",
                    "type_hint": null,
                    "comment": "object-fit for a ratio-boxed image: 'cover' (fill + crop) or 'contain' (letterbox, no crop). Ignored without a ratio.",
                    "examples": [],
                    "values": [
                        "cover",
                        "contain"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "rounded",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Corner rounding token: false (none) or true (--radius-wk-md).",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "loading",
                    "default": "'lazy'",
                    "default_normalized": "'lazy'",
                    "type_hint": null,
                    "comment": "Native lazy-loading. Eager only for above-the-fold hero images.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "image-compare",
            "tag": "\u003Cx-wirekit::image-compare\u003E",
            "category": "Display",
            "description": "Before/after image comparison slider",
            "docs_url": "https://docs.wirekit.app/components/image-compare",
            "props": [
                {
                    "name": "before",
                    "default": null,
                    "default_normalized": null,
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "after",
                    "default": null,
                    "default_normalized": null,
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "beforeAlt",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "afterAlt",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "orientation",
                    "default": "'horizontal'",
                    "default_normalized": "'horizontal'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "ratio",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional intrinsic aspect-ratio (e.g. \"16/9\", \"4/3\", \"1/1\"). The component has absolutely-positioned images, so it needs a sized box. Set `ratio` and the figure sizes ITSELF (height derived from width) — no hand-rolled `\u003Cdiv style=\"aspect-ratio: …\"\u003E` wrapper needed. Leave it null to fill the height of whatever box the developer provides (the original contract).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "50",
                    "default_normalized": "50",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Form field name for the hidden input below. Declared as a prop rather than left to the attribute bag on purpose: the bag lands on the \u003Cfigure\u003E, where a `name` submits nothing, so a caller writing `name=\"reveal\"` got a figure with a name attribute and a POST body without the field.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "beforeLabel",
                    "default": "__('wirekit::Before')",
                    "default_normalized": "__('wirekit::Before')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "afterLabel",
                    "default": "__('wirekit::After')",
                    "default_normalized": "__('wirekit::After')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "labels",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "decorative",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "ariaLabel",
                    "default": "__('wirekit::Image comparison slider')",
                    "default_normalized": "__('wirekit::Image comparison slider')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "loading",
                    "default": "'lazy'",
                    "default_normalized": "'lazy'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "image-gallery",
            "tag": "\u003Cx-wirekit::image-gallery\u003E",
            "category": "Display",
            "description": "Responsive image grid with an accessible, keyboard-navigable lightbox",
            "docs_url": "https://docs.wirekit.app/components/image-gallery",
            "props": [
                {
                    "name": "emptyText",
                    "default": "__('wirekit::Nothing here yet')",
                    "default_normalized": "__('wirekit::Nothing here yet')",
                    "type_hint": null,
                    "comment": "The empty state. `empty` REPLACES the body rather than sitting beside it: the screen a new user sees FIRST is the one with no data, and a single muted sentence can only say that nothing is here — it cannot say what to do about it, which is the whole job of that screen. `emptyText` is the default, so a caller that does not care changes nothing. Same shape as data-table, which is where the reasoning was first written down.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "images",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "List of images: each an array with 'src' (required), 'alt' (required for a content image), and optional 'caption' and 'full'. A plain string is treated as a src with an empty alt (decorative) — pass the array form for real content. 'full' is the address the LIGHTBOX loads, and it defaults to 'src'. A grid tile is a few hundred pixels wide with ten of them on a page; the zoom view is the whole screen. Serving one address to both is the compromise an image ladder exists to end.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "columns",
                    "default": "'2 md:3 lg:4'",
                    "default_normalized": "'2 md:3 lg:4'",
                    "type_hint": null,
                    "comment": "Responsive grid column spec, forwarded to the grid component (e.g. \"2 md:3 lg:4\"). Literal handling lives in grid — never interpolated here.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "gap",
                    "default": "'md'",
                    "default_normalized": "'md'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "ratio",
                    "default": "'1/1'",
                    "default_normalized": "'1/1'",
                    "type_hint": null,
                    "comment": "Thumbnail aspect-ratio (CLS-safe). Null → images size themselves.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "fit",
                    "default": "'cover'",
                    "default_normalized": "'cover'",
                    "type_hint": null,
                    "comment": "object-fit forwarded to each thumbnail. 'cover' (default) crops to a uniform grid — right for mixed-orientation photo sets. Use 'contain' when a single image must be shown whole (e.g. one portrait shot the crop would slice) — the thumbnail then letterboxes inside its ratio box instead.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "lightbox",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Enable the click-to-zoom lightbox. When false the grid is static.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "itemOverlay",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Per-item overlay render-callback: a closure `fn($item, $i)` that returns the markup to layer OVER thumbnail #$i (a badge, a report control, an \"AI-generated\" label). It renders as a sibling of the zoom trigger — not nested inside it — so the overlay wrapper is pointer-events-none and the thumbnail still opens the lightbox; interactive controls inside the overlay opt back in with `pointer-events-auto`. Return a view or HtmlString for HTML (a plain string is escaped). Null → no overlay (galleries without it are byte-identical to before). It covers the THUMBNAIL only; the zoom view takes `zoomOverlay` below.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "zoomOverlay",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The zoom view's own overlay: the same `fn($item, $i)` shape as itemOverlay, laid over the image in the lightbox instead of over the thumbnail. A separate callback because the two surfaces differ (an overlay written for a square tile can sit wrong over a full-screen photo) and itemOverlay never reached the zoom view. A label that has to travel with the image, an \"AI-generated\" marking or a license note, goes to both. Ignored on a static grid, which has no zoom view. Null → no overlay.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "empty",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "product-card",
            "tag": "\u003Cx-wirekit::product-card\u003E",
            "category": "Display",
            "description": "Ecommerce product card — image, price with compare-at, rating, stock state, CTA",
            "docs_url": "https://docs.wirekit.app/components/product-card",
            "props": [
                {
                    "name": "name",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": "What it is. Rendered as the heading and used as the image's fallback name.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "href",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Where the product page is. The name becomes the link — see below for why the whole card is not one.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "image",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Cover image URL.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "imageAlt",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the image. Defaults to empty, NOT to the product name: the name is already right there in text, so repeating it makes a screen reader read the product twice. Pass it when the image shows something the name does not (\"Blue, worn open over a white shirt\").",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "price",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Price in the currency's major units, or minor units with :minor-units.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "compareAt",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "What it used to cost. Renders struck through, and the saving is announced.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "currency",
                    "default": "config('wirekit.currency', 'USD')",
                    "default_normalized": "config('wirekit.currency', 'USD')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "minorUnits",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "rating",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Average rating out of 5, and how many people gave it.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "reviewCount",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "description",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Short line under the name.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "availability",
                    "default": "'in-stock'",
                    "default_normalized": "'in-stock'",
                    "type_hint": null,
                    "comment": "'in-stock' | 'low-stock' | 'out-of-stock'. Out of stock disables the CTA.",
                    "examples": [],
                    "values": [
                        "in-stock",
                        "low-stock",
                        "out-of-stock"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "level",
                    "default": "3",
                    "default_normalized": "3",
                    "type_hint": null,
                    "comment": "Heading level for the title (1-6). Defaults to 3 — a card in a grid of products — so nothing moves for a caller who never sets it. Set it to match the surrounding document outline: a component cannot know where in the page it sits, and a guessed level is worse than a chosen one. A skipped level is what `heading-order` reports, and that rule lives in axe's best-practice tag rather than the WCAG tags most suites run — so it is invisible to an axe sweep and visible in Lighthouse.",
                    "examples": [],
                    "values": [
                        "1",
                        "2",
                        "3",
                        "4",
                        "5",
                        "6"
                    ],
                    "value_type": "int"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "media",
                    "required": false
                },
                {
                    "name": "badge",
                    "required": false
                },
                {
                    "name": "action",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "progress",
            "tag": "\u003Cx-wirekit::progress\u003E",
            "category": "Display",
            "description": "Progress bar with optional value display",
            "docs_url": "https://docs.wirekit.app/components/progress",
            "props": [
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "numeric value (0..max). null = indeterminate",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "max",
                    "default": "100",
                    "default_normalized": "100",
                    "type_hint": null,
                    "comment": "max value the bar represents",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "visible label rendered above the bar",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "showValue",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "show \"42 / 100\" next to label",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "variant",
                    "default": "config('wirekit.components.progress.variant', 'primary')",
                    "default_normalized": "config('wirekit.components.progress.variant', 'primary')",
                    "type_hint": null,
                    "comment": "back-compat alias of `intent`",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "intent",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "canonical color axis: primary | success | warning | danger | info | neutral (+ accent alias). null → falls back to `variant`",
                    "examples": [],
                    "values": [
                        "primary",
                        "accent",
                        "success",
                        "warning",
                        "danger",
                        "info",
                        "neutral"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.progress.size', 'md')",
                    "default_normalized": "config('wirekit.components.progress.size', 'md')",
                    "type_hint": null,
                    "comment": "sm | md | lg",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "animation",
                    "default": "'none'",
                    "default_normalized": "'none'",
                    "type_hint": null,
                    "comment": "Optional motion on the DETERMINATE fill — the \"work in flight\" affordance (uploads, streaming). none (default) | stripes (barber-pole) | shimmer (a light sweep). Purely additive polish: gated by prefers-reduced-motion, and the bar's value/width is unchanged, so nothing depends on the motion.",
                    "examples": [],
                    "values": [
                        "none",
                        "stripes",
                        "shimmer"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "valueExpression",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The NAME of an Alpine property to read the value from, for a value that only exists in the browser — an upload percentage, a streamed count. `value` is a PHP prop evaluated at render time, so it cannot carry one; binding to the rendered element cannot either, because `x-bind:value` sets an attribute on a `\u003Cdiv\u003E` that nothing reads. Pass the property name, not an expression: `value-expression=\"percent\"` resolves against the surrounding `x-data` through Alpine's scope chain.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": [
                {
                    "name": "progress.circle",
                    "tag": "\u003Cx-wirekit::progress.circle\u003E",
                    "props": [
                        {
                            "name": "value",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "max",
                            "default": "100",
                            "default_normalized": "100",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "label",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "showValue",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "variant",
                            "default": "config('wirekit.components.progress.variant', 'accent')",
                            "default_normalized": "config('wirekit.components.progress.variant', 'accent')",
                            "type_hint": null,
                            "comment": "back-compat alias of `intent`",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "intent",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "canonical color axis: success | warning | danger (anything else = accent). null → falls back to `variant`",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "size",
                            "default": "config('wirekit.components.progress.circle-size', 'md')",
                            "default_normalized": "config('wirekit.components.progress.circle-size', 'md')",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "qr-code",
            "tag": "\u003Cx-wirekit::qr-code\u003E",
            "category": "Display",
            "description": "QR code generator",
            "docs_url": "https://docs.wirekit.app/components/qr-code",
            "props": [
                {
                    "name": "value",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "200",
                    "default_normalized": "200",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "color",
                    "default": "'#000000'",
                    "default_normalized": "'#000000'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "background",
                    "default": "'#ffffff'",
                    "default_normalized": "'#ffffff'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "errorCorrection",
                    "default": "'L'",
                    "default_normalized": "'L'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "margin",
                    "default": "4",
                    "default_normalized": "4",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "accessibleLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the QR code. Defaults to a generic \"QR code\" string; authors should pass a descriptive label like \"Scan to install WireKit\" via this prop. WCAG 1.1.1 — non-text content needs a text alternative; encourage purpose-describing labels over raw URLs.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "reading-bookmark",
            "tag": "\u003Cx-wirekit::reading-bookmark\u003E",
            "category": "Display",
            "description": "Save / restore scroll position with return-prompt UX",
            "docs_url": null,
            "props": [
                {
                    "name": "key",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "target",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "threshold",
                    "default": "0.1",
                    "default_normalized": "0.1",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "float"
                },
                {
                    "name": "promptOnReturn",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "minDwellSeconds",
                    "default": "30",
                    "default_normalized": "30",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "previewMode",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "boundary",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`boundary` — null (default) = the resume-prompt pill pins to the viewport via Tailwind `fixed`. `'container'` = scoped to the nearest positioned ancestor via Tailwind `absolute`. Use `'container'` when the bookmark surface lives inside a contained reading frame (preview iframe, sidebar pane, modal body).",
                    "examples": [],
                    "values": [
                        "container",
                        "\u003Ccss-selector-string\u003E"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "reading-meta",
            "tag": "\u003Cx-wirekit::reading-meta\u003E",
            "category": "Display",
            "description": "Time-to-read estimate from word count, optional remaining-time + per-paragraph annotations",
            "docs_url": null,
            "props": [
                {
                    "name": "target",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "wpm",
                    "default": "225",
                    "default_normalized": "225",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "showRemaining",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "perParagraph",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "totalLabel",
                    "default": "__('wirekit::min read')",
                    "default_normalized": "__('wirekit::min read')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "remainingLabel",
                    "default": "__('wirekit::min remaining')",
                    "default_normalized": "__('wirekit::min remaining')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "paragraphLabelTemplate",
                    "default": "__('wirekit::{n} min')",
                    "default_normalized": "__('wirekit::{n} min')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "paragraphMinWords",
                    "default": "30",
                    "default_normalized": "30",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "cjkCharsPerMinute",
                    "default": "500",
                    "default_normalized": "500",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "reading-minimap",
            "tag": "\u003Cx-wirekit::reading-minimap\u003E",
            "category": "Display",
            "description": "Every-item density overview with click + drag-pan navigation",
            "docs_url": null,
            "props": [
                {
                    "name": "target",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "itemSelector",
                    "default": "'a, h2, h3, [data-minimap-item]'",
                    "default_normalized": "'a, h2, h3, [data-minimap-item]'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "width",
                    "default": "'60px'",
                    "default_normalized": "'60px'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "side",
                    "default": "'right'",
                    "default_normalized": "'right'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "left",
                        "right"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "draggable",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "hideBelow",
                    "default": "'lg'",
                    "default_normalized": "'lg'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "mode",
                    "default": "'stripes'",
                    "default_normalized": "'stripes'",
                    "type_hint": null,
                    "comment": "'stripes' (default, back-compat) | 'rendered'",
                    "examples": [],
                    "values": [
                        "stripes",
                        "rendered"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "renderTarget",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "CSS selector for the source to clone (defaults to `target`)",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "itemStyle",
                    "default": "'line'",
                    "default_normalized": "'line'",
                    "type_hint": null,
                    "comment": "stripe-mode visual: 'line' (default, thin 2px stripes per item) | 'block' (taller skeleton-style gray rectangles whose height tracks each source item's natural height — gives the minimap a content-texture instead of a sparse list of lines)",
                    "examples": [],
                    "values": [
                        "line",
                        "block"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "hoverPreview",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "E1 — magnified popover near cursor",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "showBookmarks",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "E2 — bookmark marker (auto-wires if a reading-bookmark sibling is present)",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "headingAnchors",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "E3 — clickable mini-anchors on the outboard edge",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "headingLevels",
                    "default": "'2,3'",
                    "default_normalized": "'2,3'",
                    "type_hint": null,
                    "comment": "E3 — CSV of heading levels to surface as anchors",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "autoFadeIdle",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "E4 — fade to --reading-minimap-idle-opacity after 3s idle",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "reading-progress",
            "tag": "\u003Cx-wirekit::reading-progress\u003E",
            "category": "Display",
            "description": "Viewport-pinned reading-progress indicator (bar or dot)",
            "docs_url": null,
            "props": [
                {
                    "name": "position",
                    "default": "'top'",
                    "default_normalized": "'top'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "height",
                    "default": "'md'",
                    "default_normalized": "'md'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "variant",
                    "default": "'primary'",
                    "default_normalized": "'primary'",
                    "type_hint": null,
                    "comment": "back-compat alias of `intent`",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "intent",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "canonical color axis: primary | neutral | success | warning | danger | info | auto. null → falls back to `variant`",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "showAfter",
                    "default": "0",
                    "default_normalized": "0",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "target",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "indicator",
                    "default": "'bar'",
                    "default_normalized": "'bar'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "segments",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "milestones",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "boundary",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`boundary` — when null (default), the progress indicator pins to the viewport via `position: fixed`. Set to `\"container\"` to swap to `position: sticky` so the bar/dot stays inside the nearest positioned ancestor (a modal body, a sidebar pane, an article preview surface). Sticky requires a scrolling parent with a defined height; in a non-scrolling parent the indicator falls back to static positioning and disappears — verify your wrapper has `overflow: auto` (or scroll) plus an explicit height.",
                    "examples": [],
                    "values": [
                        "container",
                        "\u003Ccss-selector-string\u003E"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "reading-shell",
            "tag": "\u003Cx-wirekit::reading-shell\u003E",
            "category": "Display",
            "description": "Composition wrapper with toggles + density preset",
            "docs_url": null,
            "props": [
                {
                    "name": "bookmarkKey",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "progress",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Toggles default to null so the density preset's per-primitive default wins. An explicit bool (`:spine=\"false\"`) overrides the density's baseline. Net effect for the developer: `density=\"minimal\"` actually hides things; passing the toggle explicitly always wins.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "spine",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "minimap",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "toc",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "bookmark",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "meta",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "density",
                    "default": "'comfortable'",
                    "default_normalized": "'comfortable'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "comfortable",
                        "compact",
                        "minimal"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "previewMode",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "boundary",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`boundary` — pass-through to the composed primitives (reading-progress, reading-spine, reading-bookmark). Default `null` keeps the viewport- pinned behavior. Set to `'container'` to scope every composed primitive to the shell's nearest positioned ancestor — required when embedding the entire reading surface inside a modal body, sidebar pane, preview iframe, or Livewire panel.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "reading-spine",
            "tag": "\u003Cx-wirekit::reading-spine\u003E",
            "category": "Display",
            "description": "Sidebar mini-TOC tracking scroll, expanding on hover/focus",
            "docs_url": null,
            "props": [
                {
                    "name": "target",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "exclude",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A selector for subtrees whose headings are NOT this page's structure. Reported from the documentation site: a page embedding live component demos listed 41 entries of which 23 were demo content — an accordion's panel titles, a carousel's product names — and `target` could not help, because the demos sit INSIDE the article that holds the real sections. Unset (the default) changes nothing about an existing call site.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "levels",
                    "default": "'2,3'",
                    "default_normalized": "'2,3'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "position",
                    "default": "'right'",
                    "default_normalized": "'right'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "edgeOffset",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "How far in from the edge `position` chose. `position` picks WHICH edge; this picks the distance, and `0` is expressible — a spine flush against the window was unreachable before, because both arms carried `1rem` as a literal. Reported from the documentation site, which had reached for an unlayered stylesheet override: that reaches every spine in the app rather than the one call that wants it, and it wins only because Tailwind v4 emits its utilities into a layer. Null keeps the 1rem that shipped, so no existing call site moves.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "expand",
                    "default": "'hover'",
                    "default_normalized": "'hover'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "offset",
                    "default": "'6rem'",
                    "default_normalized": "'6rem'",
                    "type_hint": null,
                    "comment": "NOT the distance from the edge — that is `edgeOffset` above. This is the scroll/observer offset the plugin measures a section's arrival against.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "hideBelow",
                    "default": "'md'",
                    "default_normalized": "'md'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "numbered",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "fillSections",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "sectionEvents",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "backToTop",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "boundary",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`boundary` — null (default) = viewport-pinned via Tailwind `fixed`. `'container'` = scoped to the nearest positioned ancestor via Tailwind `absolute`. Use `'container'` when embedding the spine inside a contained reading surface (a modal body, a sidebar pane, a docs preview frame) so it doesn't escape to the outer viewport.",
                    "examples": [],
                    "values": [
                        "container",
                        "\u003Ccss-selector-string\u003E"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "filter",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "reading-toc",
            "tag": "\u003Cx-wirekit::reading-toc\u003E",
            "category": "Display",
            "description": "Horizontal sticky-strip TOC for marketing landing pages",
            "docs_url": null,
            "props": [
                {
                    "name": "target",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "levels",
                    "default": "'2'",
                    "default_normalized": "'2'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "position",
                    "default": "'top'",
                    "default_normalized": "'top'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "offset",
                    "default": "'0'",
                    "default_normalized": "'0'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "hideBelow",
                    "default": "'sm'",
                    "default_normalized": "'sm'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "flush",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "`flush` — when true, the strip runs viewport-edge-to-viewport-edge: zero horizontal padding on the nav AND the inner list AND the first / last link. The strip's chrome (background + bottom border) and the visible \"Features\" / \"Pricing\" / \"…\" text both run flush to the viewport boundary. Use when the TOC sits below an edge-to-edge marketing-page chrome (brand-bar with no `padding=\"lg\"` setting, or sandwiched between a hero and the article body). The hover-state background keeps its internal padding on the opposite edge so the rounded background still has breathing room around the rendered text. Default `false` keeps backward-compatible rendering with every link symmetrically padded.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "replay-button",
            "tag": "\u003Cx-wirekit::replay-button\u003E",
            "category": "Display",
            "description": "Re-mount the closest [data-replay-target] ancestor — companion to the `data-replayable` animation contract",
            "docs_url": "https://docs.wirekit.app/components/replay-button",
            "props": [
                {
                    "name": "label",
                    "default": "__('wirekit::Replay')",
                    "default_normalized": "__('wirekit::Replay')",
                    "type_hint": null,
                    "comment": "Accessible label for the button. Default is the well-known \"Replay\" verb so screen readers announce a clear affordance.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "target",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional explicit data-replay-target selector when the closest ancestor isn't the right re-mount root. Pass a CSS selector and the click handler walks up via $el.closest(selector) instead.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "scroll-area",
            "tag": "\u003Cx-wirekit::scroll-area\u003E",
            "category": "Display",
            "description": "Scrollable content area with styled scrollbar",
            "docs_url": "https://docs.wirekit.app/components/scroll-area",
            "props": [
                {
                    "name": "orientation",
                    "default": "'vertical'",
                    "default_normalized": "'vertical'",
                    "type_hint": null,
                    "comment": "vertical | horizontal | both",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "maxHeight",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "fade",
                    "default": "config('wirekit.components.scroll-area.fade', false)",
                    "default_normalized": "config('wirekit.components.scroll-area.fade', false)",
                    "type_hint": null,
                    "comment": "Edge fade: false (none) | 'both' | 'start' | 'end' | 'auto'. Masks the overflow edge(s) along the scroll axis so the content itself dissolves into the background — a background-agnostic \"there's more to scroll\" hint (mask-image, not a colored overlay). Removed on :focus-within so a keyboard-focused child near an edge is never clipped by the mask. The named edges are pure CSS and unconditional, which is also their limit: they fade an edge the content does not continue past — at the very top, at the very bottom, and on an area whose content fits and cannot scroll at all. 'auto' opts into an Alpine plugin that measures instead and fades only where there really is more. Without JavaScript it renders no mask, which is the right way round: a missing hint beats dissolved text.",
                    "examples": [],
                    "values": [
                        "both",
                        "start",
                        "end",
                        "auto"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the scroll region, and the switch that makes it a LANDMARK. `role=\"region\"` plus a name is a landmark, so ten unnamed scroll areas on one page were ten rotor entries all called \"Scrollable content\" — axe reports it as `landmark-unique`, and the name meant to tell them apart is what made them identical. Without a name the element keeps `tabindex=\"0\"` and no role: still keyboard-reachable (WCAG 2.1.1), just deliberately not a destination. Name it after the CONTENT (\"Release notes\"), never after the mechanism.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "segmented-control",
            "tag": "\u003Cx-wirekit::segmented-control\u003E",
            "category": "Display",
            "description": "Segmented toggle control",
            "docs_url": "https://docs.wirekit.app/components/segmented-control",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "error",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "`error` was undeclared while `label` was not, so `:error` on this control landed in the attribute bag and rendered as a stray HTML attribute — a validation message the developer wrote, silently not shown, on a control that is part of forms.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "announceError",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A11y: render the error message in a polite live region by default so a server-side validation error that appears after submit (when focus is elsewhere) is announced. Mirrors the input component. Set false to opt out — an app that runs its OWN error summary would otherwise double-announce here.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hint",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "Livewire method to call optimistically. The segment moves immediately and is put back if the call fails. Absent -\u003E this component renders exactly as it did before, down to the byte. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "options",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.segmented-control.size', 'md')",
                    "default_normalized": "config('wirekit.components.segmented-control.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "disabled",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Disable the whole control: aria-disabled on the radiogroup + each segment, the buttons become non-interactive, and the group dims via --opacity-wk-disabled.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "skeleton",
            "tag": "\u003Cx-wirekit::skeleton\u003E",
            "category": "Display",
            "description": "Loading placeholder skeleton",
            "docs_url": "https://docs.wirekit.app/components/skeleton",
            "props": [
                {
                    "name": "type",
                    "default": "'text'",
                    "default_normalized": "'text'",
                    "type_hint": null,
                    "comment": "text | avatar | card | custom",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "lines",
                    "default": "3",
                    "default_normalized": "3",
                    "type_hint": null,
                    "comment": "for type=text",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "animation",
                    "default": "config('wirekit.components.skeleton.animation', 'shimmer')",
                    "default_normalized": "config('wirekit.components.skeleton.animation', 'shimmer')",
                    "type_hint": null,
                    "comment": "Animation mode: shimmer (gradient sweep, default) · pulse (opacity fade, lighter on the GPU) · none (static placeholder, no animation).",
                    "examples": [],
                    "values": [
                        "shimmer",
                        "pulse",
                        "none"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "shimmer",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "legacy bool — false → pulse (kept for back-compat)",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "skeleton.avatar",
                    "tag": "\u003Cx-wirekit::skeleton.avatar\u003E",
                    "props": [
                        {
                            "name": "animation",
                            "default": "config('wirekit.components.skeleton.animation', 'shimmer')",
                            "default_normalized": "config('wirekit.components.skeleton.animation', 'shimmer')",
                            "type_hint": null,
                            "comment": "shimmer | pulse | none",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "shimmer",
                            "default": "true",
                            "default_normalized": "true",
                            "type_hint": null,
                            "comment": "legacy bool — false → pulse (see skeleton.blade.php)",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "skeleton.card",
                    "tag": "\u003Cx-wirekit::skeleton.card\u003E",
                    "props": [
                        {
                            "name": "animation",
                            "default": "config('wirekit.components.skeleton.animation', 'shimmer')",
                            "default_normalized": "config('wirekit.components.skeleton.animation', 'shimmer')",
                            "type_hint": null,
                            "comment": "shimmer | pulse | none",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "shimmer",
                            "default": "true",
                            "default_normalized": "true",
                            "type_hint": null,
                            "comment": "legacy bool — false → pulse (see skeleton.blade.php)",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "skeleton.table",
                    "tag": "\u003Cx-wirekit::skeleton.table\u003E",
                    "props": [
                        {
                            "name": "rows",
                            "default": "5",
                            "default_normalized": "5",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "cols",
                            "default": "4",
                            "default_normalized": "4",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "animation",
                            "default": "config('wirekit.components.skeleton.animation', 'shimmer')",
                            "default_normalized": "config('wirekit.components.skeleton.animation', 'shimmer')",
                            "type_hint": null,
                            "comment": "shimmer | pulse | none",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "shimmer",
                            "default": "true",
                            "default_normalized": "true",
                            "type_hint": null,
                            "comment": "legacy bool — false → pulse (see skeleton.blade.php)",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "skeleton.text",
                    "tag": "\u003Cx-wirekit::skeleton.text\u003E",
                    "props": [
                        {
                            "name": "lines",
                            "default": "3",
                            "default_normalized": "3",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "int"
                        },
                        {
                            "name": "animation",
                            "default": "config('wirekit.components.skeleton.animation', 'shimmer')",
                            "default_normalized": "config('wirekit.components.skeleton.animation', 'shimmer')",
                            "type_hint": null,
                            "comment": "shimmer | pulse | none",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "shimmer",
                            "default": "true",
                            "default_normalized": "true",
                            "type_hint": null,
                            "comment": "legacy bool — false → pulse (see skeleton.blade.php)",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "spinner",
            "tag": "\u003Cx-wirekit::spinner\u003E",
            "category": "Display",
            "description": "Accessible loading spinner (size + semantic intent, role=status)",
            "docs_url": "https://docs.wirekit.app/components/spinner",
            "props": [
                {
                    "name": "size",
                    "default": "config('wirekit.components.spinner.size', 'md')",
                    "default_normalized": "config('wirekit.components.spinner.size', 'md')",
                    "type_hint": null,
                    "comment": "Visual size of the spinner glyph.",
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "intent",
                    "default": "config('wirekit.components.spinner.intent', null)",
                    "default_normalized": "config('wirekit.components.spinner.intent', null)",
                    "type_hint": null,
                    "comment": "Optional semantic color. Default (null) inherits the surrounding text color via currentColor, so a spinner drops into a button / badge / any text context and matches. Set to a semantic intent for a standalone colored indicator.",
                    "examples": [],
                    "values": [
                        "accent",
                        "primary",
                        "info",
                        "success",
                        "warning",
                        "danger",
                        "neutral"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "label",
                    "default": "__('wirekit::Loading')",
                    "default_normalized": "__('wirekit::Loading')",
                    "type_hint": null,
                    "comment": "Screen-reader accessible name announced via the role=\"status\" live region.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "shimmer",
            "tag": "\u003Cx-wirekit::shimmer\u003E",
            "category": "Display",
            "description": "Animated text-glyph shimmer for live/streaming status (background-clip:text, Livewire :active-bindable)",
            "docs_url": "https://docs.wirekit.app/components/shimmer",
            "props": [
                {
                    "name": "active",
                    "default": "config('wirekit.components.shimmer.active', true)",
                    "default_normalized": "config('wirekit.components.shimmer.active', true)",
                    "type_hint": null,
                    "comment": "Whether the shimmer sweep animates across the text glyphs. Bind it to a Livewire property — :active=\"$isStreaming\" — to run the effect ONLY while streaming / loading and settle to plain text when done. This is the Livewire-native differentiator: the React-only equivalents toggle the effect by conditionally rendering the class; here the server drives it.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "as",
                    "default": "'span'",
                    "default_normalized": "'span'",
                    "type_hint": null,
                    "comment": "The wrapper tag. Defaults to an inline \u003Cspan\u003E so a shimmer drops into a sentence (\"Generating response…\"); use as=\"div\"/\"p\" for block text.",
                    "examples": [],
                    "values": [
                        "span",
                        "div",
                        "p",
                        "strong",
                        "em"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "duration",
                    "default": "config('wirekit.components.shimmer.duration', null)",
                    "default_normalized": "config('wirekit.components.shimmer.duration', null)",
                    "type_hint": null,
                    "comment": "Animation duration — any CSS \u003Ctime\u003E. Overrides the --shimmer-wk-duration token for THIS instance only (slower = calmer, faster = more urgent).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "chart-mixed",
            "tag": "\u003Cx-wirekit::chart-mixed\u003E",
            "category": "Display",
            "description": "Multi-type / multi-axis chart (per-dataset type field, dual y-axis)",
            "docs_url": "https://docs.wirekit.app/components/chart-mixed",
            "props": [
                {
                    "name": "labels",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "datasets",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "options",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "height",
                    "default": "'380px'",
                    "default_normalized": "'380px'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "wireStream",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Pass-through props that flow into the underlying class-based chart delegate. Without these declared here, attribute-bag would NOT carry them onto the inner chart — the chart-mixed wrapper is anonymous Blade, so attributes only flow where explicitly bound. Each prop mirrors the Chart class constructor (src/Components/Chart.php).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "wireStreamMode",
                    "default": "'strict'",
                    "default_normalized": "'strict'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "wireStreamCap",
                    "default": "100",
                    "default_normalized": "100",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "annotations",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "inline",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "replayable",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "library",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "sparkline",
            "tag": "\u003Cx-wirekit::sparkline\u003E",
            "category": "Display",
            "description": "Inline trend sparkline (axis-less line/area chart)",
            "docs_url": "https://docs.wirekit.app/components/sparkline",
            "props": [
                {
                    "name": "data",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "trend",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "inline",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "height",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "library",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Per-instance chart-library override pass-through. See the `library` prop on src/Components/Chart.php for full semantics. Without explicit declaration here the prop would NOT reach the inner chart — sparkline is an anonymous Blade wrapper, so attribute-bag flow is opt-in per prop.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "spine-aware",
            "tag": "\u003Cx-wirekit::spine-aware\u003E",
            "category": "Layout",
            "description": "Opt-in wrapper that joins the page-edge content spine via WireKit::spinePadding()",
            "docs_url": "https://docs.wirekit.app/components/spine-aware",
            "props": [
                {
                    "name": "tier",
                    "default": "'lg'",
                    "default_normalized": "'lg'",
                    "type_hint": null,
                    "comment": "`tier` — which `--padding-wk-x-*` token to read. Default `lg` (the canonical page-edge spine). Pass `sm` / `md` / `xl` for a different inline-padding tier. The spine-participant convention applies to the `lg` tier — other tiers are valid but produce a visually-distinct left edge from brand-bar / main / footer.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "stage-card",
            "tag": "\u003Cx-wirekit::stage-card\u003E",
            "category": "Display",
            "description": "Pipeline / kanban / roadmap stage card with intent left-stripe, count pill, and optional progress",
            "docs_url": "https://docs.wirekit.app/components/stage-card",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Visible stage title (e.g. \"In progress\", \"Q3 2026\", \"Backlog\").",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "intent",
                    "default": "'neutral'",
                    "default_normalized": "'neutral'",
                    "type_hint": null,
                    "comment": "Semantic color for the intent-tinted border + body. primary | success | warning | danger | info | neutral.",
                    "examples": [],
                    "values": [
                        "primary",
                        "accent",
                        "success",
                        "warning",
                        "danger",
                        "info",
                        "neutral"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "count",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional item count rendered as a pill in the header.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "progress",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional 0..100 completion percentage rendered as a thin progress bar.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "stat",
            "tag": "\u003Cx-wirekit::stat\u003E",
            "category": "Display",
            "description": "Single statistic display",
            "docs_url": "https://docs.wirekit.app/components/stat",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "change",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "trend",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "'up' | 'down' | 'neutral' | null",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "icon",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "description",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "citation",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "animate",
                    "default": "config('wirekit.components.stat.animate', false)",
                    "default_normalized": "config('wirekit.components.stat.animate', false)",
                    "type_hint": null,
                    "comment": "Opt-in counter animation. When true, the value text is wrapped in an Alpine x-data=\"wirekitStatAnimate\" handler that animates 0 → value over 1.2s once the stat scrolls into view. Respects prefers-reduced-motion (snaps to value, no animation).",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "descriptionDeferred",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Description animation Option A — defer fade-in. When true AND animate=true, the description span is hidden via x-show while the counter runs (~1.2s) and fades in once the animation settles. Mutually exclusive with descriptionAnimate.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "descriptionAnimate",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Description animation Option C — synchronous color count-up. When true AND animate=true, the description text color interpolates from --color-wk-text-muted → --color-wk-text on the same 1.2s timeline as the value. Mutually exclusive with descriptionDeferred.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "animateIn",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional reveal animation when stat scrolls into view (separate from the value count-up `animate` prop). Null = no reveal (default).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "intent",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "KPI-tile chrome: when set, the stat gains an intent-colored 4-sided border + a faint intent-tinted body — the pattern dashboard blueprints hand-rolled per tile. null = the existing plain card surface, unchanged. primary | success | warning | danger | info | neutral.",
                    "examples": [],
                    "values": [
                        "primary",
                        "accent",
                        "success",
                        "warning",
                        "danger",
                        "info",
                        "neutral"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "iconSlot",
                    "required": false
                },
                {
                    "name": "sparkline",
                    "required": false
                },
                {
                    "name": "progress",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "stats",
            "tag": "\u003Cx-wirekit::stats\u003E",
            "category": "Display",
            "description": "Statistics group container",
            "docs_url": "https://docs.wirekit.app/components/stats",
            "props": [
                {
                    "name": "cols",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "stagger",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Cascade entrance animations across direct children. null = no stagger (default), true = 75ms step, int = custom ms step.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "step-marker",
            "tag": "\u003Cx-wirekit::step-marker\u003E",
            "category": "Display",
            "description": "Numbered step chip — a filled square-cornered marker for onboarding and how-to sequences",
            "docs_url": "https://docs.wirekit.app/components/step-marker",
            "props": [
                {
                    "name": "intent",
                    "default": "config('wirekit.components.step-marker.intent', 'neutral')",
                    "default_normalized": "config('wirekit.components.step-marker.intent', 'neutral')",
                    "type_hint": null,
                    "comment": "Color role. Same vocabulary as badge / button, so a call site that knows one knows this.",
                    "examples": [],
                    "values": [
                        "primary",
                        "accent",
                        "success",
                        "warning",
                        "danger",
                        "info",
                        "neutral"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.step-marker.size', 'md')",
                    "default_normalized": "config('wirekit.components.step-marker.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "status-matrix",
            "tag": "\u003Cx-wirekit::status-matrix\u003E",
            "category": "Display",
            "description": "2D grid of typed status cells (tristate / toggle / status / heat) with sticky headers",
            "docs_url": "https://docs.wirekit.app/components/status-matrix",
            "props": [
                {
                    "name": "emptyText",
                    "default": "__('wirekit::Nothing here yet')",
                    "default_normalized": "__('wirekit::Nothing here yet')",
                    "type_hint": null,
                    "comment": "The empty state. `empty` REPLACES the body rather than sitting beside it: the screen a new user sees FIRST is the one with no data, and a single muted sentence can only say that nothing is here — it cannot say what to do about it, which is the whole job of that screen. `emptyText` is the default, so a caller that does not care changes nothing. Same shape as data-table, which is where the reasoning was first written down.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "rows",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "[{key,label}] — the matrix rows (left axis)",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "columns",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "[{key,label}] — the matrix columns (top axis)",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "cells",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "value map: [\"rowKey:colKey\" =\u003E value] OR [rowKey =\u003E [colKey =\u003E value]]",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "cellType",
                    "default": "config('wirekit.components.status-matrix.cell-type', 'status')",
                    "default_normalized": "config('wirekit.components.status-matrix.cell-type', 'status')",
                    "type_hint": null,
                    "comment": "tristate | toggle | status | heat",
                    "examples": [],
                    "values": [
                        "tristate",
                        "toggle",
                        "status",
                        "heat"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "editable",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "tristate / toggle become interactive",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "cornerLabel",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": "top-left header cell label (the row-axis name)",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "ariaLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the grid, and the switch that makes the scroll wrapper a LANDMARK. Two elements read this prop, and they treat it differently on purpose. The inner `\u003Ctable\u003E` is ALWAYS named — a table with no accessible name is a worse outcome than a duplicated region, so the fallback below survives for it. The outer scroll wrapper only becomes `role=\"region\"` when the CALLER named it: unnamed, three matrices on one page were three rotor entries called \"Status matrix\" (axe: `landmark-unique`).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "hidden-input name for form submission (editable)",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "heatFrom",
                    "default": "'var(--color-wk-warning)'",
                    "default_normalized": "'var(--color-wk-warning)'",
                    "type_hint": null,
                    "comment": "low end (cold)",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "heatTo",
                    "default": "'var(--color-wk-danger)'",
                    "default_normalized": "'var(--color-wk-danger)'",
                    "type_hint": null,
                    "comment": "high end (hot)",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "heatMin",
                    "default": "0",
                    "default_normalized": "0",
                    "type_hint": null,
                    "comment": "heat scale lower bound",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "heatMax",
                    "default": "100",
                    "default_normalized": "100",
                    "type_hint": null,
                    "comment": "heat scale upper bound",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "heatUnit",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": "suffix on heat value labels (e.g. '%')",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "legend",
                    "default": "config('wirekit.components.status-matrix.legend', true)",
                    "default_normalized": "config('wirekit.components.status-matrix.legend', true)",
                    "type_hint": null,
                    "comment": "render the cell-type legend",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "empty",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "status-tiles",
            "tag": "\u003Cx-wirekit::status-tiles\u003E",
            "category": "Display",
            "description": "N entities as colored status tiles, one glance — a fleet light with optional legend and colorblind-safe status icons",
            "docs_url": "https://docs.wirekit.app/components/status-tiles",
            "props": [
                {
                    "name": "emptyText",
                    "default": "__('wirekit::Nothing here yet')",
                    "default_normalized": "__('wirekit::Nothing here yet')",
                    "type_hint": null,
                    "comment": "The empty state. `empty` REPLACES the body rather than sitting beside it: the screen a new user sees FIRST is the one with no data, and a single muted sentence can only say that nothing is here — it cannot say what to do about it, which is the whole job of that screen. `emptyText` is the default, so a caller that does not care changes nothing. Same shape as data-table, which is where the reasoning was first written down.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "items",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The fleet: a list of entities to render as status tiles. Each entry: ['key' =\u003E 'app-1', 'label' =\u003E __('wirekit::shop.example'), 'intent' =\u003E 'danger', 'href' =\u003E '…', 'meta' =\u003E '2 issues'] intent ∈ success | warning | danger | info | neutral (anything else → neutral). 'href' makes the tile a keyboard-operable link; 'meta' is an optional caption.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "legend",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Show a count-per-intent legend above the grid (only intents present are listed).",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "columns",
                    "default": "'2 sm:3 md:4 lg:6'",
                    "default_normalized": "'2 sm:3 md:4 lg:6'",
                    "type_hint": null,
                    "comment": "Responsive grid column spec, forwarded verbatim to the grid component (never interpolated here — the literal-class safelist lives in grid).",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "gap",
                    "default": "'sm'",
                    "default_normalized": "'sm'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "showStatus",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Promote the status word from the screen-reader-only span into a visible, intent-tinted caption on every tile. Off by default so existing tiles are unchanged.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "wrapMeta",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Let the caption wrap instead of clamping it to one line. Off by default, and that default is load-bearing rather than caution: a wrapping caption grows the whole grid row, so flipping it for everyone would move every dashboard that uses this. On for the case the clamp destroys — when the caption IS the message (\"Used disk space: 87% on /var\") rather than a two-word count.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "empty",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "stream",
            "tag": "\u003Cx-wirekit::stream\u003E",
            "category": "Display",
            "description": "Streaming text output (SSE) with correct live-region a11y, reduced-motion buffering, and defined abort / error states",
            "docs_url": "https://docs.wirekit.app/components/stream",
            "props": [
                {
                    "name": "url",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The Server-Sent Events endpoint to stream from. Null → the component stays idle (seed it with `initial-text` and drive it from your own controls).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "eventName",
                    "default": "'message'",
                    "default_normalized": "'message'",
                    "type_hint": null,
                    "comment": "SSE event name to listen for, and the payload that ends the stream.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "doneSignal",
                    "default": "'[DONE]'",
                    "default_normalized": "'[DONE]'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "announce",
                    "default": "'result'",
                    "default_normalized": "'result'",
                    "type_hint": null,
                    "comment": "How the result is announced to assistive tech once the stream settles: 'result' (default) — announce the final text once. 'status'           — announce only \"Response ready\". 'none'             — announce nothing, and render NO live region. 'none' exists for one situation and is wrong everywhere else: an application that already has its own status region for this response. Two regions announcing the same completion is not twice the accessibility — a screen-reader user hears it twice and cannot tell which one is the real one. Pair it with the `output` slot, which replaces the visible block for the same reason. If you use it and do NOT announce completion yourself, the response finishes silently for anyone not watching the screen. That is the trade, stated rather than buried: this prop hands the announcement contract to the caller, it does not delete it.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "autoStart",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Open the stream on init. Set false to start it from your own control.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "initialText",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Seed text — resume a completed response (SSR) or show a static example.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "source",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Where the tokens come from: 'sse' (default) — the browser's EventSource. GET-only and body-less. 'fetch'         — POST (or any method) and read the response body. The shape LLM APIs use, because the request IS the payload: prompt, options and model belong in a body, not a URL. 'manual'        — no transport at all. Feed the component yourself with push()/finish()/fail() or the wirekit-stream-* events, e.g. from Laravel's own Reverb/Echo WebSocket stack.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "method",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "fetch mode only — request shape.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "body",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "headers",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Names this stream so the wirekit-stream-* events can address one of several on the same page (a pane per voice).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "simulate",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Simulate mode: stream THIS text token-by-token from a local timer, with no SSE endpoint. Drives a live-looking demo (and a typewriter effect), and opts the component into the docs \"↻ Replay\" affordance so a reader can re-watch it.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "simulateSpeed",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Milliseconds per token in simulate mode (default 55).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "startMessage",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "What the screen reader is told at each turn of the state machine. Each defaults to the shipped catalog, so an application that publishes the lang files gets its own language with no prop at all — these exist for the copy that differs per surface (\"Translating…\" rather than \"Generating response…\"). The failure ones were unreachable: the announcement and all five reasons were literals in the JavaScript, so every failure spoke English no matter what language the rest of the interface was in — in the one moment the reader most needs to understand what happened.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "readyMessage",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "stoppedMessage",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "failedMessage",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "output",
                    "required": false
                },
                {
                    "name": "error",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "swap",
            "tag": "\u003Cx-wirekit::swap\u003E",
            "category": "Display",
            "description": "Two-state icon primitive — fade (crossfade), rotate or flip between two children",
            "docs_url": "https://docs.wirekit.app/components/swap",
            "props": [
                {
                    "name": "expression",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "An Alpine expression naming the state, e.g. expression=\"isDark\". Use this whenever the swap has to react to something on the client — which is nearly always, since a swap that cannot change is just an icon. It exists because `active` alone CANNOT work here: `active` is resolved in PHP at render time, so the swap would be frozen at whatever the server thought and never move again. That is not a hypothetical — it is the bug this component shipped with for exactly one afternoon.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "active",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Static state, for a swap the server already knows the answer to and that never changes on the client.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "effect",
                    "default": "config('wirekit.components.swap.effect', 'fade')",
                    "default_normalized": "config('wirekit.components.swap.effect', 'fade')",
                    "type_hint": null,
                    "comment": "How the two states trade places. 'fade'   — crossfade (the quiet default) 'rotate' — half a turn, for a sun/moon or a chevron 'flip'   — a card flip",
                    "examples": [],
                    "values": [
                        "fade",
                        "rotate",
                        "flip"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "on",
                    "required": false
                },
                {
                    "name": "off",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "table",
            "tag": "\u003Cx-wirekit::table\u003E",
            "category": "Display",
            "description": "Data table with sorting and styling options",
            "docs_url": "https://docs.wirekit.app/components/table",
            "props": [
                {
                    "name": "striped",
                    "default": "config('wirekit.components.table.striped', false)",
                    "default_normalized": "config('wirekit.components.table.striped', false)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "hoverable",
                    "default": "config('wirekit.components.table.hoverable', false)",
                    "default_normalized": "config('wirekit.components.table.hoverable', false)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "compact",
                    "default": "config('wirekit.components.table.compact', false)",
                    "default_normalized": "config('wirekit.components.table.compact', false)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "responsive",
                    "default": "config('wirekit.components.table.responsive', true)",
                    "default_normalized": "config('wirekit.components.table.responsive', true)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "stickyHeader",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "stickyHeaderMax",
                    "default": "config('wirekit.components.table.sticky-header-max', '24rem')",
                    "default_normalized": "config('wirekit.components.table.sticky-header-max', '24rem')",
                    "type_hint": null,
                    "comment": "How tall the scroll-confined body may get before it scrolls. `stickyHeader` needs a bounded height to mean anything at all — the wrapper already carries `overflow-x: auto`, which makes it a scroll container on BOTH axes, so a `sticky` heading measures itself against a box that never scrolls vertically and therefore never sticks. The height is the CONDITION, not the decoration. It was a fixed `24rem` until a reader with a five-row table reported the obvious consequence: a box that reserves 24rem, never scrolls, and is visibly worse than the plain table it replaced. The default stays `24rem` so nothing that renders today moves; a viewport-relative value like `70vh` is what a table of unknown length wants, because the limit then simply never applies to the short case. Any CSS length, taken exactly as written. The value reaches the element as an inline max-height rather than as a utility class, so it is not confined to the lengths a build has already seen — `calc(100vh - 4rem)` arrives with its spaces intact. A length the browser cannot parse is dropped like any other bad declaration, so an unusable value leaves no max-height rather than a wrong one. The reasoning is with the code below.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "stickyColumn",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "freeze the FIRST column while the rest scroll horizontally",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "alpineSort",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "enable client-side Alpine sorting (no Livewire needed)",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "tableLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the responsive scroll wrapper, and the switch that makes it a LANDMARK. The wrapper is keyboard-reachable either way (WCAG 2.1.1 — `tabindex=\"0\"` is unconditional); the role only joins it once there is a name worth navigating to. It used to fall back to \"Scrollable table\", which made every table on a page answer to the same rotor entry — axe reports that as `landmark-unique`. Name it after the DATA (\"Customer list\"), never after the widget.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "table.body",
                    "tag": "\u003Cx-wirekit::table.body\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "table.caption",
                    "tag": "\u003Cx-wirekit::table.caption\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "table.foot",
                    "tag": "\u003Cx-wirekit::table.foot\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "table.head",
                    "tag": "\u003Cx-wirekit::table.head\u003E",
                    "props": [
                        {
                            "name": "variant",
                            "default": "config('wirekit.components.table.head.variant', 'filled')",
                            "default_normalized": "config('wirekit.components.table.head.variant', 'filled')",
                            "type_hint": null,
                            "comment": "`flush` drops the fill and keeps everything else — the divider, the sticky rules, the spacing. The fill was painted unconditionally, so a table head that needed no background could only be reached by overriding the whole class string, which also discards the sticky behavior and the border a reader relies on. One opinion about one property should not cost the rest of the component.",
                            "examples": [],
                            "values": [
                                "filled",
                                "flush"
                            ],
                            "value_type": "string"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "table.row",
                    "tag": "\u003Cx-wirekit::table.row\u003E",
                    "props": [
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "table.td",
                    "tag": "\u003Cx-wirekit::table.td\u003E",
                    "props": [
                        {
                            "name": "align",
                            "default": "'left'",
                            "default_normalized": "'left'",
                            "type_hint": null,
                            "comment": "left | center | right",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "table.th",
                    "tag": "\u003Cx-wirekit::table.th\u003E",
                    "props": [
                        {
                            "name": "sortable",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "sortDirection",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "null | 'asc' | 'desc' — current sort state (Livewire mode)",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "column",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "column identifier for Alpine sort mode (pairs with table alpine-sort)",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "sortAction",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "Livewire-sort mode only: the wire:click method call for a keyboard-operable sort button, e.g. \"sortBy('name')\". When set, the header label + indicator are wrapped in a \u003Cbutton wire:click\u003E so the sort is reachable by keyboard (WCAG 2.1.1) — the plain \u003Cth\u003E click on a cursor-pointer cell is mouse-only. Null keeps today's static \u003Cspan\u003E (the developer supplies their own control via $attributes), so existing markup renders byte-identically. Ignored in Alpine-sort mode (the `column` prop already renders its own button model).",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "align",
                            "default": "'left'",
                            "default_normalized": "'left'",
                            "type_hint": null,
                            "comment": "left | center | right",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "headerScope",
                            "default": "'col'",
                            "default_normalized": "'col'",
                            "type_hint": null,
                            "comment": "HTML \u003Cth scope\u003E attribute — 'col' (default) for a column header, 'row' for a per-row header cell (WCAG 1.3.1: a row-header cell identifies its data row). Distinct from the `scope` prop above, which is WireKit's token-scope override — overloading that would break scoped theming for the 200+ components that share it.",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        }
                    ]
                }
            ]
        },
        {
            "name": "ticker",
            "tag": "\u003Cx-wirekit::ticker\u003E",
            "category": "Display",
            "description": "Compact label + value + delta widget for dashboards",
            "docs_url": "https://docs.wirekit.app/components/ticker",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "delta",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "deltaFormat",
                    "default": "'percent'",
                    "default_normalized": "'percent'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "intent",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "trend",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "trendLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Names the sparkline in the default slot. Opt-in, and null by default: a graphic that already carries its own name must not be given a second, worse one — see the block that renders the slot.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.ticker.size', 'md')",
                    "default_normalized": "config('wirekit.components.ticker.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "sm",
                        "md",
                        "lg"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "footer",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "testimonial",
            "tag": "\u003Cx-wirekit::testimonial\u003E",
            "category": "Marketing",
            "description": "Cited customer quote — figure/blockquote semantics, author, role, logo, optional rating",
            "docs_url": "https://docs.wirekit.app/components/testimonial",
            "props": [
                {
                    "name": "author",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": "Who said it. An unattributed testimonial is just marketing copy in quotation marks, so this carries the whole credibility of the block.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "role",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Their role / company (\"CTO, Acme\").",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "avatar",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Avatar image for the author. Without one, the author's initials are derived and rendered instead — never an empty gray circle.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "initials",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Override the derived initials (non-Latin names, mononyms, brand accounts).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "logo",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Company logo shown beside the attribution.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "logoAlt",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the logo. Leave null when the author is already named in text (the logo is then decoration and stays silent); pass it when the logo is the ONLY attribution.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "logoAspect",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Intrinsic aspect ratio of `$logo`, as `'width/height'` — e.g. `'3/1'`. Same reasoning as brand's `logoAspect`: the mark is `h-6 w-auto`, so the height is fixed and the width comes from the image. Until its bytes arrive there is nothing to derive that width from, and the attribution row re-flows when they land. The min-width floor below keeps the worst case at a square rather than at nothing.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "rating",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Optional star rating (0..5). Always read-only — a testimonial is a record, not an input.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "testimonial-grid",
            "tag": "\u003Cx-wirekit::testimonial-grid\u003E",
            "category": "Marketing",
            "description": "Responsive grid of testimonials, exposed as a labeled list",
            "docs_url": null,
            "props": [
                {
                    "name": "label",
                    "default": "config('wirekit.components.testimonial-grid.label') ?? __('wirekit::Testimonials')",
                    "default_normalized": "config('wirekit.components.testimonial-grid.label') ?? __('wirekit::Testimonials')",
                    "type_hint": null,
                    "comment": "Accessible name for the set of quotes.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "theme-controller",
            "tag": "\u003Cx-wirekit::theme-controller\u003E",
            "category": "Layout",
            "description": "Drop-in dark-mode control — button, switch, menu or system/light/dark select",
            "docs_url": "https://docs.wirekit.app/components/theme-controller",
            "props": [
                {
                    "name": "variant",
                    "default": "config('wirekit.components.theme-controller.variant', 'button')",
                    "default_normalized": "config('wirekit.components.theme-controller.variant', 'button')",
                    "type_hint": null,
                    "comment": "How the control looks. 'button' — an icon button that flips light/dark (the compact default) 'switch' — a labeled switch, for a settings row 'select' — System / Light / Dark in a native control 'menu'   — a trigger naming the mode that is on, with a menu of all three `select` and `menu` are the three-valued shapes: only they can say \"system\". A two-state control cannot, and that is not a gap to fill — it has to freeze the reader onto an explicit choice the moment they touch it, and then their machine going dark at sunset leaves this page behind.",
                    "examples": [],
                    "values": [
                        "button",
                        "switch",
                        "select",
                        "menu"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.theme-controller.size', 'md')",
                    "default_normalized": "config('wirekit.components.theme-controller.size', 'md')",
                    "type_hint": null,
                    "comment": "Button-variant chrome (ignored by switch/select/menu). size:    'sm' (32px) | 'md' (36px, default) — matches the button size scale surface: 'filled' (bordered, elevated — the default) | 'ghost' (borderless, transparent, muted) so the toggle sits flush next to surface=\"ghost\" size=\"sm\" buttons in a top bar.",
                    "examples": [],
                    "values": [
                        "sm",
                        "md"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "surface",
                    "default": "config('wirekit.components.theme-controller.surface', 'filled')",
                    "default_normalized": "config('wirekit.components.theme-controller.surface', 'filled')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "filled",
                        "ghost"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "label",
                    "default": "__('wirekit::Dark mode')",
                    "default_normalized": "__('wirekit::Dark mode')",
                    "type_hint": null,
                    "comment": "Accessible name. The control has no visible text in the button variant, so without this it announces as \"button\" and nothing else.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "hideLabel",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Render the switch/select label sr-only (kept as the control's accessible name) — for a header or toolbar where the surrounding chrome already says what the control is. The \u003Clabel\u003E WRAPS the control here, so the name is associated with the element rather than with the visible text and survives being taken off the screen. No-op on the button variant, which has no visible text at all. Mirrors input / select / textarea / combobox / checkbox `hideLabel`. On `menu` it hides something else, and the difference is worth knowing: there is no \u003Clabel\u003E and no `label` prop in play at all. What it takes off the screen is the mode NAME beside the trigger's glyph, leaving the icon alone — for a bar where the word is a line too wide. The trigger keeps its accessible name either way, because the name is that same word rendered sr-only rather than removed.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "options",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Wording for the three modes, used by the `select` and `menu` variants. Translated by default; pass your own to change the WORDS rather than just the language — an app may want \"Automatic / Day / Night\", which no locale file can express.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "iconOn",
                    "required": false
                },
                {
                    "name": "iconOff",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "timeline",
            "tag": "\u003Cx-wirekit::timeline\u003E",
            "category": "Display",
            "description": "Vertical timeline of events",
            "docs_url": "https://docs.wirekit.app/components/timeline",
            "props": [
                {
                    "name": "variant",
                    "default": "'default'",
                    "default_normalized": "'default'",
                    "type_hint": null,
                    "comment": "default | centered | compact",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "before",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "show dotted fade-in line above first item",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "after",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "show dotted fade-out line below last item",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "timeline.item",
                    "tag": "\u003Cx-wirekit::timeline.item\u003E",
                    "props": [
                        {
                            "name": "time",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "datetime",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "variant",
                            "default": "'default'",
                            "default_normalized": "'default'",
                            "type_hint": null,
                            "comment": "back-compat alias of `intent`",
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "intent",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "canonical color axis: default | success | warning | danger. null → falls back to `variant`",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "tree-view",
            "tag": "\u003Cx-wirekit::tree-view\u003E",
            "category": "Display",
            "description": "Hierarchical tree view",
            "docs_url": "https://docs.wirekit.app/components/tree-view",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Names the tree. A `role=\"tree\"` is announced by its name and nothing else.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": [
                {
                    "name": "tree-view.node",
                    "tag": "\u003Cx-wirekit::tree-view.node\u003E",
                    "props": [
                        {
                            "name": "label",
                            "default": "''",
                            "default_normalized": "''",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "string"
                        },
                        {
                            "name": "icon",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "expanded",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "selected",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "conversation",
            "tag": "\u003Cx-wirekit::conversation\u003E",
            "category": "Display",
            "description": "Stick-to-bottom chat transcript scroller — follow-output, unread jump-to-latest, and history anchor-preserve",
            "docs_url": "https://docs.wirekit.app/components/conversation",
            "props": [
                {
                    "name": "label",
                    "default": "__('wirekit::Conversation')",
                    "default_normalized": "__('wirekit::Conversation')",
                    "type_hint": null,
                    "comment": "Accessible name for the transcript log region.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "maxHeight",
                    "default": "config('wirekit.components.conversation.max-height', '24rem')",
                    "default_normalized": "config('wirekit.components.conversation.max-height', '24rem')",
                    "type_hint": null,
                    "comment": "Height cap of the scroll viewport. A transcript needs a bounded height — without one there is nothing to scroll and follow-output is meaningless.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "threshold",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "px tolerance for \"at bottom\". Null → the plugin default (24).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "footer",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "data-table",
            "tag": "\u003Cx-wirekit::data-table\u003E",
            "category": "Display",
            "description": "Client-mode data table with sort, search, selection, density, and column manager",
            "docs_url": "https://docs.wirekit.app/components/data-table",
            "props": [
                {
                    "name": "rows",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "row objects (client mode)",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "columns",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "[{key,label,sortable?,sortStart?,align?,cellType?,hrefKey?,intents?,subKey?,intentKey?,avatarKey?,prominence?}] cellType: text|number|badge|badges|code|link · intents: value -\u003E success|warning|danger|neutral hrefKey: for a link column, the ROW field holding the URL. A row without one reads as text. subKey / intentKey / avatarKey: the ROW names its second line, its intent, its avatar. prominence: strong|muted — how loud the column reads. Absent is the middle. sortStart: asc|desc — the direction of the column's first click. Absent is asc.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "rowKey",
                    "default": "'id'",
                    "default_normalized": "'id'",
                    "type_hint": null,
                    "comment": "unique id field for selection + morph keying",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "selectable",
                    "default": "config('wirekit.components.data-table.selectable', false)",
                    "default_normalized": "config('wirekit.components.data-table.selectable', false)",
                    "type_hint": null,
                    "comment": "per-row + header selection checkboxes",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "stickyColumn",
                    "default": "config('wirekit.components.data-table.sticky-column', false)",
                    "default_normalized": "config('wirekit.components.data-table.sticky-column', false)",
                    "type_hint": null,
                    "comment": "Freeze the first column while the rest scroll sideways. In an overview the first column NAMES the row, and on a phone it is the first thing a swipe takes away. With `selectable` BOTH leading columns freeze — the checkbox and the name — because a checkbox that scrolls out from under its own row is worse than one that never moved. The offset is knowable rather than measured: the selection column's width is set here, by this component, at `w-10`.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "searchable",
                    "default": "config('wirekit.components.data-table.searchable', false)",
                    "default_normalized": "config('wirekit.components.data-table.searchable', false)",
                    "type_hint": null,
                    "comment": "toolbar search box (client-side filter)",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "density",
                    "default": "config('wirekit.components.data-table.density', 'comfortable')",
                    "default_normalized": "config('wirekit.components.data-table.density', 'comfortable')",
                    "type_hint": null,
                    "comment": "comfortable | compact",
                    "examples": [],
                    "values": [
                        "comfortable",
                        "compact"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "columnManager",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "show/hide-columns dropdown",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "hidden",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "initially-hidden column keys",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "server",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "server-driven: stop local sort/filter, emit events only",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "sortKey",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The order the table starts in: a column key and a direction. In server mode, the order the server already applied, so `aria-sort` and the arrow describe the rows on screen. Without them every column read \"none\" over a sorted table, and a screen reader said so.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "sortDir",
                    "default": "'asc'",
                    "default_normalized": "'asc'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "search",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The filter the server applied, for a server-mode table. It fills the search field on the first render (a page opened as `?q=…` shows its filter) and whenever the server changes it on its own, such as a \"clear filters\" control. Null leaves the field to the reader.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "searchDebounce",
                    "default": "config('wirekit.components.data-table.search-debounce', 300)",
                    "default_normalized": "config('wirekit.components.data-table.search-debounce', 300)",
                    "type_hint": null,
                    "comment": "Milliseconds to wait after the last keystroke before announcing `search-change`. Only the OUTBOUND event waits. `x-model` still updates on every keystroke, so the client-side filter stays instant and the box never feels laggy — what this delays is the round trip a server-mode table makes, which was one request per CHARACTER. Typing an eight-letter name asked the application eight questions and threw away the first seven answers, each of them a query. Configurable because the right value is a property of the BACKEND, not of the table: a local index wants it short, a rate-limited third-party search wants it long. 0 disables the wait entirely, for a developer who throttles on their own side.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "searchPlaceholder",
                    "default": "__('wirekit::Search…')",
                    "default_normalized": "__('wirekit::Search…')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "emptyText",
                    "default": "__('wirekit::No results')",
                    "default_normalized": "__('wirekit::No results')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "loading",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "A wait the server declares. Server mode exists for datasets whose round trip is SLOW, and every sort click and every keystroke in the search field starts one — meanwhile the table keeps showing the previous page's rows with nothing to say a query is on its way. A sighted reader cannot tell a slow query from an ignored click, and a screen-reader user gets no WCAG 4.1.3 status until the rows change. The table marks itself busy for the round trips it starts (a sort, a search), from the moment the commit that carries one is sent until it comes back. This prop is for a wait the table cannot see: a server-side process the page is waiting on. A render that passes `true` holds the table busy until a render passes `false`.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "caption",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "accessible table caption / name",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "bulkActionsLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the bulk-action bar, and the switch that makes it a LANDMARK. Same rule as `caption` below the table: `role=\"region\"` plus a name is a landmark, and several tables on one page each emitted a bar called \"Bulk actions\" — one name across N rotor entries, which is what axe reports as `landmark-unique`. So the role waits for a name the CALLER chose. Nothing is lost without it: the bar is not a scroll region (no `overflow-*`, no `max-h-*`), so it needs no `tabindex` for WCAG 2.1.1, its controls are in the tab order on their own, and the selection count is announced through the `aria-live` span rather than through the landmark.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "hidden-input name mirroring the selected ids",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "toolbar",
                    "required": false
                },
                {
                    "name": "rowActions",
                    "required": false
                },
                {
                    "name": "empty",
                    "required": false
                },
                {
                    "name": "bulkActions",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "date-separator",
            "tag": "\u003Cx-wirekit::date-separator\u003E",
            "category": "Display",
            "description": "Horizontal divider with centered date label",
            "docs_url": "https://docs.wirekit.app/components/date-separator",
            "props": [
                {
                    "name": "date",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "variant",
                    "default": "'inline'",
                    "default_normalized": "'inline'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "inline",
                        "sticky"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "format",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "now",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "timezone",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "event-calendar",
            "tag": "\u003Cx-wirekit::event-calendar\u003E",
            "category": "Display",
            "description": "Scheduling calendar with month, week, and agenda views",
            "docs_url": "https://docs.wirekit.app/components/event-calendar",
            "props": [
                {
                    "name": "events",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "[{id,title,start,end?,allDay?,intent?}]",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "dayMarkers",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "[{date,label,type?,blocked?}] day-level holiday/working/note markers",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "selectableDays",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Day selection, opt-in. `selectableDays` makes each month day number a button that dispatches `wirekit:event-calendar-day-select` with the day (YYYY-MM-DD) and the ids of its events; `dayDetail` adds a built-in list of that day's events under the month grid and implies the first. Both default off: a button in every cell is a tab stop in every cell.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "dayDetail",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "filterable",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "One toggle per event `category`, above the views. Events without a category are never filtered. Off by default, and rendered only when the events carry two categories or more: a single chip filters nothing.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "view",
                    "default": "config('wirekit.components.event-calendar.view', 'month')",
                    "default_normalized": "config('wirekit.components.event-calendar.view', 'month')",
                    "type_hint": null,
                    "comment": "month | week | agenda",
                    "examples": [],
                    "values": [
                        "month",
                        "week",
                        "agenda"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "date",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "ISO date the calendar opens on (default today)",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "weekStartsOn",
                    "default": "config('wirekit.components.event-calendar.week-starts-on', 1)",
                    "default_normalized": "config('wirekit.components.event-calendar.week-starts-on', 1)",
                    "type_hint": null,
                    "comment": "0 Sun .. 1 Mon",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "locale",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "BCP-47 locale for every date and time the calendar prints. Null → the application locale, which is what the rest of the component is already written in. Its own prop for the one case the app locale cannot serve: a calendar showing a schedule that belongs to a different region than the page around it.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "ariaLabel",
                    "default": "__('wirekit::Calendar')",
                    "default_normalized": "__('wirekit::Calendar')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "weekLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Accessible name for the WEEK time-grid, and the switch that makes it a LANDMARK. Its own prop rather than a reuse of `ariaLabel`: that one names the whole calendar, and a region inheriting the widget's name announces the part as the whole. The grid's name was a hardcoded \"Week schedule\", so two calendars on a page produced two identical rotor entries (axe: `landmark-unique`). Unnamed, the grid keeps `tabindex=\"0\"` and no role — reachable per WCAG 2.1.1, deliberately not a destination.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "level",
                    "default": "2",
                    "default_normalized": "2",
                    "type_hint": null,
                    "comment": "Heading level for the title (1-6). Defaults to 2 — the calendar's period label — so nothing moves for a caller who never sets it. Set it to match the surrounding document outline: a component cannot know where in the page it sits, and a guessed level is worse than a chosen one. A skipped level is what `heading-order` reports, and that rule lives in axe's best-practice tag rather than the WCAG tags most suites run — so it is invisible to an axe sweep and visible in Lighthouse.",
                    "examples": [],
                    "values": [
                        "1",
                        "2",
                        "3",
                        "4",
                        "5",
                        "6"
                    ],
                    "value_type": "int"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "kanban",
            "tag": "\u003Cx-wirekit::kanban\u003E",
            "category": "Display",
            "description": "Horizontal scrollable board of status columns",
            "docs_url": "https://docs.wirekit.app/components/kanban",
            "props": [
                {
                    "name": "orientation",
                    "default": "'horizontal'",
                    "default_normalized": "'horizontal'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "horizontal",
                        "vertical"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "sortable",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "crossColumn",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Cards may move BETWEEN sortable columns: dragged onto another one, or moved with ArrowLeft/ArrowRight while lifted. Opt-in, because it changes what those two keys do on this board — without it they move a lifted card within its own column, which is what every board shipped so far has taught its users.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "kanban-column",
            "tag": "\u003Cx-wirekit::kanban-column\u003E",
            "category": "Display",
            "description": "Single column within a kanban board",
            "docs_url": null,
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "count",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "intent",
                    "default": "'neutral'",
                    "default_normalized": "'neutral'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "neutral",
                        "primary",
                        "success",
                        "warning",
                        "danger",
                        "info"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "limit",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "sortable",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "columnId",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "What the application calls this column when a card moves between columns on a `cross-column` board: it arrives as `from.column` / `to.column` in `wirekit:sortable:moved`. Without one the column is named by its position among the board's sortable columns — honest, and only usable by a server that addresses columns positionally, the same rule a card without a `data-sortable-id` follows.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "header",
                    "required": false
                },
                {
                    "name": "footer",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "message",
            "tag": "\u003Cx-wirekit::message\u003E",
            "category": "Display",
            "description": "Chat/comment message bubble with author, timestamp, and delivery status",
            "docs_url": "https://docs.wirekit.app/components/message",
            "props": [
                {
                    "name": "author",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "timestamp",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "side",
                    "default": "'left'",
                    "default_normalized": "'left'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "left",
                        "right"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "intent",
                    "default": "'neutral'",
                    "default_normalized": "'neutral'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "neutral",
                        "primary",
                        "info",
                        "success",
                        "warning",
                        "danger"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "edited",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "status",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Delivery ladder for an outgoing message: sending | sent | delivered | read | failed. Null (default) renders nothing — most threads only track status on the messages the current user sent.",
                    "examples": [],
                    "values": [
                        "sending",
                        "sent",
                        "delivered",
                        "read",
                        "failed"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "statusTime",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "When the status was reached (Carbon|string). Given → the status glyph carries a tooltip AND its accessible text reads \"Read at 9:15 AM\" instead of just \"Read\". Formatted with the same locale-aware short time as the message timestamp (or `timeFormat`).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "actionsReveal",
                    "default": "config('wirekit.components.message.actions-reveal', 'hover')",
                    "default_normalized": "config('wirekit.components.message.actions-reveal', 'hover')",
                    "type_hint": null,
                    "comment": "How the actions slot is revealed. 'hover' (default) shows it on hover OR keyboard focus; 'always' keeps it visible — the accessible path for touch (no hover) and for surfaces where the actions should always be reachable.",
                    "examples": [],
                    "values": [
                        "hover",
                        "always"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "timeFormat",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Carbon format string for the timestamp. Null (default) renders the locale-aware short time via isoFormat('LT') — \"9:15 PM\" for en (identical to the old hardcoded format), \"21:15\" for de and other 24h locales. Pass an explicit format (e.g. 'H:i') to override.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "reactions",
                    "required": false
                },
                {
                    "name": "attachments",
                    "required": false
                },
                {
                    "name": "actions",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "message-group",
            "tag": "\u003Cx-wirekit::message-group\u003E",
            "category": "Display",
            "description": "A run of messages from one sender, with the avatar and name printed once",
            "docs_url": "https://docs.wirekit.app/components/message-group",
            "props": [
                {
                    "name": "author",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The same shape `x-wirekit::message` takes: ['name' =\u003E …, 'avatar' =\u003E …, 'role' =\u003E …]. The group prints it ONCE and the messages inside stop repeating it — that is the whole component. Each message keeps its own timestamp: a run shares a sender, not a moment. ⚠️ No angle brackets around a component name in this file, here or anywhere else in it. Blade's tag compiler runs over the raw source before anything understands PHP comments, so a tag written inside one is compiled as a tag — which leaves the view with a `$component-\u003EwithAttributes()` call and no component, and the error names an undefined variable rather than the comment that caused it.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "side",
                    "default": "'left'",
                    "default_normalized": "'left'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "left",
                        "right"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                },
                {
                    "name": "component",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "message-typing",
            "tag": "\u003Cx-wirekit::message-typing\u003E",
            "category": "Display",
            "description": "Animated three-dot typing indicator bubble for chat threads",
            "docs_url": "https://docs.wirekit.app/components/message-typing",
            "props": [
                {
                    "name": "author",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Who is typing — used for the announcement (\"Ada is typing…\"). Null keeps it generic.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "side",
                    "default": "'left'",
                    "default_normalized": "'left'",
                    "type_hint": null,
                    "comment": "Side the bubble sits on, mirroring the message component's `side` prop.",
                    "examples": [],
                    "values": [
                        "left",
                        "right"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "announce",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Announce the typing state to assistive technology. Off by default: a transcript that announces every keystroke-driven typing flicker is unusable with a screen reader. Turn it on for a one-off \"assistant is working\" row.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "notification-center",
            "tag": "\u003Cx-wirekit::notification-center\u003E",
            "category": "Display",
            "description": "Bell trigger with unread badge and a grouped, realtime-capable notification panel",
            "docs_url": "https://docs.wirekit.app/components/notification-center",
            "props": [
                {
                    "name": "items",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "[{id,type,title,body?,timeLabel?,read?,group?,href?,actionLabel?}]",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "groupBy",
                    "default": "config('wirekit.components.notification-center.group-by', 'none')",
                    "default_normalized": "config('wirekit.components.notification-center.group-by', 'none')",
                    "type_hint": null,
                    "comment": "none | time | type ('time' groups by each item's `group` label)",
                    "examples": [],
                    "values": [
                        "none",
                        "time",
                        "type"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "title",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Panel heading, bell name — and the switch that makes the list a LANDMARK. Four elements read this and only one of them is gated on it. The trigger, the panel and the heading are ALWAYS named, so the fallback below survives for them; the scrolling list becomes `role=\"region\"` only when the caller supplied a title, because the derived \"Notifications list\" was identical on every unnamed center on a page (axe: `landmark-unique`).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "filters",
                    "default": "config('wirekit.components.notification-center.filters', false)",
                    "default_normalized": "config('wirekit.components.notification-center.filters', false)",
                    "type_hint": null,
                    "comment": "show type-filter tabs",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "realtimeEvent",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "window event name to listen for new items",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "open",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "start with the panel open (inline embeds / demos)",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "seeAllHref",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "footer \"see all\" link",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "seeAllLabel",
                    "default": "__('wirekit::See all')",
                    "default_normalized": "__('wirekit::See all')",
                    "type_hint": null,
                    "comment": "Both defaults resolve through the catalog, the way faq's `label` does. They were English literals, so a German application rendered a fully translated panel with an English footer link and an English empty state — the catalog that would have fixed it was already installed; the strings simply never asked.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "emptyText",
                    "default": "__(\"wirekit::You're all caught up\")",
                    "default_normalized": "__(\"wirekit::You're all caught up\")",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "hidden-input name mirroring the unread count",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "pricing-table",
            "tag": "\u003Cx-wirekit::pricing-table\u003E",
            "category": "Marketing",
            "description": "Responsive grid of pricing plans, exposed as a labeled list",
            "docs_url": "https://docs.wirekit.app/components/pricing-table",
            "props": [
                {
                    "name": "label",
                    "default": "config('wirekit.components.pricing-table.label') ?? __('wirekit::Pricing plans')",
                    "default_normalized": "config('wirekit.components.pricing-table.label') ?? __('wirekit::Pricing plans')",
                    "type_hint": null,
                    "comment": "Accessible name for the group of plans.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "intervals",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Billing intervals, as key =\u003E label, e.g. :intervals=\"['monthly' =\u003E 'Monthly', 'annual' =\u003E 'Annual']\". Given, the table renders a toggle above the plans and the tiers switch their interval-keyed `prices`. Omitted (the default), nothing changes and no toggle renders.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "intervalLabel",
                    "default": "__('wirekit::Billing interval')",
                    "default_normalized": "__('wirekit::Billing interval')",
                    "type_hint": null,
                    "comment": "Accessible name for the interval toggle.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "columns",
                    "default": "3",
                    "default_normalized": "3",
                    "type_hint": null,
                    "comment": "How many plans sit side by side at the widest breakpoint. Default keeps the historical 1 / 2 / 3 ladder; a 2-plan table would otherwise render a gappy three-column grid.",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "name",
                    "default": "'interval'",
                    "default_normalized": "'interval'",
                    "type_hint": null,
                    "comment": "Name of the hidden input the interval is written to, so the choice reaches a surrounding \u003Cform\u003E. Only rendered when intervals are given.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "interval",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "The interval as the SERVER sees it. Distinct from the first key of `intervals`, which is only the opening position: this one keeps arriving, so a checkout decided on the server can both read the choice and correct it.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "pricing-tier",
            "tag": "\u003Cx-wirekit::pricing-tier\u003E",
            "category": "Marketing",
            "description": "A single pricing plan — name, formatted amount, features, CTA, optional featured highlight",
            "docs_url": null,
            "props": [
                {
                    "name": "name",
                    "default": "''",
                    "default_normalized": "''",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "price",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Raw amount — formatted by the price component, so a plan never hard-codes a currency string.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "prices",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Interval-keyed amounts for a table that offers a billing toggle, e.g. :prices=\"['monthly' =\u003E 4900, 'annual' =\u003E 49000]\". Every amount is rendered and FORMATTED SERVER-SIDE; the surrounding pricing-table's toggle only switches which one is visible, so the currency/locale/minor-unit logic is never reimplemented in JavaScript. `price` still works on its own.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "currency",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "period",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "\"mo\", \"year\", \"seat/mo\" — rendered next to the amount.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "periods",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Per-interval period labels, e.g. :periods=\"['monthly' =\u003E 'mo', 'annual' =\u003E 'yr']. Falls back to `period` for any interval not listed.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "description",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Copy under the plan name.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "featured",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "The recommended plan. Highlighted with a badge AND a ring — never a tint alone (WCAG 1.4.1).",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "featuredLabel",
                    "default": "__('wirekit::Most popular')",
                    "default_normalized": "__('wirekit::Most popular')",
                    "type_hint": null,
                    "comment": "Text for the featured badge.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "priceLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Shown instead of an amount (\"Let's talk\") for a contact-us tier.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "minorUnits",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": "Forwarded to the inner price component so a tier can render minor-unit amounts (e.g. 4900 -\u003E EUR 49.00), locale-format them, and size the amount — previously the wrapper hardcoded size=\"lg\" and dropped the rest.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "locale",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "priceSize",
                    "default": "'lg'",
                    "default_normalized": "'lg'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "features",
                    "required": false
                },
                {
                    "name": "action",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "price",
            "tag": "\u003Cx-wirekit::price\u003E",
            "category": "Display",
            "description": "Locale-aware currency display with optional discount",
            "docs_url": "https://docs.wirekit.app/components/price",
            "props": [
                {
                    "name": "amount",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "currency",
                    "default": "config('wirekit.currency', 'USD')",
                    "default_normalized": "config('wirekit.currency', 'USD')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "locale",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "base",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "unitPrice",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "unitMeasure",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "delta",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "deltaFormat",
                    "default": "'percent'",
                    "default_normalized": "'percent'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "size",
                    "default": "config('wirekit.components.price.size', 'md')",
                    "default_normalized": "config('wirekit.components.price.size', 'md')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "xs",
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "minorUnits",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "suffix",
                    "required": false
                }
            ],
            "sub_components": []
        },
        {
            "name": "quick-replies",
            "tag": "\u003Cx-wirekit::quick-replies\u003E",
            "category": "Display",
            "description": "Suggested replies under a message — a named group of chips that dispatch the answer the reader picked",
            "docs_url": "https://docs.wirekit.app/components/quick-replies",
            "props": [
                {
                    "name": "replies",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The suggested replies, in the order they are offered. An entry is either a string — the label, which is then also the value — or an array with `label`, an optional `value` (defaults to the label) and an optional `disabled`.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Names the group. A group of buttons with no name is announced as a group of nothing, so an unset label falls back to a translated default rather than to silence.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "reaction",
            "tag": "\u003Cx-wirekit::reaction\u003E",
            "category": "Display",
            "description": "Emoji reaction pill with count and toggle state",
            "docs_url": "https://docs.wirekit.app/components/reaction",
            "props": [
                {
                    "name": "optimisticArgs",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "The Livewire method this reaction should call, when it should show the new state before the server has agreed to it. Null leaves the component exactly as it has always rendered: server markup, no Alpine. Extra arguments appended to the optimistic action call, after the new value. A list of identical controls — one per row — needs to tell the server WHICH row, and the optimistic layer has always been able to carry that: it spreads `args` into the call. No component exposed it, so the capability existed and was unreachable, and the only way to build the commonest optimistic surface there is was to hand-mount the factory and give up the component.",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "optimistic",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "emoji",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "count",
                    "default": "0",
                    "default_normalized": "0",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "active",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "users",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "reveal",
            "tag": "\u003Cx-wirekit::reveal\u003E",
            "category": "Display",
            "description": "Animation wrapper — viewport / click / manual triggers, 11 in/out presets",
            "docs_url": "https://docs.wirekit.app/components/reveal",
            "props": [
                {
                    "name": "preset",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Animation preset name. One of 11 in-presets: fade, slide-up, slide-down, slide-left, slide-right, scale, zoom, flip, rotate, bounce, spring",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "trigger",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Trigger mode: 'viewport' (IntersectionObserver), 'click', or 'manual' (developer dispatches Alpine.$dispatch('wirekit:reveal')).",
                    "examples": [],
                    "values": [
                        "viewport",
                        "click",
                        "manual"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "duration",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Duration token: 'fast' (150ms), 'normal' (300ms, default), 'slow' (600ms).",
                    "examples": [],
                    "values": [
                        "fast",
                        "normal",
                        "slow"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "once",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Re-fire on every trigger? Default true = animate once and stop.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "threshold",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "IntersectionObserver threshold (only used when trigger='viewport'). 0..1.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "delay",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Delay before the entrance animation begins. One of: null   — no delay (default — animation begins immediately on trigger) 'none'/'sm'/'md'/'lg'/'xl' — token name → maps to --motion-wk-delay-* var int    — raw milliseconds (e.g. delay=\"125\" for a custom rhythm)",
                    "examples": [],
                    "values": [
                        "none",
                        "sm",
                        "md",
                        "lg",
                        "xl"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "toolbar",
            "tag": "\u003Cx-wirekit::toolbar\u003E",
            "category": "Navigation",
            "description": "Horizontal bar with search, filters, and action buttons",
            "docs_url": "https://docs.wirekit.app/components/toolbar",
            "props": [
                {
                    "name": "sticky",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "density",
                    "default": "'comfortable'",
                    "default_normalized": "'comfortable'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "comfortable",
                        "compact"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "align",
                    "default": "'between'",
                    "default_normalized": "'between'",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "between",
                        "start",
                        "end"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "ariaLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "leading",
                    "required": false
                },
                {
                    "name": "filters",
                    "required": false
                },
                {
                    "name": "trailing",
                    "required": false
                },
                {
                    "name": "slot",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "usage-meter",
            "tag": "\u003Cx-wirekit::usage-meter\u003E",
            "category": "Display",
            "description": "Usage-vs-limit meter with threshold intent, panel grid, and plan-paywall gate",
            "docs_url": "https://docs.wirekit.app/components/usage-meter",
            "props": [
                {
                    "name": "label",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "visible metric name (e.g. \"Orders this month\")",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "used",
                    "default": "0",
                    "default_normalized": "0",
                    "type_hint": null,
                    "comment": "current usage (numeric)",
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "limit",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "plan limit; null = unlimited",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "unit",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "unit suffix (e.g. \"orders\", \"seats\")",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "period",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "reset cadence hint: 'day'|'week'|'month'|'year'",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "resetAt",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "explicit reset note (overrides period hint)",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "warn",
                    "default": "config('wirekit.components.usage-meter.warn', 0.8)",
                    "default_normalized": "config('wirekit.components.usage-meter.warn', 0.8)",
                    "type_hint": null,
                    "comment": "warning threshold ratio",
                    "examples": [],
                    "values": null,
                    "value_type": "float"
                },
                {
                    "name": "danger",
                    "default": "config('wirekit.components.usage-meter.danger', 1.0)",
                    "default_normalized": "config('wirekit.components.usage-meter.danger', 1.0)",
                    "type_hint": null,
                    "comment": "danger/over threshold ratio",
                    "examples": [],
                    "values": null,
                    "value_type": "float"
                },
                {
                    "name": "showValue",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "show \"X / Y (Z%)\" readout",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "unlimitedLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "override the \"Unlimited\" word (a plan NAME is a proper noun)",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "action",
                    "required": false
                }
            ],
            "sub_components": [
                {
                    "name": "usage-meter.gate",
                    "tag": "\u003Cx-wirekit::usage-meter.gate\u003E",
                    "props": [
                        {
                            "name": "over",
                            "default": "false",
                            "default_normalized": "false",
                            "type_hint": null,
                            "comment": "true = limit reached, gate the action",
                            "examples": [],
                            "values": null,
                            "value_type": "bool"
                        },
                        {
                            "name": "reason",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "why the action is blocked (shown when over)",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                },
                {
                    "name": "usage-meter.panel",
                    "tag": "\u003Cx-wirekit::usage-meter.panel\u003E",
                    "props": [
                        {
                            "name": "title",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": "optional panel heading (e.g. \"Plan usage\")",
                            "examples": [],
                            "values": null,
                            "value_type": null
                        },
                        {
                            "name": "columns",
                            "default": "1",
                            "default_normalized": "1",
                            "type_hint": null,
                            "comment": "responsive column count: 1 | 2 | 3",
                            "examples": [],
                            "values": [
                                "1",
                                "2",
                                "3"
                            ],
                            "value_type": "int"
                        },
                        {
                            "name": "scope",
                            "default": "null",
                            "default_normalized": "null",
                            "type_hint": null,
                            "comment": null,
                            "examples": [],
                            "values": null,
                            "value_type": null
                        }
                    ]
                }
            ]
        },
        {
            "name": "chart",
            "tag": "\u003Cx-wirekit-chart\u003E",
            "tag_alias": "\u003Cx-wirekit::chart\u003E",
            "category": "System",
            "description": "Chart.js wrapper component",
            "docs_url": "https://docs.wirekit.app/components/chart",
            "props": [
                {
                    "name": "type",
                    "default": "'bar'",
                    "default_normalized": "'bar'",
                    "type_hint": "string",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "labels",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": "array",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "datasets",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": "array",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "options",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": "array",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "height",
                    "default": "'380px'",
                    "default_normalized": "'380px'",
                    "type_hint": "string",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "wire-stream",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": "?string",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "wire-stream-mode",
                    "default": "'strict'",
                    "default_normalized": "'strict'",
                    "type_hint": "string",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "wire-stream-cap",
                    "default": "100",
                    "default_normalized": "100",
                    "type_hint": "int",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "annotations",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": "array",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "inline",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": "bool",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "replayable",
                    "default": "false",
                    "default_normalized": "false",
                    "type_hint": "bool",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "library",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": "?string",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "value-decimals",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": "string|int|null",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "value-prefix",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": "?string",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "value-suffix",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": "?string",
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                }
            ],
            "component_kind": "class",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "fonts",
            "tag": "\u003Cx-wirekit::fonts\u003E",
            "category": "System",
            "description": "GDPR-compliant font loader",
            "docs_url": "https://docs.wirekit.app/components/fonts",
            "props": [
                {
                    "name": "nonce",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A CSP nonce for the inline \u003Cstyle\u003E below. Left out, it resolves itself from the container binding or Vite — see WireKit::cspNonce(). Pass one explicitly when the application mints a value per response and publishes it nowhere.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [
                {
                    "name": "preloadSans",
                    "required": true
                }
            ],
            "sub_components": []
        },
        {
            "name": "glass",
            "tag": "\u003Cx-wirekit::glass\u003E",
            "category": "System",
            "description": "Liquid Glass extension — include once in the layout head; takes no props and renders no slot",
            "docs_url": null,
            "props": [],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "icon",
            "tag": "\u003Cx-wirekit::icon\u003E",
            "category": "System",
            "description": "SVG icon with preset support",
            "docs_url": "https://docs.wirekit.app/components/icon",
            "props": [
                {
                    "name": "name",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "size",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "xs",
                        "sm",
                        "md",
                        "lg",
                        "xl",
                        "2xl"
                    ],
                    "value_type": "string"
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "map",
            "tag": "\u003Cx-wirekit::map\u003E",
            "category": "System",
            "description": "Map adapter (MapLibre/Leaflet peer dependency) with markers and an accessible location list",
            "docs_url": "https://docs.wirekit.app/components/map",
            "props": [
                {
                    "name": "center",
                    "default": "[0, 0]",
                    "default_normalized": "[0, 0]",
                    "type_hint": null,
                    "comment": "[lat, lng]",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "zoom",
                    "default": "config('wirekit.components.map.zoom', 2)",
                    "default_normalized": "config('wirekit.components.map.zoom', 2)",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "int"
                },
                {
                    "name": "markers",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": "[{id,lat,lng,label,body?,intent?}]",
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "provider",
                    "default": "config('wirekit.components.map.provider', 'maplibre')",
                    "default_normalized": "config('wirekit.components.map.provider', 'maplibre')",
                    "type_hint": null,
                    "comment": "maplibre | leaflet (peer dependency)",
                    "examples": [],
                    "values": [
                        "maplibre",
                        "leaflet"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "styleUrl",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "tile/style URL (provider-specific)",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "attribution",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "tile attribution HTML, e.g. '© OpenStreetMap contributors' — shown by Leaflet's attribution control; required by some tile sources (OSM)",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "height",
                    "default": "'24rem'",
                    "default_normalized": "'24rem'",
                    "type_hint": null,
                    "comment": "map canvas height (CSS length)",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "ariaLabel",
                    "default": "__('wirekit::Map')",
                    "default_normalized": "__('wirekit::Map')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "reducedData",
                    "default": "config('wirekit.components.map.reduced-data', 'respect')",
                    "default_normalized": "config('wirekit.components.map.reduced-data', 'respect')",
                    "type_hint": null,
                    "comment": "'respect' (default) | 'ignore' — what to do when the reader's browser reports `prefers-reduced-data: reduce`. Tiles are the largest network cost this library can cause and the only one it controls at runtime: a map fetches tile after tile as it settles, and again on every pan. Nothing else WireKit ships fetches anything — the stylesheet contains no `url()` at all — so this is where the preference can actually be honored rather than merely acknowledged. On 'respect' the canvas is withheld and the marker list carries the content, with a control to load the map anyway. Use 'ignore' where the canvas IS the content rather than an illustration of it — a delivery-tracking view, a route editor.",
                    "examples": [],
                    "values": null,
                    "value_type": "string"
                },
                {
                    "name": "listLabel",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "Heading above the marker list — and the switch that makes that list a LANDMARK. The visible heading is ALWAYS rendered, so the fallback survives as a resolved variable; only the `role=\"region\"` waits for a caller-supplied name. Unnamed it fell back to \"Locations\", which made every map on a store-locator page the same rotor entry (axe: `landmark-unique`).",
                    "examples": [],
                    "values": null,
                    "value_type": null
                },
                {
                    "name": "list",
                    "default": "true",
                    "default_normalized": "true",
                    "type_hint": null,
                    "comment": "Show the marker-list sidebar. Set list=\"false\" for a map-only surface — the list stays in the DOM as an sr-only accessible companion (a map is opaque to assistive tech, so the locations must remain reachable), only the visual sidebar is hidden and the canvas fills the width.",
                    "examples": [],
                    "values": null,
                    "value_type": "bool"
                },
                {
                    "name": "highlight",
                    "default": "config('wirekit.components.map.highlight', 'ring')",
                    "default_normalized": "config('wirekit.components.map.highlight', 'ring')",
                    "type_hint": null,
                    "comment": "Selected-row highlight: 'ring' (inset frame — the default) or 'fill' (tinted row background), colored via highlightColor (intent vocabulary). Both variants are demonstrated side by side on the docs MapLibre page.",
                    "examples": [],
                    "values": [
                        "ring",
                        "fill"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "highlightColor",
                    "default": "config('wirekit.components.map.highlight-color', 'accent')",
                    "default_normalized": "config('wirekit.components.map.highlight-color', 'accent')",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": [
                        "accent",
                        "success",
                        "warning",
                        "danger",
                        "neutral"
                    ],
                    "value_type": "string"
                },
                {
                    "name": "scope",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        },
        {
            "name": "structured-data",
            "tag": "\u003Cx-wirekit::structured-data\u003E",
            "category": "System",
            "description": "JSON-LD script block emitter (XSS-safe via JSON_HEX_TAG)",
            "docs_url": "https://docs.wirekit.app/components/structured-data",
            "props": [
                {
                    "name": "data",
                    "default": "[]",
                    "default_normalized": "[]",
                    "type_hint": null,
                    "comment": null,
                    "examples": [],
                    "values": null,
                    "value_type": "array"
                },
                {
                    "name": "nonce",
                    "default": "null",
                    "default_normalized": "null",
                    "type_hint": null,
                    "comment": "A CSP nonce for the JSON-LD block below. Left out, it resolves itself from the container binding or Vite — see WireKit::cspNonce(). Pass one explicitly when the application mints a value per response and publishes it nowhere. A JSON-LD block is data rather than code, and it is still a \u003Cscript\u003E element: `script-src` is specified over the ELEMENT, not over its type, so a nonce-based policy can reject it and take the page's structured data with it — silently, because nothing on the page looks different. The attribute costs one string when a nonce exists and nothing at all when it does not.",
                    "examples": [],
                    "values": null,
                    "value_type": null
                }
            ],
            "component_kind": "anonymous",
            "slots": [],
            "sub_components": []
        }
    ]
}
