# nodes

id: docs:docs/components/ren-alert-dialog.html
type: docs_page
name: ren-alert-dialog docs
path: docs/components/ren-alert-dialog.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Alert Dialog — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-8) var(--space-5); display: flex; gap: var(--space-3); align-items: center; justify-content: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html" aria-current="page">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Alert Dialog</li></ol></nav>
        <p class="dx-kicker">Composite</p>
        <h1>Alert Dialog <span class="dx-api-badge dx-api-badge-css" title="Styled with CSS; opened with the native dialog API">CSS-only</span></h1>
        <p class="lede">A confirmation dialog for destructive or irreversible actions. Same shell as <a href="ren-dialog.html" class="ren-link">Dialog</a>, but the user must press a button to close — backdrop click and Escape are suppressed.</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>Use Alert Dialog when accidental dismissal would be costly — deleting an account, force-quitting a long upload, sending an email that can't be unsent. The dialog stays open until the user explicitly chooses Cancel or the destructive action; there's no "click outside to ignore."</p>
        <div class="dx-callout">
          <p><strong>Reserve alert dialogs for genuine destructive moments.</strong> If every confirm uses an alert dialog, users learn to dismiss them on autopilot.</p>
        </div>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <button class="ren-btn ren-btn-danger" type="button" data-trigger="alert-demo" aria-haspopup="dialog" aria-controls="alert-demo">Delete account</button>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;button type="button" onclick="confirmDelete.showModal()"&gt;Delete account&lt;/button&gt;

&lt;dialog id="confirmDelete" class="ren-alert-dialog"
  aria-labelledby="cd-title" aria-describedby="cd-description" closedby="none"&gt;
  &lt;h2 id="cd-title" class="ren-alert-dialog-title"&gt;Delete this account?&lt;/h2&gt;
  &lt;p id="cd-description" class="ren-alert-dialog-description"&gt;
    All projects, files, and history will be permanently removed.
  &lt;/p&gt;
  &lt;form method="dialog" class="ren-alert-dialog-actions"&gt;
    &lt;button value="cancel" class="ren-btn ren-btn-secondary"&gt;Keep account&lt;/button&gt;
    &lt;button value="delete" class="ren-btn ren-btn-danger"&gt;Delete account&lt;/button&gt;
  &lt;/form&gt;
&lt;/dialog&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>
        <p>Alert Dialog uses the native <code>&lt;dialog&gt;</code> API directly. The component supplies the decision-focused visual treatment; the browser owns modality, focus, and form return values.</p>
        <table class="dx-api">
          <thead><tr><th>Class / element</th><th>Effect</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">.ren-alert-dialog</code></td><td>Class applied directly to a native <code>&lt;dialog&gt;</code>.</td></tr>
            <tr><td><code class="dx-api-name">closedby="none"</code></td><td>Requires an explicit action instead of Escape or backdrop dismissal.</td></tr>
            <tr><td><code class="dx-api-name">showModal()</code></td><td>Opens the alert in the top layer and makes background content inert.</td></tr>
          </tbody>
        </table>
        <p>Read the selected action from the native dialog's <code>returnValue</code> after its <code>close</code> event.</p>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <ul>
          <li>A real <code>&lt;dialog&gt;</code> exposes modal semantics through the platform and is labelled by its decision heading.</li>
          <li>Focus is trapped inside until a button is clicked.</li>
          <li><kbd>Esc</kbd> and light dismissal are suppressed with <code>closedby="none"</code>.</li>
          <li>Backdrop click does nothing — the user must commit to a choice.</li>
        </ul>
        <div class="dx-callout">
          <p><strong>Pair the destructive button with the destructive label.</strong> "Delete account" — not "Confirm". Users who scan only the buttons should still understand what they're confirming.</p>
        </div>
      </section>

    </main>
  </div>
  <dialog id="alert-demo" class="ren-alert-dialog" aria-labelledby="alert-demo-title" aria-describedby="alert-demo-description" closedby="none">
    <div class="ren-alert-dialog-icon ren-alert-dialog-icon-danger" aria-hidden="true">!</div>
    <h2 id="alert-demo-title" class="ren-alert-dialog-title">Delete this account?</h2>
    <p id="alert-demo-description" class="ren-alert-dialog-description">All projects, files, and history will be permanently removed. This cannot be undone.</p>
    <form method="dialog" class="ren-alert-dialog-actions">
      <button value="cancel" class="ren-btn ren-btn-secondary">Keep account</button>
      <button value="delete" class="ren-btn ren-btn-danger">Delete account</button>
    </form>
  </dialog>
  <script>
    const alertDemo = document.getElementById('alert-demo');
    const alertDemoTrigger = document.querySelector('[data-trigger="alert-demo"]');
    alertDemoTrigger.addEventListener('click', () => alertDemo.showModal());
    // `closedby="none"` is not implemented consistently by every engine yet.
    // Keep the destructive confirmation explicit in WebKit as well.
    alertDemo.addEventListener('cancel', (event) => event.preventDefault());
    alertDemo.addEventListener('close', () => alertDemoTrigger.focus());
  </script>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-avatar.html
type: docs_page
name: ren-avatar docs
path: docs/components/ren-avatar.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Avatar — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); padding-top: var(--space-3); }
    .dx-vrow-items { padding: var(--space-3); background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    @media (max-width: 720px) { .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); } .dx-vrow-label { padding-top: 0; } }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html" aria-current="page">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Avatar</li></ol></nav>
        <p class="dx-kicker">Primitive</p>
        <h1>Avatar <span class="dx-api-badge dx-api-badge-css" title="Works without any JavaScript">CSS-only</span></h1>
        <p class="lede">User photos, initials, and presence indicators. Six sizes, square / round, with optional online / offline / busy status dot.</p>
      </header>
      <section class="dx-section" id="overview"><p class="dx-kicker">About</p><h2>Overview</h2><p>Avatars represent people or entities. They handle the messy details: image fallback when the photo fails to load, initials when there's no photo, status dots for presence.</p></section>
      <section class="dx-section" id="demo"><p class="dx-kicker">Live</p><h2>Demo</h2><div class="dx-demo"><div class="dx-demo-preview"><div style="width: 32px; height: 32px; border-radius: 50%; background: var(--color-accent); color: var(--color-on-accent); display: grid; place-items: center; font-size: var(--text-xs); font-weight: var(--weight-semibold);">JD</div><div style="width: 40px; height: 40px; border-radius: 50%; background: var(--color-success); color: var(--color-on-success); display: grid; place-items: center; font-size: var(--text-sm); font-weight: var(--weight-semibold);">AB</div><div style="width: 56px; height: 56px; border-radius: 50%; background: var(--color-warning); color: var(--color-on-warning); display: grid; place-items: center; font-size: var(--text-base); font-weight: var(--weight-semibold);">CD</div><div style="position: relative; width: 40px; height: 40px;"><div style="width: 40px; height: 40px; border-radius: 50%; background: var(--color-accent); color: var(--color-on-accent); display: grid; place-items: center; font-size: var(--text-sm); font-weight: var(--weight-semibold);">EF</div><span style="position: absolute; bottom: 0; right: 0; width: 12px; height: 12px; background: var(--color-success); border: 2px solid var(--color-surface); border-radius: 50%;"></span></div></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;img class="ren-avatar ren-avatar-md" src="/u/ren.jpg" alt="Ren"&gt;
&lt;span class="ren-avatar ren-avatar-md"&gt;JD&lt;/span&gt; &lt;!-- initials fallback --&gt;</code></pre></div></section>
      <section class="dx-section" id="api"><p class="dx-kicker">Reference</p><h2>API</h2><table class="dx-api"><thead><tr><th>Class</th><th>Effect</th></tr></thead><tbody><tr><td><code class="dx-api-name">.ren-avatar</code></td><td>Base. Works on <code>&lt;img&gt;</code> or any element holding initials.</td></tr><tr><td><code class="dx-api-name">.ren-avatar-xs</code> / <code class="dx-api-name">-sm</code> / <code class="dx-api-name">-md</code> / <code class="dx-api-name">-lg</code> / <code class="dx-api-name">-xl</code> / <code class="dx-api-name">-2xl</code></td><td>Sizes from 24 px to 64 px.</td></tr><tr><td><code class="dx-api-name">.ren-avatar-square</code></td><td>Rounded-square instead of circle.</td></tr><tr><td><code class="dx-api-name">.ren-avatar-status</code></td><td>Wrapper that positions a presence dot at the bottom-right.</td></tr></tbody></table></section>
      <section class="dx-section" id="a11y"><p class="dx-kicker">Inclusive by default</p><h2>Accessibility</h2><ul><li>Image avatars need <code>alt="{Person name}"</code>. The avatar is functionally a label.</li><li>Initials avatars use <code>aria-label</code> with the full name (initials alone don't identify a person to a screen reader).</li><li>Status dots are decorative — the status word should appear elsewhere in the row.</li></ul></section>
    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-badge.html
type: docs_page
name: ren-badge docs
path: docs/components/ren-badge.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Badge — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); padding-top: var(--space-3); }
    .dx-vrow-items { display: flex; flex-wrap: wrap; gap: var(--space-2); padding: var(--space-3); background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); align-items: center; }
    @media (max-width: 720px) { .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); } .dx-vrow-label { padding-top: 0; } }
  </style>
</head>
<body>
  <header class="dx-nav">
    <div class="dx-nav-inner">
      <a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a>
      <nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav>
      <div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div>
    </div>
  </header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html" aria-current="page">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Badge</li></ol></nav>
        <p class="dx-kicker">Primitive</p>
        <h1>Badge <span class="dx-api-badge dx-api-badge-css" title="Works without any JavaScript">CSS-only</span></h1>
        <p class="lede">Tiny inline status labels: counts, statuses, tags. Eight variants, dot indicator, outline option. Use them next to titles, inside list rows, or on top of icons to convey unread / pending / new state.</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>A badge is the smallest possible visual indicator: a colored chip with a one-or-two-word label. Use it to show counts ("3 new"), states ("Beta", "Pending"), or category tags. Don't use badges for clickable filters — that's <a href="ren-tag.html" class="ren-link">Tag</a>'s job.</p>
        <div class="dx-callout">
          <p><strong>Badges aren't interactive.</strong> They have no hover, no focus, no click target. If a user can act on it, it's a Tag (or a button styled like a chip).</p>
        </div>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <span class="ren-badge">Default</span>
            <span class="ren-badge ren-badge-primary">Primary</span>
            <span class="ren-badge ren-badge-secondary">Secondary</span>
            <span class="ren-badge ren-badge-success">Active</span>
            <span class="ren-badge ren-badge-warning">Pending</span>
            <span class="ren-badge ren-badge-danger">Failed</span>
            <span class="ren-badge ren-badge-info">Info</span>
            <span class="ren-badge ren-badge-outline">Outline</span>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;span class="ren-badge"&gt;Default&lt;/span&gt;
&lt;span class="ren-badge ren-badge-success"&gt;Active&lt;/span&gt;
&lt;span class="ren-badge ren-badge-danger"&gt;Failed&lt;/span&gt;
&lt;span class="ren-badge ren-badge-outline"&gt;Outline&lt;/span&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="variants">
        <p class="dx-kicker">Shapes</p>
        <h2>Variants</h2>
        <div class="dx-vgrid">
          <div class="dx-vrow"><span class="dx-vrow-label">Status</span><div class="dx-vrow-items">
            <span class="ren-badge ren-badge-success">Active</span>
            <span class="ren-badge ren-badge-warning">Pending</span>
            <span class="ren-badge ren-badge-danger">Inactive</span>
            <span class="ren-badge ren-badge-info">Beta</span>
          </div></div>
          <div class="dx-vrow"><span class="dx-vrow-label">With dot</span><div class="dx-vrow-items">
            <span class="ren-badge ren-badge-success"><span class="ren-badge-dot ren-badge-dot-success"></span>Online</span>
            <span class="ren-badge ren-badge-warning"><span class="ren-badge-dot ren-badge-dot-warning"></span>Idle</span>
            <span class="ren-badge ren-badge-danger"><span class="ren-badge-dot ren-badge-dot-danger"></span>Offline</span>
          </div></div>
          <div class="dx-vrow"><span class="dx-vrow-label">Counter</span><div class="dx-vrow-items">
            <span class="ren-badge ren-badge-primary">3</span>
            <span class="ren-badge ren-badge-primary">12</span>
            <span class="ren-badge ren-badge-primary">99+</span>
          </div></div>
          <div class="dx-vrow"><span class="dx-vrow-label">Outline</span><div class="dx-vrow-items">
            <span class="ren-badge ren-badge-outline">Draft</span>
            <span class="ren-badge ren-badge-outline">v2.0</span>
          </div></div>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>
        <h3>CSS classes</h3>
        <table class="dx-api">
          <thead><tr><th>Class</th><th>Effect</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">.ren-badge</code></td><td>Base. Required. Default neutral fill, subtle border.</td></tr>
            <tr><td><code class="dx-api-name">.ren-badge-primary</code></td><td>Accent fill, on-accent text.</td></tr>
            <tr><td><code class="dx-api-name">.ren-badge-secondary</code></td><td>Secondary fill — muted gray, for less prominent labels.</td></tr>
            <tr><td><code class="dx-api-name">.ren-badge-success</code> / <code class="dx-api-name">-warning</code> / <code class="dx-api-name">-danger</code> / <code class="dx-api-name">-info</code></td><td>Status variants in the matching semantic color.</td></tr>
            <tr><td><code class="dx-api-name">.ren-badge-outline</code></td><td>Border only, transparent background. For secondary contexts.</td></tr>
            <tr><td><code class="dx-api-name">.ren-badge-dot</code></td><td>The 6 px circle prefix inside a status badge. Combine with <code>.ren-badge-dot-{status}</code>.</td></tr>
          </tbody>
        </table>
        <p>No JavaScript. Pure CSS — render any element (<code>span</code>, <code>div</code>, <code>a</code>) with these classes.</p>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <p>Badges are decorative by default. If a badge conveys information not present elsewhere, give it semantic context.</p>
        <ul>
          <li><strong>Counters next to labels</strong>: pair the count with the noun it counts. <code>&lt;a&gt;Inbox &lt;span class="ren-badge"&gt;3 unread&lt;/span&gt;&lt;/a&gt;</code> reads correctly. <code>&lt;a&gt;Inbox &lt;span class="ren-badge"&gt;3&lt;/span&gt;&lt;/a&gt;</code> doesn't.</li>
          <li><strong>Status with color only</strong>: don't rely on the color alone — include the status word. "Online" / "Offline" beats just a green / red dot.</li>
          <li><strong>Live counters</strong>: if the count updates dynamically, wrap the number in <code>aria-live="polite"</code> on the parent so screen readers re-announce.</li>
        </ul>
        <div class="dx-callout">
          <p><strong>Don't use a badge as a label for an icon-only button.</strong> A badge is decoration. The button needs <code>aria-label</code> to be discoverable.</p>
        </div>
      </section>

      <section class="dx-section" id="examples">
        <p class="dx-kicker">Patterns</p>
        <h2>Examples</h2>
        <h3>Status next to a title</h3>
        <div class="dx-pre" tabindex="0"><code>&lt;h2&gt;
  Project Atlas
  &lt;span class="ren-badge ren-badge-warning"&gt;Pending review&lt;/span&gt;
&lt;/h2&gt;</code></div>

        <h3>Unread count on a nav link</h3>
        <div class="dx-pre" tabindex="0"><code>&lt;a href="/inbox" class="nav-link"&gt;
  Inbox
  &lt;span class="ren-badge ren-badge-primary" aria-label="3 unread"&gt;3&lt;/span&gt;
&lt;/a&gt;</code></div>

        <h3>Online indicator</h3>
        <div class="dx-pre" tabindex="0"><code>&lt;span class="ren-badge ren-badge-success"&gt;
  &lt;span class="ren-badge-dot ren-badge-dot-success"&gt;&lt;/span&gt;
  Online
&lt;/span&gt;</code></div>
      </section>

    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-banner.html
type: docs_page
name: ren-banner docs
path: docs/components/ren-banner.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Banner — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); padding-top: var(--space-3); }
    .dx-vrow-items { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3); background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); }
    @media (max-width: 720px) { .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); } .dx-vrow-label { padding-top: 0; } }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html" aria-current="page">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Banner</li></ol></nav>
        <p class="dx-kicker">Primitive</p>
        <h1>Banner <span class="dx-api-badge dx-api-badge-css" title="Works without any JavaScript">CSS-only</span></h1>
        <p class="lede">Page-level callouts for system messages: maintenance windows, success confirmations, errors, neutral announcements. Five status variants, optional icon, action slot, dismissible.</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>A Banner sits above (or inside) a content region and announces something the user should know before continuing. Use them for app-wide notices ("Scheduled maintenance Saturday"), success feedback after a critical action, or contextual warnings inside a form.</p>
        <div class="dx-callout">
          <p><strong>Banner vs Toast vs Dialog.</strong> Banner is persistent and contextual. Toast is transient. Dialog blocks. Pick based on how important the message is and whether the user has to act on it.</p>
        </div>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <div class="ren-banner ren-banner-info" role="status">
              <span class="ren-banner-icon" aria-hidden="true">ℹ</span>
              <div class="ren-banner-content">
                <p class="ren-banner-title">Scheduled maintenance</p>
                <p class="ren-banner-message">The service will be briefly unavailable Saturday 2 AM – 3 AM ART.</p>
              </div>
              <button class="ren-banner-dismiss" type="button" aria-label="Dismiss">×</button>
            </div>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-banner ren-banner-info" role="status"&gt;
  &lt;span class="ren-banner-icon" aria-hidden="true"&gt;ℹ&lt;/span&gt;
  &lt;div class="ren-banner-content"&gt;
    &lt;p class="ren-banner-title"&gt;Scheduled maintenance&lt;/p&gt;
    &lt;p class="ren-banner-message"&gt;The service will be briefly unavailable…&lt;/p&gt;
  &lt;/div&gt;
  &lt;button class="ren-banner-dismiss" aria-label="Dismiss"&gt;×&lt;/button&gt;
&lt;/div&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="variants">
        <p class="dx-kicker">Status</p>
        <h2>Variants</h2>
        <div class="dx-vgrid">
          <div class="dx-vrow"><span class="dx-vrow-label">Status</span><div class="dx-vrow-items">
            <div class="ren-banner ren-banner-success" role="status"><span class="ren-banner-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg></span><div class="ren-banner-content"><p class="ren-banner-title">Saved</p></div></div>
            <div class="ren-banner ren-banner-warning" role="status"><span class="ren-banner-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><line x1="12" x2="12" y1="9" y2="13"/><line x1="12" x2="12.01" y1="17" y2="17"/></svg></span><div class="ren-banner-content"><p class="ren-banner-title">Approaching plan limit</p></div></div>
            <div class="ren-banner ren-banner-danger" role="alert"><span class="ren-banner-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></span><div class="ren-banner-content"><p class="ren-banner-title">Sync failed</p><p class="ren-banner-message">Check your connection and retry.</p></div></div>
            <div class="ren-banner ren-banner-info" role="status"><span class="ren-banner-icon">ℹ</span><div class="ren-banner-content"><p class="ren-banner-title">New version available</p></div></div>
            <div class="ren-banner ren-banner-neutral" role="status"><span class="ren-banner-icon">·</span><div class="ren-banner-content"><p class="ren-banner-title">Read-only mode</p></div></div>
          </div></div>

          <div class="dx-vrow"><span class="dx-vrow-label">With action</span><div class="dx-vrow-items">
            <div class="ren-banner ren-banner-warning" role="status">
              <span class="ren-banner-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><line x1="12" x2="12" y1="9" y2="13"/><line x1="12" x2="12.01" y1="17" y2="17"/></svg></span>
              <div class="ren-banner-content">
                <p class="ren-banner-title">Verify your email</p>
                <p class="ren-banner-message">Some features are limited until you confirm.</p>
              </div>
              <div class="ren-banner-actions">
                <button class="ren-btn ren-btn-secondary ren-btn-sm">Resend</button>
              </div>
            </div>
          </div></div>

          <div class="dx-vrow"><span class="dx-vrow-label">Compact</span><div class="dx-vrow-items">
            <div class="ren-banner ren-banner-info ren-banner-compact" role="status">
              <span class="ren-banner-icon">ℹ</span>
              <div class="ren-banner-content"><p class="ren-banner-title">Cookies are required for sign-in.</p></div>
            </div>
          </div></div>

          <div class="dx-vrow"><span class="dx-vrow-label">Full-bleed</span><div class="dx-vrow-items">
            <div class="ren-banner ren-banner-danger ren-banner-full" role="alert" style="border-radius: 0; margin-inline: calc(var(--space-3) * -1);">
              <span class="ren-banner-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></span>
              <div class="ren-banner-content"><p class="ren-banner-title">Service degraded — see status page</p></div>
            </div>
          </div></div>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>
        <h3>CSS classes</h3>
        <table class="dx-api">
          <thead><tr><th>Class</th><th>Effect</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">.ren-banner</code></td><td>Base. Flex row with icon · content · actions · dismiss.</td></tr>
            <tr><td><code class="dx-api-name">.ren-banner-success</code> / <code class="dx-api-name">-warning</code> / <code class="dx-api-name">-danger</code> / <code class="dx-api-name">-info</code> / <code class="dx-api-name">-neutral</code></td><td>Status variants. Tints icon, accent border, and subtle background.</td></tr>
            <tr><td><code class="dx-api-name">.ren-banner-icon</code></td><td>Leading icon slot. Use a real SVG or a unicode glyph; mark <code>aria-hidden</code>.</td></tr>
            <tr><td><code class="dx-api-name">.ren-banner-content</code></td><td>Title + optional message. The message reflows under the title when present.</td></tr>
            <tr><td><code class="dx-api-name">.ren-banner-title</code></td><td>Bold one-liner.</td></tr>
            <tr><td><code class="dx-api-name">.ren-banner-message</code></td><td>Secondary line. Optional.</td></tr>
            <tr><td><code class="dx-api-name">.ren-banner-actions</code></td><td>Trailing slot for one or two buttons. Right-aligned.</td></tr>
            <tr><td><code class="dx-api-name">.ren-banner-dismiss</code></td><td>The × close button. Always pair with <code>aria-label</code>.</td></tr>
            <tr><td><code class="dx-api-name">.ren-banner-compact</code></td><td>Tighter padding, smaller icon. For inline contexts.</td></tr>
            <tr><td><code class="dx-api-name">.ren-banner-full</code></td><td>Full-bleed, no border-radius. For app-wide bars at the top of the layout.</td></tr>
          </tbody>
        </table>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <ul>
          <li><strong>Use <code>role="status"</code></strong> for non-critical banners (info / success / neutral / warning) — screen readers announce when idle.</li>
          <li><strong>Use <code>role="alert"</code></strong> for danger banners — they interrupt the current announcement.</li>
          <li><strong>Don't rely on color alone</strong> — the icon and the title text should make the status clear without color.</li>
          <li><strong>Dismiss button</strong>: always include <code>aria-label="Dismiss"</code> (or more specific). Don't make dismissal the only way to act on a critical message.</li>
        </ul>
        <div class="dx-callout">
          <p><strong>Don't auto-dismiss banners.</strong> Unlike Toast, banners are persistent — the user reads them in their own time. Auto-hiding defeats the purpose.</p>
        </div>
      </section>

      <section class="dx-section" id="examples">
        <p class="dx-kicker">Patterns</p>
        <h2>Examples</h2>
        <h3>App-wide notice at top of page</h3>
        <div class="dx-pre" tabindex="0"><code>&lt;div class="ren-banner ren-banner-warning ren-banner-full" role="status"&gt;
  &lt;span class="ren-banner-icon"&gt;&lt;!-- alert SVG --&gt;&lt;/span&gt;
  &lt;div class="ren-banner-content"&gt;
    &lt;p class="ren-banner-title"&gt;Read-only mode — database migration in progress&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></div>

        <h3>Empty-state hint inside a card</h3>
        <div class="dx-pre" tabindex="0"><code>&lt;div class="ren-banner ren-banner-info ren-banner-compact" role="status"&gt;
  &lt;span class="ren-banner-icon"&gt;ℹ&lt;/span&gt;
  &lt;div class="ren-banner-content"&gt;
    &lt;p class="ren-banner-title"&gt;No invoices yet&lt;/p&gt;
    &lt;p class="ren-banner-message"&gt;Your first invoice will appear here once you onboard a client.&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class="ren-banner-actions"&gt;
    &lt;button class="ren-btn ren-btn-primary ren-btn-sm"&gt;Add client&lt;/button&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></div>
      </section>

    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-breadcrumb.html
type: docs_page
name: ren-breadcrumb docs
path: docs/components/ren-breadcrumb.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Breadcrumb — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); padding-top: var(--space-3); }
    .dx-vrow-items { padding: var(--space-3); background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: flex; flex-direction: column; gap: var(--space-2); }
    @media (max-width: 720px) { .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); } .dx-vrow-label { padding-top: 0; } }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html" aria-current="page">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Breadcrumb</li></ol></nav>
        <p class="dx-kicker">Primitive</p>
        <h1>Breadcrumb <span class="dx-api-badge dx-api-badge-css" title="Works without any JavaScript">CSS-only</span></h1>
        <p class="lede">Trail of links showing where the user is in a hierarchy. Always rendered as <code>&lt;nav&gt; &lt;ol&gt; &lt;li&gt;</code> with <code>aria-label</code> and <code>aria-current="page"</code> on the leaf — semantics first, decoration second.</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>Breadcrumbs help orient the user when pages live deep in a hierarchy: Docs › Components › Breadcrumb. Each step links upward; the leaf (current page) is text, not a link. Use them for hierarchical content (docs, file systems, e-commerce categories) — not for chronological flows like multi-step forms (use a stepper for that).</p>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <nav class="ren-breadcrumb" aria-label="Breadcrumb">
              <ol>
                <li><a href="#">Docs</a></li>
                <li><a href="#">Components</a></li>
                <li><a href="#">Primitives</a></li>
                <li aria-current="page">Breadcrumb</li>
              </ol>
            </nav>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;nav class="ren-breadcrumb" aria-label="Breadcrumb"&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href="/docs"&gt;Docs&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="/docs/components"&gt;Components&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="/docs/components/primitives"&gt;Primitives&lt;/a&gt;&lt;/li&gt;
    &lt;li aria-current="page"&gt;Breadcrumb&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="variants">
        <p class="dx-kicker">Shapes</p>
        <h2>Variants</h2>
        <div class="dx-vgrid">
          <div class="dx-vrow"><span class="dx-vrow-label">Default separator</span><div class="dx-vrow-items">
            <nav class="ren-breadcrumb" aria-label="Default"><ol>
              <li><a href="#">Docs</a></li><li><a href="#">Components</a></li><li aria-current="page">Breadcrumb</li>
            </ol></nav>
          </div></div>

          <div class="dx-vrow"><span class="dx-vrow-label">Slash separator</span><div class="dx-vrow-items">
            <nav class="ren-breadcrumb" style="--breadcrumb-separator: '/';" aria-label="Slash variant"><ol>
              <li><a href="#">Home</a></li><li><a href="#">Projects</a></li><li><a href="#">Atlas</a></li><li aria-current="page">README</li>
            </ol></nav>
          </div></div>

          <div class="dx-vrow"><span class="dx-vrow-label">Truncated</span><div class="dx-vrow-items">
            <nav class="ren-breadcrumb ren-breadcrumb-truncated" aria-label="Truncated"><ol>
              <li><a href="#">Docs</a></li>
              <li><a href="#">Components</a></li>
              <li><a href="#">Primitives</a></li>
              <li><a href="#">Form controls</a></li>
              <li><a href="#">Inputs</a></li>
              <li aria-current="page">Email</li>
            </ol></nav>
            <p style="font-size: var(--text-xs); color: var(--color-text-muted); margin: 0;">Middle items collapse to … under <code>.ren-breadcrumb-truncated</code> — first and last two stay visible.</p>
          </div></div>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>
        <h3>CSS classes & tokens</h3>
        <table class="dx-api">
          <thead><tr><th>Class / token</th><th>Effect</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">.ren-breadcrumb</code></td><td>Wraps the <code>&lt;nav&gt;</code>. Sets the typography and color.</td></tr>
            <tr><td><code class="dx-api-name">.ren-breadcrumb &gt; ol</code></td><td>The list itself. Inline-flex with gap; resets list styling.</td></tr>
            <tr><td><code class="dx-api-name">--breadcrumb-separator</code></td><td>CSS custom property for the separator glyph. Default <code>'›'</code>. Use <code>'/'</code> or <code>'›'</code> for variants.</td></tr>
            <tr><td><code class="dx-api-name">.ren-breadcrumb-truncated</code></td><td>Collapses middle items to <code>…</code>; keeps first and last two.</td></tr>
            <tr><td><code class="dx-api-name">[aria-current="page"]</code></td><td>Marks the leaf. Renders as plain text, no underline. Required.</td></tr>
          </tbody>
        </table>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <ul>
          <li><strong>Wrap in <code>&lt;nav aria-label="Breadcrumb"&gt;</code></strong>. Without the label, screen readers announce a generic "navigation".</li>
          <li><strong>Use a real <code>&lt;ol&gt;</code></strong>, not a sequence of spans. Order matters in a breadcrumb; the list reflects that.</li>
          <li><strong>Mark the current page</strong> with <code>aria-current="page"</code>. It's a plain <code>&lt;li&gt;</code> with no link — assistive tech announces it as the active step.</li>
          <li><strong>Don't link the current page to itself.</strong> Confusing for everyone.</li>
        </ul>
      </section>

      <section class="dx-section" id="examples">
        <p class="dx-kicker">Patterns</p>
        <h2>Examples</h2>
        <h3>App documentation</h3>
        <div class="dx-pre" tabindex="0"><code>&lt;nav class="ren-breadcrumb" aria-label="Breadcrumb"&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href="/docs"&gt;Docs&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="/docs/getting-started"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
    &lt;li aria-current="page"&gt;Install&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;</code></div>

        <h3>File path</h3>
        <div class="dx-pre" tabindex="0"><code>&lt;nav class="ren-breadcrumb" style="--breadcrumb-separator: '/';" aria-label="File path"&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;a href="/files"&gt;files&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="/files/projects"&gt;projects&lt;/a&gt;&lt;/li&gt;
    &lt;li aria-current="page"&gt;atlas.md&lt;/li&gt;
  &lt;/ol&gt;
&lt;/nav&gt;</code></div>
      </section>

    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-button.html
type: docs_page
name: ren-button docs
path: docs/components/ren-button.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Button — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    /* Page-specific styles — chrome lives in shell.css */

    /* ═══════════════════════════════════════════════════════════
       Component-page specific patterns (new)
       ═══════════════════════════════════════════════════════════ */

    /* Demo block: preview frame + code block, stacked */
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview {
      background: var(--color-surface-raised);
      padding: var(--space-8) var(--space-5);
      display: flex;
      flex-wrap: wrap;
      gap: var(--space-3);
      align-items: center;
      justify-content: center;
      min-height: 96px;
    }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }

    /* Variant grid: structured rows for Variants section */
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label {
      font-size: var(--text-xs);
      font-weight: var(--weight-semibold);
      text-transform: uppercase;
      letter-spacing: 0.06em;
      color: var(--color-text-muted);
      padding-top: var(--space-3);
    }
    .dx-vrow-items {
      display: flex;
      flex-wrap: wrap;
      gap: var(--space-3);
      align-items: center;
      padding: var(--space-3);
      background: var(--color-surface-raised);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
    }
    @media (max-width: 720px) {
      .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); }
      .dx-vrow-label { padding-top: 0; }
    }

    /* Anatomy: assembled button on top, 2x2 grid of part specimens below */
    .dx-anatomy {
      margin: var(--space-4) 0;
      display: grid;
      gap: var(--space-4);
    }

    /* Number badge — guaranteed AA: text on surface (black on white / white on black) */
    .dx-anatomy-num {
      display: inline-grid;
      place-items: center;
      width: 22px;
      height: 22px;
      border-radius: 50%;
      background: var(--color-text);
      color: var(--color-surface);
      font-size: var(--text-xs);
      font-weight: var(--weight-bold);
      flex-shrink: 0;
    }

    /* Top: assembled reference */
    .dx-anatomy-stage {
      background: var(--color-surface-raised);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      padding: var(--space-8) var(--space-5);
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: var(--space-3);
    }
    .dx-anatomy-stage-label {
      font-size: var(--text-xs);
      text-transform: uppercase;
      letter-spacing: 0.06em;
      color: var(--color-text-muted);
      font-weight: var(--weight-semibold);
      margin: 0;
    }
    .dx-anatomy-stage .ren-btn { pointer-events: none; }

    /* Bottom: 2x2 grid of parts */
    .dx-anatomy-parts {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: var(--space-3);
    }
    @media (max-width: 720px) { .dx-anatomy-parts { grid-template-columns: 1fr; } }

    .dx-anatomy-part {
      background: var(--color-surface-raised);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      padding: var(--space-4);
      display: grid;
      gap: var(--space-3);
    }
    .dx-anatomy-part-header {
      display: flex;
      align-items: center;
      gap: var(--space-2);
    }
    .dx-anatomy-part-name {
      font-size: var(--text-sm);
      font-weight: var(--weight-semibold);
      color: var(--color-text);
    }
    .dx-anatomy-part-spec {
      background: var(--color-surface-sunken);
      border: 1px dashed var(--color-border);
      border-radius: var(--radius-sm);
      min-height: 64px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: var(--color-text);
    }
    .dx-anatomy-part-spec svg { display: block; }
    .dx-anatomy-part-spec .container-frame {
      width: 110px;
      height: 32px;
      border: 2px solid var(--color-accent);
      border-radius: var(--radius-md);
      background: transparent;
    }
    .dx-anatomy-part-desc {
      font-size: var(--text-sm);
      line-height: 1.5;
      color: var(--color-text-secondary);
      margin: 0;
    }
    .dx-anatomy-part-desc code {
      font-size: 0.85em;
    }

    /* .dx-api and .dx-keys live in shell.css so every reference table
       on every component page shares the same column boundary. */
  </style>
</head>
<body>

  <!-- Top nav -->
  <header class="dx-nav">
    <div class="dx-nav-inner">
      <a href="../index.html" class="dx-brand">
        <span class="dx-brand-mark">R</span>
        <span>RenDS</span>
        <span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span>
      </a>
      <nav class="dx-nav-menu" aria-label="Primary">
        <a href="../index.html">Docs</a>
        <a href="../components.html" aria-current="page">Components</a>
        <a href="../../templates/index.html">Templates</a>
        <a href="../../create/index.html">Theme Builder</a>
      </nav>
      <div class="dx-nav-actions">
        <a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a>
        <a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a>
      </div>
    </div>
  </header>

  <div class="dx-shell dx-shell-grid">

    <!-- Persistent sidebar — same nav as the catalog so context is never lost -->
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html" aria-current="page">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <!-- Content -->
    <main class="dx-content">

      <!-- Page header -->
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);">
          <ol>
            <li><a href="../index.html" class="ren-link-plain">Docs</a></li>
            <li><a href="../components.html" class="ren-link-plain">Components</a></li>
            <li aria-current="page">Button</li>
          </ol>
        </nav>
        <p class="dx-kicker">Primitive</p>
        <h1>Button <span class="dx-api-badge dx-api-badge-hybrid" title="Renders without JS; JS adds enhancements">Hybrid</span></h1>
        <p class="lede">A multi-variant action trigger with built-in loading and disabled states. Works as a CSS-only class set <em>or</em> as the <code>&lt;ren-button&gt;</code> custom element. Meets a 44 px touch target and AA contrast in every variant out of the box.</p>
      </header>

    <!-- ═══════════════════════════════════════════════════════════
         1. OVERVIEW
         ═══════════════════════════════════════════════════════════ -->
    <section class="dx-section" id="overview">
      <p class="dx-kicker">About</p>
      <h2>Overview</h2>
      <p>A button triggers an action — submitting a form, opening a dialog, deleting a record. RenDS gives you one component with seven visual variants (primary, secondary, ghost, outline, danger, link, accent), three sizes, and a built-in loading state that flips the button to <code>aria-busy="true"</code> and disables interaction without you wiring anything.</p>

      <p>Every variant ships with a 44 px minimum touch target (Apple HIG), a visible focus ring, hover/active feedback that respects <code>prefers-reduced-motion</code>, and AA contrast in both light and dark mode.</p>

      <h3>When to use</h3>
      <ul>
        <li>To trigger an action on the current page (submit, save, delete, copy, run).</li>
        <li>To open or close an overlay (dialog, popover, menu).</li>
        <li>For a primary CTA, group it with a secondary or ghost button — never two primaries side by side.</li>
      </ul>

      <h3>When not to use</h3>
      <ul>
        <li>For navigation to a different page or a different URL — that's <code>&lt;a&gt;</code> or <code>ren-link</code>. A button that navigates breaks browser conventions (no middle-click open, no copy-link).</li>
        <li>For an inline call-to-read-more inside body text — use the <code>link</code> variant only when a button is genuinely needed; otherwise reach for <code>ren-link</code>.</li>
        <li>For a binary state choice — that's <code>ren-toggle</code> or a checkbox.</li>
      </ul>

      <div class="dx-callout">
        <p><strong>Native button, semantically.</strong> The <code>&lt;ren-button&gt;</code> custom element wraps a native <code>&lt;button&gt;</code> in light DOM. Forms still submit, focus still works, screen readers still announce "button". You're not opting out of the platform — you're styling it.</p>
      </div>
    </section>

    <!-- ═══════════════════════════════════════════════════════════
         2. ANATOMY
         ═══════════════════════════════════════════════════════════ -->
    <section class="dx-section" id="anatomy">
      <p class="dx-kicker">Structure</p>
      <h2>Anatomy</h2>
      <p>A button has up to four visible parts. Only the label is mandatory — the rest are optional and combine freely.</p>

      <div class="dx-anatomy">

        <!-- Top: assembled button as reference -->
        <div class="dx-anatomy-stage">
          <p class="dx-anatomy-stage-label">Assembled</p>
          <button class="ren-btn ren-btn-primary ren-btn-lg" type="button" tabindex="-1" aria-hidden="true">
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
              <path d="M12 5v14M5 12h14"/>
            </svg>
            Add item
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
              <polyline points="9 18 15 12 9 6"/>
            </svg>
          </button>
        </div>

        <!-- Bottom: 4 parts shown in isolation -->
        <div class="dx-anatomy-parts">

          <div class="dx-anatomy-part">
            <div class="dx-anatomy-part-header">
              <span class="dx-anatomy-num" aria-hidden="true">1</span>
              <span class="dx-anatomy-part-name">Container</span>
            </div>
            <div class="dx-anatomy-part-spec" aria-hidden="true">
              <span class="container-frame"></span>
            </div>
            <p class="dx-anatomy-part-desc">The whole clickable surface. Sets the variant color, padding, border-radius, and the 44&nbsp;px touch target. Receives focus.</p>
          </div>

          <div class="dx-anatomy-part">
            <div class="dx-anatomy-part-header">
              <span class="dx-anatomy-num" aria-hidden="true">2</span>
              <span class="dx-anatomy-part-name">Leading icon</span>
            </div>
            <div class="dx-anatomy-part-spec" aria-hidden="true">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 5v14M5 12h14"/></svg>
            </div>
            <p class="dx-anatomy-part-desc">Optional. Placed before the label, gap-spaced with <code>--space-2</code>. Decorative icons should carry <code>aria-hidden="true"</code>.</p>
          </div>

          <div class="dx-anatomy-part">
            <div class="dx-anatomy-part-header">
              <span class="dx-anatomy-num" aria-hidden="true">3</span>
              <span class="dx-anatomy-part-name">Label</span>
            </div>
            <div class="dx-anatomy-part-spec" aria-hidden="true">
              <span style="font-size: var(--text-base); font-weight: var(--weight-medium);">Add item</span>
            </div>
            <p class="dx-anatomy-part-desc">The visible text. Required for non-icon buttons. For icon-only buttons, omit it and add <code>aria-label</code> on the button itself.</p>
          </div>

          <div class="dx-anatomy-part">
            <div class="dx-anatomy-part-header">
              <span class="dx-anatomy-num" aria-hidden="true">4</span>
              <span class="dx-anatomy-part-name">Trailing icon</span>
            </div>
            <div class="dx-anatomy-part-spec" aria-hidden="true">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 18 15 12 9 6"/></svg>
            </div>
            <p class="dx-anatomy-part-desc">Optional. Same rules as the leading icon. Common cases: a chevron for "more options", an external-link arrow.</p>
          </div>

        </div>
      </div>
    </section>

    <!-- ═══════════════════════════════════════════════════════════
         3. DEMO
         ═══════════════════════════════════════════════════════════ -->
    <section class="dx-section" id="demo">
      <p class="dx-kicker">Live</p>
      <h2>Demo</h2>
      <p>The default button — primary variant, medium size. Tab to it, press Space or Enter to fire the click handler.</p>

      <div class="dx-demo">
        <div class="dx-demo-preview">
          <button class="ren-btn ren-btn-primary" type="button">Primary action</button>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;!-- CSS-only --&gt;
&lt;button class="ren-btn ren-btn-primary" type="button"&gt;Primary action&lt;/button&gt;

&lt;!-- Web Component (same output, attribute-driven) --&gt;
&lt;ren-button variant="primary"&gt;Primary action&lt;/ren-button&gt;</code></pre>
      </div>

      <div class="dx-callout">
        <p><strong>Two ways to use it, one component.</strong> The CSS classes work standalone — you don't need the JS at all. The <code>&lt;ren-button&gt;</code> element exists for two reasons: declarative attributes (<code>variant</code>, <code>loading</code>) you can flip from JS, and built-in ARIA wiring for the loading state.</p>
      </div>
    </section>

    <!-- ═══════════════════════════════════════════════════════════
         4. VARIANTS
         ═══════════════════════════════════════════════════════════ -->
    <section class="dx-section" id="variants">
      <p class="dx-kicker">Catalog</p>
      <h2>Variants</h2>
      <p>Pick the variant that matches the action's <em>weight</em>, not its category. Primary for the one most-likely action on the screen, secondary for everything else, danger for destructive, ghost when the button has to disappear into the chrome.</p>

      <div class="dx-vgrid">

        <div class="dx-vrow">
          <span class="dx-vrow-label">Variant</span>
          <div class="dx-vrow-items">
            <button class="ren-btn ren-btn-primary" type="button">Primary</button>
            <button class="ren-btn ren-btn-secondary" type="button">Secondary</button>
            <button class="ren-btn ren-btn-ghost" type="button">Ghost</button>
            <button class="ren-btn ren-btn-outline" type="button">Outline</button>
            <button class="ren-btn ren-btn-danger" type="button">Danger</button>
            <button class="ren-btn ren-btn-link" type="button">Link</button>
          </div>
        </div>

        <div class="dx-vrow">
          <span class="dx-vrow-label">Size</span>
          <div class="dx-vrow-items">
            <button class="ren-btn ren-btn-primary ren-btn-sm" type="button">Small</button>
            <button class="ren-btn ren-btn-primary" type="button">Medium</button>
            <button class="ren-btn ren-btn-primary ren-btn-lg" type="button">Large</button>
          </div>
        </div>

        <div class="dx-vrow">
          <span class="dx-vrow-label">State</span>
          <div class="dx-vrow-items">
            <button class="ren-btn ren-btn-primary" type="button">Default</button>
            <button class="ren-btn ren-btn-primary" type="button" disabled>Disabled</button>
            <button class="ren-btn ren-btn-primary" type="button" data-loading aria-busy="true">Loading</button>
          </div>
        </div>

        <div class="dx-vrow">
          <span class="dx-vrow-label">Icon-only</span>
          <div class="dx-vrow-items">
            <button class="ren-btn ren-btn-primary ren-btn-icon" type="button" aria-label="Add">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
            </button>
            <button class="ren-btn ren-btn-secondary ren-btn-icon" type="button" aria-label="Search">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
            </button>
            <button class="ren-btn ren-btn-ghost ren-btn-icon" type="button" aria-label="More options">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
            </button>
          </div>
        </div>

        <div class="dx-vrow">
          <span class="dx-vrow-label">Full width</span>
          <div class="dx-vrow-items" style="display: block;">
            <button class="ren-btn ren-btn-primary ren-btn-full" type="button">Continue</button>
          </div>
        </div>

        <div class="dx-vrow">
          <span class="dx-vrow-label">Group</span>
          <div class="dx-vrow-items">
            <div class="ren-btn-group">
              <button class="ren-btn ren-btn-secondary" type="button">Day</button>
              <button class="ren-btn ren-btn-secondary" type="button" aria-pressed="true">Week</button>
              <button class="ren-btn ren-btn-secondary" type="button">Month</button>
            </div>
          </div>
        </div>

      </div>
    </section>

    <!-- ═══════════════════════════════════════════════════════════
         5. API
         ═══════════════════════════════════════════════════════════ -->
    <section class="dx-section" id="api">
      <p class="dx-kicker">Reference</p>
      <h2>API</h2>
      <p>Two parallel surfaces. Pick the one that matches your codebase: CSS classes for static markup, the custom element for declarative attributes you can flip at runtime.</p>

      <h3>CSS classes</h3>
      <table class="dx-api">
        <thead>
          <tr>
            <th>Class</th>
            <th>Effect</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><code class="dx-api-name">.ren-btn</code></td>
            <td>Base. Required on every button. Resolves to <em>primary</em> if no variant modifier is present.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">.ren-btn-primary</code></td>
            <td>Filled accent. The default — also implicit when only <code>.ren-btn</code> is set.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">.ren-btn-secondary</code></td>
            <td>Filled neutral. The most common companion to a primary.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">.ren-btn-ghost</code></td>
            <td>No background until hover. For toolbars and dense chrome.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">.ren-btn-outline</code></td>
            <td>Border only, transparent fill. A lighter secondary.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">.ren-btn-danger</code></td>
            <td>Destructive actions. Filled red, text-on-red passes AA in both modes.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">.ren-btn-link</code></td>
            <td>Looks like an inline link but behaves as a button. Use sparingly.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">.ren-btn-sm</code> / <code class="dx-api-name">.ren-btn-lg</code></td>
            <td>Size modifiers. Default (no modifier) is medium with a 44 px touch target.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">.ren-btn-icon</code></td>
            <td>Square aspect ratio for icon-only buttons. Pair with <code>aria-label</code>.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">.ren-btn-full</code></td>
            <td>Stretches to <code>width: 100%</code>. For mobile CTAs and stepped forms.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">.ren-btn-group</code></td>
            <td>Wrapper class. Joins adjacent buttons into a segmented control with shared borders.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">[data-loading]</code></td>
            <td>Attribute, not a class. Shows a spinner, hides the label, sets <code>aria-busy</code>.</td>
          </tr>
        </tbody>
      </table>

      <h3>Web Component attributes</h3>
      <p>Set on the <code>&lt;ren-button&gt;</code> element. All are reactive — flipping them in JS re-renders the underlying button.</p>
      <table class="dx-api dx-api-cols-4">
        <thead>
          <tr>
            <th>Attribute</th>
            <th>Type</th>
            <th>Default</th>
            <th>Notes</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><code class="dx-api-name">variant</code></td>
            <td><span class="dx-api-type">"primary" | "secondary" | "ghost" | "outline" | "danger" | "link"</span></td>
            <td><span class="dx-api-default">"primary"</span></td>
            <td>Visual variant.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">size</code></td>
            <td><span class="dx-api-type">"sm" | "md" | "lg"</span></td>
            <td><span class="dx-api-default">"md"</span></td>
            <td>Padding and font scale.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">loading</code></td>
            <td><span class="dx-api-type">boolean</span></td>
            <td><span class="dx-api-default">false</span></td>
            <td>Adds <code>data-loading</code> + <code>aria-busy="true"</code>.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">disabled</code></td>
            <td><span class="dx-api-type">boolean</span></td>
            <td><span class="dx-api-default">false</span></td>
            <td>Mirrors the native <code>disabled</code> + sets <code>aria-disabled</code>.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">icon</code></td>
            <td><span class="dx-api-type">boolean</span></td>
            <td><span class="dx-api-default">false</span></td>
            <td>Square button for icon-only usage.</td>
          </tr>
          <tr>
            <td><code class="dx-api-name">full</code></td>
            <td><span class="dx-api-type">boolean</span></td>
            <td><span class="dx-api-default">false</span></td>
            <td>Stretches to 100% width.</td>
          </tr>
        </tbody>
      </table>

      <h3>JS properties</h3>
      <p>The <code>RenButton</code> class exposes getters/setters that mirror the boolean attributes. Useful when you'd rather flip a property than toggle an attribute.</p>
      <div class="dx-pre" tabindex="0"><code>const btn = document.querySelector('ren-button');
btn.loading = true;          // shows spinner
btn.disabled = true;
btn.variant  = 'danger';     // re-renders</code></div>
    </section>

    <!-- ═══════════════════════════════════════════════════════════
         6. ACCESSIBILITY
         ═══════════════════════════════════════════════════════════ -->
    <section class="dx-section" id="a11y">
      <p class="dx-kicker">Inclusive by default</p>
      <h2>Accessibility</h2>
      <p>Every button passes WCAG 2.1 AA in both modes and every variant. The component does most of the work for you, but a few things are still your call.</p>

      <h3>Keyboard</h3>
      <div class="dx-keys">
        <div class="dx-keyrow">
          <span class="keys"><kbd class="ren-kbd">Tab</kbd></span>
          <span>Moves focus to the button (skips disabled buttons).</span>
        </div>
        <div class="dx-keyrow">
          <span class="keys"><kbd class="ren-kbd">Space</kbd></span>
          <span>Fires the click handler. Standard native behavior.</span>
        </div>
        <div class="dx-keyrow">
          <span class="keys"><kbd class="ren-kbd">Enter</kbd></span>
          <span>Fires the click handler. Inside a form, also submits the form unless <code>type="button"</code> is set.</span>
        </div>
      </div>

      <div class="dx-callout">
        <p><strong>Always set <code>type="button"</code></strong> on buttons that aren't form submitters. The browser default is <code>type="submit"</code>, which will submit the nearest enclosing form on Enter — usually not what you want for "Cancel", "Open menu", or any non-submit action.</p>
      </div>

      <h3>ARIA wiring</h3>
      <ul>
        <li>The button has <code>role="button"</code> implicitly via the native <code>&lt;button&gt;</code>. No need to set it.</li>
        <li>For <strong>icon-only</strong> buttons, set <code>aria-label</code> on the button. Decorative icons inside should carry <code>aria-hidden="true"</code>.</li>
        <li>For <strong>loading</strong> state, the component sets <code>aria-busy="true"</code> automatically. Screen readers will announce the state change.</li>
        <li>For <strong>disabled</strong> state, both <code>disabled</code> and <code>aria-disabled="true"</code> are set. Disabled buttons are skipped in tab order; if you need a focusable-but-inert button (rare), use <code>aria-disabled</code> alone and handle the click guard yourself.</li>
        <li>For <strong>toggle</strong> buttons (a button that flips between two states), add <code>aria-pressed="true"</code> or <code>"false"</code>. The <em>group</em> example above uses this.</li>
      </ul>

      <h3>Screen reader announcements</h3>
      <ul>
        <li>"Add to cart, button" — for a regular labelled button.</li>
        <li>"Search, button, busy" — when <code>loading</code> is set.</li>
        <li>"Save, button, dimmed" (or similar) — when <code>disabled</code> is set.</li>
        <li>"Week, button, pressed" — for a toggled button in a group.</li>
      </ul>

      <h3>Touch and pointer</h3>
      <ul>
        <li>Default and large sizes meet the <strong>44 × 44 px</strong> minimum touch target. The small size is below that and should only be used in dense desktop UI (toolbars, table cells).</li>
        <li>The press-down feedback (a <code>scale(0.97)</code> on <code>:active</code>) respects <code>prefers-reduced-motion</code> via the semantic motion tokens — it stays subtle for users who request reduced motion.</li>
        <li>Hover styles never replace focus styles. A keyboard user always sees a focus ring on the focused button, even when a different button is hovered.</li>
      </ul>
    </section>

    <!-- ═══════════════════════════════════════════════════════════
         7. EXAMPLES
         ═══════════════════════════════════════════════════════════ -->
    <section class="dx-section" id="examples">
      <p class="dx-kicker">Recipes</p>
      <h2>Examples</h2>
      <p>Common patterns that combine the variants above with other RenDS primitives. Copy the markup, swap the labels.</p>

      <h3>Primary + secondary pair</h3>
      <p>The classic "confirm and cancel" pairing. Primary on the right (or last), secondary on the left.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview">
          <div class="ren-cluster" style="--cluster-gap: var(--space-2);">
            <button class="ren-btn ren-btn-secondary" type="button">Cancel</button>
            <button class="ren-btn ren-btn-primary" type="button">Save changes</button>
          </div>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-cluster"&gt;
  &lt;button class="ren-btn ren-btn-secondary" type="button"&gt;Cancel&lt;/button&gt;
  &lt;button class="ren-btn ren-btn-primary"   type="button"&gt;Save changes&lt;/button&gt;
&lt;/div&gt;</code></pre>
      </div>

      <h3>Destructive confirmation</h3>
      <p>For irreversible actions. The danger variant signals stakes; pair with secondary, never with another colored variant.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview">
          <div class="ren-cluster" style="--cluster-gap: var(--space-2);">
            <button class="ren-btn ren-btn-secondary" type="button">Keep account</button>
            <button class="ren-btn ren-btn-danger" type="button">Delete account</button>
          </div>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-cluster"&gt;
  &lt;button class="ren-btn ren-btn-secondary" type="button"&gt;Keep account&lt;/button&gt;
  &lt;button class="ren-btn ren-btn-danger"    type="button"&gt;Delete account&lt;/button&gt;
&lt;/div&gt;</code></pre>
      </div>

      <h3>Loading from JS</h3>
      <p>Flip <code>loading</code> on submit, flip it back when the request resolves.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview">
          <ren-button id="demo-load" variant="primary">Save</ren-button>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>const btn = document.querySelector('ren-button#demo-load');
btn.addEventListener('click', async () =&gt; {
  btn.loading = true;
  try {
    await fetch('/api/save', { method: 'POST' });
  } finally {
    btn.loading = false;
  }
});</code></pre>
      </div>

      <h3>Icon-only in a toolbar</h3>
      <p>Ghost icon buttons disappear into chrome until hovered. Always set <code>aria-label</code>.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview">
          <div class="ren-cluster" style="--cluster-gap: var(--space-1);">
            <button class="ren-btn ren-btn-ghost ren-btn-icon" type="button" aria-label="Bold">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" aria-hidden="true"><path d="M14 12a4 4 0 0 0 0-8H6v8"/><path d="M15 20a4 4 0 0 0 0-8H6v8z"/></svg>
            </button>
            <button class="ren-btn ren-btn-ghost ren-btn-icon" type="button" aria-label="Italic">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><line x1="19" y1="4" x2="10" y2="4"/><line x1="14" y1="20" x2="5" y2="20"/><line x1="15" y1="4" x2="9" y2="20"/></svg>
            </button>
            <button class="ren-btn ren-btn-ghost ren-btn-icon" type="button" aria-label="Underline">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M6 4v6a6 6 0 0 0 12 0V4"/><line x1="4" y1="20" x2="20" y2="20"/></svg>
            </button>
          </div>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-cluster"&gt;
  &lt;button class="ren-btn ren-btn-ghost ren-btn-icon" type="button" aria-label="Bold"&gt;
    &lt;svg ... aria-hidden="true"&gt;...&lt;/svg&gt;
  &lt;/button&gt;
  &lt;!-- repeat for italic, underline --&gt;
&lt;/div&gt;</code></pre>
      </div>

      <h3>Segmented control</h3>
      <p>Three buttons in a group, one pressed. Manage <code>aria-pressed</code> from JS as the user clicks.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview">
          <div class="ren-btn-group" role="group" aria-label="View by">
            <button class="ren-btn ren-btn-secondary" type="button">Day</button>
            <button class="ren-btn ren-btn-secondary" type="button" aria-pressed="true">Week</button>
            <button class="ren-btn ren-btn-secondary" type="button">Month</button>
          </div>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-btn-group" role="group" aria-label="View by"&gt;
  &lt;button class="ren-btn ren-btn-secondary" type="button"&gt;Day&lt;/button&gt;
  &lt;button class="ren-btn ren-btn-secondary" type="button" aria-pressed="true"&gt;Week&lt;/button&gt;
  &lt;button class="ren-btn ren-btn-secondary" type="button"&gt;Month&lt;/button&gt;
&lt;/div&gt;</code></pre>
      </div>

      <h3>Full-width on mobile</h3>
      <p>Stretch the primary CTA on small screens for comfortable thumb reach.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview" style="display: block;">
          <button class="ren-btn ren-btn-primary ren-btn-lg ren-btn-full" type="button">Continue</button>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;button class="ren-btn ren-btn-primary ren-btn-lg ren-btn-full" type="button"&gt;
  Continue
&lt;/button&gt;</code></pre>
      </div>
    </section>

    </main>

  </div>

  <!-- Web Component registration so the live demos render -->
  <script type="module" src="../../components/primitives/ren-button/ren-button.js"></script>

  <!-- Demo: simulate loading toggle -->
  <script>
    const demoLoad = document.getElementById('demo-load');
    if (demoLoad) {
      demoLoad.addEventListener('click', () => {
        if (demoLoad.loading) return;
        demoLoad.loading = true;
        setTimeout(() => { demoLoad.loading = false; }, 1600);
      });
    }
  </script>

  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-calendar.html
type: docs_page
name: ren-calendar docs
path: docs/components/ren-calendar.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Calendar — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; justify-content: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }

    /* Demo calendar */
    .demo-cal {
      padding: var(--space-3);
      background: var(--color-surface);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      width: 280px;
    }
    .demo-cal-head {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: var(--space-2);
    }
    .demo-cal-grid {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      gap: 2px;
      text-align: center;
      font-size: var(--text-xs);
    }
    .demo-cal-grid .wd {
      color: var(--color-text-muted);
      padding: var(--space-1);
      font-weight: var(--weight-semibold);
    }
    .demo-cal-grid .day {
      padding: var(--space-1);
      cursor: pointer;
      border-radius: 4px;
    }
    .demo-cal-grid .day:hover { background: var(--color-fill); }
    .demo-cal-grid .day.outside { color: var(--color-text-faint); }
    .demo-cal-grid .day.today { font-weight: var(--weight-semibold); color: var(--color-accent); }
    .demo-cal-grid .day.selected {
      background: var(--color-accent);
      color: var(--color-on-accent);
      font-weight: var(--weight-semibold);
    }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html" aria-current="page">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);">
          <ol>
            <li><a href="../index.html" class="ren-link-plain">Docs</a></li>
            <li><a href="../components.html" class="ren-link-plain">Components</a></li>
            <li aria-current="page">Calendar</li>
          </ol>
        </nav>
        <p class="dx-kicker">Composite</p>
        <h1>Calendar <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">Monthly grid for picking a date. Locale-aware first day of week, full keyboard navigation, plus optional range and multi-select modes.</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>The standalone calendar grid. Use it inline in a page (event scheduling, availability picker, booking flow), or wire it up to a trigger via <a href="ren-date-picker.html" class="ren-link">Date Picker</a> when the calendar should appear in a popover. For start + end pairs, see <a href="ren-date-range-picker.html" class="ren-link">Date Range Picker</a>.</p>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <div class="demo-cal" role="application" aria-label="Calendar, May 2026">
              <div class="demo-cal-head">
                <button class="ren-btn ren-btn-ghost ren-btn-sm" type="button" aria-label="Previous month">‹</button>
                <strong style="font-size: var(--text-sm);">May 2026</strong>
                <button class="ren-btn ren-btn-ghost ren-btn-sm" type="button" aria-label="Next month">›</button>
              </div>
              <div class="demo-cal-grid">
                <span class="wd">M</span><span class="wd">T</span><span class="wd">W</span><span class="wd">T</span><span class="wd">F</span><span class="wd">S</span><span class="wd">S</span>
                <span class="day outside">27</span><span class="day outside">28</span><span class="day outside">29</span><span class="day outside">30</span>
                <span class="day">1</span><span class="day">2</span><span class="day">3</span>
                <span class="day">4</span><span class="day">5</span><span class="day">6</span>
                <span class="day selected" aria-selected="true">7</span>
                <span class="day">8</span><span class="day">9</span><span class="day">10</span>
                <span class="day">11</span><span class="day">12</span><span class="day">13</span><span class="day">14</span>
                <span class="day">15</span><span class="day">16</span><span class="day">17</span>
                <span class="day">18</span><span class="day">19</span><span class="day">20</span><span class="day">21</span>
                <span class="day">22</span><span class="day">23</span><span class="day">24</span>
                <span class="day">25</span><span class="day">26</span><span class="day">27</span><span class="day">28</span>
                <span class="day">29</span><span class="day">30</span><span class="day">31</span>
                <span class="day outside">1</span><span class="day outside">2</span><span class="day outside">3</span><span class="day outside">4</span>
              </div>
            </div>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-calendar value="2026-05-07" locale="en-US"&gt;&lt;/ren-calendar&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>
        <table class="dx-api dx-api-cols-4">
          <thead>
            <tr><th>Attribute</th><th>Type</th><th>Default</th><th>Notes</th></tr>
          </thead>
          <tbody>
            <tr>
              <td><code class="dx-api-name">value</code></td>
              <td><span class="dx-api-type">"YYYY-MM-DD"</span></td>
              <td><span class="dx-api-default">today</span></td>
              <td>Currently selected date.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">min</code> / <code class="dx-api-name">max</code></td>
              <td><span class="dx-api-type">"YYYY-MM-DD"</span></td>
              <td><span class="dx-api-default">—</span></td>
              <td>Restrict the selectable range.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">locale</code></td>
              <td><span class="dx-api-type">BCP-47 string</span></td>
              <td><span class="dx-api-default">"en"</span></td>
              <td>Affects month / weekday names and the first day of the week.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">mode</code></td>
              <td><span class="dx-api-type">"single" | "range" | "multi"</span></td>
              <td><span class="dx-api-default">"single"</span></td>
              <td>Selection mode.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">disabled-dates</code></td>
              <td><span class="dx-api-type">string[]</span></td>
              <td><span class="dx-api-default">[]</span></td>
              <td>Array of <code>YYYY-MM-DD</code> strings to disable individually.</td>
            </tr>
          </tbody>
        </table>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <ul>
          <li>Implements the WAI-ARIA Date Picker dialog pattern. The grid is a <code>role="grid"</code>; each day is a <code>role="gridcell"</code>.</li>
          <li>Arrow keys move day-by-day, <kbd>Page Up</kbd> / <kbd>Page Down</kbd> move by month, <kbd>Shift</kbd>+<kbd>Page Up</kbd>/<kbd>Page Down</kbd> by year, <kbd>Home</kbd> / <kbd>End</kbd> jump to the start / end of the week.</li>
          <li>Each day cell carries an <code>aria-label</code> with the full date so screen readers announce <em>"Thursday, May 7, 2026"</em> rather than just <em>"7"</em>.</li>
          <li>The currently selected day uses <code>aria-selected="true"</code>; disabled days use <code>aria-disabled="true"</code>.</li>
        </ul>
      </section>

    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-card.html
type: docs_page
name: ren-card docs
path: docs/components/ren-card.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Card — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    /* Page-specific styles — chrome lives in shell.css */

    /* ═══════════════════════════════════════════════════════════
       Component-page specific patterns
       ═══════════════════════════════════════════════════════════ */

    /* Demo block */
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview {
      background: var(--color-surface-raised);
      padding: var(--space-6) var(--space-5);
      display: flex;
      flex-wrap: wrap;
      gap: var(--space-3);
      align-items: center;
      justify-content: center;
      min-height: 96px;
    }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }

    /* Variant grid */
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); padding-top: var(--space-3); }
    .dx-vrow-items { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3); background: var(--color-surface); border: 1px solid var(--color-border-muted); border-radius: var(--radius-md); }
    @media (max-width: 720px) { .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); } .dx-vrow-label { padding-top: 0; } }

    /* Anatomy */
    .dx-anatomy { margin: var(--space-4) 0; display: grid; gap: var(--space-4); }
    .dx-anatomy-num { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--color-text); color: var(--color-surface); font-size: var(--text-xs); font-weight: var(--weight-bold); flex-shrink: 0; }
    .dx-anatomy-stage { background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-6); display: flex; flex-direction: column; align-items: center; gap: var(--space-3); }
    .dx-anatomy-stage-label { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); font-weight: var(--weight-semibold); margin: 0; }
    .dx-anatomy-parts { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
    @media (max-width: 720px) { .dx-anatomy-parts { grid-template-columns: 1fr; } }
    .dx-anatomy-part { background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-4); display: grid; gap: var(--space-3); }
    .dx-anatomy-part-header { display: flex; align-items: center; gap: var(--space-2); }
    .dx-anatomy-part-name { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--color-text); }
    .dx-anatomy-part-spec {
      background: var(--color-surface-sunken);
      border: 1px dashed var(--color-border);
      border-radius: var(--radius-sm);
      min-height: 72px;
      padding: var(--space-3);
      display: flex;
      align-items: center;
      justify-content: center;
      color: var(--color-text);
    }
    .dx-anatomy-part-desc { font-size: var(--text-sm); line-height: 1.5; color: var(--color-text-secondary); margin: 0; }
    .dx-anatomy-part-desc code { font-size: 0.85em; }

    /* Body p reset for demos that use raw <p> inside .ren-card-body (the title
       and description resets now live in ren-card.css itself, post-fix). */
    .dx-demo-preview .ren-card-body p,
    .dx-anatomy-stage .ren-card-body p { margin: 0; }

    /* .dx-api and .dx-keys live in shell.css so every reference table
       on every component page shares the same column boundary. */
  </style>
</head>
<body>

  <header class="dx-nav">
    <div class="dx-nav-inner">
      <a href="../index.html" class="dx-brand">
        <span class="dx-brand-mark">R</span>
        <span>RenDS</span>
        <span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span>
      </a>
      <nav class="dx-nav-menu" aria-label="Primary">
        <a href="../index.html">Docs</a>
        <a href="../components.html" aria-current="page">Components</a>
        <a href="../../templates/index.html">Templates</a>
        <a href="../../create/index.html">Theme Builder</a>
      </nav>
      <div class="dx-nav-actions">
        <a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a>
        <a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a>
      </div>
    </div>
  </header>

  <div class="dx-shell dx-shell-grid">

    <!-- Persistent sidebar — same nav as the catalog so context is never lost -->
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html" aria-current="page">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <!-- Content -->
    <main class="dx-content">

      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);">
          <ol>
            <li><a href="../index.html" class="ren-link-plain">Docs</a></li>
            <li><a href="../components.html" class="ren-link-plain">Components</a></li>
            <li aria-current="page">Card</li>
          </ol>
        </nav>
        <p class="dx-kicker">Primitive</p>
        <h1>Card <span class="dx-api-badge dx-api-badge-css" title="Works without any JavaScript">CSS-only</span></h1>
        <p class="lede">A flexible content container with optional header, body, and footer sections. Five visual variants, status accents, and built-in interactive / selectable patterns. Pure CSS — no JavaScript required.</p>
      </header>

    <!-- 1. OVERVIEW -->
    <section class="dx-section" id="overview">
      <p class="dx-kicker">About</p>
      <h2>Overview</h2>
      <p>A card groups related content into a single visual unit — a profile, a stat, a settings panel, a list item, an article preview. RenDS gives you one base component with optional header / body / footer slots, five visual variants, and three interaction states (static, interactive, selectable).</p>

      <p>Cards are entirely CSS-driven. There's no <code>&lt;ren-card&gt;</code> Web Component because there's nothing for JS to do — the structure is plain HTML, the variants are class modifiers, and the interactivity (hover, focus, selection) is handled by CSS pseudo-classes plus standard ARIA attributes.</p>

      <h3>When to use</h3>
      <ul>
        <li>To group a chunk of content (text + actions + metadata) that the user will visually scan as a single unit.</li>
        <li>To present a list of similar items (a grid of products, posts, profiles, settings groups).</li>
        <li>For status surfaces — use the <code>data-status</code> attribute to signal success, warning, danger, or info at a glance.</li>
      </ul>

      <h3>When not to use</h3>
      <ul>
        <li>For a single line of content — a card adds visual weight that body text doesn't need. Use a paragraph or a banner.</li>
        <li>For a modal dialog — that's <code>ren-dialog</code>, which traps focus and dims the rest of the page.</li>
        <li>For navigation between pages — wrap an anchor or use <code>ren-link</code>; cards make poor primary navigation.</li>
      </ul>

      <div class="dx-callout">
        <p><strong>Cards are containers, not components.</strong> They don't dictate what goes inside. Mix and match — drop in a button group, an avatar, a chart, a form. The card supplies the surface; you supply the content.</p>
      </div>
    </section>

    <!-- 2. ANATOMY -->
    <section class="dx-section" id="anatomy">
      <p class="dx-kicker">Structure</p>
      <h2>Anatomy</h2>
      <p>A card has a container plus three optional section slots. Each slot has its own padding rules so they nest cleanly without you fighting margins.</p>

      <div class="dx-anatomy">
        <div class="dx-anatomy-stage">
          <p class="dx-anatomy-stage-label">Assembled</p>
          <div class="ren-card" style="max-width: 320px; width: 100%;">
            <div class="ren-card-header">
              <h4 class="ren-card-title" style="margin: 0;">Project update</h4>
              <p class="ren-card-description" style="margin: 0;">Last edited 2 hours ago</p>
            </div>
            <div class="ren-card-body">
              <p style="margin: 0;">Dashboard ready for review. All components passed a11y audit.</p>
            </div>
            <div class="ren-card-footer">
              <button type="button" class="ren-btn ren-btn-secondary ren-btn-sm">Dismiss</button>
              <button type="button" class="ren-btn ren-btn-primary ren-btn-sm">View</button>
            </div>
          </div>
        </div>

        <div class="dx-anatomy-parts">

          <div class="dx-anatomy-part">
            <div class="dx-anatomy-part-header">
              <span class="dx-anatomy-num" aria-hidden="true">1</span>
              <span class="dx-anatomy-part-name">Container (.ren-card)</span>
            </div>
            <div class="dx-anatomy-part-spec" aria-hidden="true">
              <div style="width: 80%; height: 56px; background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-lg);"></div>
            </div>
            <p class="dx-anatomy-part-desc">The outer surface. Sets background (<code>--color-surface-raised</code>), border, radius, and clips children with <code>overflow: hidden</code>.</p>
          </div>

          <div class="dx-anatomy-part">
            <div class="dx-anatomy-part-header">
              <span class="dx-anatomy-num" aria-hidden="true">2</span>
              <span class="dx-anatomy-part-name">Header (.ren-card-header)</span>
            </div>
            <div class="dx-anatomy-part-spec" aria-hidden="true">
              <div class="ren-card" style="width: 100%;">
                <div class="ren-card-header">
                  <h4 class="ren-card-title">Title here</h4>
                  <p class="ren-card-description">Description below</p>
                </div>
                <div class="ren-card-body">
                  <p style="margin: 0; opacity: 0.35; font-size: var(--text-sm);">…body…</p>
                </div>
              </div>
            </div>
            <p class="dx-anatomy-part-desc">Optional. Top section for title + description. Stack of <code>.ren-card-title</code> + <code>.ren-card-description</code>.</p>
          </div>

          <div class="dx-anatomy-part">
            <div class="dx-anatomy-part-header">
              <span class="dx-anatomy-num" aria-hidden="true">3</span>
              <span class="dx-anatomy-part-name">Body (.ren-card-body)</span>
            </div>
            <div class="dx-anatomy-part-spec" aria-hidden="true">
              <div class="ren-card" style="width: 100%;">
                <div class="ren-card-header">
                  <p class="ren-card-description" style="opacity: 0.35;">…header…</p>
                </div>
                <div class="ren-card-body">
                  <p style="margin: 0; font-size: var(--text-sm); color: var(--color-text-secondary);">Main content goes here.</p>
                </div>
              </div>
            </div>
            <p class="dx-anatomy-part-desc">The main content area. Padded uniformly. When following a header, top padding tightens automatically.</p>
          </div>

          <div class="dx-anatomy-part">
            <div class="dx-anatomy-part-header">
              <span class="dx-anatomy-num" aria-hidden="true">4</span>
              <span class="dx-anatomy-part-name">Footer (.ren-card-footer)</span>
            </div>
            <div class="dx-anatomy-part-spec" aria-hidden="true">
              <div class="ren-card" style="width: 100%;">
                <div class="ren-card-body">
                  <p style="margin: 0; opacity: 0.35; font-size: var(--text-sm);">…body…</p>
                </div>
                <div class="ren-card-footer">
                  <button type="button" class="ren-btn ren-btn-secondary ren-btn-sm" tabindex="-1">Cancel</button>
                  <button type="button" class="ren-btn ren-btn-primary ren-btn-sm" tabindex="-1">Save</button>
                </div>
              </div>
            </div>
            <p class="dx-anatomy-part-desc">Optional. Bottom row for actions. Use <code>.ren-card-footer-border</code> for a separating line above the footer.</p>
          </div>

        </div>
      </div>
    </section>

    <!-- 3. DEMO -->
    <section class="dx-section" id="demo">
      <p class="dx-kicker">Live</p>
      <h2>Demo</h2>
      <p>The default card with all three sections. Drop in your own content — RenDS won't fight you.</p>

      <div class="dx-demo">
        <div class="dx-demo-preview">
          <div class="ren-card" style="max-width: 360px; width: 100%;">
            <div class="ren-card-header">
              <h4 class="ren-card-title" style="margin: 0;">Welcome back</h4>
              <p class="ren-card-description" style="margin: 0;">Pick up where you left off</p>
            </div>
            <div class="ren-card-body">
              <p style="margin: 0;">Three drafts saved, two pull requests waiting for review, and a deployment scheduled for tomorrow.</p>
            </div>
            <div class="ren-card-footer">
              <button type="button" class="ren-btn ren-btn-ghost ren-btn-sm">Later</button>
              <button type="button" class="ren-btn ren-btn-primary ren-btn-sm">Open dashboard</button>
            </div>
          </div>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-card"&gt;
  &lt;div class="ren-card-header"&gt;
    &lt;h4 class="ren-card-title"&gt;Welcome back&lt;/h4&gt;
    &lt;p class="ren-card-description"&gt;Pick up where you left off&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class="ren-card-body"&gt;
    &lt;p&gt;Three drafts saved, two pull requests waiting for review…&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class="ren-card-footer"&gt;
    &lt;button class="ren-btn ren-btn-ghost ren-btn-sm"&gt;Later&lt;/button&gt;
    &lt;button class="ren-btn ren-btn-primary ren-btn-sm"&gt;Open dashboard&lt;/button&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
      </div>

      <p>Sections are all optional. A card with only <code>.ren-card-body</code> works. A card with no sections at all (just children) auto-pads its first and last child via <code>:first-child</code> / <code>:last-child</code> selectors.</p>
    </section>

    <!-- 4. VARIANTS -->
    <section class="dx-section" id="variants">
      <p class="dx-kicker">Catalog</p>
      <h2>Variants</h2>
      <p>Five visual variants — pick the one that matches the card's role. Plus three interaction states layered on top, and four status accents for at-a-glance signals.</p>

      <div class="dx-vgrid">

        <div class="dx-vrow">
          <span class="dx-vrow-label">Visual</span>
          <div class="dx-vrow-items" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));">
            <div class="ren-card">
              <div class="ren-card-body"><strong>Default</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-xs); color: var(--color-text-muted);">Surface + border</p></div>
            </div>
            <div class="ren-card ren-card-elevated">
              <div class="ren-card-body"><strong>Elevated</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-xs); color: var(--color-text-muted);">Shadow, no border</p></div>
            </div>
            <div class="ren-card ren-card-outline">
              <div class="ren-card-body"><strong>Outline</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-xs); color: var(--color-text-muted);">Border, transparent bg</p></div>
            </div>
            <div class="ren-card ren-card-ghost">
              <div class="ren-card-body"><strong>Ghost</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-xs); color: var(--color-text-muted);">No surface, grouping only</p></div>
            </div>
            <div class="ren-card ren-card-sunken">
              <div class="ren-card-body"><strong>Sunken</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-xs); color: var(--color-text-muted);">Recessed surface</p></div>
            </div>
          </div>
        </div>

        <div class="dx-vrow">
          <span class="dx-vrow-label">Interaction</span>
          <div class="dx-vrow-items" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));">
            <div class="ren-card ren-card-interactive" tabindex="0">
              <div class="ren-card-body"><strong>Interactive</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-xs); color: var(--color-text-muted);">Hover lifts, click feedback</p></div>
            </div>
            <div class="ren-card ren-card-selectable" tabindex="0">
              <div class="ren-card-body"><strong>Selectable</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-xs); color: var(--color-text-muted);">Click to set <code>aria-selected</code></p></div>
            </div>
            <div class="ren-card ren-card-selectable" tabindex="0" aria-selected="true">
              <div class="ren-card-body"><strong>Selectable (selected)</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-xs); color: var(--color-text-muted);">Accent border + ring</p></div>
            </div>
          </div>
        </div>

        <div class="dx-vrow">
          <span class="dx-vrow-label">Status</span>
          <div class="dx-vrow-items" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));">
            <div class="ren-card" data-status="success">
              <div class="ren-card-body"><strong>Success</strong></div>
            </div>
            <div class="ren-card" data-status="warning">
              <div class="ren-card-body"><strong>Warning</strong></div>
            </div>
            <div class="ren-card" data-status="danger">
              <div class="ren-card-body"><strong>Danger</strong></div>
            </div>
            <div class="ren-card" data-status="info">
              <div class="ren-card-body"><strong>Info</strong></div>
            </div>
          </div>
        </div>

      </div>
    </section>

    <!-- 5. API -->
    <section class="dx-section" id="api">
      <p class="dx-kicker">Reference</p>
      <h2>API</h2>
      <p>CSS classes only. There is no Web Component for card.</p>

      <h3>Container</h3>
      <table class="dx-api">
        <thead><tr><th>Class</th><th>Effect</th></tr></thead>
        <tbody>
          <tr><td><code class="dx-api-name">.ren-card</code></td><td>Base container. Required.</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-elevated</code></td><td>Removes border, adds <code>--shadow-md</code>. For floating UI.</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-outline</code></td><td>Border only, transparent background. Lighter weight.</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-ghost</code></td><td>Removes both border and background. Pure structural grouping.</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-sunken</code></td><td>Inverted depth — sits below the surface. Use sparingly.</td></tr>
        </tbody>
      </table>

      <h3>Sections</h3>
      <table class="dx-api">
        <thead><tr><th>Class</th><th>Use</th></tr></thead>
        <tbody>
          <tr><td><code class="dx-api-name">.ren-card-header</code></td><td>Top section. Stack of title + description with auto-spacing.</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-title</code></td><td>Heading inside the header. Set on the actual heading tag (<code>&lt;h3&gt;</code>, <code>&lt;h4&gt;</code>, etc).</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-description</code></td><td>Subtitle / metadata under the title. Muted color.</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-body</code></td><td>Main content. Self-padded.</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-footer</code></td><td>Bottom row, no separator. For action clusters.</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-footer-border</code></td><td>Footer with a top border separator. Heavier visual weight.</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-simple</code></td><td>Quick padding shorthand for cards without explicit sections.</td></tr>
        </tbody>
      </table>

      <h3>Interaction</h3>
      <table class="dx-api">
        <thead><tr><th>Class / attribute</th><th>Effect</th></tr></thead>
        <tbody>
          <tr><td><code class="dx-api-name">.ren-card-interactive</code></td><td>Hover lift + shadow + border emphasis. Adds <code>cursor: pointer</code>, focus ring on <code>:focus-visible</code>. Wrap in or apply to a focusable element (<code>&lt;a&gt;</code>, <code>&lt;button&gt;</code>, or <code>tabindex="0"</code>).</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-selectable</code></td><td>Hover swaps border to accent. Combine with <code>aria-selected="true"</code> or <code>data-selected</code> for the chosen state.</td></tr>
          <tr><td><code class="dx-api-name">[data-status="success|warning|danger|info"]</code></td><td>Adds a 3px accent border on top in the matching status color. Stacks with any visual variant.</td></tr>
        </tbody>
      </table>

      <h3>Layout helper</h3>
      <table class="dx-api">
        <thead><tr><th>Class</th><th>Effect</th></tr></thead>
        <tbody>
          <tr><td><code class="dx-api-name">.ren-card-group</code></td><td>Auto-fill grid of cards at <code>min(100%, 280px)</code> per column. Drop on the parent of the cards.</td></tr>
          <tr><td><code class="dx-api-name">.ren-card-cover</code></td><td>For a full-bleed image at the top of a card. <code>width: 100%; object-fit: cover</code>.</td></tr>
        </tbody>
      </table>
    </section>

    <!-- 6. ACCESSIBILITY -->
    <section class="dx-section" id="a11y">
      <p class="dx-kicker">Inclusive by default</p>
      <h2>Accessibility</h2>
      <p>Static cards are non-interactive — they're just visual containers and don't need any ARIA. Interactive and selectable cards inherit semantics from the wrapping element you choose.</p>

      <h3>Static cards</h3>
      <ul>
        <li>Use semantic content inside — proper heading levels (<code>&lt;h2&gt;</code>–<code>&lt;h4&gt;</code>) for titles, real <code>&lt;p&gt;</code> tags for prose, real <code>&lt;button&gt;</code>s for actions.</li>
        <li>Don't add ARIA roles to the card itself — it's a generic <code>&lt;div&gt;</code> by intent.</li>
        <li>For status accents, the visual <code>data-status="danger"</code> top border isn't enough on its own. Pair with a text label, an icon, or an <code>aria-describedby</code> for screen reader users.</li>
      </ul>

      <h3>Interactive cards</h3>
      <p>If the entire card is clickable, wrap the card content in an <code>&lt;a&gt;</code> or <code>&lt;button&gt;</code>, or set <code>tabindex="0"</code> + <code>role="button"</code> if neither makes sense.</p>
      <div class="dx-keys">
        <div class="dx-keyrow"><span class="keys"><kbd class="ren-kbd">Tab</kbd></span><span>Moves focus into the interactive card.</span></div>
        <div class="dx-keyrow"><span class="keys"><kbd class="ren-kbd">Enter</kbd></span><span>Activates the card (follows the wrapping <code>&lt;a&gt;</code> or fires <code>&lt;button&gt;</code>'s click).</span></div>
        <div class="dx-keyrow"><span class="keys"><kbd class="ren-kbd">Space</kbd></span><span>Activates if the wrapper is a <code>&lt;button&gt;</code>. Anchors don't respond to Space — use Enter.</span></div>
      </div>

      <div class="dx-callout">
        <p><strong>Don't nest interactive elements.</strong> An interactive card that contains a button creates a confusing focus order — Tab, Tab, Tab to land somewhere predictable. Pick one: either the whole card is clickable, or the card has internal buttons. Not both.</p>
      </div>

      <h3>Selectable cards (radio / checkbox patterns)</h3>
      <ul>
        <li>For exclusive choice (one of N), wrap each card in a <code>&lt;label&gt;</code> with a hidden <code>&lt;input type="radio"&gt;</code>, or use <code>role="radio"</code> + <code>aria-checked</code>.</li>
        <li>For multi-select, use <code>role="checkbox"</code> + <code>aria-checked</code>, or a hidden <code>&lt;input type="checkbox"&gt;</code> in a label.</li>
        <li>Set <code>aria-selected="true"</code> on the chosen card so screen readers announce "selected". The CSS targets both <code>aria-selected</code> and <code>data-selected</code> for the accent ring.</li>
      </ul>

      <h3>Reduced motion</h3>
      <p>The hover-lift on interactive cards uses <code>--duration-tactile</code> and respects <code>prefers-reduced-motion</code> via the semantic motion tokens. Users who request reduced motion get a quieter transition (color change without scale).</p>
    </section>

    <!-- 7. EXAMPLES -->
    <section class="dx-section" id="examples">
      <p class="dx-kicker">Recipes</p>
      <h2>Examples</h2>
      <p>Common compositions. Copy the markup, swap the content.</p>

      <h3>KPI / stat card</h3>
      <p>For dashboards. One number, one label, optional trend.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview">
          <div class="ren-card" style="max-width: 240px; width: 100%;">
            <div class="ren-card-body">
              <p style="margin: 0; font-size: var(--text-sm); color: var(--color-text-muted);">Active users</p>
              <p style="margin: var(--space-1) 0 0; font-size: var(--text-3xl); font-weight: var(--weight-bold); line-height: 1.1;">12,430</p>
              <p style="margin: var(--space-2) 0 0; font-size: var(--text-sm); color: var(--color-success); font-weight: var(--weight-medium);">↑ 12.5% vs last month</p>
            </div>
          </div>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-card"&gt;
  &lt;div class="ren-card-body"&gt;
    &lt;p class="stat-label"&gt;Active users&lt;/p&gt;
    &lt;p class="stat-value"&gt;12,430&lt;/p&gt;
    &lt;p class="stat-trend"&gt;↑ 12.5% vs last month&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
      </div>

      <h3>Selectable plan card (radio pattern)</h3>
      <p>For pricing tiers, plan switchers, theme pickers.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--space-3); width: 100%;">
          <label class="ren-card ren-card-selectable" style="cursor: pointer; display: block;">
            <input type="radio" name="plan-demo" style="position: absolute; opacity: 0; pointer-events: none;">
            <div class="ren-card-body">
              <strong>Free</strong>
              <p style="margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--color-text-muted);">$0/mo · 3 projects</p>
            </div>
          </label>
          <label class="ren-card ren-card-selectable" style="cursor: pointer; display: block;" aria-selected="true">
            <input type="radio" name="plan-demo" style="position: absolute; opacity: 0; pointer-events: none;" checked>
            <div class="ren-card-body">
              <strong>Pro</strong>
              <p style="margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--color-text-muted);">$12/mo · unlimited</p>
            </div>
          </label>
          <label class="ren-card ren-card-selectable" style="cursor: pointer; display: block;">
            <input type="radio" name="plan-demo" style="position: absolute; opacity: 0; pointer-events: none;">
            <div class="ren-card-body">
              <strong>Team</strong>
              <p style="margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--color-text-muted);">$32/mo · 10 seats</p>
            </div>
          </label>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;label class="ren-card ren-card-selectable"&gt;
  &lt;input type="radio" name="plan" /&gt;
  &lt;div class="ren-card-body"&gt;
    &lt;strong&gt;Pro&lt;/strong&gt;
    &lt;p&gt;$12/mo · unlimited&lt;/p&gt;
  &lt;/div&gt;
&lt;/label&gt;</code></pre>
      </div>

      <h3>Article preview (interactive card with cover)</h3>
      <p>Wrap the whole card in <code>&lt;a&gt;</code> so the entire surface is one click target.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview">
          <a href="#" class="ren-card ren-card-interactive" style="display: block; max-width: 320px; width: 100%; text-decoration: none; color: inherit;">
            <div style="aspect-ratio: 16/9; background: var(--color-accent-subtle); border-bottom: 1px solid var(--color-border);"></div>
            <div class="ren-card-header">
              <h4 class="ren-card-title" style="margin: 0;">From Tailwind to vanilla in a weekend</h4>
              <p class="ren-card-description" style="margin: 0;">5 min read · Engineering</p>
            </div>
            <div class="ren-card-body">
              <p style="margin: 0;">How we replaced a 180&nbsp;KB toolchain with a CSS-first design system and shipped faster.</p>
            </div>
          </a>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;a href="/post/123" class="ren-card ren-card-interactive"&gt;
  &lt;div class="cover"&gt;&lt;/div&gt;
  &lt;div class="ren-card-header"&gt;
    &lt;h4 class="ren-card-title"&gt;From Tailwind to vanilla…&lt;/h4&gt;
    &lt;p class="ren-card-description"&gt;5 min read · Engineering&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class="ren-card-body"&gt;
    &lt;p&gt;How we replaced a 180 KB toolchain…&lt;/p&gt;
  &lt;/div&gt;
&lt;/a&gt;</code></pre>
      </div>

      <h3>Danger-zone card</h3>
      <p>For destructive actions in settings panels. Status border + danger button.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview">
          <div class="ren-card" data-status="danger" style="max-width: 480px; width: 100%;">
            <div class="ren-card-header">
              <h4 class="ren-card-title" style="margin: 0;">Delete account</h4>
              <p class="ren-card-description" style="margin: 0;">Permanently remove your account and all associated data.</p>
            </div>
            <div class="ren-card-footer-border" style="justify-content: flex-end;">
              <button type="button" class="ren-btn ren-btn-danger ren-btn-sm">Delete account</button>
            </div>
          </div>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-card" data-status="danger"&gt;
  &lt;div class="ren-card-header"&gt;
    &lt;h4 class="ren-card-title"&gt;Delete account&lt;/h4&gt;
    &lt;p class="ren-card-description"&gt;Permanently remove…&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class="ren-card-footer-border"&gt;
    &lt;button class="ren-btn ren-btn-danger ren-btn-sm"&gt;Delete account&lt;/button&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
      </div>

      <h3>Card group (auto-grid)</h3>
      <p>One class on the parent gives you a responsive grid of cards.</p>
      <div class="dx-demo">
        <div class="dx-demo-preview">
          <div class="ren-card-group" style="width: 100%;">
            <div class="ren-card"><div class="ren-card-body"><strong>Item one</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--color-text-muted);">Auto-sized</p></div></div>
            <div class="ren-card"><div class="ren-card-body"><strong>Item two</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--color-text-muted);">Wraps responsively</p></div></div>
            <div class="ren-card"><div class="ren-card-body"><strong>Item three</strong><p style="margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--color-text-muted);">No JS needed</p></div></div>
          </div>
        </div>
        <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-card-group"&gt;
  &lt;div class="ren-card"&gt;…&lt;/div&gt;
  &lt;div class="ren-card"&gt;…&lt;/div&gt;
  &lt;div class="ren-card"&gt;…&lt;/div&gt;
&lt;/div&gt;</code></pre>
      </div>
    </section>

    </main>

  </div>

  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-carousel.html
type: docs_page
name: ren-carousel docs
path: docs/components/ren-carousel.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Carousel — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html" aria-current="page">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Carousel</li></ol></nav>
        <p class="dx-kicker">Composite</p>
        <h1>Carousel <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">Scroll-snap gallery with prev / next buttons and dot indicators. Touch- and keyboard-friendly. Built on CSS scroll snap, no janky JS animation.</p>
      </header>
      <section class="dx-section" id="overview"><p class="dx-kicker">About</p><h2>Overview</h2><p>Use Carousel for image galleries, hero slideshows, "more like this" rows. The scroll-snap underpinning means it feels native on touch and keyboard.</p><div class="dx-callout"><p><strong>Don't auto-rotate carousels.</strong> Auto-rotation is one of the most-criticized patterns on the web. If a slide must auto-advance, give the user a clear pause / play and pause on hover and focus.</p></div></section>
      <section class="dx-section" id="demo"><p class="dx-kicker">Live</p><h2>Demo</h2><div class="dx-demo"><div class="dx-demo-preview" style="display: block;"><div style="display: flex; gap: var(--space-3); overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: var(--space-2);"><div style="flex: 0 0 200px; scroll-snap-align: start; aspect-ratio: 4/3; background: var(--color-accent-subtle); border: 1px solid var(--color-accent); border-radius: var(--radius-md); display: grid; place-items: center; color: var(--color-accent-active); font-weight: var(--weight-semibold);">1</div><div style="flex: 0 0 200px; scroll-snap-align: start; aspect-ratio: 4/3; background: var(--color-surface-sunken); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: grid; place-items: center; color: var(--color-text-muted); font-weight: var(--weight-semibold);">2</div><div style="flex: 0 0 200px; scroll-snap-align: start; aspect-ratio: 4/3; background: var(--color-surface-sunken); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: grid; place-items: center; color: var(--color-text-muted); font-weight: var(--weight-semibold);">3</div><div style="flex: 0 0 200px; scroll-snap-align: start; aspect-ratio: 4/3; background: var(--color-surface-sunken); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: grid; place-items: center; color: var(--color-text-muted); font-weight: var(--weight-semibold);">4</div><div style="flex: 0 0 200px; scroll-snap-align: start; aspect-ratio: 4/3; background: var(--color-surface-sunken); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: grid; place-items: center; color: var(--color-text-muted); font-weight: var(--weight-semibold);">5</div></div></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-carousel aria-label="Featured posts"&gt;
  &lt;article slot="slide"&gt;Slide 1&lt;/article&gt;
  &lt;article slot="slide"&gt;Slide 2&lt;/article&gt;
&lt;/ren-carousel&gt;</code></pre></div></section>
      <section class="dx-section" id="api"><p class="dx-kicker">Reference</p><h2>API</h2><table class="dx-api dx-api-cols-4"><thead><tr><th>Attribute</th><th>Type</th><th>Default</th><th>Notes</th></tr></thead><tbody><tr><td><code class="dx-api-name">orientation</code></td><td><span class="dx-api-type">"horizontal" | "vertical"</span></td><td><span class="dx-api-default">"horizontal"</span></td><td>Scroll direction.</td></tr><tr><td><code class="dx-api-name">loop</code></td><td><span class="dx-api-type">boolean</span></td><td><span class="dx-api-default">false</span></td><td>Wrap from last slide back to first.</td></tr><tr><td><code class="dx-api-name">snap</code></td><td><span class="dx-api-type">"start" | "center" | "none"</span></td><td><span class="dx-api-default">"start"</span></td><td>CSS scroll-snap alignment.</td></tr></tbody></table></section>
      <section class="dx-section" id="a11y"><p class="dx-kicker">Inclusive by default</p><h2>Accessibility</h2><ul><li>Wrap in <code>role="region"</code> with <code>aria-label="…"</code> describing the gallery.</li><li>Arrow keys move between slides; Tab moves out of the carousel entirely.</li><li>Slides with images need real alt text — they're content, not decoration.</li></ul></section>
    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-checkbox.html
type: docs_page
name: ren-checkbox docs
path: docs/components/ren-checkbox.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Checkbox — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); padding-top: var(--space-3); }
    .dx-vrow-items { padding: var(--space-4); background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: flex; flex-direction: column; gap: var(--space-3); }
    @media (max-width: 720px) { .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); } .dx-vrow-label { padding-top: 0; } }
    .dx-anatomy-stage { background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-6) var(--space-5); margin: var(--space-4) 0; }
  </style>
</head>
<body>

  <header class="dx-nav">
    <div class="dx-nav-inner">
      <a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a>
      <nav class="dx-nav-menu" aria-label="Primary">
        <a href="../index.html">Docs</a>
        <a href="../components.html" aria-current="page">Components</a>
        <a href="../../templates/index.html">Templates</a>
        <a href="../../create/index.html">Theme Builder</a>
      </nav>
      <div class="dx-nav-actions">
        <a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a>
        <a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a>
      </div>
    </div>
  </header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html" aria-current="page">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);">
          <ol>
            <li><a href="../index.html" class="ren-link-plain">Docs</a></li>
            <li><a href="../components.html" class="ren-link-plain">Components</a></li>
            <li aria-current="page">Checkbox</li>
          </ol>
        </nav>
        <p class="dx-kicker">Primitive</p>
        <h1>Checkbox <span class="dx-api-badge dx-api-badge-hybrid" title="Renders without JS; JS adds enhancements">Hybrid</span></h1>
        <p class="lede">A boolean toggle wrapped around a native <code>&lt;input type="checkbox"&gt;</code>. Custom-styled control, native semantics, full keyboard and screen-reader support out of the box. Indeterminate state included.</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>Checkbox is a CSS-only enhancement over the native input. The actual checkbox is the hidden <code>&lt;input&gt;</code> — keyboard, screen readers, and form submission all use the platform's standard behavior. RenDS only paints the visual control on top via <code>.ren-checkbox-control</code>.</p>
        <div class="dx-callout">
          <p><strong>Use a Switch instead</strong> when the checkbox represents an immediate setting that takes effect right away (notifications on/off, dark mode). Use a Checkbox for things that get committed on form submit.</p>
        </div>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <label class="ren-checkbox">
              <input type="checkbox">
              <span class="ren-checkbox-control"></span>
              <span>Subscribe to the weekly digest</span>
            </label>
            <label class="ren-checkbox">
              <input type="checkbox" checked>
              <span class="ren-checkbox-control"></span>
              <span>Email me about product updates</span>
            </label>
            <label class="ren-checkbox">
              <input type="checkbox" disabled>
              <span class="ren-checkbox-control"></span>
              <span>Marketing emails (disabled — change in account settings)</span>
            </label>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;label class="ren-checkbox"&gt;
  &lt;input type="checkbox"&gt;
  &lt;span class="ren-checkbox-control"&gt;&lt;/span&gt;
  &lt;span&gt;Subscribe to the weekly digest&lt;/span&gt;
&lt;/label&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="variants">
        <p class="dx-kicker">States</p>
        <h2>Variants</h2>
        <div class="dx-vgrid">
          <div class="dx-vrow">
            <span class="dx-vrow-label">States</span>
            <div class="dx-vrow-items">
              <label class="ren-checkbox"><input type="checkbox"><span class="ren-checkbox-control"></span><span>Unchecked</span></label>
              <label class="ren-checkbox"><input type="checkbox" checked><span class="ren-checkbox-control"></span><span>Checked</span></label>
              <label class="ren-checkbox"><input type="checkbox" id="indet-demo"><span class="ren-checkbox-control"></span><span>Indeterminate</span></label>
              <label class="ren-checkbox"><input type="checkbox" disabled><span class="ren-checkbox-control"></span><span>Disabled (unchecked)</span></label>
              <label class="ren-checkbox"><input type="checkbox" checked disabled><span class="ren-checkbox-control"></span><span>Disabled (checked)</span></label>
              <script>document.getElementById('indet-demo').indeterminate = true;</script>
            </div>
          </div>
          <div class="dx-vrow">
            <span class="dx-vrow-label">Group</span>
            <div class="dx-vrow-items">
              <fieldset style="border: 0; padding: 0; margin: 0;">
                <legend style="font-size: var(--label-size); font-weight: var(--label-weight); margin-bottom: var(--space-2);">Notify me about</legend>
                <div style="display: flex; flex-direction: column; gap: var(--space-2);">
                  <label class="ren-checkbox"><input type="checkbox" name="notify" value="comments" checked><span class="ren-checkbox-control"></span><span>Comments on my posts</span></label>
                  <label class="ren-checkbox"><input type="checkbox" name="notify" value="mentions" checked><span class="ren-checkbox-control"></span><span>Mentions</span></label>
                  <label class="ren-checkbox"><input type="checkbox" name="notify" value="follows"><span class="ren-checkbox-control"></span><span>New followers</span></label>
                </div>
              </fieldset>
            </div>
          </div>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>
        <h3>CSS classes</h3>
        <table class="dx-api">
          <thead><tr><th>Class</th><th>Effect</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">.ren-checkbox</code></td><td>The label wrapper. Inline-flex layout with the control + text. Clicking anywhere in the label toggles the input.</td></tr>
            <tr><td><code class="dx-api-name">.ren-checkbox-control</code></td><td>The painted box. Sits next to the hidden input and listens to <code>:checked</code> via the adjacent sibling selector.</td></tr>
            <tr><td><code class="dx-api-name">.ren-checkbox &gt; input[type="checkbox"]</code></td><td>The native input. Visually hidden but keyboard- and screen-reader-accessible. Submits with the form like any other checkbox.</td></tr>
          </tbody>
        </table>
        <h3>States handled by CSS</h3>
        <table class="dx-api">
          <thead><tr><th>State</th><th>Selector</th></tr></thead>
          <tbody>
            <tr><td>Checked</td><td><code>input:checked + .ren-checkbox-control</code> (filled with accent color, white check mark)</td></tr>
            <tr><td>Indeterminate</td><td><code>input:indeterminate + .ren-checkbox-control</code> (filled with a horizontal bar)</td></tr>
            <tr><td>Hover</td><td><code>.ren-checkbox:hover &gt; .ren-checkbox-control</code> (border darkens)</td></tr>
            <tr><td>Focus visible</td><td><code>input:focus-visible + .ren-checkbox-control</code> (focus ring)</td></tr>
            <tr><td>Disabled</td><td><code>.ren-checkbox:has(input:disabled)</code> (opacity reduced, cursor not-allowed)</td></tr>
          </tbody>
        </table>
        <p>No JavaScript or Web Component — every state is pure CSS.</p>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <p>Because the actual control is a real <code>&lt;input type="checkbox"&gt;</code>, every accessibility behavior comes from the platform: Tab focus, Space to toggle, screen reader announcement of state, native form participation.</p>
        <h3>Keyboard</h3>
        <div class="dx-keys">
          <div class="dx-keyrow"><span class="keys"><kbd>Tab</kbd></span><span>Moves focus to the input.</span></div>
          <div class="dx-keyrow"><span class="keys"><kbd>Space</kbd></span><span>Toggles the checked state.</span></div>
        </div>
        <div class="dx-callout">
          <p><strong>Always wrap the input in the label.</strong> The pattern <code>&lt;label class="ren-checkbox"&gt;&lt;input&gt;…&lt;/label&gt;</code> means the click target is the entire label — not just the small box. That's a 44 px touch target without any extra work.</p>
        </div>
        <h3>Indeterminate state</h3>
        <p>Set programmatically: <code>checkbox.indeterminate = true</code>. Use it for parent checkboxes that summarize a mixed group of children. Any user interaction (click or Space) clears the indeterminate flag.</p>
      </section>

      <section class="dx-section" id="examples">
        <p class="dx-kicker">Patterns</p>
        <h2>Examples</h2>
        <h3>Select-all with indeterminate parent</h3>
        <div class="dx-pre" tabindex="0"><code>const all = document.querySelector('#all');
const items = document.querySelectorAll('input[name="items"]');

const sync = () =&gt; {
  const checked = Array.from(items).filter(i =&gt; i.checked);
  all.checked = checked.length === items.length;
  all.indeterminate = checked.length &gt; 0 &amp;&amp; checked.length &lt; items.length;
};

all.addEventListener('change', () =&gt; {
  items.forEach(i =&gt; i.checked = all.checked);
});
items.forEach(i =&gt; i.addEventListener('change', sync));
sync();</code></pre>
      </section>

    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-collapsible.html
type: docs_page
name: ren-collapsible docs
path: docs/components/ren-collapsible.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Collapsible — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html" aria-current="page">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Collapsible</li></ol></nav>
        <p class="dx-kicker">Composite</p>
        <h1>Collapsible <span class="dx-api-badge dx-api-badge-hybrid" title="Renders without JS; JS adds enhancements">Hybrid</span></h1>
        <p class="lede">Single show/hide region — the simplest disclosure pattern. Built on native <code>&lt;details&gt;</code>.</p>
      </header>
      <section class="dx-section" id="overview"><p class="dx-kicker">About</p><h2>Overview</h2><p>For a single section that toggles open / closed, <code>&lt;details&gt;</code> is the right primitive. RenDS just styles it. For groups of collapsibles use <a href="ren-accordion.html" class="ren-link">Accordion</a>.</p></section>
      <section class="dx-section" id="demo"><p class="dx-kicker">Live</p><h2>Demo</h2><div class="dx-demo"><div class="dx-demo-preview" style="flex-direction: column; align-items: stretch; width: 100%;"><details class="ren-collapsible"><summary>Show advanced settings</summary><p style="margin-top: var(--space-3); font-size: var(--text-sm); color: var(--color-text-secondary);">Tweaks for power users — log level, request timeout, retry count.</p></details></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;details class="ren-collapsible"&gt;
  &lt;summary&gt;Show advanced settings&lt;/summary&gt;
  &lt;p&gt;Hidden content here…&lt;/p&gt;
&lt;/details&gt;</code></pre></div></section>
      <section class="dx-section" id="api"><p class="dx-kicker">Reference</p><h2>API</h2><table class="dx-api"><thead><tr><th>Class</th><th>Effect</th></tr></thead><tbody><tr><td><code class="dx-api-name">.ren-collapsible</code></td><td>On <code>&lt;details&gt;</code>. Adds chevron rotation, padding, hover background.</td></tr></tbody></table></section>
      <section class="dx-section" id="a11y"><p class="dx-kicker">Inclusive by default</p><h2>Accessibility</h2><p>Native <code>&lt;details&gt;</code> handles all keyboard / screen reader behavior. Tab to summary, Enter / Space to toggle.</p></section>
    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-color-picker.html
type: docs_page
name: ren-color-picker docs
path: docs/components/ren-color-picker.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Color Picker — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html" aria-current="page">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Color Picker</li></ol></nav>
        <p class="dx-kicker">Composite</p>
        <h1>Color Picker <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">Color selection with hue-saturation gradient, alpha slider, hex / RGB / HSL inputs and a swatch palette of recent colors.</p>
      </header>
      <section class="dx-section" id="overview"><p class="dx-kicker">About</p><h2>Overview</h2><p>Use Color Picker in design tools, theme builders and visual editors. For form-style "pick from a palette" use a Toggle Group of swatches instead — full pickers are heavy.</p></section>
      <section class="dx-section" id="demo"><p class="dx-kicker">Live</p><h2>Demo</h2><div class="dx-demo"><div class="dx-demo-preview"><label style="display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm);"><span>Brand color</span><input type="color" value="#0063D1" style="width: 44px; height: 32px; border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: 0; cursor: pointer;"><code>#0063D1</code></label></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-color-picker name="brand" value="#0063D1"&gt;&lt;/ren-color-picker&gt;</code></pre></div></section>
      <section class="dx-section" id="api"><p class="dx-kicker">Reference</p><h2>API</h2><table class="dx-api dx-api-cols-4"><thead><tr><th>Attribute</th><th>Type</th><th>Default</th><th>Notes</th></tr></thead><tbody><tr><td><code class="dx-api-name">value</code></td><td><span class="dx-api-type">string (hex)</span></td><td><span class="dx-api-default">"#000000"</span></td><td>Initial color.</td></tr><tr><td><code class="dx-api-name">format</code></td><td><span class="dx-api-type">"hex" | "rgb" | "hsl"</span></td><td><span class="dx-api-default">"hex"</span></td><td>Output format on the <code>ren-change</code> event.</td></tr><tr><td><code class="dx-api-name">alpha</code></td><td><span class="dx-api-type">boolean</span></td><td><span class="dx-api-default">false</span></td><td>Show alpha (transparency) slider.</td></tr><tr><td><code class="dx-api-name">placement</code></td><td><span class="dx-api-type">"top" | "right" | "bottom" | "left"</span></td><td><span class="dx-api-default">"bottom"</span></td><td>Preferred side for the popover. Reflected to <code>data-side</code>.</td></tr></tbody></table></section>
      <section class="dx-section" id="a11y"><p class="dx-kicker">Inclusive by default</p><h2>Accessibility</h2><ul><li>Always provide a hex / RGB text input alongside the visual picker — it's the only path for users who can't see colors.</li><li>The 2D HSV gradient is keyboard-accessible: arrow keys move the cursor, Page Up / Down jumps in larger steps.</li></ul></section>
    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-combobox.html
type: docs_page
name: ren-combobox docs
path: docs/components/ren-combobox.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Combobox — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: visible; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); padding-top: var(--space-3); }
    .dx-vrow-items { padding: var(--space-4); background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start; }
    @media (max-width: 720px) { .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); } .dx-vrow-label { padding-top: 0; } }
    .dx-anatomy { margin: var(--space-4) 0; display: grid; gap: var(--space-4); }
    .dx-anatomy-num { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--color-text); color: var(--color-surface); font-size: var(--text-xs); font-weight: var(--weight-bold); flex-shrink: 0; }
    .dx-anatomy-stage { background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-6) var(--space-5); }
    .dx-anatomy-stage-label { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); font-weight: var(--weight-semibold); margin: 0 0 var(--space-3); }
    .dx-anatomy-parts { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
    @media (max-width: 720px) { .dx-anatomy-parts { grid-template-columns: 1fr; } }
    .dx-anatomy-part { background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--space-4); display: grid; gap: var(--space-2); }
    .dx-anatomy-part-header { display: flex; align-items: center; gap: var(--space-2); }
    .dx-anatomy-part-name { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--color-text); }
    .dx-anatomy-part-desc { font-size: var(--text-sm); line-height: 1.5; color: var(--color-text-secondary); margin: 0; }
    .dx-anatomy-part-desc code { font-size: 0.85em; }

    /* Constrain demo width */
    .dx-demo-preview ren-combobox { max-width: 280px; }
  </style>
</head>
<body>

  <header class="dx-nav">
    <div class="dx-nav-inner">
      <a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a>
      <nav class="dx-nav-menu" aria-label="Primary">
        <a href="../index.html">Docs</a>
        <a href="../components.html" aria-current="page">Components</a>
        <a href="../../templates/index.html">Templates</a>
        <a href="../../create/index.html">Theme Builder</a>
      </nav>
      <div class="dx-nav-actions">
        <a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a>
        <a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a>
      </div>
    </div>
  </header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html" aria-current="page">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);">
          <ol>
            <li><a href="../index.html" class="ren-link-plain">Docs</a></li>
            <li><a href="../components.html" class="ren-link-plain">Components</a></li>
            <li aria-current="page">Combobox</li>
          </ol>
        </nav>
        <p class="dx-kicker">Composite</p>
        <h1>Combobox <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">A typeahead-searchable picker. Combines a text input with a filtered listbox so users can either type to filter or arrow-key through options. Use it when you have more than ~15 options and need search, but don't need full free-text input (use <code>&lt;input type="text"&gt;</code> with a datalist for that).</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>Combobox is a Select with a search box on top. The user can either click the trigger to see all options, or start typing to narrow them down. Each keystroke filters the visible items, arrow keys jump between them, Enter picks one. The chosen value is submitted via a hidden input named after the <code>name</code> attribute.</p>
        <div class="dx-callout">
          <p><strong>Combobox vs Select vs native select.</strong> Use <strong>native</strong> for short lists where the platform dropdown is fine. Use <a href="ren-select.html" class="ren-link">Select</a> for richer item rendering but no search. Use <strong>Combobox</strong> when there are too many items to scroll comfortably and the user knows roughly what they want.</p>
        </div>
      </section>

      <section class="dx-section" id="anatomy">
        <p class="dx-kicker">Parts</p>
        <h2>Anatomy</h2>
        <div class="dx-anatomy">
          <div class="dx-anatomy-stage">
            <p class="dx-anatomy-stage-label">Assembled</p>
            <div style="display: flex; justify-content: center;">
              <div class="demo-combo" data-anatomy>
                <input class="demo-combo-input" type="text" placeholder="Type to search…" value="Argentina" readonly>
              </div>
            </div>
          </div>
          <div class="dx-anatomy-parts">
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header"><span class="dx-anatomy-num">1</span><span class="dx-anatomy-part-name">Container</span></div>
              <p class="dx-anatomy-part-desc"><code>&lt;ren-combobox&gt;</code> wrapper. Manages selection, filtering, and the hidden form value.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header"><span class="dx-anatomy-num">2</span><span class="dx-anatomy-part-name">Input</span></div>
              <p class="dx-anatomy-part-desc"><code>&lt;input role="combobox"&gt;</code>. Holds the search query when open, the chosen label when closed.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header"><span class="dx-anatomy-num">3</span><span class="dx-anatomy-part-name">Listbox</span></div>
              <p class="dx-anatomy-part-desc"><code>role="listbox"</code> popover with the visible (filtered) items. Hides items that don't match the query.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header"><span class="dx-anatomy-num">4</span><span class="dx-anatomy-part-name">Item</span></div>
              <p class="dx-anatomy-part-desc"><code>.ren-combobox-item</code> with <code>role="option"</code> and a <code>data-value</code>. Filtering matches against the visible text.</p>
            </div>
          </div>
        </div>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <ren-combobox name="country" placeholder="Search a country…">
              <div class="ren-combobox-item" data-value="ar">Argentina</div>
              <div class="ren-combobox-item" data-value="br">Brazil</div>
              <div class="ren-combobox-item" data-value="cl">Chile</div>
              <div class="ren-combobox-item" data-value="co">Colombia</div>
              <div class="ren-combobox-item" data-value="ec">Ecuador</div>
              <div class="ren-combobox-item" data-value="mx">Mexico</div>
              <div class="ren-combobox-item" data-value="pe">Peru</div>
              <div class="ren-combobox-item" data-value="us">United States</div>
              <div class="ren-combobox-item" data-value="uy">Uruguay</div>
            </ren-combobox>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-combobox name="country" placeholder="Search a country…"&gt;
  &lt;div class="ren-combobox-item" data-value="ar"&gt;Argentina&lt;/div&gt;
  &lt;div class="ren-combobox-item" data-value="br"&gt;Brazil&lt;/div&gt;
  &lt;div class="ren-combobox-item" data-value="cl"&gt;Chile&lt;/div&gt;
  …
&lt;/ren-combobox&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="variants">
        <p class="dx-kicker">Shapes</p>
        <h2>Variants</h2>
        <div class="dx-vgrid">
          <div class="dx-vrow">
            <span class="dx-vrow-label">With descriptions</span>
            <div class="dx-vrow-items"><p style="margin: 0; font-size: var(--text-sm); color: var(--color-text-muted);">Items can hold structured content — a primary line and a muted secondary line. Useful for "User name + email" or "Repo name + organization" patterns.</p></div>
          </div>
          <div class="dx-vrow">
            <span class="dx-vrow-label">Grouped</span>
            <div class="dx-vrow-items"><p style="margin: 0; font-size: var(--text-sm); color: var(--color-text-muted);">Wrap related items in <code>.ren-combobox-group</code> with an optional <code>.ren-combobox-group-label</code>. Filtering keeps the group label visible while any of its items match.</p></div>
          </div>
          <div class="dx-vrow">
            <span class="dx-vrow-label">Async loading</span>
            <div class="dx-vrow-items"><p style="margin: 0; font-size: var(--text-sm); color: var(--color-text-muted);">Listen for <code>ren-search</code> and replace the items as the user types. Show <code>.ren-combobox-loading</code> while a request is in flight.</p></div>
          </div>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>

        <h3>CSS classes</h3>
        <table class="dx-api">
          <thead><tr><th>Class</th><th>Effect</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">.ren-combobox</code></td><td>Wrapper. Sets up positioning context for the floating list.</td></tr>
            <tr><td><code class="dx-api-name">.ren-combobox-input</code></td><td>The text input. <code>role="combobox"</code>, <code>aria-autocomplete="list"</code>.</td></tr>
            <tr><td><code class="dx-api-name">.ren-combobox-list</code></td><td>The listbox popover. Shows below the input on open.</td></tr>
            <tr><td><code class="dx-api-name">.ren-combobox-item</code></td><td>One option. Use with <code>role="option"</code> and <code>data-value</code>.</td></tr>
            <tr><td><code class="dx-api-name">.ren-combobox-group</code> / <code class="dx-api-name">-group-label</code></td><td>Optional grouping for items.</td></tr>
            <tr><td><code class="dx-api-name">.ren-combobox-empty</code></td><td>"No results" message shown when the filter matches nothing.</td></tr>
            <tr><td><code class="dx-api-name">.ren-combobox-loading</code></td><td>Loading row for async data.</td></tr>
          </tbody>
        </table>

        <h3>Web Component attributes</h3>
        <table class="dx-api dx-api-cols-4">
          <thead><tr><th>Attribute</th><th>Type</th><th>Default</th><th>Notes</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">name</code></td><td><span class="dx-api-type">string</span></td><td><span class="dx-api-default">—</span></td><td>Form field name. Submitted via a hidden input.</td></tr>
            <tr><td><code class="dx-api-name">value</code></td><td><span class="dx-api-type">string</span></td><td><span class="dx-api-default">—</span></td><td>Initial selected <code>data-value</code>.</td></tr>
            <tr><td><code class="dx-api-name">placeholder</code></td><td><span class="dx-api-type">string</span></td><td><span class="dx-api-default">"Search..."</span></td><td>Empty-state text in the input.</td></tr>
            <tr><td><code class="dx-api-name">placement</code></td><td><span class="dx-api-type">"top" | "bottom"</span></td><td><span class="dx-api-default">"bottom"</span></td><td>Preferred side for the local list. Reflected to <code>data-side</code>; <code>top</code> opens above the input.</td></tr>
            <tr><td><code class="dx-api-name">disabled</code></td><td><span class="dx-api-type">boolean</span></td><td><span class="dx-api-default">false</span></td><td>Locks the input.</td></tr>
            <tr><td><code class="dx-api-name">async</code></td><td><span class="dx-api-type">boolean</span></td><td><span class="dx-api-default">false</span></td><td>If present, suppresses local filtering — the parent app provides items via <code>ren-search</code>.</td></tr>
          </tbody>
        </table>

        <h3>Events</h3>
        <table class="dx-api">
          <thead><tr><th>Event</th><th>Detail</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">ren-change</code></td><td>Selection changed. <code>{ value, item }</code>. Bubbles, composed.</td></tr>
            <tr><td><code class="dx-api-name">ren-search</code></td><td>User typed. <code>{ query }</code>. Use this for async loading. Bubbles.</td></tr>
            <tr><td><code class="dx-api-name">ren-open</code> / <code class="dx-api-name">ren-close</code></td><td>Listbox opened / closed. Bubbles, composed.</td></tr>
          </tbody>
        </table>

        <h3>JavaScript methods</h3>
        <table class="dx-api dx-api-cols-4">
          <thead><tr><th>Method</th><th>Returns</th><th>Args</th><th>Notes</th></tr></thead>
          <tbody>
            <tr>
              <td><code class="dx-api-name">.value</code></td>
              <td><span class="dx-api-type">string</span></td>
              <td><span class="dx-api-default">—</span></td>
              <td>Getter / setter for the selected <code>data-value</code>. Setting it updates the input and dispatches <code>ren-change</code>.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.open()</code></td>
              <td><span class="dx-api-type">void</span></td>
              <td><span class="dx-api-default">—</span></td>
              <td>Programmatically opens the listbox.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.close()</code></td>
              <td><span class="dx-api-type">void</span></td>
              <td><span class="dx-api-default">—</span></td>
              <td>Programmatically closes the listbox.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.setLoading(state)</code></td>
              <td><span class="dx-api-type">void</span></td>
              <td><span class="dx-api-type">boolean</span></td>
              <td>Toggles the <code>.ren-combobox-loading</code> row. Pair with <code>ren-search</code> to indicate an async fetch is in flight.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.setItems(items)</code></td>
              <td><span class="dx-api-type">void</span></td>
              <td><span class="dx-api-type">Array&lt;{value, label, description?}&gt;</span></td>
              <td>Replaces the visible options. Use with the <code>async</code> attribute when the parent app owns filtering.</td>
            </tr>
          </tbody>
        </table>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <h3>Keyboard</h3>
        <div class="dx-keys">
          <div class="dx-keyrow"><span class="keys"><kbd>↓</kbd></span><span>Opens the list, highlights the first match.</span></div>
          <div class="dx-keyrow"><span class="keys"><kbd>↑</kbd> / <kbd>↓</kbd></span><span>Navigate the visible items.</span></div>
          <div class="dx-keyrow"><span class="keys"><kbd>Enter</kbd></span><span>Select the highlighted item.</span></div>
          <div class="dx-keyrow"><span class="keys"><kbd>Esc</kbd></span><span>Closes the list. Press again to clear the input.</span></div>
          <div class="dx-keyrow"><span class="keys">Type</span><span>Filters the items. Filtering is case-insensitive substring match by default.</span></div>
        </div>
        <h3>Labelling</h3>
        <p>Wrap inside <a href="ren-field.html" class="ren-link">Form Field</a>, or set <code>aria-label</code> on the input. Don't use the placeholder as a label.</p>
        <div class="dx-callout">
          <p><strong>Always handle the empty state.</strong> When filtering yields zero items, show <code>.ren-combobox-empty</code>. Silence is worse than "No results — try a different word".</p>
        </div>
      </section>

      <section class="dx-section" id="examples">
        <p class="dx-kicker">Patterns</p>
        <h2>Examples</h2>
        <h3>Async loading</h3>
        <div class="dx-pre" tabindex="0"><code>const combo = document.querySelector('ren-combobox[async]');

combo.addEventListener('ren-search', async (e) =&gt; {
  combo.setLoading(true);
  const results = await fetch(`/api/users?q=${encodeURIComponent(e.detail.query)}`).then(r =&gt; r.json());
  combo.setItems(results.map(u =&gt; ({ value: u.id, label: u.name, description: u.email })));
  combo.setLoading(false);
});</code></pre>

        <h3>Pre-selecting</h3>
        <div class="dx-pre" tabindex="0"><code>&lt;ren-combobox name="country" value="ar"&gt;
  &lt;div class="ren-combobox-item" data-value="ar"&gt;Argentina&lt;/div&gt;
  &lt;div class="ren-combobox-item" data-value="br"&gt;Brazil&lt;/div&gt;
&lt;/ren-combobox&gt;</code></pre>
      </section>

    </main>
  </div>

  <script type="module" src="../../components/composites/ren-combobox/ren-combobox.js"></script>

  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-command.html
type: docs_page
name: ren-command docs
path: docs/components/ren-command.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Command Palette — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html" aria-current="page">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Command Palette</li></ol></nav>
        <p class="dx-kicker">Composite</p>
        <h1>Command Palette <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">Searchable command launcher (⌘K). Fuzzy matching, keyboard-first, grouped by category. The fastest way for power users to do anything in the app.</p>
      </header>
      <section class="dx-section" id="overview"><p class="dx-kicker">About</p><h2>Overview</h2><p>Command palettes turn your app into a keyboard-first surface. Bind <kbd>⌘</kbd>+<kbd>K</kbd> globally and let users type to find any action — navigation, settings, recently-used items.</p></section>
      <section class="dx-section" id="demo"><p class="dx-kicker">Live</p><h2>Demo</h2><div class="dx-demo"><div class="dx-demo-preview"><button class="ren-btn ren-btn-secondary" type="button">Press <kbd>⌘</kbd>+<kbd>K</kbd> to open</button></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-command id="cmd"&gt;
  &lt;input slot="input" placeholder="Type a command…"&gt;
  &lt;ren-command-group label="Recent"&gt;
    &lt;ren-command-item value="open-project"&gt;Open project…&lt;/ren-command-item&gt;
  &lt;/ren-command-group&gt;
  &lt;ren-command-group label="Settings"&gt;
    &lt;ren-command-item value="theme"&gt;Toggle theme&lt;/ren-command-item&gt;
  &lt;/ren-command-group&gt;
&lt;/ren-command&gt;</code></pre></div></section>
      <section class="dx-section" id="api"><p class="dx-kicker">Reference</p><h2>API</h2><table class="dx-api"><thead><tr><th>Class</th><th>Effect</th></tr></thead><tbody><tr><td><code class="dx-api-name">.ren-command</code></td><td>The dialog wrapper. Opens centered, dimmed backdrop.</td></tr><tr><td><code class="dx-api-name">.ren-command-input</code></td><td>The search input.</td></tr><tr><td><code class="dx-api-name">.ren-command-list</code></td><td>The filtered results.</td></tr><tr><td><code class="dx-api-name">.ren-command-group</code> / <code class="dx-api-name">-group-label</code></td><td>Optional grouping of commands.</td></tr><tr><td><code class="dx-api-name">.ren-command-item</code></td><td>One command. <code>data-value</code> identifies it; <code>data-keywords</code> adds extra matching terms.</td></tr></tbody></table></section>
      <section class="dx-section" id="a11y"><p class="dx-kicker">Inclusive by default</p><h2>Accessibility</h2><ul><li>Implements the WAI-ARIA Combobox + Listbox pattern.</li><li>Up / Down navigate, Enter runs the command, Esc closes.</li><li>Always include keyboard fallbacks for users who can't reach the ⌘K shortcut — every command should also be reachable from a menu.</li></ul></section>
    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-context-menu.html
type: docs_page
name: ren-context-menu docs
path: docs/components/ren-context-menu.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Context Menu — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-8) var(--space-5); }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .demo-target { padding: var(--space-8) var(--space-5); background: var(--color-surface); border: 2px dashed var(--color-border); border-radius: var(--radius-md); text-align: center; color: var(--color-text-muted); font-size: var(--text-sm); }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html" aria-current="page">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Context Menu</li></ol></nav>
        <p class="dx-kicker">Composite</p>
        <h1>Context Menu <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">A right-click menu anchored to the cursor position. Same engine as <a href="ren-menu.html" class="ren-link">Menu</a> — actions list with icons, shortcuts, separators, danger styling — but triggered by <code>contextmenu</code> events instead of a button.</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>Context menus give power users a faster path to common actions on an element they've already located. Use them in editors, file lists, design canvases — anywhere the user thinks "I want to do something to <em>this thing</em>."</p>
        <div class="dx-callout">
          <p><strong>Always provide a non-context-menu path.</strong> Touch users have no right-click. Every action in a context menu must also be reachable via a button, keyboard shortcut, or regular menu.</p>
        </div>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <p>Right-click the area below to open the context menu (touch: long-press).</p>
        <div class="dx-demo">
          <div class="dx-demo-preview" style="position: relative;">
            <div class="demo-target" id="demo-cm-target" data-context="demo-cm-menu" tabindex="0">Right-click anywhere in this box</div>
            <div class="ren-context-menu" id="demo-cm-menu" popover="manual">
              <button role="menuitem" class="ren-menu-item">Cut <span class="ren-menu-item-shortcut">⌘X</span></button>
              <button role="menuitem" class="ren-menu-item">Copy <span class="ren-menu-item-shortcut">⌘C</span></button>
              <button role="menuitem" class="ren-menu-item">Paste <span class="ren-menu-item-shortcut">⌘V</span></button>
              <hr class="ren-menu-separator">
              <button role="menuitem" class="ren-menu-item ren-menu-item-danger">Delete</button>
            </div>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div id="editor-canvas" data-context="editor-menu" tabindex="0"&gt;
  Right-click this area
&lt;/div&gt;

&lt;div id="editor-menu" class="ren-context-menu" popover="manual"&gt;
  &lt;button class="ren-menu-item"&gt;Cut&lt;span class="ren-menu-item-shortcut"&gt;⌘X&lt;/span&gt;&lt;/button&gt;
  &lt;button class="ren-menu-item"&gt;Copy&lt;span class="ren-menu-item-shortcut"&gt;⌘C&lt;/span&gt;&lt;/button&gt;
  &lt;button class="ren-menu-item"&gt;Paste&lt;span class="ren-menu-item-shortcut"&gt;⌘V&lt;/span&gt;&lt;/button&gt;
  &lt;hr class="ren-menu-separator"&gt;
  &lt;button class="ren-menu-item ren-menu-item-danger"&gt;Delete&lt;/button&gt;
&lt;/div&gt;

&lt;script type="module"&gt;
  import { initContextMenu } from './ren-context-menu.js';
  initContextMenu('editor-menu');
&lt;/script&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>
        <p>Visual classes are inherited from <a href="ren-menu.html" class="ren-link">Menu</a> — <code>.ren-menu</code>, <code>.ren-menu-item</code>, <code>.ren-menu-separator</code>, <code>.ren-menu-item-icon</code>, <code>.ren-menu-item-shortcut</code>, <code>.ren-menu-item-danger</code>.</p>
        <h3>Initializer contract</h3>
        <table class="dx-api dx-api-cols-4">
          <thead><tr><th>Attribute</th><th>Type</th><th>Default</th><th>Notes</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">data-context</code></td><td><span class="dx-api-type">string (menu id)</span></td><td><span class="dx-api-default">required</span></td><td>Add to each element that should trigger the context menu.</td></tr>
            <tr><td><code class="dx-api-name">id</code></td><td><span class="dx-api-type">string</span></td><td><span class="dx-api-default">required</span></td><td>The popover element id passed to <code>initContextMenu(id)</code>.</td></tr>
            <tr><td><code class="dx-api-name">popover</code></td><td><span class="dx-api-type">manual</span></td><td><span class="dx-api-default">manual</span></td><td>Uses manual popover mode so the menu stays open after the right-click gesture completes.</td></tr>
          </tbody>
        </table>
        <p>For full event and item documentation see the <a href="ren-menu.html#api" class="ren-link">Menu API</a>.</p>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <ul>
          <li>Trigger via <code>contextmenu</code> event — works for right-click, two-finger tap on Mac trackpads, and the Menu key on keyboards.</li>
          <li>Keyboard fallback: <kbd>Shift</kbd>+<kbd>F10</kbd> opens a context menu on the focused element.</li>
          <li>The actions inside use the same Menu component, so arrow-key navigation, Enter to activate, and Escape to close all work.</li>
          <li>Don't put exclusive functionality in a context menu — touch users won't find it.</li>
        </ul>
      </section>

    </main>
  </div>
  <script type="module">
    import { initContextMenu } from '../../components/composites/ren-context-menu/ren-context-menu.js';

    initContextMenu('demo-cm-menu');
  </script>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-date-picker.html
type: docs_page
name: ren-date-picker docs
path: docs/components/ren-date-picker.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Date Picker — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html" aria-current="page">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Date Picker</li></ol></nav>
        <p class="dx-kicker">Composite</p>
        <h1>Date Picker <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">Input + calendar popover. Type the date manually or pick from the calendar — both stay in sync. Format-aware, with min / max constraints and disabled-date support.</p>
      </header>
      <section class="dx-section" id="overview"><p class="dx-kicker">About</p><h2>Overview</h2><p>The bread-and-butter date control: a text input the user can type into, plus a calendar that opens on focus or click. Combines <a href="ren-field.html" class="ren-link">Form Field</a> with <a href="ren-calendar.html" class="ren-link">Calendar</a>.</p></section>
      <section class="dx-section" id="demo"><p class="dx-kicker">Live</p><h2>Demo</h2><div class="dx-demo"><div class="dx-demo-preview"><label style="display: flex; flex-direction: column; gap: 4px; font-size: var(--text-sm);"><span>Birthday</span><input type="date" class="ren-input" value="1990-04-12" style="width: 200px;"></label></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-date-picker name="birthday" value="1990-04-12"&gt;
  &lt;label slot="label"&gt;Birthday&lt;/label&gt;
&lt;/ren-date-picker&gt;</code></pre></div></section>
      <section class="dx-section" id="api"><p class="dx-kicker">Reference</p><h2>API</h2><p>Inherits all <a href="ren-calendar.html#api" class="ren-link">Calendar attributes</a>. Plus:</p><table class="dx-api dx-api-cols-4"><thead><tr><th>Attribute</th><th>Type</th><th>Default</th><th>Notes</th></tr></thead><tbody><tr><td><code class="dx-api-name">format</code></td><td><span class="dx-api-type">string</span></td><td><span class="dx-api-default">locale-default</span></td><td>Display format ("MM/DD/YYYY", "DD-MM-YYYY"…). Submitted value is always ISO 8601.</td></tr><tr><td><code class="dx-api-name">placeholder</code></td><td><span class="dx-api-type">string</span></td><td><span class="dx-api-default">"YYYY-MM-DD"</span></td><td>Input placeholder.</td></tr><tr><td><code class="dx-api-name">placement</code></td><td><span class="dx-api-type">"top" | "right" | "bottom" | "left"</span></td><td><span class="dx-api-default">"bottom"</span></td><td>Preferred side for the calendar popover. Reflected to <code>data-side</code>.</td></tr></tbody></table></section>
      <section class="dx-section" id="a11y"><p class="dx-kicker">Inclusive by default</p><h2>Accessibility</h2><ul><li>The text input accepts free typing — assistive tech users don't need to navigate the calendar grid.</li><li>The calendar trigger button has <code>aria-label="Open calendar"</code> and <code>aria-haspopup="dialog"</code>.</li></ul></section>
    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-date-range-picker.html
type: docs_page
name: ren-date-range-picker docs
path: docs/components/ren-date-range-picker.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Date Range Picker — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html" aria-current="page">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Date Range Picker</li></ol></nav>
        <p class="dx-kicker">Composite</p>
        <h1>Date Range Picker <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">Two-handle date range with presets (last 7 days, this month, last quarter…). For analytics filters, booking flows, report scopes.</p>
      </header>
      <section class="dx-section" id="overview"><p class="dx-kicker">About</p><h2>Overview</h2><p>For "from–to" date ranges. Renders two inputs (start / end) plus an optional preset list ("Last 7 days", "Last 30 days", "This year"). The calendar lets users pick both ends visually.</p></section>
      <section class="dx-section" id="demo"><p class="dx-kicker">Live</p><h2>Demo</h2><div class="dx-demo"><div class="dx-demo-preview"><div style="display: flex; gap: var(--space-2); align-items: center;"><input type="date" class="ren-input" value="2026-04-01" style="width: 160px;"><span>→</span><input type="date" class="ren-input" value="2026-04-30" style="width: 160px;"></div></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-date-range-picker name="period"
                       start="2026-04-01" end="2026-04-30"
                       presets="7d,30d,90d,year"&gt;
&lt;/ren-date-range-picker&gt;</code></pre></div></section>
      <section class="dx-section" id="api"><p class="dx-kicker">Reference</p><h2>API</h2><table class="dx-api dx-api-cols-4"><thead><tr><th>Attribute</th><th>Type</th><th>Default</th><th>Notes</th></tr></thead><tbody><tr><td><code class="dx-api-name">start</code> / <code class="dx-api-name">end</code></td><td><span class="dx-api-type">"YYYY-MM-DD"</span></td><td><span class="dx-api-default">—</span></td><td>Range bounds.</td></tr><tr><td><code class="dx-api-name">max-range</code></td><td><span class="dx-api-type">number (days)</span></td><td><span class="dx-api-default">—</span></td><td>Limit the maximum span the user can pick.</td></tr><tr><td><code class="dx-api-name">presets</code></td><td><span class="dx-api-type">string list</span></td><td><span class="dx-api-default">—</span></td><td>Comma-separated preset keys: <code>7d, 30d, 90d, year, ytd, last-quarter</code>.</td></tr><tr><td><code class="dx-api-name">placement</code></td><td><span class="dx-api-type">"top" | "right" | "bottom" | "left"</span></td><td><span class="dx-api-default">"bottom"</span></td><td>Preferred side for the range popover. Reflected to <code>data-side</code>.</td></tr></tbody></table></section>
      <section class="dx-section" id="a11y"><p class="dx-kicker">Inclusive by default</p><h2>Accessibility</h2><ul><li>Inside the calendar, the two ends of the range have distinct ARIA labels ("Start of range", "End of range").</li><li>Days that would fall outside the allowed range get <code>aria-disabled="true"</code>.</li></ul></section>
    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-dialog.html
type: docs_page
name: ren-dialog docs
path: docs/components/ren-dialog.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Dialog — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    /* Page-specific styles — chrome and tables live in shell.css */

    /* Demo block: preview frame + code block, stacked */
    .dx-demo {
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      overflow: hidden;
      margin: var(--space-4) 0;
    }
    .dx-demo-preview {
      background: var(--color-surface-raised);
      padding: var(--space-8) var(--space-5);
      display: flex;
      flex-wrap: wrap;
      gap: var(--space-3);
      align-items: center;
      justify-content: center;
      min-height: 96px;
    }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }

    /* Variant rows — labeled groups of demos */
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label {
      font-size: var(--text-xs);
      font-weight: var(--weight-semibold);
      text-transform: uppercase;
      letter-spacing: 0.06em;
      color: var(--color-text-muted);
      padding-top: var(--space-3);
    }
    .dx-vrow-items {
      display: flex;
      flex-wrap: wrap;
      gap: var(--space-3);
      align-items: center;
      padding: var(--space-3);
      background: var(--color-surface-raised);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
    }
    @media (max-width: 720px) {
      .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); }
      .dx-vrow-label { padding-top: 0; }
    }

    /* Anatomy: assembled dialog on top, parts breakdown below */
    .dx-anatomy {
      margin: var(--space-4) 0;
      display: grid;
      gap: var(--space-4);
    }
    .dx-anatomy-num {
      display: inline-grid;
      place-items: center;
      width: 22px;
      height: 22px;
      border-radius: 50%;
      background: var(--color-text);
      color: var(--color-surface);
      font-size: var(--text-xs);
      font-weight: var(--weight-bold);
      flex-shrink: 0;
    }
    .dx-anatomy-stage {
      background: var(--color-surface-raised);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      padding: var(--space-6) var(--space-5);
    }
    .dx-anatomy-stage-label {
      font-size: var(--text-xs);
      text-transform: uppercase;
      letter-spacing: 0.06em;
      color: var(--color-text-muted);
      font-weight: var(--weight-semibold);
      margin: 0 0 var(--space-3);
    }
    .dx-anatomy-parts {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: var(--space-3);
    }
    @media (max-width: 720px) { .dx-anatomy-parts { grid-template-columns: 1fr; } }
    .dx-anatomy-part {
      background: var(--color-surface-raised);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      padding: var(--space-4);
      display: grid;
      gap: var(--space-2);
    }
    .dx-anatomy-part-header {
      display: flex;
      align-items: center;
      gap: var(--space-2);
    }
    .dx-anatomy-part-name {
      font-size: var(--text-sm);
      font-weight: var(--weight-semibold);
      color: var(--color-text);
    }
    .dx-anatomy-part-desc {
      font-size: var(--text-sm);
      line-height: 1.5;
      color: var(--color-text-secondary);
      margin: 0;
    }
    .dx-anatomy-part-desc code { font-size: 0.85em; }

    /* Mocked dialog illustration — a static, non-interactive preview of the
       dialog frame so users can visualize the parts without opening the modal.
       Intentionally light: no internal dividers, transparent close button,
       header/body/footer separated only by spacing. */
    .dx-dialog-mock {
      width: 100%;
      max-width: 380px;
      margin-inline: auto;
      background: var(--color-surface);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-xl);
      box-shadow: var(--shadow-xl, 0 12px 48px rgba(0,0,0,0.18));
      padding: var(--space-5) var(--space-5) var(--space-4);
    }
    .dx-dialog-mock-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--space-3);
    }
    .dx-dialog-mock-title {
      font-size: var(--text-base);
      font-weight: var(--weight-semibold);
      margin: 0;
      line-height: 1.2;
    }
    .dx-dialog-mock-close {
      width: 24px;
      height: 24px;
      display: grid;
      place-items: center;
      background: transparent;
      border: 0;
      padding: 0;
      color: var(--color-text-muted);
      cursor: pointer;
      line-height: 1;
      font-size: 18px;
    }
    .dx-dialog-mock-close:hover { color: var(--color-text); }
    .dx-dialog-mock-body {
      margin-block: var(--space-3) var(--space-4);
      font-size: var(--text-sm);
      color: var(--color-text-secondary);
      line-height: 1.6;
    }
    .dx-dialog-mock-footer {
      display: flex;
      justify-content: flex-end;
      gap: var(--space-2);
    }
  </style>
</head>
<body>

  <!-- Top bar (shell.css) -->
  <header class="dx-nav">
    <div class="dx-nav-inner">
      <a href="../index.html" class="dx-brand">
        <span class="dx-brand-mark">R</span>
        <span>RenDS</span>
        <span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span>
      </a>
      <nav class="dx-nav-menu" aria-label="Primary">
        <a href="../index.html">Docs</a>
        <a href="../components.html" aria-current="page">Components</a>
        <a href="../../templates/index.html">Templates</a>
        <a href="../../create/index.html">Theme Builder</a>
      </nav>
      <div class="dx-nav-actions">
        <a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a>
        <a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a>
      </div>
    </div>
  </header>

  <!-- Sidebar + content shell -->
  <div class="dx-shell dx-shell-grid">

    <!-- Persistent sidebar — same nav as the catalog so context is never lost -->
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html" aria-current="page">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <!-- Content -->
    <main class="dx-content">

      <!-- Page header -->
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);">
          <ol>
            <li><a href="../index.html" class="ren-link-plain">Docs</a></li>
            <li><a href="../components.html" class="ren-link-plain">Components</a></li>
            <li aria-current="page">Dialog</li>
          </ol>
        </nav>
        <p class="dx-kicker">Composite</p>
        <h1>Dialog <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">A modal overlay built on the native <code>&lt;dialog&gt;</code> element. Focus trap, keyboard handling, click-outside dismiss, and smooth entry / exit animations come for free. Available as a CSS class set <em>or</em> as the <code>&lt;ren-dialog&gt;</code> Web Component with auto-wired triggers.</p>
      </header>

      <!-- ═══════════════════════════════════════════════════════════
           1. OVERVIEW
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>A dialog interrupts the user's current flow to confirm an action, gather a small piece of input, or surface a focused decision. RenDS uses the browser's native <code>&lt;dialog&gt;</code> element under the hood, so a lot of the hard parts — modal scroll lock, top-layer rendering, focus trapping, escape-to-close — come from the platform. The component layers smooth animations, mobile sheet behavior, and declarative auto-wiring on top.</p>

        <p>Use a dialog when the user needs to make a deliberate choice before the rest of the UI continues. If the action is destructive or irreversible, use the <strong>alert</strong> variant so the dialog can't be dismissed by clicking the backdrop.</p>

        <div class="dx-callout">
          <p><strong>Don't reach for a dialog by default.</strong> If the decision can live on the page (an inline form, a popover, an expandable panel), prefer those. A modal blocks everything else and shouldn't be the answer to "where do I put this content?".</p>
        </div>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           2. ANATOMY
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="anatomy">
        <p class="dx-kicker">Parts</p>
        <h2>Anatomy</h2>
        <p>A dialog is composed of five regions. Three are required (container, body, footer with at least one action), two are conventional (header with title and close button, backdrop).</p>

        <div class="dx-anatomy">
          <!-- Assembled reference -->
          <div class="dx-anatomy-stage">
            <p class="dx-anatomy-stage-label">Assembled</p>
            <div class="dx-dialog-mock" aria-hidden="true">
              <div class="dx-dialog-mock-header">
                <h4 class="dx-dialog-mock-title">Confirm changes</h4>
                <button class="dx-dialog-mock-close" type="button" tabindex="-1">×</button>
              </div>
              <div class="dx-dialog-mock-body">Save the edits to your profile? You can revert any time from settings.</div>
              <div class="dx-dialog-mock-footer">
                <button type="button" class="ren-btn ren-btn-secondary ren-btn-sm" tabindex="-1">Cancel</button>
                <button type="button" class="ren-btn ren-btn-primary ren-btn-sm" tabindex="-1">Save</button>
              </div>
            </div>
          </div>

          <!-- Parts -->
          <div class="dx-anatomy-parts">
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header">
                <span class="dx-anatomy-num">1</span>
                <span class="dx-anatomy-part-name">Container</span>
              </div>
              <p class="dx-anatomy-part-desc">The dialog box itself — <code>&lt;dialog class="ren-dialog"&gt;</code>. Sized by a width variant token (<code>--dialog-max-width</code>). Renders in the browser's top layer.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header">
                <span class="dx-anatomy-num">2</span>
                <span class="dx-anatomy-part-name">Backdrop</span>
              </div>
              <p class="dx-anatomy-part-desc">The dimmed scrim. Styled via <code>::backdrop</code>. Click to dismiss (unless <code>alert</code> is set). Fades in with the dialog.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header">
                <span class="dx-anatomy-num">3</span>
                <span class="dx-anatomy-part-name">Header</span>
              </div>
              <p class="dx-anatomy-part-desc"><code>.ren-dialog-header</code> with <code>.ren-dialog-title</code> and an optional close button (<code>data-dialog-close</code>). Bottom-bordered, padded.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header">
                <span class="dx-anatomy-num">4</span>
                <span class="dx-anatomy-part-name">Body</span>
              </div>
              <p class="dx-anatomy-part-desc"><code>.ren-dialog-body</code>. Scrolls when content exceeds the dialog's max-height. Independent scrollbar so the page beneath stays locked.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header">
                <span class="dx-anatomy-num">5</span>
                <span class="dx-anatomy-part-name">Footer</span>
              </div>
              <p class="dx-anatomy-part-desc"><code>.ren-dialog-footer</code> with action buttons. Conventionally right-aligned, primary action last. Top-bordered.</p>
            </div>
          </div>
        </div>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           3. DEMO
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <p>Click any trigger to open the dialog. <kbd>Esc</kbd> closes it; clicking outside the dialog closes it (except for alert dialogs). Tab cycles through the focusable elements without escaping.</p>

        <div class="dx-demo">
          <div class="dx-demo-preview">
            <button type="button" class="ren-btn ren-btn-primary" data-dialog-trigger="demo-confirm">Open dialog</button>
            <button type="button" class="ren-btn ren-btn-danger" data-dialog-trigger="demo-alert">Open alert dialog</button>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;button data-dialog-trigger="dlg-confirm"&gt;Open dialog&lt;/button&gt;

&lt;ren-dialog id="dlg-confirm"&gt;
  &lt;dialog class="ren-dialog"&gt;
    &lt;div class="ren-dialog-header"&gt;
      &lt;h2 class="ren-dialog-title"&gt;Confirm changes&lt;/h2&gt;
      &lt;button class="ren-dialog-close" data-dialog-close aria-label="Close"&gt;×&lt;/button&gt;
    &lt;/div&gt;
    &lt;div class="ren-dialog-body"&gt;
      Save the edits to your profile?
    &lt;/div&gt;
    &lt;div class="ren-dialog-footer"&gt;
      &lt;button class="ren-btn ren-btn-secondary" data-dialog-close&gt;Cancel&lt;/button&gt;
      &lt;button class="ren-btn ren-btn-primary"&gt;Save&lt;/button&gt;
    &lt;/div&gt;
  &lt;/dialog&gt;
&lt;/ren-dialog&gt;</code></pre>
        </div>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           4. VARIANTS
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="variants">
        <p class="dx-kicker">Shapes</p>
        <h2>Variants</h2>
        <p>Five sizes plus an alert mode. Default is <code>md</code>. Pick the smallest size that fits the content — bigger isn't friendlier.</p>

        <div class="dx-vgrid">
          <div class="dx-vrow">
            <span class="dx-vrow-label">Sizes</span>
            <div class="dx-vrow-items">
              <button type="button" class="ren-btn ren-btn-secondary" data-dialog-trigger="demo-size-sm">sm</button>
              <button type="button" class="ren-btn ren-btn-secondary" data-dialog-trigger="demo-size-md">md (default)</button>
              <button type="button" class="ren-btn ren-btn-secondary" data-dialog-trigger="demo-size-lg">lg</button>
              <button type="button" class="ren-btn ren-btn-secondary" data-dialog-trigger="demo-size-xl">xl</button>
              <button type="button" class="ren-btn ren-btn-secondary" data-dialog-trigger="demo-size-full">full</button>
            </div>
          </div>

          <div class="dx-vrow">
            <span class="dx-vrow-label">Alert</span>
            <div class="dx-vrow-items">
              <button type="button" class="ren-btn ren-btn-danger" data-dialog-trigger="demo-alert">Delete account</button>
              <span style="font-size: var(--text-sm); color: var(--color-text-muted);">No backdrop dismiss · forces a button choice</span>
            </div>
          </div>

          <div class="dx-vrow">
            <span class="dx-vrow-label">No Escape</span>
            <div class="dx-vrow-items">
              <button type="button" class="ren-btn ren-btn-secondary" data-dialog-trigger="demo-no-escape">Open critical flow</button>
              <span style="font-size: var(--text-sm); color: var(--color-text-muted);"><kbd>Esc</kbd> is suppressed · use the in-dialog buttons</span>
            </div>
          </div>
        </div>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           5. API
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>

        <h3>CSS classes</h3>
        <p>Apply directly to the <code>&lt;dialog&gt;</code> element. They work even if you don't use the Web Component (you'd just script open / close yourself).</p>
        <table class="dx-api">
          <thead>
            <tr>
              <th>Class</th>
              <th>Effect</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code class="dx-api-name">.ren-dialog</code></td>
              <td>Base. Required on the <code>&lt;dialog&gt;</code> element. Provides background, border-radius, shadow, animations, and the backdrop styling.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-dialog-header</code></td>
              <td>Top region. Flex row with a bottom border. Holds the title and close button.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-dialog-title</code></td>
              <td>Heading inside the header. Set on the actual heading tag (<code>&lt;h2&gt;</code>, <code>&lt;h3&gt;</code>) so screen readers announce it correctly.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-dialog-description</code></td>
              <td>Optional sub-title under the title. Muted color.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-dialog-body</code></td>
              <td>Main content region. Scrolls independently when its content exceeds <code>max-height: 85dvh</code>.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-dialog-footer</code></td>
              <td>Bottom region for action buttons. Top-bordered, right-aligned by default.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-dialog-close</code></td>
              <td>The icon close button placed in the header. Square, ghost-styled, focus ring matches the system token.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-dialog-sm</code> / <code class="dx-api-name">-md</code> / <code class="dx-api-name">-lg</code> / <code class="dx-api-name">-xl</code> / <code class="dx-api-name">-full</code></td>
              <td>Size modifiers. Set <code>--dialog-max-width</code>: 24rem · 32rem · 42rem · 56rem · 95dvw.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-alert-dialog</code></td>
              <td>Alert flavor. Suppresses click-outside dismissal. Used by <code>&lt;ren-alert-dialog&gt;</code> internally.</td>
            </tr>
          </tbody>
        </table>

        <h3>Web Component attributes</h3>
        <p>Set on the <code>&lt;ren-dialog&gt;</code> wrapper. All are reactive — flipping them in JS opens, closes, or resizes the dialog without rebuilding the markup.</p>
        <table class="dx-api dx-api-cols-4">
          <thead>
            <tr>
              <th>Attribute</th>
              <th>Type</th>
              <th>Default</th>
              <th>Notes</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code class="dx-api-name">open</code></td>
              <td><span class="dx-api-type">boolean</span></td>
              <td><span class="dx-api-default">false</span></td>
              <td>Opens the dialog when present. Mirrors <code>&lt;dialog open&gt;</code> but routes through the component lifecycle (events, focus trap).</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">size</code></td>
              <td><span class="dx-api-type">"sm" | "md" | "lg" | "xl" | "full"</span></td>
              <td><span class="dx-api-default">"md"</span></td>
              <td>Width variant. Adds the matching <code>.ren-dialog-*</code> class to the inner dialog.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">alert</code></td>
              <td><span class="dx-api-type">boolean</span></td>
              <td><span class="dx-api-default">false</span></td>
              <td>Disables backdrop click dismissal. The user must press a button to close.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">no-escape</code></td>
              <td><span class="dx-api-type">boolean</span></td>
              <td><span class="dx-api-default">false</span></td>
              <td>Suppresses <kbd>Esc</kbd> closing the dialog. Use sparingly — it traps the user.</td>
            </tr>
          </tbody>
        </table>

        <h3>JavaScript methods</h3>
        <p>Available on every <code>&lt;ren-dialog&gt;</code> instance. All return Promises so you can <code>await</code> open / close transitions before continuing.</p>
        <table class="dx-api">
          <thead>
            <tr>
              <th>Method</th>
              <th>Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code class="dx-api-name">show()</code> / <code class="dx-api-name">open()</code></td>
              <td>Opens the dialog. Returns a Promise that resolves once the entry animation finishes. Aliases.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">close(returnValue?)</code></td>
              <td>Closes the dialog. Optional <code>returnValue</code> is forwarded to the <code>ren-close</code> event detail. Promise resolves after the exit animation.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">isOpen</code></td>
              <td>Boolean getter. <code>true</code> while the dialog is visible.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">dialog</code></td>
              <td>Getter that returns the underlying native <code>&lt;dialog&gt;</code> element if you need to call its DOM API directly.</td>
            </tr>
          </tbody>
        </table>

        <div class="dx-pre" tabindex="0"><code>const dialog = document.querySelector('ren-dialog');

await dialog.show();              // wait for it to be visible
const result = await dialog.close('confirmed');  // returnValue surfaces in ren-close

if (dialog.isOpen) { /* still open */ }</code></div>

        <h3>Events</h3>
        <p>Both events bubble and are composed. Listen on the wrapper or any ancestor.</p>
        <table class="dx-api">
          <thead>
            <tr>
              <th>Event</th>
              <th>Detail</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code class="dx-api-name">ren-open</code></td>
              <td>Fired after the entry animation completes. <code>event.detail</code> is empty.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">ren-close</code></td>
              <td>Fired after the exit animation completes. <code>event.detail.returnValue</code> contains the value passed to <code>close()</code>, if any.</td>
            </tr>
          </tbody>
        </table>

        <h3>Auto-wiring</h3>
        <p>You don't need to write JavaScript for the common case. Two declarative attributes wire opening and closing:</p>
        <table class="dx-api">
          <thead>
            <tr>
              <th>Attribute</th>
              <th>Effect</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code class="dx-api-name">data-dialog-trigger="ID"</code></td>
              <td>On any element. Click opens the <code>&lt;ren-dialog&gt;</code> with the matching <code>id</code>.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">data-dialog-close</code></td>
              <td>On any element inside the dialog. Click closes the parent dialog.</td>
            </tr>
          </tbody>
        </table>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           6. ACCESSIBILITY
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <p>Because the component renders an actual <code>&lt;dialog&gt;</code> element, the platform handles most of the work. RenDS adds the focus management, motion preferences, and labelling conventions on top.</p>

        <h3>Keyboard</h3>
        <div class="dx-keys">
          <div class="dx-keyrow">
            <span class="keys"><kbd>Tab</kbd></span>
            <span>Moves focus to the next focusable element inside the dialog. Cycles back to the first when it reaches the end.</span>
          </div>
          <div class="dx-keyrow">
            <span class="keys"><kbd>Shift</kbd> + <kbd>Tab</kbd></span>
            <span>Moves focus backward, cycling at the start of the dialog.</span>
          </div>
          <div class="dx-keyrow">
            <span class="keys"><kbd>Esc</kbd></span>
            <span>Closes the dialog. Suppressed when <code>no-escape</code> is set.</span>
          </div>
          <div class="dx-keyrow">
            <span class="keys"><kbd>Enter</kbd></span>
            <span>Activates the focused button or submits the focused form, as the platform default. Not intercepted.</span>
          </div>
        </div>

        <h3>Focus management</h3>
        <ul>
          <li>On open, focus moves to the first focusable element inside the dialog. To override, mark a specific element with <code>autofocus</code>.</li>
          <li>While open, focus is trapped inside the dialog — Tab and Shift+Tab cycle without leaving.</li>
          <li>On close, focus returns to the element that opened the dialog (the trigger button). The user never has to find their place again.</li>
        </ul>

        <h3>Labelling</h3>
        <p>Always pair the dialog with an accessible name. The simplest path is to give the title an <code>id</code> and reference it via <code>aria-labelledby</code>:</p>
        <div class="dx-pre" tabindex="0"><code>&lt;ren-dialog id="dlg-labelling" aria-labelledby="dlg-labelling-title"&gt;
  &lt;dialog class="ren-dialog"&gt;
    &lt;div class="ren-dialog-header"&gt;
      &lt;h2 class="ren-dialog-title" id="dlg-labelling-title"&gt;Delete file&lt;/h2&gt;
    &lt;/div&gt;
    ...
  &lt;/dialog&gt;
&lt;/ren-dialog&gt;</code></div>
        <p>If you also have descriptive prose under the title, link it with <code>aria-describedby</code>.</p>

        <h3>Motion</h3>
        <p>Entry and exit animations use the <code>--duration-enter</code> motion token. Under <code>prefers-reduced-motion: reduce</code> the transitions are disabled — the dialog appears and disappears instantly.</p>

        <div class="dx-callout">
          <p><strong>Use the alert variant for destructive confirmations.</strong> A backdrop click on a regular dialog dismisses it silently — fine for most cases, dangerous when the user is about to delete something. The alert variant forces an explicit button choice.</p>
        </div>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           7. EXAMPLES
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="examples">
        <p class="dx-kicker">Patterns</p>
        <h2>Examples</h2>

        <h3>Confirmation</h3>
        <p>The classic: a dialog asks the user to confirm a non-trivial action.</p>
        <div class="dx-pre" tabindex="0"><code>&lt;button data-dialog-trigger="dlg-save"&gt;Save&lt;/button&gt;

&lt;ren-dialog id="dlg-save" aria-labelledby="save-title"&gt;
  &lt;dialog class="ren-dialog"&gt;
    &lt;div class="ren-dialog-header"&gt;
      &lt;h2 class="ren-dialog-title" id="save-title"&gt;Save changes?&lt;/h2&gt;
    &lt;/div&gt;
    &lt;div class="ren-dialog-body"&gt;
      Your edits will be visible to the team immediately.
    &lt;/div&gt;
    &lt;div class="ren-dialog-footer"&gt;
      &lt;button class="ren-btn ren-btn-secondary" data-dialog-close&gt;Cancel&lt;/button&gt;
      &lt;button class="ren-btn ren-btn-primary"&gt;Save&lt;/button&gt;
    &lt;/div&gt;
  &lt;/dialog&gt;
&lt;/ren-dialog&gt;</code></div>

        <h3>Destructive (alert)</h3>
        <p>Backdrop click is suppressed; the user must press one of the two buttons.</p>
        <div class="dx-pre" tabindex="0"><code>&lt;button class="ren-btn ren-btn-danger" data-dialog-trigger="dlg-delete"&gt;Delete account&lt;/button&gt;

&lt;ren-alert-dialog id="dlg-delete" aria-labelledby="delete-title"&gt;
  &lt;dialog class="ren-dialog ren-alert-dialog"&gt;
    &lt;div class="ren-dialog-header"&gt;
      &lt;h2 class="ren-dialog-title" id="delete-title"&gt;Delete this account?&lt;/h2&gt;
    &lt;/div&gt;
    &lt;div class="ren-dialog-body"&gt;
      All projects, files, and history will be permanently removed. This cannot be undone.
    &lt;/div&gt;
    &lt;div class="ren-dialog-footer"&gt;
      &lt;button class="ren-btn ren-btn-secondary" data-dialog-close&gt;Keep account&lt;/button&gt;
      &lt;button class="ren-btn ren-btn-danger"&gt;Delete account&lt;/button&gt;
    &lt;/div&gt;
  &lt;/dialog&gt;
&lt;/ren-alert-dialog&gt;</code></div>

        <h3>Form dialog</h3>
        <p>Using a dialog to collect a small piece of input. Submit the form to close.</p>
        <div class="dx-pre" tabindex="0"><code>&lt;button data-dialog-trigger="dlg-rename"&gt;Rename project&lt;/button&gt;

&lt;ren-dialog id="dlg-rename" aria-labelledby="dlg-rename-title"&gt;
  &lt;dialog class="ren-dialog ren-dialog-sm"&gt;
    &lt;form method="dialog"&gt;
      &lt;div class="ren-dialog-header"&gt;
        &lt;h2 class="ren-dialog-title" id="dlg-rename-title"&gt;Rename project&lt;/h2&gt;
      &lt;/div&gt;
      &lt;div class="ren-dialog-body"&gt;
        &lt;label for="project-name" class="ren-field-label"&gt;New name&lt;/label&gt;
        &lt;input id="project-name" name="project-name" class="ren-input" autofocus required&gt;
      &lt;/div&gt;
      &lt;div class="ren-dialog-footer"&gt;
        &lt;button class="ren-btn ren-btn-secondary" type="button" data-dialog-close&gt;Cancel&lt;/button&gt;
        &lt;button class="ren-btn ren-btn-primary" type="submit"&gt;Rename&lt;/button&gt;
      &lt;/div&gt;
    &lt;/form&gt;
  &lt;/dialog&gt;
&lt;/ren-dialog&gt;</code></div>

        <h3>Reading the result</h3>
        <p>When you need to know <em>which</em> button closed the dialog, listen to <code>ren-close</code> and pass a <code>returnValue</code>.</p>
        <div class="dx-pre" tabindex="0"><code>const dialog = document.querySelector('#dlg-save');

dialog.querySelector('.ren-btn-primary')
  .addEventListener('click', () =&gt; dialog.close('save'));

dialog.querySelector('.ren-btn-secondary')
  .addEventListener('click', () =&gt; dialog.close('cancel'));

dialog.addEventListener('ren-close', (e) =&gt; {
  if (e.detail.returnValue === 'save') {
    persist();
  }
});</code></div>
      </section>

    </main>

  </div>

  <!-- ═══════════════════════════════════════════════════════════
       Live demo dialogs — kept at the end of the body so they sit
       outside the dx-shell-grid (top-layer rendering still works
       no matter where in the DOM the dialog lives).
       ═══════════════════════════════════════════════════════════ -->

  <ren-dialog id="demo-confirm" aria-labelledby="demo-confirm-title">
    <dialog class="ren-dialog">
      <div class="ren-dialog-header">
        <h2 class="ren-dialog-title" id="demo-confirm-title">Confirm changes</h2>
        <button class="ren-dialog-close" data-dialog-close aria-label="Close">×</button>
      </div>
      <div class="ren-dialog-body">
        Save the edits to your profile? You can revert any time from settings.
      </div>
      <div class="ren-dialog-footer">
        <button type="button" class="ren-btn ren-btn-secondary" data-dialog-close>Cancel</button>
        <button type="button" class="ren-btn ren-btn-primary" data-dialog-close>Save</button>
      </div>
    </dialog>
  </ren-dialog>

  <ren-alert-dialog id="demo-alert" aria-labelledby="demo-alert-title">
    <dialog class="ren-dialog ren-alert-dialog">
      <div class="ren-dialog-header">
        <h2 class="ren-dialog-title" id="demo-alert-title">Delete this account?</h2>
      </div>
      <div class="ren-dialog-body">
        All projects, files, and history will be permanently removed. This cannot be undone.
      </div>
      <div class="ren-dialog-footer">
        <button type="button" class="ren-btn ren-btn-secondary" data-dialog-close>Keep account</button>
        <button type="button" class="ren-btn ren-btn-danger" data-dialog-close>Delete account</button>
      </div>
    </dialog>
  </ren-alert-dialog>

  <ren-dialog id="demo-size-sm" size="sm" aria-labelledby="demo-size-sm-title">
    <dialog class="ren-dialog ren-dialog-sm">
      <div class="ren-dialog-header">
        <h2 class="ren-dialog-title" id="demo-size-sm-title">Small dialog</h2>
        <button class="ren-dialog-close" data-dialog-close aria-label="Close">×</button>
      </div>
      <div class="ren-dialog-body">24 rem (384 px) max-width. For tight, single-decision dialogs.</div>
      <div class="ren-dialog-footer">
        <button type="button" class="ren-btn ren-btn-primary" data-dialog-close>OK</button>
      </div>
    </dialog>
  </ren-dialog>

  <ren-dialog id="demo-size-md" size="md" aria-labelledby="demo-size-md-title">
    <dialog class="ren-dialog ren-dialog-md">
      <div class="ren-dialog-header">
        <h2 class="ren-dialog-title" id="demo-size-md-title">Medium dialog (default)</h2>
        <button class="ren-dialog-close" data-dialog-close aria-label="Close">×</button>
      </div>
      <div class="ren-dialog-body">32 rem (512 px) max-width. The everyday default — fits a paragraph of context plus a couple of buttons.</div>
      <div class="ren-dialog-footer">
        <button type="button" class="ren-btn ren-btn-primary" data-dialog-close>OK</button>
      </div>
    </dialog>
  </ren-dialog>

  <ren-dialog id="demo-size-lg" size="lg" aria-labelledby="demo-size-lg-title">
    <dialog class="ren-dialog ren-dialog-lg">
      <div class="ren-dialog-header">
        <h2 class="ren-dialog-title" id="demo-size-lg-title">Large dialog</h2>
        <button class="ren-dialog-close" data-dialog-close aria-label="Close">×</button>
      </div>
      <div class="ren-dialog-body">42 rem (672 px) max-width. Use for forms with multiple fields or list-pickers.</div>
      <div class="ren-dialog-footer">
        <button type="button" class="ren-btn ren-btn-primary" data-dialog-close>OK</button>
      </div>
    </dialog>
  </ren-dialog>

  <ren-dialog id="demo-size-xl" size="xl" aria-labelledby="demo-size-xl-title">
    <dialog class="ren-dialog ren-dialog-xl">
      <div class="ren-dialog-header">
        <h2 class="ren-dialog-title" id="demo-size-xl-title">Extra-large dialog</h2>
        <button class="ren-dialog-close" data-dialog-close aria-label="Close">×</button>
      </div>
      <div class="ren-dialog-body">56 rem (896 px) max-width. For media browsers, multi-step wizards, or rich previews.</div>
      <div class="ren-dialog-footer">
        <button type="button" class="ren-btn ren-btn-primary" data-dialog-close>OK</button>
      </div>
    </dialog>
  </ren-dialog>

  <ren-dialog id="demo-size-full" size="full" aria-labelledby="demo-size-full-title">
    <dialog class="ren-dialog ren-dialog-full">
      <div class="ren-dialog-header">
        <h2 class="ren-dialog-title" id="demo-size-full-title">Full-bleed dialog</h2>
        <button class="ren-dialog-close" data-dialog-close aria-label="Close">×</button>
      </div>
      <div class="ren-dialog-body">95 dvw — almost edge-to-edge. Reserve for full-screen takeovers (image lightbox, focus modes).</div>
      <div class="ren-dialog-footer">
        <button type="button" class="ren-btn ren-btn-primary" data-dialog-close>OK</button>
      </div>
    </dialog>
  </ren-dialog>

  <ren-dialog id="demo-no-escape" no-escape aria-labelledby="demo-no-escape-title">
    <dialog class="ren-dialog">
      <div class="ren-dialog-header">
        <h2 class="ren-dialog-title" id="demo-no-escape-title">Critical step</h2>
      </div>
      <div class="ren-dialog-body">
        <kbd>Esc</kbd> won't close this. Use one of the buttons below to leave. (You'd reserve this for moments where dismissing accidentally would lose work — e.g. mid-payment-flow.)
      </div>
      <div class="ren-dialog-footer">
        <button type="button" class="ren-btn ren-btn-secondary" data-dialog-close>Cancel</button>
        <button type="button" class="ren-btn ren-btn-primary" data-dialog-close>Continue</button>
      </div>
    </dialog>
  </ren-dialog>

  <!-- Web Component registration (focus trap, animations, auto-wiring) -->
  <script type="module" src="../../components/composites/ren-dialog/ren-dialog.js"></script>

  <!-- Demo wiring — vanilla, uses the native <dialog> API so triggers fire
       even if the Web Component never registers. -->
  <script>
    // Open: any [data-dialog-trigger="ID"] opens the matching dialog
    document.querySelectorAll('[data-dialog-trigger]').forEach(trigger => {
      const targetId = trigger.getAttribute('data-dialog-trigger');
      trigger.addEventListener('click', (e) => {
        e.preventDefault();
        const wrapper = document.getElementById(targetId);
        if (!wrapper) return;
        const dialog = wrapper.tagName === 'DIALOG' ? wrapper : wrapper.querySelector('dialog');
        if (dialog && typeof dialog.showModal === 'function' && !dialog.open) {
          dialog.showModal();
        }
      });
    });

    // Close: any [data-dialog-close] inside a <dialog> closes it
    document.querySelectorAll('[data-dialog-close]').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.preventDefault();
        const dialog = btn.closest('dialog');
        if (dialog && typeof dialog.close === 'function') {
          dialog.close();
        }
      });
    });

    // Backdrop click closes non-alert dialogs (skip <ren-alert-dialog> wrappers)
    document.querySelectorAll('dialog').forEach(dialog => {
      const isAlert = dialog.closest('ren-alert-dialog') || dialog.classList.contains('ren-alert-dialog');
      if (isAlert) return;
      dialog.addEventListener('click', (e) => {
        // Click on the backdrop registers as a click on the <dialog> element itself
        if (e.target === dialog) dialog.close();
      });
    });
  </script>

  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-dropzone.html
type: docs_page
name: ren-dropzone docs
path: docs/components/ren-dropzone.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Dropzone — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .demo-dz { border: 2px dashed var(--color-border); border-radius: var(--radius-md); padding: var(--space-8) var(--space-5); text-align: center; background: var(--color-surface); cursor: pointer; transition: var(--transition-state); }
    .demo-dz:hover, .demo-dz[data-drag] { border-color: var(--color-accent); background: var(--color-accent-subtle); }
    .demo-dz-icon { font-size: var(--text-3xl); color: var(--color-text-muted); margin-bottom: var(--space-2); }
    .demo-dz-title { font-size: var(--text-base); font-weight: var(--weight-semibold); margin: 0 0 var(--space-1); }
    .demo-dz-hint { font-size: var(--text-sm); color: var(--color-text-muted); margin: 0; }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html" aria-current="page">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Dropzone</li></ol></nav>
        <p class="dx-kicker">Composite</p>
        <h1>Dropzone <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">A file-drop area with drag-over feedback, click-to-browse fallback, and multi-file support. Wraps a hidden <code>&lt;input type="file"&gt;</code> so all the platform niceties — file picker, accept filtering, multiple — come along.</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>Dropzone gives users two paths to upload: drag a file in, or click and browse. Both end at the same hidden <code>&lt;input type="file"&gt;</code>. The component adds visual drag-over state, file type / size validation hooks, and a built-in error display. Use it for avatars, document uploads, image galleries — anywhere "drop a file" feels right.</p>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <label class="demo-dz" for="demo-dz-input">
              <input type="file" id="demo-dz-input" hidden>
              <div class="demo-dz-icon">↑</div>
              <p class="demo-dz-title">Drop a file or click to browse</p>
              <p class="demo-dz-hint">PDF, PNG, JPG up to 10 MB</p>
            </label>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-dropzone accept="image/*" max-size="10485760"&gt;
  &lt;input type="file" hidden&gt;
  &lt;div class="ren-dropzone-icon"&gt;↑&lt;/div&gt;
  &lt;p class="ren-dropzone-title"&gt;Drop a file or click to browse&lt;/p&gt;
  &lt;p class="ren-dropzone-hint"&gt;PDF, PNG, JPG up to 10 MB&lt;/p&gt;
&lt;/ren-dropzone&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>
        <table class="dx-api">
          <thead><tr><th>Class</th><th>Effect</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">.ren-dropzone</code></td><td>The drop region. Dashed border, hover / drag-over / accepted / rejected states all via CSS.</td></tr>
            <tr><td><code class="dx-api-name">.ren-dropzone-icon</code></td><td>Optional leading icon (or up-arrow glyph).</td></tr>
            <tr><td><code class="dx-api-name">.ren-dropzone-title</code></td><td>Primary message — "Drop a file or click to browse".</td></tr>
            <tr><td><code class="dx-api-name">.ren-dropzone-hint</code></td><td>Secondary hint — accepted formats, size limit.</td></tr>
            <tr><td><code class="dx-api-name">.ren-dropzone-list</code></td><td>Accepted files render here once dropped / picked.</td></tr>
          </tbody>
        </table>
        <h3>Web Component attributes</h3>
        <table class="dx-api dx-api-cols-4">
          <thead><tr><th>Attribute</th><th>Type</th><th>Default</th><th>Notes</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">accept</code></td><td><span class="dx-api-type">string</span></td><td><span class="dx-api-default">"*"</span></td><td>MIME pattern, mirrors <code>&lt;input accept&gt;</code>. e.g. <code>image/*</code>, <code>.pdf,.docx</code>.</td></tr>
            <tr><td><code class="dx-api-name">multiple</code></td><td><span class="dx-api-type">boolean</span></td><td><span class="dx-api-default">false</span></td><td>Allow multiple files per drop.</td></tr>
            <tr><td><code class="dx-api-name">max-size</code></td><td><span class="dx-api-type">number (bytes)</span></td><td><span class="dx-api-default">—</span></td><td>Reject files larger than this. Component shows an error message.</td></tr>
          </tbody>
        </table>
        <h3>Events</h3>
        <table class="dx-api">
          <thead><tr><th>Event</th><th>Detail</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">ren-files</code></td><td>Files were accepted. <code>{ files: File[] }</code>.</td></tr>
            <tr><td><code class="dx-api-name">ren-reject</code></td><td>Files rejected (wrong type, too big). <code>{ files: File[], reason: string }</code>.</td></tr>
          </tbody>
        </table>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <ul>
          <li>The dropzone is a real <code>&lt;label&gt;</code> wrapping the hidden file input — clicking anywhere opens the file picker, no JS needed.</li>
          <li>Keyboard users can <kbd>Tab</kbd> to the input and press <kbd>Enter</kbd> / <kbd>Space</kbd> to open the file picker.</li>
          <li>Drag-over is visual only; without it, the component is still fully usable.</li>
          <li>Show clear feedback on rejection — wrong type, too big — and announce it with <code>role="alert"</code>.</li>
        </ul>
      </section>

    </main>
  </div>
  <script type="module" src="../../components/composites/ren-dropzone/ren-dropzone.js"></script>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-empty-state.html
type: docs_page
name: ren-empty-state docs
path: docs/components/ren-empty-state.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Empty State — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .demo-empty { text-align: center; padding: var(--space-8) var(--space-5); }
    .demo-empty-icon { color: var(--color-text-muted); margin-bottom: var(--space-3); display: inline-flex; }
    .demo-empty-icon svg { width: 40px; height: 40px; }
    .demo-empty-title { font-size: var(--text-lg); font-weight: var(--weight-semibold); margin: 0 0 var(--space-1); }
    .demo-empty-desc { font-size: var(--text-sm); color: var(--color-text-muted); margin: 0 0 var(--space-4); max-width: 38ch; margin-inline: auto; line-height: 1.55; }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html" aria-current="page">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Empty State</li></ol></nav>
        <p class="dx-kicker">Pattern</p>
        <h1>Empty State <span class="dx-api-badge dx-api-badge-css" title="Works without any JavaScript">CSS-only</span></h1>
        <p class="lede">"Nothing here yet" panels — the first impression a user has of a feature before they've created data. Icon, headline, supporting copy, and one clear next action. Get them right and the empty page becomes onboarding.</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>Use an empty state when a list, table, or section has no content yet. The structure is rigid for a reason — it makes empty pages feel intentional instead of broken: a small illustration, a one-line headline ("No invoices yet"), one short paragraph of context, and a single primary action to get started.</p>
        <div class="dx-callout">
          <p><strong>Empty states are onboarding in disguise.</strong> First-time users land here. Phrase the copy as encouragement, not as an apology — "Create your first project" beats "Sorry, you have no projects".</p>
        </div>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <div class="ren-empty-state demo-empty">
              <div class="demo-empty-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M16.5 9.4 7.55 4.24"/><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/></svg></div>
              <h2 class="demo-empty-title">No projects yet</h2>
              <p class="demo-empty-desc">Projects are how you organize your work. Create one to start inviting collaborators and tracking progress.</p>
              <button class="ren-btn ren-btn-primary">Create your first project</button>
            </div>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-empty-state"&gt;
  &lt;div class="ren-empty-state-icon"&gt;
    &lt;!-- SVG illustration --&gt;
  &lt;/div&gt;
  &lt;h2 class="ren-empty-state-title"&gt;No projects yet&lt;/h2&gt;
  &lt;p class="ren-empty-state-desc"&gt;
    Projects are how you organize your work. Create one to start
    inviting collaborators and tracking progress.
  &lt;/p&gt;
  &lt;button class="ren-btn ren-btn-primary"&gt;Create your first project&lt;/button&gt;
&lt;/div&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>
        <table class="dx-api">
          <thead><tr><th>Class</th><th>Effect</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">.ren-empty-state</code></td><td>The container. Center-aligned, generous vertical padding.</td></tr>
            <tr><td><code class="dx-api-name">.ren-empty-state-icon</code></td><td>The illustration slot. Sized to ~64–80 px square.</td></tr>
            <tr><td><code class="dx-api-name">.ren-empty-state-title</code></td><td>Headline. Use a real heading tag (<code>h2</code> or <code>h3</code>) at the right document level.</td></tr>
            <tr><td><code class="dx-api-name">.ren-empty-state-desc</code></td><td>Supporting copy — one or two lines max. Capped to ~38ch for readability.</td></tr>
            <tr><td><code class="dx-api-name">.ren-empty-state-actions</code></td><td>Optional cluster for one or two action buttons. Right-align primary action when there are two.</td></tr>
          </tbody>
        </table>
        <h3>Variants</h3>
        <ul>
          <li><strong>First run</strong> — the default. "Get started" tone.</li>
          <li><strong>Search returned nothing</strong> — different copy. "No results for 'foo'. Try a different keyword."</li>
          <li><strong>Filtered out</strong> — "All your items are in another tab. Clear filters to see them."</li>
          <li><strong>Permission</strong> — "You don't have access. Ask an admin to invite you."</li>
        </ul>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <ul>
          <li>The illustration is decorative — wrap it in <code>aria-hidden="true"</code> so screen readers skip it.</li>
          <li>The headline is a real <code>&lt;h2&gt;</code> or <code>&lt;h3&gt;</code> at the appropriate document level. Don't use a styled <code>&lt;p&gt;</code>.</li>
          <li>The action button is reachable by Tab. If there's just one action, make it the page's primary CTA.</li>
          <li>Don't replace the empty state with a permanent loading spinner — show a skeleton during load, then the empty state when the response arrives.</li>
        </ul>
        <div class="dx-callout">
          <p><strong>Empty states deserve copy review.</strong> The wording is the entire pattern — bad copy makes a beautifully designed empty state feel hollow. Have someone read it cold and confirm they know what to do next.</p>
        </div>
      </section>

    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-field.html
type: docs_page
name: ren-field docs
path: docs/components/ren-field.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Field — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    /* Page-specific styles — chrome and tables live in shell.css */

    /* Demo block: preview frame + code block, stacked */
    .dx-demo {
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      overflow: hidden;
      margin: var(--space-4) 0;
    }
    .dx-demo-preview {
      background: var(--color-surface-raised);
      padding: var(--space-6) var(--space-5);
    }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }

    /* Variant rows */
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label {
      font-size: var(--text-xs);
      font-weight: var(--weight-semibold);
      text-transform: uppercase;
      letter-spacing: 0.06em;
      color: var(--color-text-muted);
      padding-top: var(--space-3);
    }
    .dx-vrow-items {
      padding: var(--space-4);
      background: var(--color-surface-raised);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      display: flex;
      flex-direction: column;
      gap: var(--space-3);
    }
    @media (max-width: 720px) {
      .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); }
      .dx-vrow-label { padding-top: 0; }
    }

    /* Anatomy */
    .dx-anatomy { margin: var(--space-4) 0; display: grid; gap: var(--space-4); }
    .dx-anatomy-num {
      display: inline-grid; place-items: center;
      width: 22px; height: 22px;
      border-radius: 50%;
      background: var(--color-text); color: var(--color-surface);
      font-size: var(--text-xs); font-weight: var(--weight-bold);
      flex-shrink: 0;
    }
    .dx-anatomy-stage {
      background: var(--color-surface-raised);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      padding: var(--space-6) var(--space-5);
    }
    .dx-anatomy-stage-label {
      font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.06em;
      color: var(--color-text-muted); font-weight: var(--weight-semibold);
      margin: 0 0 var(--space-3);
    }
    .dx-anatomy-parts {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: var(--space-3);
    }
    @media (max-width: 720px) { .dx-anatomy-parts { grid-template-columns: 1fr; } }
    .dx-anatomy-part {
      background: var(--color-surface-raised);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      padding: var(--space-4);
      display: grid;
      gap: var(--space-2);
    }
    .dx-anatomy-part-header { display: flex; align-items: center; gap: var(--space-2); }
    .dx-anatomy-part-name { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--color-text); }
    .dx-anatomy-part-desc { font-size: var(--text-sm); line-height: 1.5; color: var(--color-text-secondary); margin: 0; }
    .dx-anatomy-part-desc code { font-size: 0.85em; }

    /* Custom element fallback display */
    ren-field { display: block; }

    /* Form row helper for the examples section */
    .demo-form-row {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: var(--space-3);
    }
    @media (max-width: 540px) { .demo-form-row { grid-template-columns: 1fr; } }
  </style>
</head>
<body>

  <!-- Top bar (shell.css) -->
  <header class="dx-nav">
    <div class="dx-nav-inner">
      <a href="../index.html" class="dx-brand">
        <span class="dx-brand-mark">R</span>
        <span>RenDS</span>
        <span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span>
      </a>
      <nav class="dx-nav-menu" aria-label="Primary">
        <a href="../index.html">Docs</a>
        <a href="../components.html" aria-current="page">Components</a>
        <a href="../../templates/index.html">Templates</a>
        <a href="../../create/index.html">Theme Builder</a>
      </nav>
      <div class="dx-nav-actions">
        <a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a>
        <a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a>
      </div>
    </div>
  </header>

  <!-- Sidebar + content shell -->
  <div class="dx-shell dx-shell-grid">

    <!-- Persistent sidebar -->
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html" aria-current="page">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <!-- Content -->
    <main class="dx-content">

      <!-- Page header -->
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);">
          <ol>
            <li><a href="../index.html" class="ren-link-plain">Docs</a></li>
            <li><a href="../components.html" class="ren-link-plain">Components</a></li>
            <li aria-current="page">Field</li>
          </ol>
        </nav>
        <p class="dx-kicker">Primitive</p>
        <h1>Field <span class="dx-api-badge dx-api-badge-hybrid" title="Renders without JS; JS adds enhancements">Hybrid</span></h1>
        <p class="lede">The smallest accessible unit of a form: label, input, helper text, error message — wired together. Use the CSS classes directly, or wrap your markup in <code>&lt;ren-field&gt;</code> and let the component generate IDs and ARIA attributes for you.</p>
      </header>

      <!-- ═══════════════════════════════════════════════════════════
           1. OVERVIEW
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>A form field is the building block of every form in your app. RenDS gives you two ways to compose it: write the classes manually if you like full control, or wrap semantic HTML in <code>&lt;ren-field&gt;</code> and the component will fill in the parts that humans regularly forget — generated <code>id</code>s, the <code>for</code> attribute on the label, <code>aria-describedby</code> for the helper text, <code>aria-errormessage</code> for validation messages, and <code>data-required</code> on the label when the input is required.</p>

        <p>The visual styling lives entirely in CSS. The Web Component is a thin layer of accessibility wiring on top — your form still works without it, just with fewer ARIA hooks.</p>

        <div class="dx-callout">
          <p><strong>Use one field per question.</strong> A field bundles a label and one input. Don't reuse the wrapper to group several inputs — for that, use a <code>fieldset</code> with a <code>legend</code> instead.</p>
        </div>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           2. ANATOMY
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="anatomy">
        <p class="dx-kicker">Parts</p>
        <h2>Anatomy</h2>
        <p>A complete field has four content parts plus the container. Description and error are optional.</p>

        <div class="dx-anatomy">
          <div class="dx-anatomy-stage">
            <p class="dx-anatomy-stage-label">Assembled</p>
            <div class="ren-field" style="max-width: 360px; margin-inline: auto;">
              <label class="ren-field-label" data-required for="anatomy-email">Work email</label>
              <input class="ren-input" type="email" id="anatomy-email" placeholder="name@example.com" aria-describedby="anatomy-email-desc">
              <span class="ren-field-description" id="anatomy-email-desc">We'll send the verification link here.</span>
            </div>
          </div>

          <div class="dx-anatomy-parts">
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header">
                <span class="dx-anatomy-num">1</span>
                <span class="dx-anatomy-part-name">Container</span>
              </div>
              <p class="dx-anatomy-part-desc"><code>.ren-field</code> wrapper. Stacks the parts vertically with a small gap. Use <code>&lt;ren-field&gt;</code> if you want auto-wiring.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header">
                <span class="dx-anatomy-num">2</span>
                <span class="dx-anatomy-part-name">Label</span>
              </div>
              <p class="dx-anatomy-part-desc"><code>&lt;label class="ren-field-label"&gt;</code>. Always paired to its input via <code>for</code>. Add <code>data-required</code> for the asterisk.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header">
                <span class="dx-anatomy-num">3</span>
                <span class="dx-anatomy-part-name">Control</span>
              </div>
              <p class="dx-anatomy-part-desc"><code>&lt;input class="ren-input"&gt;</code> — or <code>&lt;textarea&gt;</code> / <code>&lt;select&gt;</code> with the same class. The control owns its native validation.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header">
                <span class="dx-anatomy-num">4</span>
                <span class="dx-anatomy-part-name">Description</span>
              </div>
              <p class="dx-anatomy-part-desc"><code>.ren-field-description</code>. Helper text under the input. Linked to the input via <code>aria-describedby</code>.</p>
            </div>
            <div class="dx-anatomy-part">
              <div class="dx-anatomy-part-header">
                <span class="dx-anatomy-num">5</span>
                <span class="dx-anatomy-part-name">Error</span>
              </div>
              <p class="dx-anatomy-part-desc"><code>.ren-field-error</code> with <code>role="alert"</code>. Hidden until the field is invalid. Replaces / supplements the description on error.</p>
            </div>
          </div>
        </div>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           3. DEMO
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <p>Type something invalid and the error appears. Click the field to focus and the focus ring follows the accent color.</p>

        <div class="dx-demo">
          <div class="dx-demo-preview">
            <div class="ren-field" style="max-width: 380px; margin-inline: auto;">
              <label class="ren-field-label" for="demo-email">Email address</label>
              <input class="ren-input" type="email" id="demo-email" placeholder="name@example.com" aria-describedby="demo-email-desc">
              <span class="ren-field-description" id="demo-email-desc">We'll never share your email with anyone.</span>
            </div>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-field&gt;
  &lt;label&gt;Email address&lt;/label&gt;
  &lt;input type="email" placeholder="name@example.com"&gt;
  &lt;span data-description&gt;We'll never share your email with anyone.&lt;/span&gt;
&lt;/ren-field&gt;</code></pre>
        </div>

        <p>Same field written without the Web Component — explicit classes, manual <code>for</code> and <code>aria-describedby</code> wiring:</p>
        <div class="dx-pre" tabindex="0"><code>&lt;div class="ren-field"&gt;
  &lt;label class="ren-field-label" for="email"&gt;Email address&lt;/label&gt;
  &lt;input class="ren-input" type="email" id="email"
         placeholder="name@example.com"
         aria-describedby="email-desc"&gt;
  &lt;span class="ren-field-description" id="email-desc"&gt;
    We'll never share your email with anyone.
  &lt;/span&gt;
&lt;/div&gt;</code></pre>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           4. VARIANTS
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="variants">
        <p class="dx-kicker">Shapes</p>
        <h2>Variants</h2>
        <p>The same field structure adapts to different control types and visual densities.</p>

        <div class="dx-vgrid">

          <div class="dx-vrow">
            <span class="dx-vrow-label">Sizes</span>
            <div class="dx-vrow-items">
              <div class="ren-field">
                <label class="ren-field-label" for="size-sm">Small</label>
                <input class="ren-input ren-input-sm" id="size-sm" placeholder="ren-input-sm">
              </div>
              <div class="ren-field">
                <label class="ren-field-label" for="size-md">Medium (default)</label>
                <input class="ren-input" id="size-md" placeholder="ren-input">
              </div>
              <div class="ren-field">
                <label class="ren-field-label" for="size-lg">Large</label>
                <input class="ren-input ren-input-lg" id="size-lg" placeholder="ren-input-lg">
              </div>
            </div>
          </div>

          <div class="dx-vrow">
            <span class="dx-vrow-label">States</span>
            <div class="dx-vrow-items">
              <div class="ren-field">
                <label class="ren-field-label" for="state-default">Default</label>
                <input class="ren-input" id="state-default" placeholder="Type here">
              </div>
              <div class="ren-field">
                <label class="ren-field-label" for="state-disabled">Disabled</label>
                <input class="ren-input" id="state-disabled" placeholder="Disabled" disabled>
              </div>
              <div class="ren-field" data-invalid>
                <label class="ren-field-label" for="state-invalid">Invalid</label>
                <input class="ren-input" id="state-invalid" value="not-an-email" aria-invalid="true" aria-errormessage="state-invalid-err">
                <span class="ren-field-error" role="alert" id="state-invalid-err">Please enter a valid email address.</span>
              </div>
            </div>
          </div>

          <div class="dx-vrow">
            <span class="dx-vrow-label">Required</span>
            <div class="dx-vrow-items">
              <div class="ren-field">
                <label class="ren-field-label" data-required for="req-name">Full name</label>
                <input class="ren-input" id="req-name" required placeholder="Required field">
                <span class="ren-field-description">Marked with an asterisk via <code>data-required</code> on the label.</span>
              </div>
            </div>
          </div>

          <div class="dx-vrow">
            <span class="dx-vrow-label">With icon</span>
            <div class="dx-vrow-items">
              <div class="ren-field">
                <label class="ren-field-label" for="icon-search">Search</label>
                <div class="ren-input-wrapper">
                  <span class="ren-input-icon" aria-hidden="true">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
                  </span>
                  <input class="ren-input" type="search" id="icon-search" placeholder="Search projects…">
                </div>
              </div>
              <div class="ren-field">
                <label class="ren-field-label" for="icon-money">Amount</label>
                <div class="ren-input-wrapper">
                  <input class="ren-input" type="number" id="icon-money" placeholder="0.00">
                  <span class="ren-input-icon ren-input-icon-end" aria-hidden="true" style="font-size: var(--text-sm); color: var(--color-text-muted);">USD</span>
                </div>
              </div>
            </div>
          </div>

          <div class="dx-vrow">
            <span class="dx-vrow-label">Textarea</span>
            <div class="dx-vrow-items">
              <div class="ren-field">
                <label class="ren-field-label" for="multi-msg">Message</label>
                <textarea class="ren-input" id="multi-msg" rows="4" placeholder="Tell us what's on your mind…"></textarea>
                <span class="ren-field-description">Same <code>.ren-input</code> class works on <code>&lt;textarea&gt;</code>.</span>
              </div>
            </div>
          </div>

          <div class="dx-vrow">
            <span class="dx-vrow-label">Select</span>
            <div class="dx-vrow-items">
              <div class="ren-field">
                <label class="ren-field-label" for="multi-country">Country</label>
                <select class="ren-input" id="multi-country">
                  <option>Argentina</option>
                  <option>Chile</option>
                  <option>Mexico</option>
                  <option>United States</option>
                </select>
                <span class="ren-field-description">Native <code>&lt;select&gt;</code> with the same class. For a custom-styled dropdown, use <code>ren-select</code>.</span>
              </div>
            </div>
          </div>

        </div>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           5. API
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>

        <h3>CSS classes</h3>
        <p>Apply directly if you don't use the Web Component. The visual styling is identical either way.</p>
        <table class="dx-api">
          <thead>
            <tr>
              <th>Class</th>
              <th>Effect</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code class="dx-api-name">.ren-field</code></td>
              <td>Container. Vertical flex stack with a small gap between label, control, and description / error.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-field-label</code></td>
              <td>Label styling. Use on the actual <code>&lt;label&gt;</code> tag so the click-to-focus behavior works natively.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-field-label[data-required]</code></td>
              <td>Adds a red asterisk after the label text via <code>::after</code>. Set automatically when the input has <code>required</code>.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-input</code></td>
              <td>Base input style. Works on <code>&lt;input&gt;</code>, <code>&lt;textarea&gt;</code>, and <code>&lt;select&gt;</code>. 44 px touch target, focus ring, hover, disabled.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-input-sm</code> / <code class="dx-api-name">.ren-input-lg</code></td>
              <td>Size modifiers. Default (no modifier) is medium (44 px). Small is denser; large is more prominent.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-input-wrapper</code></td>
              <td>Use to nest an icon (or any decoration) alongside the input. Acts as a relative container.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-input-icon</code> / <code class="dx-api-name">.ren-input-icon-end</code></td>
              <td>Place an icon before (default) or after (<code>-end</code>) the input. The input is automatically padded so the icon doesn't overlap text.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-field-description</code></td>
              <td>Helper text. Muted color, smaller font. Should be linked to the input via <code>aria-describedby</code>.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-field-error</code></td>
              <td>Error message. Danger color. Hidden by default; shown when the field has <code>data-invalid</code>.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-field[data-invalid]</code></td>
              <td>Invalid container state. Recolors the input border and shows the error region.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">.ren-input-error</code></td>
              <td>Apply on the input directly to force the invalid look without using <code>data-invalid</code> on the wrapper.</td>
            </tr>
          </tbody>
        </table>

        <h3>Web Component attributes</h3>
        <p>Set on the <code>&lt;ren-field&gt;</code> wrapper. The component watches them and re-syncs ARIA state when changed.</p>
        <table class="dx-api dx-api-cols-4">
          <thead>
            <tr>
              <th>Attribute</th>
              <th>Type</th>
              <th>Default</th>
              <th>Notes</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code class="dx-api-name">data-invalid</code></td>
              <td><span class="dx-api-type">boolean</span></td>
              <td><span class="dx-api-default">false</span></td>
              <td>Presence shows the error region and sets <code>aria-invalid="true"</code> on the input. Removed automatically when the input becomes valid again on <code>input</code>.</td>
            </tr>
          </tbody>
        </table>

        <h3>Auto-wiring (the value prop)</h3>
        <p>What <code>&lt;ren-field&gt;</code> sets automatically when it mounts. You can write the simplest possible HTML — semantic tags, no IDs — and the component fills in the rest.</p>
        <table class="dx-api">
          <thead>
            <tr>
              <th>Wired up</th>
              <th>How</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Label ↔ Input</td>
              <td>Input gets a generated <code>id</code>; label gets a matching <code>for</code> attribute.</td>
            </tr>
            <tr>
              <td>Description ↔ Input</td>
              <td>Description gets a generated <code>id</code>; input's <code>aria-describedby</code> is appended (existing values preserved).</td>
            </tr>
            <tr>
              <td>Error ↔ Input</td>
              <td>Error gets a generated <code>id</code>; input's <code>aria-errormessage</code> is set. Error gets <code>role="alert"</code> + <code>aria-live="polite"</code>.</td>
            </tr>
            <tr>
              <td>Required indicator</td>
              <td>If the input has <code>required</code>, the label gets <code>data-required</code> (renders the asterisk).</td>
            </tr>
            <tr>
              <td>Validation listener</td>
              <td>Listens for native <code>invalid</code> events; sets <code>data-invalid</code> on the field and reveals the error message. Clears on next valid <code>input</code>.</td>
            </tr>
          </tbody>
        </table>

        <h3>JavaScript methods</h3>
        <p>Available on every <code>&lt;ren-field&gt;</code> instance.</p>
        <table class="dx-api">
          <thead>
            <tr>
              <th>Method</th>
              <th>Description</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code class="dx-api-name">setError(message)</code></td>
              <td>Marks the field invalid and writes the error message into the error region. Use for server-side validation results.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">clearError()</code></td>
              <td>Removes the invalid state and hides the error region.</td>
            </tr>
            <tr>
              <td><code class="dx-api-name">invalid</code></td>
              <td>Boolean getter / setter. Reads the current invalid state, or assigns one (same as <code>setError</code> / <code>clearError</code>).</td>
            </tr>
          </tbody>
        </table>

        <div class="dx-pre" tabindex="0"><code>const field = document.querySelector('ren-field');

// After a server response
if (response.error) {
  field.setError('That email is already taken.');
} else {
  field.clearError();
}</code></div>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           6. ACCESSIBILITY
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <p>Form accessibility lives in three relationships: label-to-input, description-to-input, and error-to-input. The Web Component wires all three. If you're using the CSS classes alone, you set them by hand — this section is your checklist.</p>

        <h3>Keyboard</h3>
        <div class="dx-keys">
          <div class="dx-keyrow">
            <span class="keys"><kbd>Tab</kbd></span>
            <span>Moves focus into the input. Disabled inputs are skipped.</span>
          </div>
          <div class="dx-keyrow">
            <span class="keys"><kbd>Shift</kbd> + <kbd>Tab</kbd></span>
            <span>Moves focus backward.</span>
          </div>
          <div class="dx-keyrow">
            <span class="keys">Click on the label</span>
            <span>Focuses the paired input — only works when the label has a <code>for</code> attribute matching the input's <code>id</code> (or wraps the input directly).</span>
          </div>
        </div>

        <h3>What the component sets</h3>
        <p>When you wrap your markup in <code>&lt;ren-field&gt;</code>, the following ARIA wiring is automatic:</p>
        <ul>
          <li><code>label[for]</code> ↔ <code>input[id]</code></li>
          <li><code>aria-describedby</code> on the input pointing at the description</li>
          <li><code>aria-errormessage</code> on the input pointing at the error</li>
          <li><code>aria-invalid="true"</code> when the field is in an invalid state</li>
          <li><code>role="alert"</code> and <code>aria-live="polite"</code> on the error so screen readers announce it</li>
        </ul>

        <h3>Validation messaging</h3>
        <p>Two paths, both supported:</p>
        <ul>
          <li><strong>Native HTML5</strong>: add <code>required</code>, <code>type="email"</code>, <code>pattern</code>, etc. to the input. The browser's <code>invalid</code> event flips the field into the invalid state automatically.</li>
          <li><strong>Programmatic</strong>: call <code>field.setError("custom message")</code> after a server response. The same DOM hooks render the same way.</li>
        </ul>

        <div class="dx-callout">
          <p><strong>Always pair the label.</strong> A bare input with a placeholder is not a labelled input. Screen readers announce nothing meaningful. Even a visually hidden label (<code>.ren-sr-only</code>) is better than no label.</p>
        </div>

        <h3>Don't trap focus inside the field</h3>
        <p>The field is just a wrapper. Tab and Shift+Tab move out of it normally. Don't add <code>tabindex</code> to the wrapper — focus belongs on the input itself.</p>
      </section>

      <!-- ═══════════════════════════════════════════════════════════
           7. EXAMPLES
           ═══════════════════════════════════════════════════════════ -->
      <section class="dx-section" id="examples">
        <p class="dx-kicker">Patterns</p>
        <h2>Examples</h2>

        <h3>Login form</h3>
        <p>Two required fields, primary submit. Native HTML5 validation handles the empty state.</p>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <form style="max-width: 360px; margin-inline: auto; display: flex; flex-direction: column; gap: var(--space-4);">
              <div class="ren-field">
                <label class="ren-field-label" data-required for="login-email">Email</label>
                <input class="ren-input" type="email" id="login-email" required autocomplete="email">
              </div>
              <div class="ren-field">
                <label class="ren-field-label" data-required for="login-password">Password</label>
                <input class="ren-input" type="password" id="login-password" required autocomplete="current-password">
              </div>
              <button type="submit" class="ren-btn ren-btn-primary">Sign in</button>
            </form>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;form&gt;
  &lt;ren-field&gt;
    &lt;label&gt;Email&lt;/label&gt;
    &lt;input type="email" required autocomplete="email"&gt;
  &lt;/ren-field&gt;

  &lt;ren-field&gt;
    &lt;label&gt;Password&lt;/label&gt;
    &lt;input type="password" required autocomplete="current-password"&gt;
  &lt;/ren-field&gt;

  &lt;button type="submit" class="ren-btn ren-btn-primary"&gt;Sign in&lt;/button&gt;
&lt;/form&gt;</code></pre>
        </div>

        <h3>Server-side error</h3>
        <p>Submit, get an error from the API, attach it to the right field.</p>
        <div class="dx-pre" tabindex="0"><code>const form = document.querySelector('form');
const emailField = form.querySelector('ren-field:has(input[type="email"])');

form.addEventListener('submit', async (e) =&gt; {
  e.preventDefault();
  emailField.clearError();

  const res = await fetch('/api/signup', { method: 'POST', body: new FormData(form) });
  const data = await res.json();

  if (data.error?.field === 'email') {
    emailField.setError(data.error.message);
    emailField.querySelector('input').focus();
    return;
  }

  location.assign('/dashboard');
});</code></pre>

        <h3>Search box with icon</h3>
        <p>Wrap the input in <code>.ren-input-wrapper</code> with an icon for a leading affordance.</p>
        <div class="dx-pre" tabindex="0"><code>&lt;ren-field&gt;
  &lt;label class="ren-sr-only"&gt;Search&lt;/label&gt;
  &lt;div class="ren-input-wrapper"&gt;
    &lt;span class="ren-input-icon" aria-hidden="true"&gt;
      &lt;!-- search SVG --&gt;
    &lt;/span&gt;
    &lt;input type="search" placeholder="Search projects…"&gt;
  &lt;/div&gt;
&lt;/ren-field&gt;</code></pre>

        <h3>Two fields side by side</h3>
        <p>The field is a normal block. Drop them into any layout primitive — here, a 2-column grid.</p>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <div class="demo-form-row">
              <div class="ren-field">
                <label class="ren-field-label" for="row-first">First name</label>
                <input class="ren-input" id="row-first" autocomplete="given-name">
              </div>
              <div class="ren-field">
                <label class="ren-field-label" for="row-last">Last name</label>
                <input class="ren-input" id="row-last" autocomplete="family-name">
              </div>
            </div>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;div class="ren-grid-2"&gt;
  &lt;ren-field&gt;
    &lt;label&gt;First name&lt;/label&gt;
    &lt;input autocomplete="given-name"&gt;
  &lt;/ren-field&gt;

  &lt;ren-field&gt;
    &lt;label&gt;Last name&lt;/label&gt;
    &lt;input autocomplete="family-name"&gt;
  &lt;/ren-field&gt;
&lt;/div&gt;</code></pre>
        </div>
      </section>

    </main>

  </div>

  <!-- Web Component registration — adds auto-wiring on top of the CSS-only baseline -->
  <script type="module" src="../../components/primitives/ren-field/ren-field.js"></script>

  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-form.html
type: docs_page
name: ren-form docs
path: docs/components/ren-form.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Form Validation — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html" aria-current="page">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Form Validation</li></ol></nav>
        <p class="dx-kicker">Pattern</p>
        <h1>Form Validation <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">Conventions for inline error messages, summary banners, and submit-button state. Browser-native HTML5 validation does most of the work; this pattern documents how to wire the rest.</p>
      </header>
      <section class="dx-section" id="overview"><p class="dx-kicker">About</p><h2>Overview</h2><p>Form validation is a pattern, not a component — it's how Field, Banner, Button and Toast cooperate when a form is wrong or submitted. Use HTML5 attributes (<code>required</code>, <code>type</code>, <code>pattern</code>, <code>min</code>, <code>max</code>) for client-side; show server-side errors via <code>setError()</code> on each Field.</p></section>
      <section class="dx-section" id="demo"><p class="dx-kicker">Live</p><h2>Demo</h2><div class="dx-demo"><div class="dx-demo-preview" style="flex-direction: column; align-items: stretch; max-width: 420px; margin-inline: auto; gap: var(--space-3);"><div class="ren-banner ren-banner-danger" role="alert"><span class="ren-banner-icon"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></span><div class="ren-banner-content"><p class="ren-banner-title">2 fields need your attention</p></div></div><div class="ren-field" data-invalid><label class="ren-field-label" for="vd-email">Email</label><input class="ren-input" id="vd-email" value="not-an-email" aria-invalid="true"><span class="ren-field-error" role="alert">Please enter a valid email address.</span></div><div class="ren-field"><label class="ren-field-label" data-required for="vd-pw">Password</label><input class="ren-input" id="vd-pw" type="password" required></div></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;form novalidate&gt;
  &lt;ren-field&gt;
    &lt;label&gt;Email&lt;/label&gt;
    &lt;input type="email" required&gt;
  &lt;/ren-field&gt;

  &lt;button type="submit"&gt;Save&lt;/button&gt;
&lt;/form&gt;</code></pre></div></section>
      <section class="dx-section" id="api"><p class="dx-kicker">Patterns</p><h2>Pieces</h2><ul><li><strong>HTML5 attributes</strong>: <code>required</code>, <code>type="email"</code>, <code>pattern</code>, <code>min</code>, <code>max</code>, <code>minlength</code>, <code>maxlength</code>.</li><li><strong>Per-field errors</strong>: <a href="ren-field.html" class="ren-link">Form Field</a> shows <code>aria-invalid</code> + the error message.</li><li><strong>Form-level summary</strong>: a <a href="ren-banner.html" class="ren-link">Banner</a> at the top with the count of errors and links to each one (skip-to-error pattern).</li><li><strong>Server-side errors</strong>: after a failed submit, call <code>field.setError(message)</code> for each invalid field.</li><li><strong>Submit button state</strong>: <code>data-loading</code> while submitting; disabled until the form has any input on touch (don't disable proactively before the user types — it's confusing).</li></ul></section>
      <section class="dx-section" id="multi-step"><p class="dx-kicker">Variant</p><h2>Multi-step forms</h2><p>Use a multi-step form when a single page would feel overwhelming or when steps depend on previous answers. <code>ren-form</code> supports multi-step via the <code>data-steps</code> attribute on the host and a <code>.ren-stepper</code> progress indicator.</p><div class="dx-demo"><div class="dx-demo-preview" style="flex-direction: column; align-items: stretch;"><ol class="ren-stepper" style="display: flex; gap: var(--space-3); list-style: none; padding: 0; margin: 0 0 var(--space-4); justify-content: space-between;"><li style="display: flex; align-items: center; gap: var(--space-2);"><span style="width: 24px; height: 24px; border-radius: 50%; background: var(--color-success); color: var(--color-on-success); display: grid; place-items: center; font-size: var(--text-xs); font-weight: var(--weight-bold);"><svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg></span><span style="font-size: var(--text-sm); color: var(--color-text-muted);">Account</span></li><li style="display: flex; align-items: center; gap: var(--space-2);"><span style="width: 24px; height: 24px; border-radius: 50%; background: var(--color-accent); color: var(--color-on-accent); display: grid; place-items: center; font-size: var(--text-xs); font-weight: var(--weight-bold);">2</span><span style="font-size: var(--text-sm); font-weight: var(--weight-semibold);">Profile</span></li><li style="display: flex; align-items: center; gap: var(--space-2);"><span style="width: 24px; height: 24px; border-radius: 50%; background: var(--color-fill); color: var(--color-text-muted); display: grid; place-items: center; font-size: var(--text-xs); font-weight: var(--weight-bold);">3</span><span style="font-size: var(--text-sm); color: var(--color-text-muted);">Plan</span></li></ol><p style="font-size: var(--text-sm); color: var(--color-text-muted); margin: 0;">Step 2 of 3 — current step content goes here.</p></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-form data-steps="3"&gt;
  &lt;ol class="ren-stepper" aria-label="Setup progress"&gt;
    &lt;li data-completed&gt;Account&lt;/li&gt;
    &lt;li aria-current="step"&gt;Profile&lt;/li&gt;
    &lt;li&gt;Plan&lt;/li&gt;
  &lt;/ol&gt;
  &lt;fieldset data-step="1"&gt;…&lt;/fieldset&gt;
  &lt;fieldset data-step="2" data-active&gt;…&lt;/fieldset&gt;
  &lt;fieldset data-step="3"&gt;…&lt;/fieldset&gt;
&lt;/ren-form&gt;</code></pre></div><h3>Stepper API</h3><table class="dx-api"><thead><tr><th>Class / attribute</th><th>Effect</th></tr></thead><tbody><tr><td><code class="dx-api-name">.ren-stepper</code></td><td>The progress indicator. Numbered ol with completed / current / pending states.</td></tr><tr><td><code class="dx-api-name">[aria-current="step"]</code></td><td>Marks the active step.</td></tr><tr><td><code class="dx-api-name">[data-completed]</code></td><td>Marks a past step (checkmark fill).</td></tr><tr><td><code class="dx-api-name">[data-steps="N"]</code> on host</td><td>Declares the total number of steps.</td></tr><tr><td><code class="dx-api-name">[data-active]</code> on fieldset</td><td>Marks the currently visible step; others are hidden.</td></tr></tbody></table><h3>Pattern checklist</h3><ul><li>Validate the current step before <kbd>Next</kbd> advances.</li><li>Allow free <kbd>Back</kbd> navigation — don't lose prior data.</li><li>Save progress to <code>localStorage</code> or the server so the user can leave and resume.</li><li>Last step is "Review" — show all entered data before final submit.</li><li>Autofocus the first input on each step change.</li><li>Announce progress via a polite live region: "Step 2 of 3."</li></ul><div class="dx-callout"><p><strong>Status of <code>.ren-stepper</code>:</strong> the stepper is an internal CSS pattern of <code>ren-form</code>, not a standalone component. There is no <code>ren-stepper</code> primitive, Web Component, or separate JS — it's a styled <code>&lt;ol&gt;</code> that consumer code drives. If you need a reusable Stepper outside a multi-step form (e.g. an onboarding tour, or a wizard not tied to a single form), open an issue — it's on the backlog.</p></div></section>
      <section class="dx-section" id="a11y"><p class="dx-kicker">Inclusive by default</p><h2>Accessibility</h2><ul><li>Use <code>novalidate</code> on the form so you control validation timing instead of letting the browser show its own popup before submission.</li><li>Validate on <strong>blur</strong> (not on every keystroke) for first-time entry; revalidate on input after the field has been marked invalid once.</li><li>Move focus to the first invalid field after a failed submit.</li><li>Summary banner uses <code>role="alert"</code> so screen readers announce the error count immediately.</li><li>For multi-step flows: each step is its own <code>&lt;fieldset&gt;</code> with its own focus management; the stepper uses <code>aria-current="step"</code> on the active item.</li></ul></section>
    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-hover-card.html
type: docs_page
name: ren-hover-card docs
path: docs/components/ren-hover-card.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hover Card — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: visible; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-8) var(--space-5); display: flex; gap: var(--space-3); align-items: center; justify-content: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html" aria-current="page">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Hover Card</li></ol></nav>
        <p class="dx-kicker">Composite</p>
        <h1>Hover Card <span class="dx-api-badge dx-api-badge-js" title="JavaScript is required for interaction">Requires JS</span></h1>
        <p class="lede">A rich preview that appears when the user hovers over a link or avatar. Think Twitter / GitHub profile cards on hover. Larger and more leisurely than a Tooltip; doesn't trap focus like a Popover.</p>
      </header>

      <section class="dx-section" id="overview">
        <p class="dx-kicker">About</p>
        <h2>Overview</h2>
        <p>Hover cards show a peek of related content without forcing the user to navigate. Use them on user mentions, tags, internal links — anywhere a quick preview helps. They're voluntary previews, not modals; they shouldn't carry actions the user has to take.</p>
        <div class="dx-callout">
          <p><strong>Tooltip vs Hover Card.</strong> Tooltip is text-only and small (a label, a shortcut). Hover Card is rich content with images and structure, sized like a small popover.</p>
        </div>
      </section>

      <section class="dx-section" id="demo">
        <p class="dx-kicker">Live</p>
        <h2>Demo</h2>
        <p>The component activates after a 700 ms hover delay (longer than Tooltip's 300 ms — gives the user a beat to keep moving past the trigger if they don't actually want the preview).</p>
        <div class="dx-demo">
          <div class="dx-demo-preview">
            <p style="font-size: var(--text-sm); margin: 0;">Hover the link to see the user preview: <a href="#" class="ren-link" data-hover="@ren">@ren</a> shipped this design system.</p>
          </div>
          <pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;ren-hover-card&gt;
  &lt;a slot="trigger" href="/users/ren"&gt;@ren&lt;/a&gt;
  &lt;div slot="content"&gt;
    &lt;img src="/avatars/ren.jpg" class="ren-avatar"&gt;
    &lt;h3&gt;Ren Soconese&lt;/h3&gt;
    &lt;p&gt;Designer · Buenos Aires&lt;/p&gt;
    &lt;p class="muted"&gt;Joined March 2024 · 142 projects&lt;/p&gt;
  &lt;/div&gt;
&lt;/ren-hover-card&gt;</code></pre>
        </div>
      </section>

      <section class="dx-section" id="api">
        <p class="dx-kicker">Reference</p>
        <h2>API</h2>
        <table class="dx-api">
          <thead><tr><th>Class</th><th>Effect</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">.ren-hover-card</code></td><td>The floating panel. Card-like surface with shadow and padding.</td></tr>
          </tbody>
        </table>
        <h3>Web Component attributes</h3>
        <table class="dx-api dx-api-cols-4">
          <thead><tr><th>Attribute</th><th>Type</th><th>Default</th><th>Notes</th></tr></thead>
          <tbody>
            <tr><td><code class="dx-api-name">delay</code></td><td><span class="dx-api-type">number (ms)</span></td><td><span class="dx-api-default">700</span></td><td>Hover dwell before showing.</td></tr>
            <tr><td><code class="dx-api-name">close-delay</code></td><td><span class="dx-api-type">number (ms)</span></td><td><span class="dx-api-default">300</span></td><td>Time after the cursor leaves both trigger and card before closing — gives the user a moment to move into the card.</td></tr>
            <tr><td><code class="dx-api-name">placement</code></td><td><span class="dx-api-type">"top" | "right" | "bottom" | "left"</span></td><td><span class="dx-api-default">"bottom"</span></td><td>Side relative to the trigger.</td></tr>
          </tbody>
        </table>
      </section>

      <section class="dx-section" id="a11y">
        <p class="dx-kicker">Inclusive by default</p>
        <h2>Accessibility</h2>
        <ul>
          <li>Trigger must be a real link or button. Focusing it via Tab also opens the card (not just hover).</li>
          <li>Card content is supplementary — never put critical information here. Touch users won't see it.</li>
          <li>If the card contains links or actions, those should ALSO live somewhere reachable — on the linked profile page, in a menu.</li>
          <li><kbd>Esc</kbd> closes the card while focus stays on the trigger.</li>
        </ul>
      </section>

    </main>
  </div>
  <script type="module" src="../../components/composites/ren-hover-card/ren-hover-card.js"></script>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-icon.html
type: docs_page
name: ren-icon docs
path: docs/components/ren-icon.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Icons — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); padding-top: var(--space-3); }
    .dx-vrow-items { padding: var(--space-3); background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    @media (max-width: 720px) { .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); } .dx-vrow-label { padding-top: 0; } }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html">Keyboard Key</a></li>
        <li><a href="ren-icon.html" aria-current="page">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Icons</li></ol></nav>
        <p class="dx-kicker">Primitive</p>
        <h1>Icons <span class="dx-api-badge dx-api-badge-css" title="Works without any JavaScript">CSS-only</span></h1>
        <p class="lede">Conventions for SVG icons in RenDS. 16 / 20 / 24 px sizing, currentColor stroke, semantic alt or <code>aria-hidden</code> based on whether the icon carries meaning on its own.</p>
      </header>
      <section class="dx-section" id="overview"><p class="dx-kicker">About</p><h2>Overview</h2><p>RenDS doesn't ship an icon set. Bring your own (Lucide, Heroicons, Iconoir, custom) and follow the conventions below so they look consistent and stay accessible.</p></section>
      <section class="dx-section" id="demo"><p class="dx-kicker">Live</p><h2>Demo</h2><div class="dx-demo"><div class="dx-demo-preview"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 8v4M12 16h.01"/></svg><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M12 5l7 7-7 7"/></svg><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6L9 17l-5-5"/></svg></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>&lt;svg width="20" height="20" viewBox="0 0 24 24" fill="none"
     stroke="currentColor" stroke-width="2"
     aria-hidden="true"&gt;
  &lt;path d="..."/&gt;
&lt;/svg&gt;</code></pre></div></section>
      <section class="dx-section" id="api"><p class="dx-kicker">Reference</p><h2>API</h2><h3>Sizing convention</h3><table class="dx-api"><thead><tr><th>Use case</th><th>Size</th></tr></thead><tbody><tr><td>Inline with text (next to a label)</td><td>16 px</td></tr><tr><td>Standard (buttons, menus, tabs)</td><td>20 px</td></tr><tr><td>Large (empty states, headers)</td><td>24 px</td></tr></tbody></table><h3>Color</h3><p>Set <code>stroke="currentColor"</code> (or <code>fill="currentColor"</code> for filled icons) so the icon inherits the surrounding text color. Don't hardcode colors on icons.</p></section>
      <section class="dx-section" id="a11y"><p class="dx-kicker">Inclusive by default</p><h2>Accessibility</h2><ul><li><strong>Decorative icon next to text</strong>: add <code>aria-hidden="true"</code>. The text already labels the action.</li><li><strong>Icon-only button</strong>: the button needs <code>aria-label="Action name"</code>. The icon stays <code>aria-hidden</code>.</li><li><strong>Icon as the entire link/button identity</strong> (rare): the SVG can have <code>role="img" aria-label="…"</code>.</li></ul></section>
    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


id: docs:docs/components/ren-kbd.html
type: docs_page
name: ren-kbd docs
path: docs/components/ren-kbd.html
data: {}
body:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Keyboard Key — RenDS Components</title>
  <link rel="stylesheet" href="../../index.css">
  <link rel="stylesheet" href="../../components/index.css">
  <link rel="stylesheet" href="../../themes/appearance.css">
  <link rel="stylesheet" href="../../tokens/component/tokens.css">
  <link rel="stylesheet" href="../../site/shell.css">
  <style>
    .dx-demo { border: 1px solid var(--color-border); border-radius: var(--radius-md); overflow: hidden; margin: var(--space-4) 0; }
    .dx-demo-preview { background: var(--color-surface-raised); padding: var(--space-6) var(--space-5); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    .dx-demo-code { margin: 0; border-radius: 0; border: none; border-top: 1px solid var(--color-border); }
    .dx-vgrid { display: grid; gap: var(--space-6); margin: var(--space-4) 0; }
    .dx-vrow { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-4); align-items: start; }
    .dx-vrow-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); padding-top: var(--space-3); }
    .dx-vrow-items { padding: var(--space-3); background: var(--color-surface-raised); border: 1px solid var(--color-border); border-radius: var(--radius-md); display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    @media (max-width: 720px) { .dx-vrow { grid-template-columns: 1fr; gap: var(--space-2); } .dx-vrow-label { padding-top: 0; } }
  </style>
</head>
<body>
  <header class="dx-nav"><div class="dx-nav-inner"><a href="../index.html" class="dx-brand"><span class="dx-brand-mark">R</span><span>RenDS</span><span class="ren-badge ren-badge-secondary" style="margin-left: var(--space-1);">v0.12.0</span></a><nav class="dx-nav-menu" aria-label="Primary"><a href="../index.html">Docs</a><a href="../components.html" aria-current="page">Components</a><a href="../../templates/index.html">Templates</a><a href="../../create/index.html">Theme Builder</a></nav><div class="dx-nav-actions"><a href="https://github.com/Rensoconese/ren10" class="ren-btn ren-btn-ghost ren-btn-sm">GitHub</a><a href="../getting-started.html" class="ren-btn ren-btn-primary ren-btn-sm">Get started</a></div></div></header>

  <div class="dx-shell dx-shell-grid">
    <aside class="dx-sidebar" aria-label="Site navigation">
      <h3>Guides</h3>
      <ul>
        <li><a href="../getting-started.html">Getting Started</a></li>
        <li><a href="../theming.html">Theming</a></li>
        <li><a href="../accessibility.html">Accessibility</a></li>
        <li><a href="../cli.html">CLI</a></li>
      </ul>

      <h3>Foundations</h3>
      <ul>
        <li><a href="../primitive-zero.html">Primitive Zero</a></li>
        <li><a href="../tokens.html">Tokens</a></li>
        <li><a href="../layouts.html">Layouts</a></li>
      </ul>

      <h3>Primitives</h3>
      <ul>
        <li><a href="ren-button.html">Button</a></li>
        <li><a href="ren-card.html">Card</a></li>
        <li><a href="ren-badge.html">Badge</a></li>
        <li><a href="ren-tag.html">Tag</a></li>
        <li><a href="ren-link.html">Link</a></li>
        <li><a href="ren-banner.html">Banner</a></li>
        <li><a href="ren-breadcrumb.html">Breadcrumb</a></li>
        <li><a href="ren-pagination.html">Pagination</a></li>
        <li><a href="ren-separator.html">Separator</a></li>
        <li><a href="ren-avatar.html">Avatar</a></li>
        <li><a href="ren-spinner.html">Spinner</a></li>
        <li><a href="ren-skeleton.html">Skeleton</a></li>
        <li><a href="ren-kbd.html" aria-current="page">Keyboard Key</a></li>
        <li><a href="ren-icon.html">Icons</a></li>
        <li><a href="ren-field.html">Field</a></li>
        <li><a href="ren-checkbox.html">Checkbox</a></li>
        <li><a href="ren-switch.html">Switch</a></li>
        <li><a href="ren-radio.html">Radio</a></li>
        <li><a href="ren-progress.html">Progress</a></li>
      </ul>

      <h3>Composites</h3>
      <ul>
        <li><a href="ren-tabs.html">Tabs</a></li>
        <li><a href="ren-accordion.html">Accordion</a></li>
        <li><a href="ren-dialog.html">Dialog</a></li>
        <li><a href="ren-alert-dialog.html">Alert Dialog</a></li>
        <li><a href="ren-toast.html">Toast</a></li>
        <li><a href="ren-tooltip.html">Tooltip</a></li>
        <li><a href="ren-popover.html">Popover</a></li>
        <li><a href="ren-hover-card.html">Hover Card</a></li>
        <li><a href="ren-sheet.html">Sheet</a></li>
        <li><a href="ren-collapsible.html">Collapsible</a></li>
        <li><a href="ren-toolbar.html">Toolbar</a></li>
        <li><a href="ren-dropzone.html">Dropzone</a></li>
        <li><a href="ren-combobox.html">Combobox</a></li>
        <li><a href="ren-slider.html">Slider</a></li>
        <li><a href="ren-toggle-group.html">Toggle Group</a></li>
        <li><a href="ren-scroll-area.html">Scroll Area</a></li>
        <li><a href="ren-select.html">Select</a></li>
        <li><a href="ren-menu.html">Menu</a></li>
        <li><a href="ren-menubar.html">Menubar</a></li>
        <li><a href="ren-context-menu.html">Context Menu</a></li>
        <li><a href="ren-command.html">Command Palette</a></li>
        <li><a href="ren-number-field.html">Number Field</a></li>
        <li><a href="ren-otp.html">Input OTP</a></li>
        <li><a href="ren-color-picker.html">Color Picker</a></li>
        <li><a href="ren-calendar.html">Calendar</a></li>
        <li><a href="ren-date-picker.html">Date Picker</a></li>
        <li><a href="ren-date-range-picker.html">Date Range Picker</a></li>
        <li><a href="ren-carousel.html">Carousel</a></li>
      </ul>

      <h3>Patterns</h3>
      <ul>
        <li><a href="ren-nav.html">Nav</a></li>
        <li><a href="ren-sidebar.html">Sidebar</a></li>
        <li><a href="ren-empty-state.html">Empty State</a></li>
        <li><a href="ren-table.html">Data Table</a></li>
        <li><a href="ren-form.html">Form Validation</a></li>
        <li><a href="ren-ai.html">AI Patterns</a></li>
      </ul>

      <h3>Reference</h3>
      <ul>
        <li><a href="../components.html">Components catalog</a></li>
</ul>
    </aside>

    <main class="dx-content">
      <header class="dx-header">
        <nav class="ren-breadcrumb" aria-label="Breadcrumb" style="margin-bottom: var(--space-4);"><ol><li><a href="../index.html" class="ren-link-plain">Docs</a></li><li><a href="../components.html" class="ren-link-plain">Components</a></li><li aria-current="page">Keyboard Key</li></ol></nav>
        <p class="dx-kicker">Primitive</p>
        <h1>Keyboard Key <span class="dx-api-badge dx-api-badge-css" title="Works without any JavaScript">CSS-only</span></h1>
        <p class="lede">Keyboard shortcut keys. Renders <code>&lt;kbd&gt;</code> with mono type and a subtle bottom-bordered chip look.</p>
      </header>
      <section class="dx-section" id="overview"><p class="dx-kicker">About</p><h2>Overview</h2><p>Use <code>&lt;kbd&gt;</code> for keyboard shortcuts in tooltips, menus, command palettes, and documentation. Combine with <code>+</code> for chords like <code>&lt;kbd&gt;Cmd&lt;/kbd&gt;+&lt;kbd&gt;K&lt;/kbd&gt;</code>.</p></section>
      <section class="dx-section" id="demo"><p class="dx-kicker">Live</p><h2>Demo</h2><div class="dx-demo"><div class="dx-demo-preview"><kbd class="ren-kbd">Tab</kbd><kbd class="ren-kbd">⌘</kbd>+<kbd class="ren-kbd">K</kbd><kbd class="ren-kbd">Shift</kbd>+<kbd class="ren-kbd">Enter</kbd><kbd class="ren-kbd">Esc</kbd></div><pre class="dx-pre dx-demo-code" tabindex="0"><code>Press &lt;kbd class="ren-kbd"&gt;⌘&lt;/kbd&gt;+&lt;kbd class="ren-kbd"&gt;K&lt;/kbd&gt; to open the command palette.</code></pre></div></section>
      <section class="dx-section" id="api"><p class="dx-kicker">Reference</p><h2>API</h2><table class="dx-api"><thead><tr><th>Class</th><th>Effect</th></tr></thead><tbody><tr><td><code class="dx-api-name">.ren-kbd</code></td><td>Apply on <code>&lt;kbd&gt;</code>. Mono type, subtle border, slightly bolder bottom border for the "key cap" feel.</td></tr></tbody></table></section>
      <section class="dx-section" id="a11y"><p class="dx-kicker">Inclusive by default</p><h2>Accessibility</h2><p>Always use the semantic <code>&lt;kbd&gt;</code> tag. Screen readers announce it appropriately. Inside menus or tooltips, the parent already provides context.</p></section>
    </main>
  </div>
  <script src="../../site/shell.js" defer></script>
</body>
</html>


