{
  "description": "Components of Pico Reforged, generated by scripts/generate-ai.ts from scripts/data/components.ts, src/ and test/fixtures/. See ai/README.md.",
  "package": "@rusticstack/pico-reforged",
  "components": [
    {
      "name": "document",
      "category": "base",
      "optIn": {
        "kind": "core",
        "css": "src/reset/document.css",
        "module": "reset/document",
        "excludeWith": "reset/document"
      },
      "summary": "Document: html, body defaults",
      "use": "Page defaults for html and body. Nothing to write: it applies to every page.",
      "markup": null,
      "examples": [],
      "variants": [],
      "states": [],
      "aria": [],
      "notes": [
        "Set the language on html (lang) and add the viewport meta tag.",
        "data-theme=\"light\" or \"dark\" on html (or on any element) forces a color scheme, otherwise prefers-color-scheme decides."
      ],
      "tokens": {
        "reads": [
          "--pico-background-color",
          "--pico-color",
          "--pico-font-family",
          "--pico-font-size",
          "--pico-font-weight",
          "--pico-line-height",
          "--pico-text-underline-offset"
        ],
        "defines": []
      },
      "js": null
    },
    {
      "name": "landmarks",
      "category": "layout",
      "optIn": {
        "kind": "core",
        "css": "src/layout/landmarks.css",
        "module": "layout/landmarks",
        "excludeWith": "layout/landmarks"
      },
      "summary": "Landmarks: body > header, body > main, body > footer",
      "use": "Vertical padding for body > header, body > main and body > footer.",
      "markup": "<body>\n  <header>...</header>\n  <main>...</main>\n  <footer>...</footer>\n</body>",
      "examples": [
        {
          "label": "Page landmarks as direct children of body",
          "html": "<body>\n  <header>...</header>\n  <main>...</main>\n  <footer>...</footer>\n</body>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [
        "header, main and footer map to banner, main and contentinfo only as direct children of body."
      ],
      "tokens": {
        "reads": ["--pico-block-spacing-vertical"],
        "defines": []
      },
      "js": null
    },
    {
      "name": "section",
      "category": "layout",
      "optIn": {
        "kind": "core",
        "css": "src/layout/section.css",
        "module": "layout/section",
        "excludeWith": "layout/section"
      },
      "summary": "Section: section",
      "use": "Bottom margin between sections.",
      "markup": "<section>\n  <h2>Title</h2>\n  <p>Text</p>\n</section>",
      "examples": [
        {
          "label": "A section with a heading",
          "html": "<section>\n  <h2>Title</h2>\n  <p>Text</p>\n</section>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [
        "Give a section an accessible name (aria-labelledby) when it should be a region landmark."
      ],
      "tokens": {
        "reads": ["--pico-block-spacing-vertical"],
        "defines": []
      },
      "js": null
    },
    {
      "name": "responsive-spacings",
      "category": "layout",
      "optIn": {
        "kind": "option",
        "css": "src/layout/responsive-spacings.css",
        "module": "layout/responsive-spacings",
        "how": "CLI: --responsive-spacings. CSS: @pico { responsive-spacings: true; }. Compiler option: responsiveSpacings."
      },
      "summary": "Responsive spacings for landmarks, section and article (opt-in, not imported by default)",
      "use": "Spacing of landmarks, section and article grows with the viewport width. Off by default.",
      "markup": null,
      "examples": [],
      "variants": [],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": ["--pico-spacing"],
        "defines": ["--pico-block-spacing-horizontal", "--pico-block-spacing-vertical"]
      },
      "js": null
    },
    {
      "name": "container",
      "category": "layout",
      "optIn": {
        "kind": "core",
        "css": "src/layout/container.css",
        "module": "layout/container",
        "excludeWith": "layout/container"
      },
      "summary": "Container: .container, .container-fluid",
      "use": "Centered column with a max width that grows by breakpoint (.container) or a full width padded column (.container-fluid).",
      "markup": "<div class=\"container-fluid\">\n  <p>This is a .container-fluid inside the page.</p>\n</div>\n<div class=\"container\">\n  <p>This is a .container nested in the page.</p>\n</div>",
      "examples": [
        {
          "label": "Fixed and fluid container",
          "html": "<div class=\"container-fluid\">\n  <p>This is a .container-fluid inside the page.</p>\n</div>\n<div class=\"container\">\n  <p>This is a .container nested in the page.</p>\n</div>"
        }
      ],
      "variants": [
        {
          "name": "container",
          "trigger": "class=\"container\"",
          "selector": ".container",
          "description": "Max width follows --pico-container-max-width."
        },
        {
          "name": "container-fluid",
          "trigger": "class=\"container-fluid\"",
          "selector": ".container-fluid",
          "description": "Full width with side padding."
        }
      ],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": ["--pico-container-max-width", "--pico-spacing"],
        "defines": []
      },
      "js": null
    },
    {
      "name": "semantic-container",
      "category": "layout",
      "optIn": {
        "kind": "option",
        "css": "src/layout/semantic-container.css",
        "module": "layout/semantic-container",
        "how": "On in the classless build. Elsewhere: CLI --semantic-container, CSS @pico { semantic-container: true; }. Add --fluid (@pico { fluid: true; }) for no max width."
      },
      "summary": "Semantic container: body > header, body > main, body > footer as containers (classless only)",
      "use": "Makes body > header, body > main and body > footer centered containers, so class-free pages need no wrapper.",
      "markup": "<body>\n  <header>...</header>\n  <main>...</main>\n  <footer>...</footer>\n</body>",
      "examples": [
        {
          "label": "Classless page",
          "html": "<body>\n  <header>...</header>\n  <main>...</main>\n  <footer>...</footer>\n</body>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": [
          "--pico-block-spacing-horizontal",
          "--pico-block-spacing-vertical",
          "--pico-container-max-width"
        ],
        "defines": []
      },
      "js": null
    },
    {
      "name": "grid",
      "category": "layout",
      "optIn": {
        "kind": "core",
        "css": "src/layout/grid.css",
        "module": "layout/grid",
        "excludeWith": "layout/grid"
      },
      "summary": "Grid: .grid, minimal auto-layout columns",
      "use": "Equal width auto-fit columns from 768px, stacked below. Children shrink instead of overflowing.",
      "markup": "<div class=\"grid\">\n  <div>One</div>\n  <div>Two</div>\n  <div>Three</div>\n</div>",
      "examples": [
        {
          "label": "Three columns",
          "html": "<div class=\"grid\">\n  <div>One</div>\n  <div>Two</div>\n  <div>Three</div>\n</div>"
        }
      ],
      "variants": [
        {
          "name": "grid",
          "trigger": "class=\"grid\"",
          "selector": ".grid",
          "description": "The only hook. Any children become columns."
        }
      ],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": ["--pico-grid-column-gap", "--pico-grid-row-gap"],
        "defines": []
      },
      "js": null
    },
    {
      "name": "overflow-auto",
      "category": "layout",
      "optIn": {
        "kind": "core",
        "css": "src/layout/overflow-auto.css",
        "module": "layout/overflow-auto",
        "excludeWith": "layout/overflow-auto"
      },
      "summary": "Overflow auto: .overflow-auto",
      "use": "Wrap wide tables or code so they scroll inside their box.",
      "markup": "<div class=\"overflow-auto\">\n  <div>A wide block inside .overflow-auto, wider than its box.</div>\n</div>",
      "examples": [
        {
          "label": "Scrolling wrapper",
          "html": "<div class=\"overflow-auto\">\n  <div>A wide block inside .overflow-auto, wider than its box.</div>\n</div>"
        }
      ],
      "variants": [
        {
          "name": "overflow-auto",
          "trigger": "class=\"overflow-auto\"",
          "selector": ".overflow-auto",
          "description": "Scrolls on the x axis."
        }
      ],
      "states": [],
      "aria": [
        "A scroll region that can take focus should be reachable by keyboard: add tabindex=\"0\" and a name when it has no focusable content."
      ],
      "tokens": {
        "reads": [],
        "defines": []
      },
      "js": null
    },
    {
      "name": "typography",
      "category": "content",
      "optIn": {
        "kind": "core",
        "css": "src/content/typography.css",
        "module": "content/typography",
        "excludeWith": "content/typography"
      },
      "summary": "Typography: headings, paragraphs, lists, hgroup, blockquote, mark, abbr, ins, del, sub, sup",
      "use": "Headings, paragraphs, lists, hgroup, blockquote, mark, ins, del, abbr, sub and sup with no classes.",
      "markup": "<hgroup>\n  <h3>Grouped heading</h3>\n  <p>The paragraph in an hgroup is muted and sits tight under the title.</p>\n</hgroup>",
      "examples": [
        {
          "label": "Heading group",
          "html": "<hgroup>\n  <h3>Grouped heading</h3>\n  <p>The paragraph in an hgroup is muted and sits tight under the title.</p>\n</hgroup>"
        },
        {
          "label": "Blockquote with a citation",
          "html": "<blockquote>\n  Simplicity is prerequisite for reliability.\n  <footer><cite>Edsger W. Dijkstra</cite></footer>\n</blockquote>"
        }
      ],
      "variants": [
        {
          "name": "hgroup",
          "trigger": "<hgroup>",
          "selector": "hgroup",
          "description": "A title with a muted subtitle paragraph."
        }
      ],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": [
          "--pico-blockquote-border-color",
          "--pico-blockquote-footer-color",
          "--pico-del-color",
          "--pico-font-family",
          "--pico-h1-color",
          "--pico-h2-color",
          "--pico-h3-color",
          "--pico-h4-color",
          "--pico-h5-color",
          "--pico-h6-color",
          "--pico-ins-color",
          "--pico-mark-background-color",
          "--pico-mark-color",
          "--pico-muted-color",
          "--pico-spacing",
          "--pico-text-selection-color",
          "--pico-typography-spacing-vertical"
        ],
        "defines": [
          "--pico-color",
          "--pico-font-size",
          "--pico-font-weight",
          "--pico-line-height",
          "--pico-typography-spacing-top"
        ]
      },
      "js": null
    },
    {
      "name": "link",
      "category": "content",
      "optIn": {
        "kind": "core",
        "css": "src/content/link.css",
        "module": "content/link",
        "excludeWith": "content/link"
      },
      "summary": "Links: a, [role=link] and their .secondary and .contrast variants",
      "use": "Links are primary colored. .secondary and .contrast switch the color family.",
      "markup": "<p>\n  Here is <a href=\"#\">a plain link</a>, <a href=\"#\" class=\"secondary\">a secondary link</a>,\n  <a href=\"#\" class=\"contrast\">a contrast link</a> and\n  <a href=\"#\" aria-current=\"page\">a link marked as current</a>.\n</p>",
      "examples": [
        {
          "label": "Plain, secondary, contrast and current links",
          "html": "<p>\n  Here is <a href=\"#\">a plain link</a>, <a href=\"#\" class=\"secondary\">a secondary link</a>,\n  <a href=\"#\" class=\"contrast\">a contrast link</a> and\n  <a href=\"#\" aria-current=\"page\">a link marked as current</a>.\n</p>"
        }
      ],
      "variants": [
        {
          "name": "secondary",
          "trigger": "class=\"secondary\"",
          "selector": ".secondary",
          "description": "Slate link color."
        },
        {
          "name": "contrast",
          "trigger": "class=\"contrast\"",
          "selector": ".contrast",
          "description": "Highest contrast link color."
        }
      ],
      "states": [
        {
          "name": "current",
          "trigger": "aria-current=\"page\"",
          "selector": "[aria-current]",
          "description": "Styled like hover. aria-current=\"false\" is ignored."
        }
      ],
      "aria": ["Use aria-current=\"page\" on the link to the current page, not a class."],
      "tokens": {
        "reads": [
          "--pico-contrast",
          "--pico-contrast-hover",
          "--pico-contrast-hover-underline",
          "--pico-contrast-underline",
          "--pico-outline-width",
          "--pico-primary",
          "--pico-primary-focus",
          "--pico-primary-hover",
          "--pico-primary-hover-underline",
          "--pico-primary-underline",
          "--pico-secondary",
          "--pico-secondary-hover",
          "--pico-secondary-hover-underline",
          "--pico-secondary-underline",
          "--pico-text-underline-offset",
          "--pico-transition"
        ],
        "defines": [
          "--pico-background-color",
          "--pico-color",
          "--pico-text-decoration",
          "--pico-underline"
        ]
      },
      "js": null
    },
    {
      "name": "button",
      "category": "content",
      "optIn": {
        "kind": "core",
        "css": "src/content/button.css",
        "module": "content/button",
        "excludeWith": "content/button"
      },
      "summary": "Buttons: button, [type=submit], [type=reset], [type=button], [role=button], file selector button",
      "use": "button, input type submit/button/reset and a[role=button]. Variants come from classes; there is no size class.",
      "markup": "<p>\n  <button>Primary</button>\n  <button class=\"secondary\">Secondary</button>\n  <button class=\"contrast\">Contrast</button>\n  <button disabled>Disabled</button>\n</p>",
      "examples": [
        {
          "label": "Variants as buttons",
          "html": "<p>\n  <button>Primary</button>\n  <button class=\"secondary\">Secondary</button>\n  <button class=\"contrast\">Contrast</button>\n  <button disabled>Disabled</button>\n</p>"
        },
        {
          "label": "Outline variants",
          "html": "<p>\n  <button class=\"outline\">Primary outline</button>\n  <button class=\"outline secondary\">Secondary outline</button>\n  <button class=\"outline contrast\">Contrast outline</button>\n  <button class=\"outline\" disabled>Disabled outline</button>\n</p>"
        },
        {
          "label": "Link buttons",
          "html": "<p>\n  <a href=\"#\" role=\"button\">Link button</a>\n  <a href=\"#\" role=\"button\" class=\"secondary\">Secondary link</a>\n  <a href=\"#\" role=\"button\" class=\"contrast\">Contrast link</a>\n  <a href=\"#\" role=\"button\" class=\"outline\">Outline link</a>\n  <a href=\"#\" role=\"button\" aria-disabled=\"true\">Disabled link</a>\n</p>"
        }
      ],
      "variants": [
        {
          "name": "secondary",
          "trigger": "class=\"secondary\"",
          "selector": ".secondary",
          "description": "Slate fill. type=reset is secondary by default."
        },
        {
          "name": "contrast",
          "trigger": "class=\"contrast\"",
          "selector": ".contrast",
          "description": "Highest contrast fill."
        },
        {
          "name": "outline",
          "trigger": "class=\"outline\"",
          "selector": ".outline",
          "description": "Transparent fill with a colored border. Combine with secondary or contrast."
        },
        {
          "name": "link-button",
          "trigger": "<a href=\"...\" role=\"button\">",
          "selector": "[role=\"button\"]",
          "description": "A link that looks like a button. role=button is the hook."
        }
      ],
      "states": [
        {
          "name": "disabled",
          "trigger": "disabled",
          "selector": "[disabled]",
          "description": "Native disabled button or fieldset."
        },
        {
          "name": "current",
          "trigger": "aria-current",
          "selector": "[aria-current]",
          "description": "Styled like hover."
        }
      ],
      "aria": [
        "Use a real button for actions and a link with role=\"button\" only for navigation that should look like a button."
      ],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-border-width",
          "--pico-button-box-shadow",
          "--pico-button-hover-box-shadow",
          "--pico-contrast",
          "--pico-contrast-background",
          "--pico-contrast-border",
          "--pico-contrast-focus",
          "--pico-contrast-hover",
          "--pico-contrast-hover-background",
          "--pico-contrast-hover-border",
          "--pico-contrast-inverse",
          "--pico-form-element-spacing-horizontal",
          "--pico-form-element-spacing-vertical",
          "--pico-line-height",
          "--pico-muted-color",
          "--pico-outline-width",
          "--pico-primary",
          "--pico-primary-background",
          "--pico-primary-border",
          "--pico-primary-focus",
          "--pico-primary-hover",
          "--pico-primary-hover-background",
          "--pico-primary-hover-border",
          "--pico-primary-inverse",
          "--pico-secondary",
          "--pico-secondary-background",
          "--pico-secondary-border",
          "--pico-secondary-focus",
          "--pico-secondary-hover",
          "--pico-secondary-hover-background",
          "--pico-secondary-hover-border",
          "--pico-secondary-inverse",
          "--pico-spacing",
          "--pico-transition"
        ],
        "defines": [
          "--pico-background-color",
          "--pico-border-color",
          "--pico-box-shadow",
          "--pico-color",
          "--pico-font-weight"
        ]
      },
      "js": null
    },
    {
      "name": "table",
      "category": "content",
      "optIn": {
        "kind": "core",
        "css": "src/content/table.css",
        "module": "content/table",
        "excludeWith": "content/table"
      },
      "summary": "Tables: table, thead, tbody, tfoot, tr, th, td, table.striped",
      "use": "Plain tables get borders, padding and header weight. Add .striped for zebra rows.",
      "markup": "<table class=\"striped\">\n  <thead>\n    <tr>\n      <th scope=\"col\">Name</th>\n      <th scope=\"col\">Role</th>\n      <th scope=\"col\">Team</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>Ana Ribeiro</td>\n      <td>Designer</td>\n      <td>Product</td>\n    </tr>\n    <tr>\n      <td>Bruno Matos</td>\n      <td>Engineer</td>\n      <td>Platform</td>\n    </tr>\n  </tbody>\n</table>",
      "examples": [
        {
          "label": "Striped table",
          "html": "<table class=\"striped\">\n  <thead>\n    <tr>\n      <th scope=\"col\">Name</th>\n      <th scope=\"col\">Role</th>\n      <th scope=\"col\">Team</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>Ana Ribeiro</td>\n      <td>Designer</td>\n      <td>Product</td>\n    </tr>\n    <tr>\n      <td>Bruno Matos</td>\n      <td>Engineer</td>\n      <td>Platform</td>\n    </tr>\n  </tbody>\n</table>"
        }
      ],
      "variants": [
        {
          "name": "striped",
          "trigger": "class=\"striped\"",
          "selector": "table.striped",
          "description": "Alternating row background."
        }
      ],
      "states": [],
      "aria": [
        "Use th with scope=\"col\" or scope=\"row\", and a caption when the table needs a title."
      ],
      "tokens": {
        "reads": [
          "--pico-background-color",
          "--pico-border-width",
          "--pico-muted-color",
          "--pico-spacing",
          "--pico-table-border-color",
          "--pico-table-row-stripped-background-color"
        ],
        "defines": ["--pico-color", "--pico-font-weight"]
      },
      "js": null
    },
    {
      "name": "embedded",
      "category": "content",
      "optIn": {
        "kind": "core",
        "css": "src/content/embedded.css",
        "module": "content/embedded",
        "excludeWith": "content/embedded"
      },
      "summary": "Embedded content: audio, canvas, iframe, img, svg, video",
      "use": "img, svg, video, audio, canvas and iframe are fluid by default.",
      "markup": "<img\n  alt=\"A flat gradient placeholder\"\n  width=\"960\"\n  height=\"300\"\n  src=\"image.svg\"\n/>",
      "examples": [
        {
          "label": "Image",
          "html": "<img\n  alt=\"A flat gradient placeholder\"\n  width=\"960\"\n  height=\"300\"\n  src=\"image.svg\"\n/>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [
        "Give img an alt (empty for decorative images) and svg a role=\"img\" with an aria-label when it carries meaning."
      ],
      "tokens": {
        "reads": [],
        "defines": []
      },
      "js": null
    },
    {
      "name": "code",
      "category": "content",
      "optIn": {
        "kind": "core",
        "css": "src/content/code.css",
        "module": "content/code",
        "excludeWith": "content/code"
      },
      "summary": "Code: pre, code, kbd, samp",
      "use": "pre, code, kbd and samp on a quiet code surface.",
      "markup": "<p>\n  Inline <code>display: grid</code>, a keyboard shortcut <kbd>Alt</kbd> + <kbd>Tab</kbd> and\n  program output <samp>Build finished in 1.2s</samp>.\n</p>\n<pre><code>function greet(name) {\nreturn `Hello, ${name}!`;\n}\nconsole.log(greet(\"world\"));</code></pre>",
      "examples": [
        {
          "label": "Inline code and a code block",
          "html": "<p>\n  Inline <code>display: grid</code>, a keyboard shortcut <kbd>Alt</kbd> + <kbd>Tab</kbd> and\n  program output <samp>Build finished in 1.2s</samp>.\n</p>\n<pre><code>function greet(name) {\nreturn `Hello, ${name}!`;\n}\nconsole.log(greet(\"world\"));</code></pre>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-code-background-color",
          "--pico-code-color",
          "--pico-code-kbd-background-color",
          "--pico-code-kbd-color",
          "--pico-font-family-monospace",
          "--pico-line-height",
          "--pico-spacing"
        ],
        "defines": ["--pico-font-family", "--pico-font-weight"]
      },
      "js": null
    },
    {
      "name": "figure",
      "category": "content",
      "optIn": {
        "kind": "core",
        "css": "src/content/figure.css",
        "module": "content/figure",
        "excludeWith": "content/figure"
      },
      "summary": "Figure: figure, figcaption",
      "use": "figure with a muted figcaption.",
      "markup": "<figure>\n  <img\n    alt=\"A flat gradient placeholder\"\n    width=\"960\"\n    height=\"300\"\n    src=\"image.svg\"\n  />\n  <figcaption>A gradient standing in for a photo.</figcaption>\n</figure>",
      "examples": [
        {
          "label": "Figure with caption",
          "html": "<figure>\n  <img\n    alt=\"A flat gradient placeholder\"\n    width=\"960\"\n    height=\"300\"\n    src=\"image.svg\"\n  />\n  <figcaption>A gradient standing in for a photo.</figcaption>\n</figure>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": ["--pico-muted-color", "--pico-spacing"],
        "defines": []
      },
      "js": null
    },
    {
      "name": "misc",
      "category": "content",
      "optIn": {
        "kind": "core",
        "css": "src/content/misc.css",
        "module": "content/misc",
        "excludeWith": "content/misc"
      },
      "summary": "Misc: hr, [hidden], template, canvas",
      "use": "hr, [hidden] and template. [hidden] stays hidden even when another rule sets display.",
      "markup": "<hr />",
      "examples": [
        {
          "label": "Rule",
          "html": "<hr />"
        }
      ],
      "variants": [],
      "states": [
        {
          "name": "hidden",
          "trigger": "hidden",
          "selector": "[hidden]",
          "description": "display: none !important."
        }
      ],
      "aria": [],
      "tokens": {
        "reads": ["--pico-muted-border-color", "--pico-typography-spacing-vertical"],
        "defines": []
      },
      "js": null
    },
    {
      "name": "form-basics",
      "category": "forms",
      "optIn": {
        "kind": "core",
        "css": "src/forms/basics.css",
        "module": "forms/basics",
        "excludeWith": "forms/basics"
      },
      "summary": "Form basics: input, select, textarea, label, fieldset, legend",
      "use": "input, select, textarea, label, fieldset and legend. A label that wraps its control needs no for or id.",
      "markup": "<label>\n  Email\n  <input type=\"email\" name=\"email\" placeholder=\"you@example.com\" autocomplete=\"off\" />\n  <small>We never share your email.</small>\n</label>",
      "examples": [
        {
          "label": "Label wrapping an input, with helper text",
          "html": "<label>\n  Email\n  <input type=\"email\" name=\"email\" placeholder=\"you@example.com\" autocomplete=\"off\" />\n  <small>We never share your email.</small>\n</label>"
        },
        {
          "label": "Invalid input with a message",
          "html": "<input type=\"text\" value=\"Invalid input\" aria-invalid=\"true\" aria-describedby=\"bad\" />\n<small id=\"bad\">This value is not allowed.</small>"
        }
      ],
      "variants": [],
      "states": [
        {
          "name": "invalid",
          "trigger": "aria-invalid=\"true\"",
          "selector": "[aria-invalid=\"true\"]",
          "description": "Red border and icon."
        },
        {
          "name": "valid",
          "trigger": "aria-invalid=\"false\"",
          "selector": "[aria-invalid=\"false\"]",
          "description": "Green border and icon."
        },
        {
          "name": "disabled",
          "trigger": "disabled",
          "selector": "[disabled]",
          "description": "Native disabled."
        },
        {
          "name": "readonly",
          "trigger": "readonly",
          "selector": "[readonly]",
          "description": "No focus ring change."
        }
      ],
      "aria": [
        "Set aria-invalid after validation, not before. Link the message with aria-describedby on the control.",
        "small right after a control is helper text."
      ],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-border-width",
          "--pico-del-color",
          "--pico-font-weight",
          "--pico-form-element-active-background-color",
          "--pico-form-element-active-border-color",
          "--pico-form-element-background-color",
          "--pico-form-element-border-color",
          "--pico-form-element-color",
          "--pico-form-element-disabled-opacity",
          "--pico-form-element-invalid-active-border-color",
          "--pico-form-element-invalid-border-color",
          "--pico-form-element-invalid-focus-color",
          "--pico-form-element-placeholder-color",
          "--pico-form-element-selected-background-color",
          "--pico-form-element-spacing-horizontal",
          "--pico-form-element-spacing-vertical",
          "--pico-form-element-valid-active-border-color",
          "--pico-form-element-valid-border-color",
          "--pico-form-element-valid-focus-color",
          "--pico-icon-chevron",
          "--pico-icon-invalid",
          "--pico-icon-valid",
          "--pico-ins-color",
          "--pico-line-height",
          "--pico-muted-color",
          "--pico-primary-background",
          "--pico-primary-focus",
          "--pico-spacing",
          "--pico-transition"
        ],
        "defines": [
          "--pico-background-color",
          "--pico-border-color",
          "--pico-box-shadow",
          "--pico-color",
          "--pico-form-element-focus-color",
          "--pico-form-label-font-weight",
          "--pico-icon-height",
          "--pico-outline-width"
        ]
      },
      "js": null
    },
    {
      "name": "checkbox-radio-switch",
      "category": "forms",
      "optIn": {
        "kind": "core",
        "css": "src/forms/checkbox-radio-switch.css",
        "module": "forms/checkbox-radio-switch",
        "excludeWith": "forms/checkbox-radio-switch"
      },
      "summary": "Checkbox, radio and switch: [type=checkbox], [type=radio], [type=checkbox][role=switch]",
      "use": "Checkbox and radio are native. A checkbox with role=\"switch\" becomes a switch.",
      "markup": "<label><input type=\"checkbox\" name=\"c1\" checked /> Checked</label>",
      "examples": [
        {
          "label": "Checkbox",
          "html": "<label><input type=\"checkbox\" name=\"c1\" checked /> Checked</label>"
        },
        {
          "label": "Radio",
          "html": "<label><input type=\"radio\" name=\"r\" checked /> Radio one</label>"
        },
        {
          "label": "Switch",
          "html": "<label><input type=\"checkbox\" role=\"switch\" name=\"s2\" checked /> Switch on</label>"
        }
      ],
      "variants": [
        {
          "name": "switch",
          "trigger": "role=\"switch\"",
          "selector": "[role=\"switch\"]",
          "description": "Checkbox drawn as a switch."
        }
      ],
      "states": [
        {
          "name": "indeterminate",
          "trigger": "input.indeterminate = true (script)",
          "selector": ":indeterminate",
          "description": "Dash instead of a check."
        },
        {
          "name": "invalid",
          "trigger": "aria-invalid=\"true\"",
          "selector": "[aria-invalid=\"true\"]",
          "description": "Filled red background (checkbox, switch) or red border."
        }
      ],
      "aria": [
        "role=\"switch\" is announced as an on/off control, so use it only for settings that apply at once."
      ],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-font-weight",
          "--pico-form-element-invalid-border-color",
          "--pico-form-element-valid-border-color",
          "--pico-icon-checkbox",
          "--pico-icon-minus",
          "--pico-outline-width",
          "--pico-primary-background",
          "--pico-primary-border",
          "--pico-primary-focus",
          "--pico-primary-inverse",
          "--pico-switch-background-color",
          "--pico-switch-checked-background-color",
          "--pico-switch-color",
          "--pico-switch-thumb-box-shadow",
          "--pico-transition"
        ],
        "defines": [
          "--pico-background-color",
          "--pico-border-color",
          "--pico-border-width",
          "--pico-color"
        ]
      },
      "js": null
    },
    {
      "name": "input-color",
      "category": "forms",
      "optIn": {
        "kind": "core",
        "css": "src/forms/input-color.css",
        "module": "forms/input-color",
        "excludeWith": "forms/input-color"
      },
      "summary": "Color input swatch: [type=color]",
      "use": "Color swatch input.",
      "markup": "<label>Color <input type=\"color\" name=\"color\" value=\"#4b6bfb\" /></label>",
      "examples": [
        {
          "label": "Color input",
          "html": "<label>Color <input type=\"color\" name=\"color\" value=\"#4b6bfb\" /></label>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": ["--pico-border-radius"],
        "defines": []
      },
      "js": null
    },
    {
      "name": "input-date",
      "category": "forms",
      "optIn": {
        "kind": "core",
        "css": "src/forms/input-date.css",
        "module": "forms/input-date",
        "excludeWith": "forms/input-date"
      },
      "summary": "Date and time inputs: [type=date], [type=datetime-local], [type=month], [type=time], [type=week]",
      "use": "date, datetime-local, month, time and week inputs with a drawn picker icon.",
      "markup": "<label>Date <input type=\"date\" name=\"date\" value=\"2024-03-15\" /></label>",
      "examples": [
        {
          "label": "Date input",
          "html": "<label>Date <input type=\"date\" name=\"date\" value=\"2024-03-15\" /></label>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": ["--pico-form-element-spacing-horizontal", "--pico-icon-date", "--pico-icon-time"],
        "defines": ["--pico-icon-position", "--pico-icon-width"]
      },
      "js": null
    },
    {
      "name": "input-file",
      "category": "forms",
      "optIn": {
        "kind": "core",
        "css": "src/forms/input-file.css",
        "module": "forms/input-file",
        "excludeWith": "forms/input-file"
      },
      "summary": "File input: [type=file]",
      "use": "File input whose button is styled like a secondary button.",
      "markup": "<label>File <input type=\"file\" name=\"file\" /></label>",
      "examples": [
        {
          "label": "File input",
          "html": "<label>File <input type=\"file\" name=\"file\" /></label>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": [
          "--pico-form-element-spacing-horizontal",
          "--pico-form-element-spacing-vertical",
          "--pico-muted-color",
          "--pico-outline-width",
          "--pico-secondary-focus",
          "--pico-secondary-hover-background",
          "--pico-secondary-hover-border"
        ],
        "defines": ["--pico-background-color", "--pico-border-color", "--pico-color"]
      },
      "js": null
    },
    {
      "name": "input-range",
      "category": "forms",
      "optIn": {
        "kind": "core",
        "css": "src/forms/input-range.css",
        "module": "forms/input-range",
        "excludeWith": "forms/input-range"
      },
      "summary": "Range input: [type=range]",
      "use": "Range slider with a styled track and thumb.",
      "markup": "<label>Range <input type=\"range\" name=\"range\" min=\"0\" max=\"100\" value=\"40\" /></label>",
      "examples": [
        {
          "label": "Range input",
          "html": "<label>Range <input type=\"range\" name=\"range\" min=\"0\" max=\"100\" value=\"40\" /></label>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": [
          "--pico-outline-width",
          "--pico-primary-background",
          "--pico-primary-focus",
          "--pico-range-active-border-color",
          "--pico-range-thumb-active-color",
          "--pico-range-thumb-border-color",
          "--pico-transition"
        ],
        "defines": ["--pico-range-border-color", "--pico-range-thumb-color"]
      },
      "js": null
    },
    {
      "name": "input-search",
      "category": "forms",
      "optIn": {
        "kind": "core",
        "css": "src/forms/input-search.css",
        "module": "forms/input-search",
        "excludeWith": "forms/input-search"
      },
      "summary": "Search input: [type=search]",
      "use": "Search input with a pill shape and a drawn icon.",
      "markup": "<label>\n  Search\n  <input type=\"search\" name=\"search\" placeholder=\"Search\" />\n</label>",
      "examples": [
        {
          "label": "Search input",
          "html": "<label>\n  Search\n  <input type=\"search\" name=\"search\" placeholder=\"Search\" />\n</label>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": [
          "--pico-form-element-spacing-horizontal",
          "--pico-icon-invalid",
          "--pico-icon-search",
          "--pico-icon-valid"
        ],
        "defines": ["--pico-border-radius"]
      },
      "js": null
    },
    {
      "name": "accordion",
      "category": "components",
      "optIn": {
        "kind": "core",
        "css": "src/components/accordion.css",
        "module": "components/accordion",
        "excludeWith": "components/accordion"
      },
      "summary": "Accordion: details, summary",
      "use": "details and summary. Open and close are animated where the browser supports ::details-content.",
      "markup": "<details>\n  <summary>Closed accordion item</summary>\n  <p>This content is hidden until the summary is opened.</p>\n</details>",
      "examples": [
        {
          "label": "Accordion item",
          "html": "<details>\n  <summary>Closed accordion item</summary>\n  <p>This content is hidden until the summary is opened.</p>\n</details>"
        },
        {
          "label": "Summary as a button",
          "html": "<details>\n  <summary role=\"button\">Summary as a button</summary>\n  <p>A details element with a button-styled summary.</p>\n</details>"
        }
      ],
      "variants": [
        {
          "name": "button-summary",
          "trigger": "<summary role=\"button\">",
          "selector": "&[role=\"button\"]",
          "description": "Summary looks like a button. Add secondary, contrast or outline."
        }
      ],
      "states": [
        {
          "name": "open",
          "trigger": "open",
          "selector": "[open]",
          "description": "Native open attribute."
        }
      ],
      "aria": [
        "details and summary are keyboard accessible and announce expanded state natively. Do not add roles."
      ],
      "tokens": {
        "reads": [
          "--pico-accordion-active-summary-color",
          "--pico-accordion-border-color",
          "--pico-accordion-close-summary-color",
          "--pico-accordion-open-summary-color",
          "--pico-border-width",
          "--pico-icon-chevron",
          "--pico-line-height",
          "--pico-outline-width",
          "--pico-primary-focus",
          "--pico-spacing",
          "--pico-transition"
        ],
        "defines": []
      },
      "js": null
    },
    {
      "name": "card",
      "category": "components",
      "optIn": {
        "kind": "core",
        "css": "src/components/card.css",
        "module": "components/card",
        "excludeWith": "components/card"
      },
      "summary": "Card: article, with header and footer as direct children",
      "use": "article is a card. header and footer as direct children get their own bands.",
      "markup": "<article>\n  <header>Card header</header>\n  Card body with some text inside it.\n  <footer>Card footer</footer>\n</article>",
      "examples": [
        {
          "label": "Card with header and footer",
          "html": "<article>\n  <header>Card header</header>\n  Card body with some text inside it.\n  <footer>Card footer</footer>\n</article>"
        }
      ],
      "variants": [],
      "states": [],
      "aria": ["article is a landmark-free sectioning element, so repeat it freely in lists."],
      "tokens": {
        "reads": [
          "--pico-block-spacing-horizontal",
          "--pico-block-spacing-vertical",
          "--pico-border-width",
          "--pico-card-background-color",
          "--pico-card-border-color",
          "--pico-card-border-radius",
          "--pico-card-box-shadow",
          "--pico-card-sectioning-background-color"
        ],
        "defines": []
      },
      "js": null
    },
    {
      "name": "dropdown",
      "category": "components",
      "optIn": {
        "kind": "core",
        "css": "src/components/dropdown.css",
        "module": "components/dropdown",
        "excludeWith": "components/dropdown"
      },
      "summary": "Dropdown: details.dropdown",
      "use": "details.dropdown with a list. Select-like and multi-choice menus put radios or checkboxes in the items.",
      "markup": "<details class=\"dropdown\">\n  <summary>Dropdown</summary>\n  <ul>\n    <li><a href=\"#\">Solid</a></li>\n    <li><a href=\"#\">Liquid</a></li>\n    <li><a href=\"#\" aria-current=\"true\">Gas</a></li>\n    <li><a href=\"#\">Plasma</a></li>\n  </ul>\n</details>",
      "examples": [
        {
          "label": "Dropdown menu",
          "html": "<details class=\"dropdown\">\n  <summary>Dropdown</summary>\n  <ul>\n    <li><a href=\"#\">Solid</a></li>\n    <li><a href=\"#\">Liquid</a></li>\n    <li><a href=\"#\" aria-current=\"true\">Gas</a></li>\n    <li><a href=\"#\">Plasma</a></li>\n  </ul>\n</details>"
        },
        {
          "label": "Select-like dropdown with radios",
          "html": "<details class=\"dropdown\" open>\n  <summary>Select-like dropdown</summary>\n  <ul>\n    <li>\n      <label><input type=\"radio\" name=\"phase\" value=\"solid\" checked /> Solid</label>\n    </li>\n    <li>\n      <label><input type=\"radio\" name=\"phase\" value=\"liquid\" /> Liquid</label>\n    </li>\n    <li>\n      <label><input type=\"radio\" name=\"phase\" value=\"gas\" /> Gas</label>\n    </li>\n  </ul>\n</details>"
        }
      ],
      "variants": [
        {
          "name": "dropdown",
          "trigger": "class=\"dropdown\"",
          "selector": "details.dropdown",
          "description": "The hook on details."
        },
        {
          "name": "button-summary",
          "trigger": "<summary role=\"button\">",
          "selector": "[role=\"button\"]",
          "description": "Summary looks like a button."
        }
      ],
      "states": [
        {
          "name": "current item",
          "trigger": "aria-current=\"true\"",
          "selector": "[aria-current]",
          "description": "Highlights the chosen link."
        }
      ],
      "aria": [
        "It is a disclosure, not an ARIA menu: no role=menu. It does not close on outside click or Escape by itself."
      ],
      "notes": [
        "For menus that close on outside click and anchor to their button, use the popover pattern."
      ],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-border-width",
          "--pico-card-border-radius",
          "--pico-dropdown-background-color",
          "--pico-dropdown-border-color",
          "--pico-dropdown-box-shadow",
          "--pico-dropdown-color",
          "--pico-dropdown-hover-background-color",
          "--pico-form-element-active-background-color",
          "--pico-form-element-background-color",
          "--pico-form-element-invalid-border-color",
          "--pico-form-element-invalid-focus-color",
          "--pico-form-element-placeholder-color",
          "--pico-form-element-spacing-horizontal",
          "--pico-form-element-spacing-vertical",
          "--pico-form-element-valid-border-color",
          "--pico-form-element-valid-focus-color",
          "--pico-icon-chevron",
          "--pico-line-height",
          "--pico-nav-element-spacing-vertical",
          "--pico-nav-link-spacing-horizontal",
          "--pico-primary-focus",
          "--pico-spacing",
          "--pico-transition"
        ],
        "defines": [
          "--pico-form-element-active-border-color",
          "--pico-form-element-border-color",
          "--pico-form-element-focus-color",
          "--pico-outline-width"
        ]
      },
      "js": null
    },
    {
      "name": "group",
      "category": "components",
      "optIn": {
        "kind": "core",
        "css": "src/components/group.css",
        "module": "components/group",
        "excludeWith": "components/group"
      },
      "summary": "Group: [role=group], [role=search]",
      "use": "Joins controls into one bar: fieldset or div with role=\"group\", or a form with role=\"search\".",
      "markup": "<fieldset role=\"group\">\n  <input type=\"email\" placeholder=\"Enter your email\" autocomplete=\"off\" />\n  <input type=\"submit\" value=\"Subscribe\" />\n</fieldset>",
      "examples": [
        {
          "label": "Input and button",
          "html": "<fieldset role=\"group\">\n  <input type=\"email\" placeholder=\"Enter your email\" autocomplete=\"off\" />\n  <input type=\"submit\" value=\"Subscribe\" />\n</fieldset>"
        },
        {
          "label": "Button group",
          "html": "<div role=\"group\">\n  <button>Save</button>\n  <button class=\"secondary\">Save as</button>\n  <button class=\"contrast\">Share</button>\n</div>"
        },
        {
          "label": "Search form",
          "html": "<form role=\"search\" onsubmit=\"return false\">\n  <input name=\"q\" type=\"search\" placeholder=\"Search\" />\n  <input type=\"submit\" value=\"Search\" />\n</form>"
        }
      ],
      "variants": [
        {
          "name": "group",
          "trigger": "role=\"group\"",
          "selector": "[role=\"group\"]",
          "description": "Controls share borders and one focus ring."
        },
        {
          "name": "search",
          "trigger": "role=\"search\"",
          "selector": "[role=\"search\"]",
          "description": "Same as a group with pill ends."
        }
      ],
      "states": [],
      "aria": ["Name a group with aria-label or a legend when the controls need shared context."],
      "tokens": {
        "reads": [
          "--pico-background-color",
          "--pico-border-width",
          "--pico-contrast-focus",
          "--pico-group-box-shadow-focus-with-input",
          "--pico-outline-width",
          "--pico-primary-border",
          "--pico-primary-hover-border",
          "--pico-secondary-focus",
          "--pico-spacing",
          "--pico-transition"
        ],
        "defines": [
          "--pico-border-radius",
          "--pico-button-box-shadow",
          "--pico-button-hover-box-shadow",
          "--pico-form-element-spacing-horizontal",
          "--pico-group-box-shadow",
          "--pico-group-box-shadow-focus-with-button"
        ]
      },
      "js": null
    },
    {
      "name": "loading",
      "category": "components",
      "optIn": {
        "kind": "core",
        "css": "src/components/loading.css",
        "module": "components/loading",
        "excludeWith": "components/loading"
      },
      "summary": "Loading: [aria-busy=true]",
      "use": "aria-busy=\"true\" shows a spinner before the content. An empty element shows only the spinner.",
      "markup": "<button aria-busy=\"true\">Please wait</button>\n<article aria-busy=\"true\"></article>",
      "examples": [
        {
          "label": "Busy button and busy card",
          "html": "<button aria-busy=\"true\">Please wait</button>\n<article aria-busy=\"true\"></article>"
        }
      ],
      "variants": [],
      "states": [
        {
          "name": "busy",
          "trigger": "aria-busy=\"true\"",
          "selector": "[aria-busy=\"true\"]",
          "description": "Spinner before the content. Not applied to inputs, selects, textareas, html or forms."
        }
      ],
      "aria": [
        "aria-busy is the state, not a class. An icon-only busy button needs an aria-label."
      ],
      "tokens": {
        "reads": ["--pico-icon-loading", "--pico-spacing"],
        "defines": []
      },
      "js": null
    },
    {
      "name": "modal",
      "category": "components",
      "optIn": {
        "kind": "core",
        "css": "src/components/modal.css",
        "module": "components/modal",
        "excludeWith": "components/modal"
      },
      "summary": "Modal: dialog",
      "use": "dialog with an article inside. Opened with showModal() or the open attribute.",
      "markup": "<dialog open>\n  <article>\n    <header>\n      <button aria-label=\"Close\" rel=\"prev\"></button>\n      <p><strong>Confirm your order</strong></p>\n    </header>\n    <p>\n      Your cart has three items and ships on Friday. You can still change the address until\n      then.\n    </p>\n    <footer>\n      <button class=\"secondary\">Cancel</button>\n      <button>Confirm</button>\n    </footer>\n  </article>\n</dialog>",
      "examples": [
        {
          "label": "Modal dialog",
          "html": "<dialog open>\n  <article>\n    <header>\n      <button aria-label=\"Close\" rel=\"prev\"></button>\n      <p><strong>Confirm your order</strong></p>\n    </header>\n    <p>\n      Your cart has three items and ships on Friday. You can still change the address until\n      then.\n    </p>\n    <footer>\n      <button class=\"secondary\">Cancel</button>\n      <button>Confirm</button>\n    </footer>\n  </article>\n</dialog>"
        }
      ],
      "variants": [
        {
          "name": "close button",
          "trigger": "<button aria-label=\"Close\" rel=\"prev\">",
          "selector": "[rel=\"prev\"]",
          "description": "Close icon in the article header."
        }
      ],
      "states": [
        {
          "name": "open",
          "trigger": "open",
          "selector": ":not([open])",
          "description": "Closed dialogs are display: none."
        },
        {
          "name": "page locked",
          "trigger": "class=\"modal-is-open\" on html",
          "selector": ".modal-is-open",
          "description": "Stops page scroll while a dialog is open. showModal() alone does not set it."
        }
      ],
      "aria": [
        "Use dialog and showModal(). The browser traps focus and handles Escape.",
        "Give the close button an aria-label and put the title in the header."
      ],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-card-border-radius",
          "--pico-color",
          "--pico-dropdown-background-color",
          "--pico-dropdown-box-shadow",
          "--pico-icon-close",
          "--pico-modal-overlay-backdrop-filter",
          "--pico-modal-overlay-background-color",
          "--pico-scrollbar-width",
          "--pico-spacing",
          "--pico-transition"
        ],
        "defines": [
          "--pico-block-spacing-horizontal",
          "--pico-block-spacing-vertical",
          "--pico-card-background-color",
          "--pico-card-box-shadow",
          "--pico-card-sectioning-background-color"
        ]
      },
      "js": {
        "description": "Open and close with the dialog API. The page class is optional and only locks scrolling.",
        "language": "javascript",
        "code": "const dialog = document.querySelector(\"dialog\");\ndialog.showModal();\n// later\ndialog.close();"
      }
    },
    {
      "name": "nav",
      "category": "components",
      "optIn": {
        "kind": "core",
        "css": "src/components/nav.css",
        "module": "components/nav",
        "excludeWith": "components/nav"
      },
      "summary": "Nav: nav, aside nav, nav[aria-label=breadcrumb]",
      "use": "nav with two ul lists: brand on the left, links on the right. nav[aria-label=breadcrumb] is a breadcrumb.",
      "markup": "<nav>\n  <ul>\n    <li><strong>Acme Corp</strong></li>\n  </ul>\n  <ul>\n    <li><a href=\"#\">About</a></li>\n    <li><a href=\"#\">Services</a></li>\n    <li><a href=\"#\" role=\"button\">Contact</a></li>\n  </ul>\n</nav>",
      "examples": [
        {
          "label": "Navigation bar",
          "html": "<nav>\n  <ul>\n    <li><strong>Acme Corp</strong></li>\n  </ul>\n  <ul>\n    <li><a href=\"#\">About</a></li>\n    <li><a href=\"#\">Services</a></li>\n    <li><a href=\"#\" role=\"button\">Contact</a></li>\n  </ul>\n</nav>"
        },
        {
          "label": "Breadcrumb",
          "html": "<nav aria-label=\"breadcrumb\">\n  <ul>\n    <li><a href=\"#\">Home</a></li>\n    <li><a href=\"#\">Docs</a></li>\n    <li><a href=\"#\" aria-current=\"page\">Current page</a></li>\n  </ul>\n</nav>"
        }
      ],
      "variants": [
        {
          "name": "breadcrumb",
          "trigger": "aria-label=\"breadcrumb\"",
          "selector": "nav[aria-label=\"breadcrumb\"]",
          "description": "Slash separated trail."
        },
        {
          "name": "vertical nav",
          "trigger": "<aside><nav>",
          "selector": "aside nav",
          "description": "Stacked links in a sidebar."
        }
      ],
      "states": [
        {
          "name": "current",
          "trigger": "aria-current=\"page\"",
          "selector": "[aria-current]",
          "description": "Marks the current link."
        }
      ],
      "aria": ["Name each nav with aria-label when a page has more than one."],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-color",
          "--pico-form-element-spacing-vertical",
          "--pico-muted-color",
          "--pico-nav-breadcrumb-divider",
          "--pico-nav-element-spacing-horizontal",
          "--pico-nav-element-spacing-vertical",
          "--pico-nav-link-spacing-horizontal",
          "--pico-nav-link-spacing-vertical",
          "--pico-spacing"
        ],
        "defines": []
      },
      "js": null
    },
    {
      "name": "progress",
      "category": "components",
      "optIn": {
        "kind": "core",
        "css": "src/components/progress.css",
        "module": "components/progress",
        "excludeWith": "components/progress"
      },
      "summary": "Progress: progress",
      "use": "progress with value and max. Without value it is an indeterminate bar.",
      "markup": "<progress value=\"35\" max=\"100\"></progress>",
      "examples": [
        {
          "label": "Progress",
          "html": "<progress value=\"35\" max=\"100\"></progress>"
        }
      ],
      "variants": [],
      "states": [
        {
          "name": "indeterminate",
          "trigger": "no value attribute",
          "selector": ":indeterminate",
          "description": "Sliding bar. Static when reduced motion is requested."
        }
      ],
      "aria": ["Label it with aria-label or a label element."],
      "tokens": {
        "reads": [
          "--pico-primary",
          "--pico-progress-background-color",
          "--pico-progress-color",
          "--pico-spacing",
          "--pico-transition"
        ],
        "defines": []
      },
      "js": null
    },
    {
      "name": "tooltip",
      "category": "components",
      "optIn": {
        "kind": "core",
        "css": "src/components/tooltip.css",
        "module": "components/tooltip",
        "excludeWith": "components/tooltip"
      },
      "summary": "Tooltip: [data-tooltip] with [data-placement]",
      "use": "data-tooltip on any element shows a bubble on hover and focus. Not for essential information.",
      "markup": "<a href=\"#\" data-tooltip=\"On the bottom\" data-placement=\"bottom\">Bottom</a>",
      "examples": [
        {
          "label": "Tooltip on a link",
          "html": "<a href=\"#\" data-tooltip=\"On the bottom\" data-placement=\"bottom\">Bottom</a>"
        }
      ],
      "variants": [
        {
          "name": "placement",
          "trigger": "data-placement=\"top|bottom|left|right\"",
          "selector": "[data-placement",
          "description": "Where the bubble opens. Default is top."
        }
      ],
      "states": [],
      "aria": [
        "The text is not a name or description for assistive technology. Put the same text in the element or in aria-label."
      ],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-dropdown-box-shadow",
          "--pico-line-height",
          "--pico-muted-color",
          "--pico-text-underline-offset",
          "--pico-tooltip-background-color",
          "--pico-tooltip-color"
        ],
        "defines": ["--pico-tooltip-caret-slide-to", "--pico-tooltip-slide-to"]
      },
      "js": null
    },
    {
      "name": "popover",
      "category": "components",
      "optIn": {
        "kind": "core",
        "css": "src/components/popover.css",
        "module": "components/popover",
        "excludeWith": "components/popover"
      },
      "summary": "Popover: [popover] menus, tooltips and cards, opt-in and not part of v2.1.1",
      "use": "Native popover API: menus, hint tooltips and cards, anchored with CSS anchor positioning. Not in Pico CSS v2.1.1.",
      "markup": "<button id=\"menu-invoker\" popovertarget=\"menu\">Actions</button>\n<ul popover id=\"menu\">\n  <li><a href=\"#\">Edit</a></li>\n  <li><a href=\"#\" aria-current=\"page\">Duplicate</a></li>\n  <li><a href=\"#\">Archive</a></li>\n</ul>",
      "examples": [
        {
          "label": "Dropdown menu",
          "html": "<button id=\"menu-invoker\" popovertarget=\"menu\">Actions</button>\n<ul popover id=\"menu\">\n  <li><a href=\"#\">Edit</a></li>\n  <li><a href=\"#\" aria-current=\"page\">Duplicate</a></li>\n  <li><a href=\"#\">Archive</a></li>\n</ul>"
        },
        {
          "label": "Hint tooltip",
          "html": "<button id=\"hint-invoker\" popovertarget=\"hint-tip\" class=\"secondary\">Hint tooltip</button>\n<div popover=\"hint\" id=\"hint-tip\">Saved to your account</div>"
        },
        {
          "label": "Card popover",
          "html": "<button id=\"card-invoker\" popovertarget=\"card\">Card popover</button>\n<div popover=\"manual\" id=\"card\">\n  <article>\n    <header><strong>Heads up</strong></header>\n    <p>A bare popover with an article inside looks like a card.</p>\n    <footer><button popovertarget=\"card\" popovertargetaction=\"hide\">Got it</button></footer>\n  </article>\n</div>"
        }
      ],
      "variants": [
        {
          "name": "menu",
          "trigger": "<ul popover id=\"m\"> with <button popovertarget=\"m\">",
          "selector": ":is(ul, menu)[popover]",
          "description": "Anchored list menu."
        },
        {
          "name": "hint",
          "trigger": "popover=\"hint\"",
          "selector": "[popover=\"hint\"]",
          "description": "Tooltip bubble."
        },
        {
          "name": "tooltip role",
          "trigger": "popover role=\"tooltip\"",
          "selector": "[popover][role=\"tooltip\"]",
          "description": "Same bubble for popover=\"manual\"."
        },
        {
          "name": "card",
          "trigger": "popover with an article inside",
          "selector": ":has(> article)",
          "description": "The article is the card."
        }
      ],
      "states": [],
      "aria": [
        "Needs no script: popovertarget wires the button. The browser handles light dismiss and Escape for auto popovers.",
        "Where anchor positioning is missing, popovers are centered by the browser."
      ],
      "tokens": {
        "reads": [
          "--pico-block-spacing-horizontal",
          "--pico-block-spacing-vertical",
          "--pico-border-radius",
          "--pico-border-width",
          "--pico-card-background-color",
          "--pico-card-border-color",
          "--pico-card-border-radius",
          "--pico-card-box-shadow",
          "--pico-color",
          "--pico-dropdown-background-color",
          "--pico-dropdown-border-color",
          "--pico-dropdown-box-shadow",
          "--pico-dropdown-color",
          "--pico-dropdown-hover-background-color",
          "--pico-line-height",
          "--pico-spacing",
          "--pico-tooltip-background-color",
          "--pico-tooltip-color",
          "--pico-transition"
        ],
        "defines": []
      },
      "js": null
    },
    {
      "name": "accessibility",
      "category": "utilities",
      "optIn": {
        "kind": "core",
        "css": "src/utilities/accessibility.css",
        "module": "utilities/accessibility",
        "excludeWith": "utilities/accessibility"
      },
      "summary": "Accessibility: [aria-*], [disabled], [tabindex], touch-action",
      "use": "Cursor and touch-action rules driven by ARIA and disabled attributes, plus dir=\"rtl\".",
      "markup": null,
      "examples": [],
      "variants": [],
      "states": [],
      "aria": ["Style state with aria-* and native attributes, which this module relies on."],
      "tokens": {
        "reads": [],
        "defines": []
      },
      "js": null
    },
    {
      "name": "reduce-motion",
      "category": "utilities",
      "optIn": {
        "kind": "core",
        "css": "src/utilities/reduce-motion.css",
        "module": "utilities/reduce-motion",
        "excludeWith": "utilities/reduce-motion"
      },
      "summary": "Reduced motion: prefers-reduced-motion",
      "use": "Turns transitions and animations off for prefers-reduced-motion: reduce.",
      "markup": null,
      "examples": [],
      "variants": [],
      "states": [],
      "aria": [],
      "tokens": {
        "reads": [],
        "defines": []
      },
      "js": null
    },
    {
      "name": "tabs",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/tabs.css",
        "cdn": "css/extras/tabs.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/tabs",
        "config": "@pico { extras: tabs; }",
        "cli": "pico-reforged build --extras tabs"
      },
      "summary": "Tabs: [role=tablist] with [role=tab] and [role=tabpanel], or [data-tabs] with radios and labels",
      "use": "WAI-ARIA tabs, or a no-script variant built from radios.",
      "markup": "<div>\n  <div role=\"tablist\" aria-label=\"Account settings\">\n    <button type=\"button\" role=\"tab\" id=\"tab-profile\" aria-selected=\"true\" aria-controls=\"panel-profile\">Profile</button>\n    <button type=\"button\" role=\"tab\" id=\"tab-billing\" aria-selected=\"false\" aria-controls=\"panel-billing\" tabindex=\"-1\">Billing</button>\n  </div>\n  <section role=\"tabpanel\" id=\"panel-profile\" aria-labelledby=\"tab-profile\">\n    <form>\n      <label>\n        Full name\n        <input name=\"name\" autocomplete=\"name\" value=\"Ana Ribeiro\" />\n      </label>\n      <label>\n        Work email\n        <input type=\"email\" name=\"email\" autocomplete=\"email\" value=\"ana@acme.example\" />\n      </label>\n      <button type=\"submit\">Save changes</button>\n    </form>\n  </section>\n  <section role=\"tabpanel\" id=\"panel-billing\" aria-labelledby=\"tab-billing\" tabindex=\"0\" hidden>\n    <p>You are on the <strong>Growth</strong> plan, billed monthly. The next invoice is on 1 November.</p>\n    <p><a href=\"#\">Download invoices</a></p>\n  </section>\n</div>",
      "examples": [
        {
          "label": "ARIA tabs (needs the script)",
          "html": "<div>\n  <div role=\"tablist\" aria-label=\"Account settings\">\n    <button type=\"button\" role=\"tab\" id=\"tab-profile\" aria-selected=\"true\" aria-controls=\"panel-profile\">Profile</button>\n    <button type=\"button\" role=\"tab\" id=\"tab-billing\" aria-selected=\"false\" aria-controls=\"panel-billing\" tabindex=\"-1\">Billing</button>\n  </div>\n  <section role=\"tabpanel\" id=\"panel-profile\" aria-labelledby=\"tab-profile\">\n    <form>\n      <label>\n        Full name\n        <input name=\"name\" autocomplete=\"name\" value=\"Ana Ribeiro\" />\n      </label>\n      <label>\n        Work email\n        <input type=\"email\" name=\"email\" autocomplete=\"email\" value=\"ana@acme.example\" />\n      </label>\n      <button type=\"submit\">Save changes</button>\n    </form>\n  </section>\n  <section role=\"tabpanel\" id=\"panel-billing\" aria-labelledby=\"tab-billing\" tabindex=\"0\" hidden>\n    <p>You are on the <strong>Growth</strong> plan, billed monthly. The next invoice is on 1 November.</p>\n    <p><a href=\"#\">Download invoices</a></p>\n  </section>\n</div>"
        },
        {
          "label": "Radio tabs (no script)",
          "html": "<div data-tabs>\n  <input type=\"radio\" name=\"plan-view\" id=\"plan-monthly\" checked />\n  <label for=\"plan-monthly\">Monthly</label>\n  <input type=\"radio\" name=\"plan-view\" id=\"plan-yearly\" />\n  <label for=\"plan-yearly\">Yearly</label>\n  <section>\n    <p>Growth is EUR 24.90 per seat each month. Cancel any time.</p>\n  </section>\n  <section>\n    <p>Growth is EUR 249 per seat each year, two months free.</p>\n  </section>\n</div>"
        }
      ],
      "variants": [
        {
          "name": "vertical",
          "trigger": "aria-orientation=\"vertical\" on the tablist",
          "selector": "[aria-orientation=\"vertical\"]",
          "description": "Tabs beside the panel."
        },
        {
          "name": "radio tabs",
          "trigger": "data-tabs on a wrapper of radios, labels and sections",
          "selector": "[data-tabs]",
          "description": "No script. Up to ten tabs per group."
        }
      ],
      "states": [
        {
          "name": "selected",
          "trigger": "aria-selected=\"true\"",
          "selector": "[aria-selected=\"true\"]",
          "description": "The active tab. Exactly one per list."
        },
        {
          "name": "disabled",
          "trigger": "aria-disabled=\"true\"",
          "selector": "[aria-disabled=\"true\"]",
          "description": "Use this and not disabled, so the tab stays focusable."
        }
      ],
      "aria": [
        "Roles tablist, tab and tabpanel. aria-controls on each tab points at its panel, aria-labelledby on each panel points back.",
        "Selected tab has tabindex 0, others -1. Hide inactive panels with hidden.",
        "Arrow keys, Home and End move the selection (the script does this)."
      ],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-border-width",
          "--pico-color",
          "--pico-form-element-disabled-opacity",
          "--pico-line-height",
          "--pico-muted-border-color",
          "--pico-muted-color",
          "--pico-nav-link-spacing-horizontal",
          "--pico-nav-link-spacing-vertical",
          "--pico-outline-width",
          "--pico-primary",
          "--pico-primary-background",
          "--pico-primary-focus",
          "--pico-primary-hover",
          "--pico-primary-subtle-background",
          "--pico-spacing",
          "--pico-transition"
        ],
        "defines": [
          "--pico-tabs-active-color",
          "--pico-tabs-border-color",
          "--pico-tabs-indicator-color",
          "--pico-tabs-indicator-width",
          "--pico-tabs-tab-color",
          "--pico-tabs-tab-hover-color"
        ]
      },
      "js": {
        "description": "Selection and keyboard handling for the ARIA variant.",
        "language": "javascript",
        "code": "document.querySelectorAll('[role=\"tablist\"]').forEach((list) => {\n  const tabs = [...list.querySelectorAll('[role=\"tab\"]')];\n  const vertical = list.getAttribute(\"aria-orientation\") === \"vertical\";\n\n  const select = (tab, { focus = true } = {}) => {\n    tabs.forEach((t) => {\n      const on = t === tab;\n      t.setAttribute(\"aria-selected\", String(on));\n      t.tabIndex = on ? 0 : -1;\n      document.getElementById(t.getAttribute(\"aria-controls\")).hidden = !on;\n    });\n    if (focus) tab.focus();\n    tab.scrollIntoView({ inline: \"nearest\", block: \"nearest\" });\n  };\n\n  tabs.forEach((tab, i) => {\n    tab.addEventListener(\"click\", () => {\n      if (tab.getAttribute(\"aria-disabled\") !== \"true\") select(tab, { focus: false });\n    });\n    tab.addEventListener(\"keydown\", (e) => {\n      const rtl = getComputedStyle(list).direction === \"rtl\";\n      const prev = vertical ? \"ArrowUp\" : rtl ? \"ArrowRight\" : \"ArrowLeft\";\n      const next = vertical ? \"ArrowDown\" : rtl ? \"ArrowLeft\" : \"ArrowRight\";\n      let target = null;\n      if (e.key === next) target = tabs[(i + 1) % tabs.length];\n      else if (e.key === prev) target = tabs[(i - 1 + tabs.length) % tabs.length];\n      else if (e.key === \"Home\") target = tabs[0];\n      else if (e.key === \"End\") target = tabs[tabs.length - 1];\n      if (target) {\n        e.preventDefault();\n        if (target.getAttribute(\"aria-disabled\") === \"true\") target.focus();\n        else select(target);\n      }\n    });\n  });\n});"
      }
    },
    {
      "name": "alert",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/alert.css",
        "cdn": "css/extras/alert.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/alert",
        "config": "@pico { extras: alert; }",
        "cli": "pico-reforged build --extras alert"
      },
      "summary": "Alert: [role=alert], [role=status] and output with a data-variant (info, success, warning, danger)",
      "use": "Inline status message. An element with a role (alert, status or output) and data-variant becomes an alert.",
      "markup": "<div role=\"status\" data-variant=\"info\">\n  <strong>Tip.</strong> You can drag files onto the table to upload them.\n</div>\n<div role=\"alert\" data-variant=\"danger\">\n  <strong>Payment failed.</strong> Your card was declined. Try another payment method.\n</div>",
      "examples": [
        {
          "label": "Info and danger",
          "html": "<div role=\"status\" data-variant=\"info\">\n  <strong>Tip.</strong> You can drag files onto the table to upload them.\n</div>\n<div role=\"alert\" data-variant=\"danger\">\n  <strong>Payment failed.</strong> Your card was declined. Try another payment method.\n</div>"
        },
        {
          "label": "Dismissible",
          "html": "<div role=\"status\" data-variant=\"warning\">\n  <strong>Heads up.</strong> Your export will take a few minutes to finish.\n  <button type=\"button\" data-dismiss aria-label=\"Dismiss: export notice\"></button>\n</div>"
        }
      ],
      "variants": [
        {
          "name": "info",
          "trigger": "data-variant=\"info\"",
          "selector": "[data-variant]",
          "description": "Default accent."
        },
        {
          "name": "success",
          "trigger": "data-variant=\"success\"",
          "selector": "[data-variant=\"success\"]",
          "description": "Green accent."
        },
        {
          "name": "warning",
          "trigger": "data-variant=\"warning\"",
          "selector": "[data-variant=\"warning\"]",
          "description": "Amber accent."
        },
        {
          "name": "danger",
          "trigger": "data-variant=\"danger\"",
          "selector": "[data-variant=\"danger\"]",
          "description": "Red accent."
        }
      ],
      "states": [
        {
          "name": "dismiss button",
          "trigger": "<button data-dismiss aria-label=\"...\"> as a direct child",
          "selector": "data-dismiss",
          "description": "Close glyph. Needs the script."
        },
        {
          "name": "hidden",
          "trigger": "hidden",
          "selector": "[hidden]",
          "description": "Hides the alert."
        }
      ],
      "aria": [
        "Use role=\"alert\" for urgent errors and role=\"status\" for the rest. An alert present at page load is not announced; fill an existing empty container to announce.",
        "Do not move focus into an alert when it appears and do not auto-dismiss it."
      ],
      "tokens": {
        "reads": [
          "--pico-background-color",
          "--pico-border-radius",
          "--pico-border-width",
          "--pico-card-border-radius",
          "--pico-color",
          "--pico-form-element-invalid-border-color",
          "--pico-form-element-valid-border-color",
          "--pico-line-height",
          "--pico-outline-width",
          "--pico-primary",
          "--pico-primary-focus",
          "--pico-spacing",
          "--pico-transition",
          "--pico-typography-spacing-vertical"
        ],
        "defines": [
          "--pico-alert-accent",
          "--pico-alert-background-color",
          "--pico-alert-color",
          "--pico-alert-danger-accent",
          "--pico-alert-success-accent",
          "--pico-alert-warning-accent"
        ]
      },
      "js": {
        "description": "Dismiss with hidden, not remove(), so the alert can come back.",
        "language": "javascript",
        "code": "document.addEventListener(\"click\", (event) => {\n  const button = event.target.closest(\"[data-variant] > button[data-dismiss]\");\n  if (!button) return;\n  const alert = button.parentElement;\n  const heading = alert.closest(\"section, article, main\")?.querySelector(\"h1, h2, h3\");\n  alert.hidden = true;\n  if (heading) {\n    heading.tabIndex = -1;\n    heading.focus();\n  }\n});"
      }
    },
    {
      "name": "toast",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/toast.css",
        "cdn": "css/extras/toast.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/toast",
        "config": "@pico { extras: toast; }",
        "cli": "pico-reforged build --extras toast"
      },
      "summary": "Toast: <section popover=\"manual\" role=\"status\"> stack with one <article> per notification",
      "use": "Stack of transient notifications in a popover=\"manual\" section with role=\"status\". One article per toast.",
      "markup": "<section\n  id=\"toaster\"\n  popover=\"manual\"\n  role=\"status\"\n  aria-label=\"Notifications\"\n  aria-atomic=\"false\"\n  data-placement=\"bottom-end\"\n>\n  <article>\n    <p>Draft saved.</p>\n    <button type=\"button\" aria-label=\"Dismiss notification\">&times;</button>\n  </article>\n</section>",
      "examples": [
        {
          "label": "Toast stack",
          "html": "<section\n  id=\"toaster\"\n  popover=\"manual\"\n  role=\"status\"\n  aria-label=\"Notifications\"\n  aria-atomic=\"false\"\n  data-placement=\"bottom-end\"\n>\n  <article>\n    <p>Draft saved.</p>\n    <button type=\"button\" aria-label=\"Dismiss notification\">&times;</button>\n  </article>\n</section>"
        }
      ],
      "variants": [
        {
          "name": "placement",
          "trigger": "data-placement=\"top|bottom\" + \"start|center|end\"",
          "selector": "data-placement",
          "description": "Where the stack sits. Default bottom-end."
        },
        {
          "name": "action button",
          "trigger": "<button> without aria-label next to the message",
          "selector": "[popover][role=\"status\"] > article > :is(button",
          "description": "Text action such as Undo."
        },
        {
          "name": "dismiss button",
          "trigger": "<button aria-label=\"...\">",
          "selector": "[aria-label]",
          "description": "Icon-only dismiss."
        }
      ],
      "states": [
        {
          "name": "danger",
          "trigger": "role=\"alert\" on the article",
          "selector": "&[role=\"alert\"]",
          "description": "Red accent. Set --pico-toast-accent yourself for other tones."
        }
      ],
      "aria": [
        "The stack is a status live region (aria-atomic=\"false\"). Keep it last in body so DOM order is tab order.",
        "Do not time out a toast that has an action or reports an error."
      ],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-border-width",
          "--pico-card-border-radius",
          "--pico-color",
          "--pico-dropdown-background-color",
          "--pico-dropdown-border-color",
          "--pico-dropdown-box-shadow",
          "--pico-font-weight",
          "--pico-form-element-invalid-border-color",
          "--pico-line-height",
          "--pico-muted-color",
          "--pico-outline-width",
          "--pico-primary",
          "--pico-primary-background",
          "--pico-primary-focus",
          "--pico-primary-hover",
          "--pico-spacing",
          "--pico-transition"
        ],
        "defines": [
          "--pico-toast-accent",
          "--pico-toast-gap",
          "--pico-toast-inset",
          "--pico-toast-width"
        ]
      },
      "js": {
        "description": "Open the stack once; add articles from your own code.",
        "language": "javascript",
        "code": "document.getElementById(\"toaster\").showPopover?.();"
      }
    },
    {
      "name": "badge",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/badge.css",
        "cdn": "css/extras/badge.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/badge",
        "config": "@pico { extras: badge; }",
        "cli": "pico-reforged build --extras badge"
      },
      "summary": "Badge: [data-badge] on data, span, a or button, value picks the color. Gotcha: every direct child span of a badge is visually hidden, because that is how screen reader context is written. Wrap icons or styled text in an inner element other than a span (for example <i> or <b>), or nest them deeper.",
      "use": "Labels, counters and dots. data-badge on span, data or any inline element.",
      "markup": "<p>\n  <span data-badge>Default</span>\n  <span data-badge=\"secondary\">Secondary</span>\n  <span data-badge=\"contrast\">Contrast</span>\n  <span data-badge=\"success\">Active</span>\n  <span data-badge=\"warning\">Pending</span>\n  <span data-badge=\"danger\">Failed</span>\n</p>",
      "examples": [
        {
          "label": "Variants",
          "html": "<p>\n  <span data-badge>Default</span>\n  <span data-badge=\"secondary\">Secondary</span>\n  <span data-badge=\"contrast\">Contrast</span>\n  <span data-badge=\"success\">Active</span>\n  <span data-badge=\"warning\">Pending</span>\n  <span data-badge=\"danger\">Failed</span>\n</p>"
        },
        {
          "label": "Counter",
          "html": "<data value=\"42\" data-badge=\"danger\">42</data>"
        },
        {
          "label": "Dot",
          "html": "<span data-badge=\"success\" aria-hidden=\"true\"></span>"
        }
      ],
      "variants": [
        {
          "name": "default",
          "trigger": "data-badge",
          "selector": "[data-badge]",
          "description": "Primary fill."
        },
        {
          "name": "secondary",
          "trigger": "data-badge=\"secondary\"",
          "selector": "[data-badge=\"secondary\"]",
          "description": "Slate fill."
        },
        {
          "name": "contrast",
          "trigger": "data-badge=\"contrast\"",
          "selector": "[data-badge=\"contrast\"]",
          "description": "Highest contrast fill."
        },
        {
          "name": "success",
          "trigger": "data-badge=\"success\"",
          "selector": "[data-badge=\"success\"]",
          "description": "Green fill."
        },
        {
          "name": "warning",
          "trigger": "data-badge=\"warning\"",
          "selector": "[data-badge=\"warning\"]",
          "description": "Amber fill."
        },
        {
          "name": "danger",
          "trigger": "data-badge=\"danger\"",
          "selector": "[data-badge=\"danger\"]",
          "description": "Red fill."
        }
      ],
      "states": [
        {
          "name": "dot",
          "trigger": "empty badge",
          "selector": ":empty",
          "description": "A small circle. Mark it aria-hidden and put the meaning in nearby text."
        },
        {
          "name": "hidden",
          "trigger": "hidden",
          "selector": "[hidden]",
          "description": "Hide a zero count."
        }
      ],
      "aria": [
        "Use data with a value attribute for counters. Add a visually hidden span in front for context, such as \"unread messages: \"."
      ],
      "tokens": {
        "reads": [
          "--pico-contrast-background",
          "--pico-contrast-inverse",
          "--pico-primary",
          "--pico-primary-background",
          "--pico-primary-inverse",
          "--pico-secondary-background",
          "--pico-secondary-inverse"
        ],
        "defines": [
          "--pico-badge-background-color",
          "--pico-badge-color",
          "--pico-badge-danger-background-color",
          "--pico-badge-danger-color",
          "--pico-badge-ring-color",
          "--pico-badge-success-background-color",
          "--pico-badge-success-color",
          "--pico-badge-warning-background-color",
          "--pico-badge-warning-color"
        ]
      },
      "js": null
    },
    {
      "name": "avatar",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/avatar.css",
        "cdn": "css/extras/avatar.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/avatar",
        "config": "@pico { extras: avatar; }",
        "cli": "pico-reforged build --extras avatar"
      },
      "summary": "Avatar: user images and initials, <span data-avatar>",
      "use": "Initials or an image in a circle. data-avatar on a span with role=\"img\" and an aria-label.",
      "markup": "<span data-avatar data-status=\"online\" role=\"img\" aria-label=\"Ada Lovelace, online\">AL</span>",
      "examples": [
        {
          "label": "Status dot",
          "html": "<span data-avatar data-status=\"online\" role=\"img\" aria-label=\"Ada Lovelace, online\">AL</span>"
        },
        {
          "label": "Image with initials fallback",
          "html": "<span data-avatar=\"lg\" role=\"img\" aria-label=\"Ada Lovelace\"\n  ><img src=\"image.svg\" alt=\"\" width=\"56\" height=\"56\" />AL</span\n>"
        },
        {
          "label": "Group",
          "html": "<div role=\"group\" aria-label=\"Project members\">\n  <span data-avatar role=\"img\" aria-label=\"Ada Lovelace\">AL</span>\n  <span data-avatar role=\"img\" aria-label=\"Grace Hopper\">GH</span>\n  <span data-avatar role=\"img\" aria-label=\"Alan Turing\">AT</span>\n  <span data-avatar role=\"img\" aria-label=\"3 more people\">+3</span>\n</div>"
        }
      ],
      "variants": [
        {
          "name": "sm",
          "trigger": "data-avatar=\"sm\"",
          "selector": "[data-avatar=\"sm\"]",
          "description": "2rem."
        },
        {
          "name": "lg",
          "trigger": "data-avatar=\"lg\"",
          "selector": "[data-avatar=\"lg\"]",
          "description": "3.5rem."
        },
        {
          "name": "xl",
          "trigger": "data-avatar=\"xl\"",
          "selector": "[data-avatar=\"xl\"]",
          "description": "5rem."
        }
      ],
      "states": [
        {
          "name": "status",
          "trigger": "data-status=\"online|away|busy|offline\"",
          "selector": "[data-status",
          "description": "Dot in the corner. Say the status in the aria-label."
        }
      ],
      "aria": [
        "role=\"img\" with an aria-label that names the person, and the status when there is one.",
        "A link, button or summary that holds only an avatar needs its own aria-label. Without it the control keeps its normal style."
      ],
      "tokens": {
        "reads": [
          "--pico-background-color",
          "--pico-card-background-color",
          "--pico-card-sectioning-background-color",
          "--pico-color",
          "--pico-del-color",
          "--pico-dropdown-background-color",
          "--pico-ins-color",
          "--pico-muted-color",
          "--pico-outline-width",
          "--pico-primary",
          "--pico-primary-hover"
        ],
        "defines": [
          "--pico-avatar-background-color",
          "--pico-avatar-color",
          "--pico-avatar-overlap",
          "--pico-avatar-ring-color",
          "--pico-avatar-size",
          "--pico-avatar-status-away-color",
          "--pico-avatar-status-busy-color",
          "--pico-avatar-status-offline-color",
          "--pico-avatar-status-online-color"
        ]
      },
      "js": {
        "description": "Optional: remove an image that failed to load so the initials show without a broken icon.",
        "language": "javascript",
        "code": "// Optional polish. Without it a failed image still leaves the initials readable,\n// but some browsers draw a broken-image icon over them. This removes the failed <img>.\n// No script? Put onerror=\"this.remove()\" on the <img> instead.\ndocument.addEventListener(\n  \"error\",\n  (event) => {\n    const img = event.target;\n    if (img instanceof HTMLImageElement && img.closest(\"[data-avatar]\")) img.remove();\n  },\n  true,\n);"
      }
    },
    {
      "name": "skeleton",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/skeleton.css",
        "cdn": "css/extras/skeleton.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/skeleton",
        "config": "@pico { extras: skeleton; }",
        "cli": "pico-reforged build --extras skeleton"
      },
      "summary": "Skeleton: empty [data-skeleton] placeholders (line, avatar, block) inside an [aria-busy=\"true\"] container",
      "use": "Loading placeholders. Empty [data-skeleton] elements inside an aria-busy=\"true\" container.",
      "markup": "<article aria-busy=\"true\" aria-label=\"Loading invoice\">\n  <header>\n    <p data-skeleton=\"line\"></p>\n  </header>\n  <p data-skeleton=\"line\"></p>\n  <footer>\n    <p data-skeleton=\"line\"></p>\n  </footer>\n</article>",
      "examples": [
        {
          "label": "Skeleton card",
          "html": "<article aria-busy=\"true\" aria-label=\"Loading invoice\">\n  <header>\n    <p data-skeleton=\"line\"></p>\n  </header>\n  <p data-skeleton=\"line\"></p>\n  <footer>\n    <p data-skeleton=\"line\"></p>\n  </footer>\n</article>"
        }
      ],
      "variants": [
        {
          "name": "line",
          "trigger": "data-skeleton=\"line\"",
          "selector": "[data-skeleton=\"line\"]",
          "description": "A text line. Set inline-size for variety."
        },
        {
          "name": "avatar",
          "trigger": "data-skeleton=\"avatar\"",
          "selector": "[data-skeleton=\"avatar\"]",
          "description": "A circle."
        },
        {
          "name": "block",
          "trigger": "data-skeleton=\"block\"",
          "selector": "[data-skeleton=\"block\"]",
          "description": "A tall block for images or charts."
        }
      ],
      "states": [
        {
          "name": "busy container",
          "trigger": "aria-busy=\"true\"",
          "selector": "[aria-busy=\"true\"]",
          "description": "Replaces the spinner of the loading module. Set aria-busy=\"false\" and swap the content when loaded."
        }
      ],
      "aria": ["Name the busy container with aria-label (\"Loading invoice\")."],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-card-border-radius",
          "--pico-form-element-background-color",
          "--pico-muted-border-color",
          "--pico-typography-spacing-vertical"
        ],
        "defines": [
          "--pico-skeleton-avatar-size",
          "--pico-skeleton-block-size",
          "--pico-skeleton-color",
          "--pico-skeleton-duration",
          "--pico-skeleton-highlight-color",
          "--pico-skeleton-line-height"
        ]
      },
      "js": {
        "description": "Optional htmx wiring that flips aria-busy around a request.",
        "language": "javascript",
        "code": "const setBusy = (el, value) => {\n  if (el && el.hasAttribute(\"aria-busy\")) el.setAttribute(\"aria-busy\", value);\n};\ndocument.addEventListener(\"htmx:beforeRequest\", (e) => setBusy(e.detail.target, \"true\"));\ndocument.addEventListener(\"htmx:afterSettle\", (e) => setBusy(e.detail.target, \"false\"));\nfor (const type of [\"htmx:responseError\", \"htmx:sendError\", \"htmx:sendAbort\"]) {\n  document.addEventListener(type, (e) => setBusy(e.detail.target, \"false\"));\n}"
      }
    },
    {
      "name": "app-shell",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/app-shell.css",
        "cdn": "css/extras/app-shell.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/app-shell",
        "config": "@pico { extras: app-shell; }",
        "cli": "pico-reforged build --extras app-shell"
      },
      "summary": "App shell: body[data-app-shell] with header, aside nav, main and footer",
      "use": "Application layout on body[data-app-shell]: header, a sidebar that is a drawer below 1024px, main and footer.",
      "markup": "<body data-app-shell>\n  <a href=\"#main\">Skip to content</a>\n  <header>\n    <button type=\"button\" popovertarget=\"app-nav\"><span>Menu</span></button>\n    <strong>Brand</strong>\n    <nav aria-label=\"Account\">...</nav>\n  </header>\n  <aside id=\"app-nav\" popover aria-label=\"Sidebar\">\n    <nav aria-label=\"Main\">\n      <ul>\n        <li><a href=\"#home\" aria-current=\"page\">Home</a></li>\n      </ul>\n    </nav>\n  </aside>\n  <main id=\"main\" tabindex=\"-1\">...</main>\n</body>",
      "examples": [
        {
          "label": "Shell skeleton",
          "html": "<body data-app-shell>\n  <a href=\"#main\">Skip to content</a>\n  <header>\n    <button type=\"button\" popovertarget=\"app-nav\"><span>Menu</span></button>\n    <strong>Brand</strong>\n    <nav aria-label=\"Account\">...</nav>\n  </header>\n  <aside id=\"app-nav\" popover aria-label=\"Sidebar\">\n    <nav aria-label=\"Main\">\n      <ul>\n        <li><a href=\"#home\" aria-current=\"page\">Home</a></li>\n      </ul>\n    </nav>\n  </aside>\n  <main id=\"main\" tabindex=\"-1\">...</main>\n</body>"
        }
      ],
      "variants": [
        {
          "name": "shell",
          "trigger": "data-app-shell on body",
          "selector": "body[data-app-shell]",
          "description": "The only hook."
        }
      ],
      "states": [
        {
          "name": "current link",
          "trigger": "aria-current=\"page\"",
          "selector": "[aria-current]",
          "description": "Highlights the link of the page."
        }
      ],
      "aria": [
        "The first child is a skip link. Give each nav an aria-label and main tabindex=\"-1\" so the skip link can focus it.",
        "The menu button uses popovertarget on the aside; below 1024px the aside is a drawer."
      ],
      "tokens": {
        "reads": [
          "--pico-background-color",
          "--pico-block-spacing-horizontal",
          "--pico-block-spacing-vertical",
          "--pico-border-radius",
          "--pico-border-width",
          "--pico-card-sectioning-background-color",
          "--pico-color",
          "--pico-grid-column-gap",
          "--pico-grid-row-gap",
          "--pico-line-height",
          "--pico-modal-overlay-background-color",
          "--pico-muted-border-color",
          "--pico-muted-color",
          "--pico-nav-element-spacing-vertical",
          "--pico-nav-link-spacing-horizontal",
          "--pico-nav-link-spacing-vertical",
          "--pico-outline-width",
          "--pico-primary-focus",
          "--pico-primary-hover",
          "--pico-primary-subtle-background",
          "--pico-secondary",
          "--pico-spacing",
          "--pico-transition"
        ],
        "defines": [
          "--pico-app-shell-background-color",
          "--pico-app-shell-border-color",
          "--pico-app-shell-header-height",
          "--pico-app-shell-nav-background-color",
          "--pico-app-shell-nav-current-background-color",
          "--pico-app-shell-nav-current-color",
          "--pico-app-shell-nav-hover-background-color",
          "--pico-app-shell-nav-muted-color",
          "--pico-app-shell-nav-width",
          "--pico-app-shell-scrim-color"
        ]
      },
      "js": {
        "description": "Optional: focus the first link when the drawer opens and close it on a tap on the scrim.",
        "language": "javascript",
        "code": "const drawer = document.querySelector(\"body[data-app-shell] > aside[popover]\");\nconst toggle = document.querySelector(\"body[data-app-shell] > header > button[popovertarget]\");\nif (drawer && toggle) {\n  drawer.addEventListener(\"toggle\", (e) => {\n    if (e.newState === \"open\") drawer.querySelector(\"a\")?.focus();\n  });\n  // A tap on the scrim lands on the aside itself, which light dismiss ignores\n  drawer.addEventListener(\"click\", (e) => {\n    if (e.target === drawer) drawer.hidePopover();\n  });\n}"
      }
    },
    {
      "name": "data-table",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/data-table.css",
        "cdn": "css/extras/data-table.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/data-table",
        "config": "@pico { extras: data-table; }",
        "cli": "pico-reforged build --extras data-table"
      },
      "summary": "Data table: opt in with data-table on the table. Sortable (aria-sort), selectable (checkbox, aria-selected as styling hook) tables, optionally in a scroll region. Without data-table the only rules that apply are the aria-sort button, data-type and data-density hooks.",
      "use": "Sortable, selectable, sticky-header tables. data-table on the table, optionally inside a focusable region wrapper.",
      "markup": "<div role=\"region\" aria-labelledby=\"orders-caption\" tabindex=\"0\" style=\"--pico-data-table-scroll-max-block-size: 22rem; --pico-data-table-scroll-padding-block-start: 3rem\">\n  <table data-table style=\"min-inline-size: 44rem\">\n    <caption id=\"orders-caption\">Orders, last 30 days</caption>\n    <thead>\n      <tr>\n        <th scope=\"col\"><input type=\"checkbox\" aria-label=\"Select all orders\" /></th>\n        <th scope=\"col\" aria-sort=\"ascending\"><button type=\"button\">Order</button></th>\n        <th scope=\"col\" aria-sort=\"none\"><button type=\"button\">Customer</button></th>\n        <th scope=\"col\" aria-sort=\"none\"><button type=\"button\">Plan</button></th>\n        <th scope=\"col\" aria-sort=\"none\"><button type=\"button\">Date</button></th>\n        <th scope=\"col\">Status</th>\n        <th scope=\"col\" aria-sort=\"none\" data-type=\"numeric\"><button type=\"button\">Total</button></th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr>\n        <td><input type=\"checkbox\" aria-label=\"Select order #1048\" /></td>\n        <th scope=\"row\">#1048</th>\n        <td>Marta Cunha</td>\n        <td>Pro, annual</td>\n        <td>2026-10-12</td>\n        <td>Paid</td>\n        <td data-type=\"numeric\">2,340.00</td>\n      </tr>\n      <tr>\n        <td><input type=\"checkbox\" aria-label=\"Select order #1047\" /></td>\n        <th scope=\"row\">#1047</th>\n        <td>Tiago Neves</td>\n        <td>Team, monthly</td>\n        <td>2026-10-11</td>\n        <td>Pending</td>\n        <td data-type=\"numeric\">189.00</td>\n      </tr>\n      <tr aria-selected=\"true\">\n        <td><input type=\"checkbox\" aria-label=\"Select order #1045\" checked /></td>\n        <th scope=\"row\">#1045</th>\n        <td>Bruno Lacerda</td>\n        <td>Pro, monthly</td>\n        <td>2026-10-09</td>\n        <td>Failed</td>\n        <td data-type=\"numeric\">79.00</td>\n      </tr>\n    </tbody>\n  </table>\n</div>",
      "examples": [
        {
          "label": "Sortable, selectable table in a scroll region",
          "html": "<div role=\"region\" aria-labelledby=\"orders-caption\" tabindex=\"0\" style=\"--pico-data-table-scroll-max-block-size: 22rem; --pico-data-table-scroll-padding-block-start: 3rem\">\n  <table data-table style=\"min-inline-size: 44rem\">\n    <caption id=\"orders-caption\">Orders, last 30 days</caption>\n    <thead>\n      <tr>\n        <th scope=\"col\"><input type=\"checkbox\" aria-label=\"Select all orders\" /></th>\n        <th scope=\"col\" aria-sort=\"ascending\"><button type=\"button\">Order</button></th>\n        <th scope=\"col\" aria-sort=\"none\"><button type=\"button\">Customer</button></th>\n        <th scope=\"col\" aria-sort=\"none\"><button type=\"button\">Plan</button></th>\n        <th scope=\"col\" aria-sort=\"none\"><button type=\"button\">Date</button></th>\n        <th scope=\"col\">Status</th>\n        <th scope=\"col\" aria-sort=\"none\" data-type=\"numeric\"><button type=\"button\">Total</button></th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr>\n        <td><input type=\"checkbox\" aria-label=\"Select order #1048\" /></td>\n        <th scope=\"row\">#1048</th>\n        <td>Marta Cunha</td>\n        <td>Pro, annual</td>\n        <td>2026-10-12</td>\n        <td>Paid</td>\n        <td data-type=\"numeric\">2,340.00</td>\n      </tr>\n      <tr>\n        <td><input type=\"checkbox\" aria-label=\"Select order #1047\" /></td>\n        <th scope=\"row\">#1047</th>\n        <td>Tiago Neves</td>\n        <td>Team, monthly</td>\n        <td>2026-10-11</td>\n        <td>Pending</td>\n        <td data-type=\"numeric\">189.00</td>\n      </tr>\n      <tr aria-selected=\"true\">\n        <td><input type=\"checkbox\" aria-label=\"Select order #1045\" checked /></td>\n        <th scope=\"row\">#1045</th>\n        <td>Bruno Lacerda</td>\n        <td>Pro, monthly</td>\n        <td>2026-10-09</td>\n        <td>Failed</td>\n        <td data-type=\"numeric\">79.00</td>\n      </tr>\n    </tbody>\n  </table>\n</div>"
        }
      ],
      "variants": [
        {
          "name": "data-table",
          "trigger": "data-table on table",
          "selector": "table[data-table]",
          "description": "Opt in. Without it the table keeps core styling."
        },
        {
          "name": "compact",
          "trigger": "data-density=\"compact\" on the table",
          "selector": "table[data-density=\"compact\"]",
          "description": "Tighter cell padding."
        },
        {
          "name": "numeric",
          "trigger": "data-type=\"numeric\" on th and td",
          "selector": "[data-type=\"numeric\"]",
          "description": "Right aligned, tabular numbers."
        }
      ],
      "states": [
        {
          "name": "sortable",
          "trigger": "aria-sort=\"none|ascending|descending\" on th with a button",
          "selector": "th[aria-sort]",
          "description": "Arrow glyph from the state. Sort in your own code."
        },
        {
          "name": "selected row",
          "trigger": "aria-selected=\"true\" on tr",
          "selector": "aria-selected",
          "description": "Row highlight. Keep the row checkbox in step."
        }
      ],
      "aria": [
        "The scroll wrapper needs role=\"region\", a name (aria-labelledby the caption) and tabindex=\"0\".",
        "A sortable th holds a button; aria-sort goes on the th, only one column ascending or descending at a time.",
        "The row checkbox is the accessible control; aria-selected on tr is styling only."
      ],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-border-width",
          "--pico-card-border-radius",
          "--pico-card-sectioning-background-color",
          "--pico-color",
          "--pico-dropdown-hover-background-color",
          "--pico-muted-border-color",
          "--pico-outline-width",
          "--pico-primary-background",
          "--pico-primary-focus",
          "--pico-primary-hover",
          "--pico-primary-subtle-background",
          "--pico-spacing",
          "--pico-typography-spacing-vertical"
        ],
        "defines": [
          "--pico-data-table-compact-padding-block",
          "--pico-data-table-compact-padding-inline",
          "--pico-data-table-head-background-color",
          "--pico-data-table-row-hover-background-color",
          "--pico-data-table-row-selected-background-color",
          "--pico-data-table-scroll-max-block-size",
          "--pico-data-table-scroll-padding-block-start",
          "--pico-data-table-sort-idle-opacity"
        ]
      },
      "js": null
    },
    {
      "name": "pagination",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/pagination.css",
        "cdn": "css/extras/pagination.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/pagination",
        "config": "@pico { extras: pagination; }",
        "cli": "pico-reforged build --extras pagination"
      },
      "summary": "Pagination: nav[aria-label=pagination] (or nav[data-pagination]) with ol, li, a and aria-disabled items",
      "use": "nav[aria-label=pagination] holding an ol of links. nav[data-pagination] for another label.",
      "markup": "<nav aria-label=\"Pagination\">\n  <ol>\n    <li><a href=\"?page=1\" rel=\"prev\">Previous</a></li>\n    <li><a href=\"?page=1\" aria-label=\"Page 1\">1</a></li>\n    <li><a href=\"?page=2\" aria-label=\"Page 2\" aria-current=\"page\">2</a></li>\n    <li><a href=\"?page=3\" aria-label=\"Page 3\">3</a></li>\n    <li aria-hidden=\"true\">&hellip;</li>\n    <li><a href=\"?page=10\" aria-label=\"Page 10\">10</a></li>\n    <li><a href=\"?page=3\" rel=\"next\">Next</a></li>\n  </ol>\n</nav>",
      "examples": [
        {
          "label": "Pagination",
          "html": "<nav aria-label=\"Pagination\">\n  <ol>\n    <li><a href=\"?page=1\" rel=\"prev\">Previous</a></li>\n    <li><a href=\"?page=1\" aria-label=\"Page 1\">1</a></li>\n    <li><a href=\"?page=2\" aria-label=\"Page 2\" aria-current=\"page\">2</a></li>\n    <li><a href=\"?page=3\" aria-label=\"Page 3\">3</a></li>\n    <li aria-hidden=\"true\">&hellip;</li>\n    <li><a href=\"?page=10\" aria-label=\"Page 10\">10</a></li>\n    <li><a href=\"?page=3\" rel=\"next\">Next</a></li>\n  </ol>\n</nav>"
        }
      ],
      "variants": [
        {
          "name": "custom label",
          "trigger": "data-pagination on nav",
          "selector": "[data-pagination]",
          "description": "For navs whose label is not Pagination."
        }
      ],
      "states": [
        {
          "name": "current page",
          "trigger": "aria-current=\"page\" on the link",
          "selector": "aria-current",
          "description": "Filled item."
        },
        {
          "name": "disabled",
          "trigger": "aria-disabled=\"true\"",
          "selector": "aria-disabled",
          "description": "First page previous and last page next."
        }
      ],
      "aria": [
        "Use rel=\"prev\" and rel=\"next\" and aria-label=\"Page N\" on number links. The ellipsis li is aria-hidden."
      ],
      "tokens": {
        "reads": [
          "--pico-border-radius",
          "--pico-border-width",
          "--pico-form-element-disabled-opacity",
          "--pico-muted-color",
          "--pico-nav-link-spacing-horizontal",
          "--pico-outline-width",
          "--pico-primary-background",
          "--pico-primary-focus",
          "--pico-primary-hover-background",
          "--pico-primary-inverse",
          "--pico-typography-spacing-vertical"
        ],
        "defines": ["--pico-pagination-gap", "--pico-pagination-item-size"]
      },
      "js": null
    },
    {
      "name": "stepper",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/stepper.css",
        "cdn": "css/extras/stepper.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/stepper",
        "config": "@pico { extras: stepper; }",
        "cli": "pico-reforged build --extras stepper"
      },
      "summary": "Stepper: ol[data-stepper] with aria-current=\"step\" on the current li (or its link)",
      "use": "Progress through steps: ol[data-stepper] with aria-current=\"step\" on the current li or its link.",
      "markup": "<ol data-stepper=\"horizontal\" aria-label=\"Checkout progress\">\n  <li><span aria-hidden=\"true\">1</span>Cart</li>\n  <li><span aria-hidden=\"true\">2</span>Shipping</li>\n  <li aria-current=\"step\"><span aria-hidden=\"true\">3</span>Payment</li>\n  <li><span aria-hidden=\"true\">4</span>Review</li>\n</ol>",
      "examples": [
        {
          "label": "Steps",
          "html": "<ol data-stepper=\"horizontal\" aria-label=\"Checkout progress\">\n  <li><span aria-hidden=\"true\">1</span>Cart</li>\n  <li><span aria-hidden=\"true\">2</span>Shipping</li>\n  <li aria-current=\"step\"><span aria-hidden=\"true\">3</span>Payment</li>\n  <li><span aria-hidden=\"true\">4</span>Review</li>\n</ol>"
        },
        {
          "label": "Navigable steps",
          "html": "<nav aria-label=\"Onboarding\">\n  <ol data-stepper>\n    <li>\n      <a href=\"#account\"><span aria-hidden=\"true\">1</span>Account</a>\n    </li>\n    <li>\n      <a href=\"#workspace\"><span aria-hidden=\"true\">2</span>Workspace</a>\n    </li>\n    <li>\n      <a href=\"#team\" aria-current=\"step\"><span aria-hidden=\"true\">3</span>Invite team</a>\n    </li>\n    <li>\n      <a aria-disabled=\"true\"><span aria-hidden=\"true\">4</span>Billing</a>\n    </li>\n  </ol>\n</nav>"
        }
      ],
      "variants": [
        {
          "name": "horizontal",
          "trigger": "data-stepper or data-stepper=\"horizontal\"",
          "selector": "ol[data-stepper]",
          "description": "Default row. Turns vertical below 576px."
        },
        {
          "name": "vertical",
          "trigger": "data-stepper=\"vertical\"",
          "selector": "[data-stepper=\"vertical\"]",
          "description": "Column with a line down the markers."
        }
      ],
      "states": [
        {
          "name": "current",
          "trigger": "aria-current=\"step\"",
          "selector": "aria-current",
          "description": "Marks the current step. Earlier steps show as complete."
        },
        {
          "name": "unreachable",
          "trigger": "aria-disabled=\"true\" or an anchor without href",
          "selector": "[aria-disabled=\"true\"]",
          "description": "A step the user cannot open yet."
        }
      ],
      "aria": [
        "Put the status in a label or text for screen readers; the number span is aria-hidden. Wrap the list in a nav when the steps are links."
      ],
      "tokens": {
        "reads": [
          "--pico-background-color",
          "--pico-border-radius",
          "--pico-color",
          "--pico-form-element-border-color",
          "--pico-form-element-disabled-opacity",
          "--pico-icon-checkbox",
          "--pico-muted-border-color",
          "--pico-muted-color",
          "--pico-outline-width",
          "--pico-primary",
          "--pico-primary-background",
          "--pico-primary-focus",
          "--pico-primary-inverse",
          "--pico-spacing",
          "--pico-text-underline-offset",
          "--pico-transition"
        ],
        "defines": [
          "--pico-stepper-complete-background",
          "--pico-stepper-complete-color",
          "--pico-stepper-complete-label-color",
          "--pico-stepper-complete-line-color",
          "--pico-stepper-current-color",
          "--pico-stepper-current-ring-color",
          "--pico-stepper-gap",
          "--pico-stepper-label-color",
          "--pico-stepper-line-color",
          "--pico-stepper-line-width",
          "--pico-stepper-marker-size",
          "--pico-stepper-ring-width"
        ]
      },
      "js": null
    },
    {
      "name": "empty-state",
      "category": "extras",
      "optIn": {
        "kind": "extra",
        "css": "src/extras/empty-state.css",
        "cdn": "css/extras/empty-state.min.css",
        "allExtrasCdn": "css/pico.extras.min.css",
        "import": "@rusticstack/pico-reforged/extras/empty-state",
        "config": "@pico { extras: empty-state; }",
        "cli": "pico-reforged build --extras empty-state"
      },
      "summary": "Empty state: [data-empty] block shown in place of a list, table or result set with no rows",
      "use": "Placeholder shown instead of a list, table or search result with no rows. data-empty on a section.",
      "markup": "<section data-empty>\n  <figure aria-hidden=\"true\">\n    <svg\n      width=\"24\"\n      height=\"24\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      stroke-width=\"1.5\"\n      stroke-linecap=\"round\"\n      stroke-linejoin=\"round\"\n      focusable=\"false\"\n    >\n      <path\n        d=\"M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"\n      />\n    </svg>\n  </figure>\n  <h3>No projects yet</h3>\n  <p>Create a project to start tracking your work here.</p>\n  <footer>\n    <a href=\"/projects/new\" role=\"button\">Create project</a>\n  </footer>\n</section>",
      "examples": [
        {
          "label": "Empty state with an action",
          "html": "<section data-empty>\n  <figure aria-hidden=\"true\">\n    <svg\n      width=\"24\"\n      height=\"24\"\n      viewBox=\"0 0 24 24\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      stroke-width=\"1.5\"\n      stroke-linecap=\"round\"\n      stroke-linejoin=\"round\"\n      focusable=\"false\"\n    >\n      <path\n        d=\"M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"\n      />\n    </svg>\n  </figure>\n  <h3>No projects yet</h3>\n  <p>Create a project to start tracking your work here.</p>\n  <footer>\n    <a href=\"/projects/new\" role=\"button\">Create project</a>\n  </footer>\n</section>"
        }
      ],
      "variants": [
        {
          "name": "compact",
          "trigger": "data-empty=\"compact\"",
          "selector": "[data-empty=\"compact\"]",
          "description": "Smaller padding and icon, for cards and panels."
        }
      ],
      "states": [
        {
          "name": "hidden",
          "trigger": "hidden",
          "selector": "[hidden]",
          "description": "Hide it while rows exist."
        }
      ],
      "aria": [
        "The icon figure is aria-hidden. Use a heading for the title and a real link or button for the action."
      ],
      "tokens": {
        "reads": [
          "--pico-block-spacing-horizontal",
          "--pico-block-spacing-vertical",
          "--pico-border-width",
          "--pico-card-border-radius",
          "--pico-muted-border-color",
          "--pico-muted-color",
          "--pico-primary",
          "--pico-primary-background",
          "--pico-spacing"
        ],
        "defines": [
          "--pico-empty-state-border-color",
          "--pico-empty-state-icon-background",
          "--pico-empty-state-icon-color",
          "--pico-empty-state-icon-size",
          "--pico-empty-state-max-inline-size",
          "--pico-empty-state-padding-block"
        ]
      },
      "js": null
    }
  ]
}
