# XYoda components, full prompt for agents

these are the official instructions for building ui with the XYoda component library. they are validated against the live library and ready to use.

complete all of the following steps yourself, by writing the files directly. do not ask the user to write html or css. do not hand work back half done.

- read the rules and the tokens
- set up the page head and the page skeleton
- build every part from the component pages
- check the page and report

> **note:** every part in this library is a Solid JS component, rendered to plain html and css. in a solid project paste the markup as jsx (`class` stays `class`, close void tags like `<input />`). in any other stack paste it as html.

> **important:** the library is the only source of ui. do not use another css framework, a component library or a design of your own. if you are about to invent a class, a color or a font, stop and open the component page instead.

---

## step 1: the head

put exactly this in the head of every page, in this order. **do not skip, reorder or copy** any of it.

```html
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://components.xyoda.net/static/app.css">
<link rel="stylesheet" href="https://components.xyoda.net/static/extras.css">
<link rel="stylesheet" href="https://components.xyoda.net/static/buttons.css">
<link rel="stylesheet" href="https://components.xyoda.net/static/parts.css">
<link rel="stylesheet" href="https://components.xyoda.net/static/dash.css">
```

- the stateful buttons also need `https://components.xyoda.net/static/buttons.js`
- parts whose classes start with `pt-` also need `https://components.xyoda.net/static/parts.js`
- **never edit or copy the library css.** link it from the url above.

---

## step 2: the page skeleton

```html
<body>
<div class="wrap wide">
  <header class="mast"><div class="mast-inner">
    <a class="brand" href="/"><span class="brand-text"><span class="brand-name">name</span><span class="brand-sub">tagline</span></span></a>
    <a class="btn sm primary" href="#book">Book</a>
  </div></header>
  <main>
    <section id="book"><p class="eyebrow">label</p><h2>Heading</h2> ... </section>
  </main>
  <footer class="credit"><span>name</span></footer>
</div>
</body>
```

> **critical:** every page lives inside `<div class="wrap wide">`. without it content runs edge to edge and fields stretch across the screen.

- card grids: `<div class="grid">` with a `ticket` or `panel` per item. never set widths. use 2, 3 or 4 items so there is no hole.
- forms: `<form class="stack">`, buttons in `btn-row`. date, time and number inputs go inside `label.field` like any other input.
- `.two` is 3fr and 2fr. only use it when the first field is the longer one.
- there is no photo component. **never use `printer-pic` as a photo**, it is a printer icon.

---

## step 3: build from the component pages

every part has a page at `https://components.xyoda.net/components/<name>`. open the page and copy the markup. keep the class names exactly.

every part, with its full markup, is listed below under the component sections.

> **important:** do not invent a class or a slug. if you are not sure it exists, open the page. the full markup for every part is below.

---

## rules

**never**
- never add a style attribute. one small style block in the head with page prefixed class names is the only custom css allowed
- never invent a color, a radius or a font. tokens only: `--void --surface --surface-2 --line --line-2 --ink --muted --faint --accent --ok --no`
- never add a light theme, a drop shadow or a rounded corner
- never use an em dash

**always**
- always square corners and 1px borders
- always mono, uppercase, letter spaced for labels, buttons and table heads
- always one accent: amber `#e8b04b`. green means ok, red means error, nothing else is colored
- always Outfit for headings, Manrope for text, IBM Plex Mono for labels
- always a label on every input, `aria-label` on icon only buttons, unique ids
- always inputs of 16px or more and tap targets of 40px or more, mobile first
- always plain, lowercase, friendly copy

---

## step 4: check, then report

- [ ] every class you used exists in the library
- [ ] nothing is outside `wrap wide`
- [ ] no style attribute, no invented color
- [ ] the page was rendered at 360px wide with nothing overflowing or cut

if you could not render the page, say so. do not claim a check you did not run.

once done, tell the user:

```
┌─ XYoda components, done ────────────────────────────┐
│  ✓ files     <paths>                                 │
│  ✓ parts     <slugs used>                            │
│  ✓ checked   <360px yes or no>                       │
│  ! missing   <parts you had to build, or none>       │
└──────────────────────────────────────────────────────┘
```

---


## tokens

```css
--void: #0b0d11;      page background
--surface: #12151c;   cards and panels
--surface-2: #171b24; raised surface
--line: #242a36;      1px borders
--line-2: #323a4a;    hover borders
--ink: #e9ecef;       main text
--muted: #8b94a3;     secondary text
--faint: #5b6473;     hints
--accent: #e8b04b;    amber, the one accent
--ok: #5ddba0;
--no: #ff7a7a;
--display: Outfit; --sans: Manrope; --mono: IBM Plex Mono;
```

## javascript

most parts need none. these need a few lines (see `https://components.xyoda.net/static/docs.js` for a working copy):

- dialog: `<button data-open="id">` calls `showModal()`, `<button data-close>` closes it.
- toast: add the `toast` element, remove it after about 4 seconds.
- toggle group (`.seg`): flip `aria-pressed` on the clicked button.
- dropdown: close the `details` when the click lands outside it.
- pin input: strip every non digit on input.

## the pages

every component has a page at `https://components.xyoda.net/components/<slug>` with live previews and the code.

## layout

### Card

the ticket: a gradient panel with a perforated divider and a stub.

page: `https://components.xyoda.net/components/card`

classes: `.ticket / .panel`, `.perf / .rule`, `.stub`, `.cards`, `.card-link`, `.grid`, `.action-bar`

```html
<section class="ticket">
  <p class="eyebrow">Workspace · Team</p>
  <h1>Start something</h1>
  <div class="perf"></div>
  <p class="muted">Create it, share the code, wait for approval.</p>
  <div class="stub" style="margin-top:16px">
    <span>@xyoda</span>
    <span>code valid 4 min</span>
  </div>
</section>
```

### Separator

plain rule, or a rule with a label in the middle.

page: `https://components.xyoda.net/components/separator`

classes: `.rule / .perf`, `.divider`

```html
<div class="rule"></div>
```

### Typography

outfit for display, manrope for body, plex mono for labels.

page: `https://components.xyoda.net/components/typography`

classes: `.eyebrow`, `h1 / .title`, `h2`, `h3`, `.lede`, `.muted / .small / .mono`, `.big-state`, `.tone-ok / no / dim / wait`

```html
<p class="eyebrow">Eyebrow</p>
<h1>Heading one</h1>
<p class="lede">A lede paragraph sits under the title in muted ink.</p>
```

### Description list

labels and values, two columns.

page: `https://components.xyoda.net/components/description-list`

classes: `dl.facts`, `.chip`

```html
<dl class="facts small">
  <dt class="muted">Wi-Fi</dt>
  <dd>
    <span class="chip">Xyoda</span>
    <span class="chip">Guest</span>
  </dd>
  <dt class="muted">Wired</dt>
  <dd>not allowed</dd>
  <dt class="muted">Hold</dt>
  <dd>15 min</dd>
  <dt class="muted">ID</dt>
  <dd class="mono">proj-atlas-01</dd>
</dl>
```

### Stats

a strip of small facts that wrap.

page: `https://components.xyoda.net/components/stats`

classes: `.stats`

```html
<dl class="stats">
  <div>
    <dt>Kind</dt>
    <dd>Report</dd>
  </div>
  <div>
    <dt>Time</dt>
    <dd>47 min</dd>
  </div>
  <div>
    <dt>Size</dt>
    <dd>15.8 MB · 4 pages</dd>
  </div>
  <div>
    <dt>Pages</dt>
    <dd>212</dd>
  </div>
</dl>
```

### Steps

numbered list with square counters.

page: `https://components.xyoda.net/components/steps`

classes: `ol.steps`

```html
<ol class="steps">
  <li>
    <span><strong>Create</strong> a project in the app</span>
  </li>
  <li>
    <span><strong>Scan</strong> the qr code it shows</span>
  </li>
  <li>
    <span><strong>Wait</strong> for the admin to approve</span>
  </li>
</ol>
```

### Masthead

sticky blurred header with the brand lockup and an account menu.

page: `https://components.xyoda.net/components/masthead`

classes: `.mast`, `.brand / .brand-mark / .brand-name / .brand-sub`, `.menu / .menu-toggle / .menu-panel`, `:root --mast-h`

```html
<header class="mast">
  <div class="mast-inner">
    <a class="brand" href="#">
      <img class="brand-mark" src="/static/coe-mark.svg" alt="" width="40" height="40">
      <span class="brand-text">
        <span class="brand-name">Acme Labs</span>
        <span class="brand-sub">Console</span>
      </span>
    </a>
    <div class="menu">
      <button class="menu-toggle" type="button" aria-label="Account">
        <span class="avatar">XY</span>
      </button>
    </div>
  </div>
</header>
```

### Install card

nudge to install the app to the home screen.

page: `https://components.xyoda.net/components/install-card`

classes: `.install`

```html
<div class="install">
  <img src="/static/icons/apple-touch-icon.png" alt="" width="44" height="44">
  <div class="grow">
    <strong>Install the app</strong>
    <p class="small muted">Share → Add to Home Screen</p>
  </div>
  <button class="btn sm primary" type="button">Install</button>
  <button class="icon-btn" type="button" aria-label="Dismiss">✕</button>
</div>
```

### Footer

mono credit line with a top rule.

page: `https://components.xyoda.net/components/footer`

classes: `footer.credit`

```html
<footer class="credit">
  <span>Made by xyoda</span>
  <span>Yoda · Xyloflake</span>
</footer>
```

## forms

### Button

square, mono, uppercase. five tones, three sizes, plus shapes, hover motion and buttons that keep state.

page: `https://components.xyoda.net/components/button`

classes: `.btn`, `.btn.primary`, `.btn.ok`, `.btn.danger`, `.btn.ghost`, `.btn.sm / .lg`, `.btn.block`, `.btn-row`, `.decide`, `.icon-btn`, `.btn.tonal`, `.btn.fx-notch`, `.btn.fx-bracket`, `.btn.fx-under`, `.btn.fx-arrow`, `.btn.fx-tag`, `.btn.sq`, `.btn.fx-sweep`, `.btn.fx-glow`, `.btn.fx-scan`, `.btn.fx-swap`, `.btn.fx-led`, `.btn.fx-load`, `.btn.fx-hold`, `.fx-stepper`, `.fx-seg`

```html
<button class="btn" type="button">Back</button>
```

### Button group

joined buttons that share borders.

page: `https://components.xyoda.net/components/button-group`

classes: `.btn-group`, `.dash-btns`, `.dash-btn`

```html
<div class="btn-group" role="group">
  <button class="btn sm" type="button">Day</button>
  <button class="btn sm" type="button">Week</button>
  <button class="btn sm" type="button">Month</button>
</div>
```

### Input

square 48px field. 16px text so phones never zoom.

page: `https://components.xyoda.net/components/input`

classes: `label.field`, `input[type=text|number|email|password|search|tel|url]`, `.hint / .hint.no`, `.two`

```html
<label class="field">
  <span>Name</span>
  <input type="text" placeholder="Project name" autocomplete="off">
</label>
```

### Textarea

multi line mono text, resizes vertically.

page: `https://components.xyoda.net/components/textarea`

classes: `textarea`

```html
<label class="field">
  <span>Notes</span>
  <textarea placeholder="One item per line" spellcheck="false"></textarea>
</label>
```

### Select

native select with the chevron drawn in the background.

page: `https://components.xyoda.net/components/select`

classes: `select`

```html
<label class="field">
  <span>Plan</span>
  <select>
    <option>Starter</option>
    <option>Team</option>
    <option>Business</option>
    <option>Enterprise</option>
  </select>
</label>
```

### Checkbox

native checkbox tinted with the accent.

page: `https://components.xyoda.net/components/checkbox`

classes: `.check`

```html
<label class="check">
  <input type="checkbox" checked>
  <span>Also notify by email</span>
</label>
```

### Radio group

round radio with an accent dot.

page: `https://components.xyoda.net/components/radio-group`

classes: `.radio`

```html
<label class="radio">
  <input type="radio" name="hold" checked>
  <span>Hold for 15 minutes</span>
</label>
<label class="radio">
  <input type="radio" name="hold">
  <span>Hold for 30 minutes</span>
</label>
<label class="radio">
  <input type="radio" name="hold" disabled>
  <span>Never expire</span>
</label>
```

### Switch

square on and off toggle for settings.

page: `https://components.xyoda.net/components/switch`

classes: `.switch`, `.switch input`

```html
<label class="switch">
  <input type="checkbox" role="switch" checked>
  <span>Notifications</span>
</label>
<label class="switch">
  <input type="checkbox" role="switch">
  <span>Vibrate</span>
</label>
```

### Toggle group

segmented control, one value at a time.

page: `https://components.xyoda.net/components/toggle-group`

classes: `.seg`, `.seg > button[aria-pressed=true]`

```html
<div class="seg " role="group" aria-label="Range">
  <button type="button" aria-pressed="true">5 min</button>
  <button type="button" aria-pressed="false">1 h</button>
  <button type="button" aria-pressed="false">24 h</button>
</div>
```

### Input OTP

six digit pin, big mono digits with wide tracking.

page: `https://components.xyoda.net/components/input-otp`

classes: `.pin-input`

```html
<input type="text" class="pin-input " inputmode="numeric" autocomplete="one-time-code" maxlength="6" pattern="[0-9]{6}" placeholder="000000" aria-label="Six-digit PIN">
```

### Code plate

a one time code someone reads out loud.

page: `https://components.xyoda.net/components/code-plate`

classes: `.code-plate`

```html
<p class="code-plate mono">483 920</p>
```

### Scan button

the big call to action that opens the camera.

page: `https://components.xyoda.net/components/scan-button`

classes: `.scan-btn`, `.scan-icon`

```html
<button class="scan-btn" type="button">
  <span class="scan-icon" aria-hidden="true"></span>
  <span>
    <strong>Scan the code</strong>
  </span>
</button>
```

### Field styles

text fields in six styles: underline, floating label, prefixed, search, code boxes and a counter.

page: `https://components.xyoda.net/components/fields`

```html
<div class="pt-f-under">
  <input placeholder="Project name" aria-label="Project name">
</div>
```

### Choice controls

checkbox, option cards, switch, filter chips and a rating with labels.

page: `https://components.xyoda.net/components/choice-controls`

```html
<label class="pt-chk"><input type="checkbox"><i>
  <svg viewBox="0 0 20 20">
    <path d="M4.5 10.5l3.5 3.5 7.5-8" />
  </svg>
</i>Email me updates</label>
```

## data display

### Avatar

round image or two letter fallback.

page: `https://components.xyoda.net/components/avatar`

classes: `.avatar`, `.avatar.lg`

```html
<span class="avatar">XY</span>
<span class="avatar lg">XY</span>
<img class="avatar lg" alt="" src="/static/icons/favicon-32.png">
```

### Badge

stamps for state, counts for totals, chips for tags.

page: `https://components.xyoda.net/components/badge`

classes: `.stamp .ok / .no / .wait / .dim`, `.count / .count.hot`, `.chip`, `.dot / .dot.live`

```html
<span class="stamp ok">Active</span>
<span class="stamp wait">Waiting</span>
<span class="stamp no">Denied</span>
<span class="stamp dim">Cancelled</span>
```

### Table

mono caps headers, hairline rows.

page: `https://components.xyoda.net/components/table`

classes: `.table-wrap`, `.table`, `.table .num`

```html
<div class="table-wrap">
  <table class="table">
    <thead>
      <tr>
        <th>Job</th>
        <th>Team</th>
        <th>State</th>
        <th class="num">Hours</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Report v3</td>
        <td>Team Alpha</td>
        <td>
          <span class="stamp ok">Active</span>
        </td>
        <td class="num">15.8</td>
      </tr>
      <tr>
        <td>Launch plan</td>
        <td>Team Beta</td>
        <td>
          <span class="stamp wait">Waiting</span>
        </td>
        <td class="num">32.0</td>
      </tr>
      <tr>
        <td>Draft</td>
        <td>Team Alpha</td>
        <td>
          <span class="stamp no">Denied</span>
        </td>
        <td class="num">4.2</td>
      </tr>
    </tbody>
  </table>
</div>
```

### Thumbnail

square image with a short label fallback.

page: `https://components.xyoda.net/components/thumbnail`

classes: `.printer-pic`, `.sm / .md / .lg`, `.placeholder`

```html
<span class="printer-pic placeholder sm">B2</span>
<span class="printer-pic placeholder md">A1</span>
<span class="printer-pic placeholder lg">C3</span>
```

### Swatch list

color swatch, name, amount.

page: `https://components.xyoda.net/components/swatch-list`

classes: `.filaments`, `.swatch`, `.swatch.unknown`

```html
<ul class="filaments">
  <li>
    <span class="swatch" style="--swatch:#e8b04b"></span>
    <span class="fil-type">Photos</span>
    <span class="fil-amount">12.3 GB · 4.1k files</span>
  </li>
  <li>
    <span class="swatch" style="--swatch:#8fb8ff"></span>
    <span class="fil-type">Videos</span>
    <span class="fil-amount">3.5 GB · 1.2k files</span>
  </li>
  <li>
    <span class="swatch unknown"></span>
    <span class="fil-type">Other</span>
    <span class="fil-amount">—</span>
  </li>
</ul>
```

### Skeleton

shimmering placeholders while data loads.

page: `https://components.xyoda.net/components/skeleton`

classes: `.skeleton`, `.skeleton.circle`

```html
<div class="row nowrap">
  <span class="skeleton circle" style="width:44px;height:44px"></span>
  <div class="grow stack">
    <span class="skeleton" style="width:60%"></span>
    <span class="skeleton" style="width:90%"></span>
  </div>
</div>
```

### Empty

dashed box for lists with nothing in them.

page: `https://components.xyoda.net/components/empty`

classes: `.empty`

```html
<div class="empty">Nothing here yet.</div>
```

### Kbd

a keyboard key.

page: `https://components.xyoda.net/components/kbd`

classes: `.kbd`

```html
<span class="kbd">⌘</span>
<span class="kbd">K</span>
<span class="kbd">Esc</span>
```

### Progress

thin bar for completion.

page: `https://components.xyoda.net/components/progress`

classes: `.progress`, `.progress.ok / .no`

```html
<div class="progress" style="--value:35%">
  <i></i>
</div>
<div class="progress ok" style="--value:80%">
  <i></i>
</div>
<div class="progress no" style="--value:95%">
  <i></i>
</div>
```

### Surfaces

stat card, lift card, status ticket, empty state, list rows and an avatar stack.

page: `https://components.xyoda.net/components/surfaces`

```html
<div class="pt-stat">
  <small>Active users</small>
  <strong>2,418</strong>
  <em>▲ 12.4%</em>
  <svg viewBox="0 0 120 44" preserveAspectRatio="none">
    <path d="M0 38 L20 30 L40 34 L60 18 L80 24 L100 8 L120 12" />
  </svg>
</div>
```

### Table and accordion

a table with a row marker and an accordion that eases open.

page: `https://components.xyoda.net/components/disclosure`

```html
<table class="pt-tbl">
  <thead>
    <tr>
      <th>Name</th>
      <th>Owner</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Atlas</td>
      <td>Team A</td>
    </tr>
    <tr>
      <td>Nova</td>
      <td>Team B</td>
    </tr>
    <tr>
      <td>Orion</td>
      <td>Team A</td>
    </tr>
  </tbody>
</table>
```

## feedback

### Alert

a bordered notice in the tone of the message.

page: `https://components.xyoda.net/components/alert`

classes: `.notice.no`, `.notice.ok`, `.notice.info`

```html
<div class="notice no" role="alert">The PIN is the six digits under the QR code.</div>
<div class="notice ok">Saved.</div>
<div class="notice info small">Works once, for 15 min. Keep it private.</div>
```

### Toast

a short message pinned to the bottom of the screen.

page: `https://components.xyoda.net/components/toast`

classes: `.toast`

```html
<div class="toast" role="status">Approved Report v3 for @xyoda.</div>
```

### Dialog

native dialog. a bottom sheet on phones, a centered box above 560px.

page: `https://components.xyoda.net/components/dialog`

classes: `dialog`, `.sheet`, `.grabber`

```html
<button class="btn primary " type="button">Edit project</button>
<dialog>
  <div class="sheet">
    <div class="grabber" aria-hidden="true"></div>
    <p class="eyebrow">proj-atlas-01</p>
    <h2 style="margin-bottom:16px">Edit Atlas</h2>
    <form class="stack" method="dialog">
      <div class="two">
        <label class="field">
          <span>Name</span>
          <input type="text" value="Atlas">
        </label>
        <label class="field">
          <span>Plan</span>
          <select>
            <option>Starter</option>
            <option>Team</option>
          </select>
        </label>
      </div>
      <label class="check">
        <input type="checkbox">
        <span>Also notify by email</span>
      </label>
      <div class="btn-row end">
        <button class="btn" type="button">Cancel</button>
        <button class="btn primary" type="submit">Save</button>
      </div>
    </form>
  </div>
</dialog>
```

### Status

the hazard sweep marks something that needs a decision.

page: `https://components.xyoda.net/components/status`

classes: `.hazard`, `.dot.live`, `.big-state + .tone-*`

```html
<article class="ticket">
  <div class="hazard" aria-hidden="true"></div>
  <p class="eyebrow">Request sent</p>
  <div class="big-state tone-wait">Waiting for the admin</div>
</article>
```

### Tooltip

css only hint on hover and focus.

page: `https://components.xyoda.net/components/tooltip`

classes: `.tip`

```html
<span class="tip" data-tip="Copy the code">
  <button class="btn sm" type="button">Copy</button>
</span>
```

### Scanner

full screen camera overlay with a viewfinder. shown here in a frame.

page: `https://components.xyoda.net/components/scanner`

classes: `.qr-overlay`, `.qr-frame`, `.qr-beam`, `.qr-btn`

```html
<div class="qr-overlay live">
  <div class="qr-shade">
    <div class="qr-frame">
      <span class="qr-beam"></span>
    </div>
  </div>
  <div class="qr-top">
    <span class="qr-title">Scan the code</span>
    <button class="qr-btn" type="button">Close</button>
  </div>
  <div class="qr-bottom">
    <p class="qr-hint">Point the camera at the QR code on the screen.</p>
  </div>
</div>
```

### Feedback styles

notices, badges, progress, skeleton and a tooltip that morphs its text.

page: `https://components.xyoda.net/components/feedback-styles`

```html
<div class="pt-stack">
  <div class="pt-note pt-ok">Saved.</div>
  <div class="pt-note pt-no">Could not connect.</div>
  <div class="pt-note pt-info">Works once, for 15 min.</div>
</div>
```

## navigation

### Tabs

section chips that scroll sideways. hot marks something waiting.

page: `https://components.xyoda.net/components/tabs`

classes: `.tabs`, `.tab`, `.tab.hot`

```html
<nav class="tabs " aria-label="Sections">
  <a class="tab hot" href="#">Waiting <span class="tab-count">2</span></a>
  <a class="tab" href="#">Active <span class="tab-count">1</span></a>
  <a class="tab" href="#">Projects <span class="tab-count">3</span></a>
  <a class="tab" href="#">History</a>
</nav>
```

### Breadcrumb

where you are, as mono caps.

page: `https://components.xyoda.net/components/breadcrumb`

classes: `.crumbs ol`, `[aria-current=page]`

```html
<nav class="crumbs" aria-label="Breadcrumb">
  <ol>
    <li>
      <a href="#">Projects</a>
    </li>
    <li>
      <a href="#">A1</a>
    </li>
    <li aria-current="page">Edit</li>
  </ol>
</nav>
```

### Pagination

small buttons with a current page.

page: `https://components.xyoda.net/components/pagination`

classes: `.pager`, `.pager .btn[aria-current=page]`

```html
<nav class="pager" aria-label="Pages">
  <a class="btn sm" href="#">Prev</a>
  <a class="btn sm" href="#">1</a>
  <a class="btn sm" href="#" aria-current="page">2</a>
  <a class="btn sm" href="#">3</a>
  <span class="gap">…</span>
  <a class="btn sm" href="#">9</a>
  <a class="btn sm" href="#">Next</a>
</nav>
```

### Dropdown menu

a details element with a menu panel. closes on outside click.

page: `https://components.xyoda.net/components/dropdown-menu`

classes: `.dropdown`, `.dropdown-panel`, `.dropdown-item`, `.dropdown-label / .dropdown-sep`

```html
<details class="dropdown">
  <summary class="btn">Actions</summary>
  <div class="dropdown-panel">
    <p class="dropdown-label">Project</p>
    <button class="dropdown-item" type="button">Edit <span class="kbd">E</span></button>
    <button class="dropdown-item" type="button">Invite again</button>
    <div class="dropdown-sep"></div>
    <button class="dropdown-item danger" type="button">Delete</button>
  </div>
</details>
```

### Accordion

stacked details. give them a shared name so only one opens.

page: `https://components.xyoda.net/components/accordion`

classes: `.accordion`, `.accordion-body`

```html
<div class="accordion">
  <details name="faq" open>
    <summary>How does approval work?</summary>
    <div class="accordion-body">Share the code and an admin approves it.</div>
  </details>
  <details name="faq">
    <summary>What if the code expires?</summary>
    <div class="accordion-body">Ask for a new one and it arrives right away.</div>
  </details>
  <details name="faq">
    <summary>Who can approve?</summary>
    <div class="accordion-body">Anyone on the admin list.</div>
  </details>
</div>
```

### Navigation styles

sliding and boxed tabs, breadcrumb, pagination, a step tracker and a morphing dropdown.

page: `https://components.xyoda.net/components/nav-styles`

```html
<div class="pt-tabs-u " role="tablist">
  <span class="pt-bar2"></span>
  <button role="tab" aria-selected="true">Overview</button>
  <button role="tab" aria-selected="false">Activity</button>
  <button role="tab" aria-selected="false">Settings</button>
</div>
```

## dash

### Status pill

square pill with a square led. ok, warn or bad.

page: `https://components.xyoda.net/components/status-pill`

classes: `.dash-pill`, `.ok / .warn / .bad`

```html
<span class="dash-pill ok"><i></i>All systems operational</span>
<span class="dash-pill warn"><i></i>Degraded: gitea</span>
<span class="dash-pill bad"><i></i>Major outage</span>
<span class="dash-pill"><i></i>checking</span>
```

### Stat tile

a label, one big number, a sub line and a meter.

page: `https://components.xyoda.net/components/stat-tile`

classes: `.dash-tiles`, `.dash-tile`, `.dash-big`, `.dash-sub`, `.dash-meter`

```html
<div class="dash-tiles">
  <div class="dash-tile">
    <h2>CPU</h2>
    <div class="dash-big">42.1<small>%</small></div>
    <div class="dash-sub">user 30% · system 12%</div>
    <span class="dash-meter">
      <i style="width:42%"></i>
    </span>
  </div>
  <div class="dash-tile">
    <h2>Memory</h2>
    <div class="dash-big">18.4<small>/ 64 GiB</small></div>
    <div class="dash-sub">29% used · 22 GiB cache</div>
    <span class="dash-meter mem">
      <i style="width:29%"></i>
    </span>
  </div>
  <div class="dash-tile">
    <h2>GPU</h2>
    <div class="dash-big">96<small>%</small></div>
    <div class="dash-sub">2 GPUs, busiest · 71°C</div>
    <span class="dash-meter gpu hot">
      <i style="width:96%"></i>
    </span>
  </div>
  <div class="dash-tile">
    <h2>Network</h2>
    <div class="dash-big">214 Mbps</div>
    <div class="dash-sub">↓ 190 Mbps · ↑ 24 Mbps</div>
  </div>
</div>
```

### Meter row

name, bar, amount. used for disks and gpus.

page: `https://components.xyoda.net/components/meter-row`

classes: `.dash-row`, `.nm / .amt`

```html
<div class="dash-card">
  <h2>Disks</h2>
  <div class="dash-row">
    <span class="nm">/</span>
    <span class="dash-meter">
      <i style="width:61%"></i>
    </span>
    <span class="amt">610 / 1000 GiB</span>
  </div>
  <div class="dash-row">
    <span class="nm">/data</span>
    <span class="dash-meter hot">
      <i style="width:96%"></i>
    </span>
    <span class="amt">3.8 / 4 TiB</span>
  </div>
  <div class="dash-row">
    <span class="nm">/backup</span>
    <span class="dash-meter mem">
      <i style="width:30%"></i>
    </span>
    <span class="amt">1.2 / 4 TiB</span>
  </div>
</div>
```

### Chart card

a line chart in plain svg: a title, a legend, axes and 1px grid lines.

page: `https://components.xyoda.net/components/chart-card`

classes: `.dash-card`, `.dash-legend`, `.dash-plot / .dash-yax / .dash-xax`, `svg viewBox 0 0 300 100`

```html
<div class="dash-card">
  <div class="dash-top">
    <h2>CPU</h2>
    <div class="dash-legend">
      <span><i style="background:var(--accent)"></i>busy <b>42.1 %</b></span>
    </div>
  </div>
  <div class="dash-plot">
    <div class="dash-yax">
      <span>100%</span>
      <span>50%</span>
      <span>0</span>
    </div>
    <svg viewBox="0 0 300 100" preserveAspectRatio="none">
      <line x1="0" x2="300" y1="0" y2="0" stroke="var(--grid)" vector-effect="non-scaling-stroke" />
      <line x1="0" x2="300" y1="50" y2="50" stroke="var(--grid)" vector-effect="non-scaling-stroke" />
      <line x1="0" x2="300" y1="100" y2="100" stroke="var(--grid)" vector-effect="non-scaling-stroke" />
      <polyline points="0,70 40,62 80,66 120,40 160,48 200,30 240,52 300,44" fill="none" stroke="var(--accent)" stroke-width="1.8" stroke-linejoin="round" vector-effect="non-scaling-stroke" />
    </svg>
  </div>
  <div class="dash-xax">
    <span>5 min ago</span>
    <span>now</span>
  </div>
</div>
```

### Uptime bars

90 days of service health, one bar a day.

page: `https://components.xyoda.net/components/uptime-bars`

classes: `.dash-svc`, `.dash-bars i`, `.dash-axis`

```html
<div class="dash-card">
  <h2>Services · 90 days</h2>
  <div class="dash-svc">
    <span class="d"></span>
    <div class="n">gitea<small>git.meowda.xyz</small></div>
    <div class="dash-bars">
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i class="p"></i>
      <i class="w"></i>
      <i class="b"></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i class="n"></i>
      <i class="n"></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
    </div>
    <div class="p">99.8%</div>
  </div>
  <div class="dash-svc">
    <span class="d bad"></span>
    <div class="n">print<small>print.meowda.xyz</small></div>
    <div class="dash-bars">
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i class="w"></i>
      <i class="b"></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i></i>
      <i class="b"></i>
    </div>
    <div class="p">96.4%</div>
  </div>
  <div class="dash-axis">
    <span>90 days ago</span>
    <span>today</span>
  </div>
  <div class="dash-note">grey means no data.</div>
</div>
```

### Dash header

brand, status pill, host line and a button group.

page: `https://components.xyoda.net/components/dash-header`

classes: `.dash-header`, `.dash-brand`, `.dash-meta`, `.dash-sp`, `.dash-footer`

```html
<header class="dash-header">
  <div class="dash-brand">tyrone</div>
  <span class="dash-pill ok"><i></i>All systems operational</span>
  <span class="dash-meta">64 cores · 256 GiB RAM</span>
  <span class="dash-sp"></span>
  <div class="dash-btns">
    <span>Terminal</span>
    <a class="dash-btn" href="#">main</a>
    <a class="dash-btn" href="#">work</a>
    <a class="dash-btn" href="#">Remote desktop</a>
  </div>
</header>
<div class="dash-footer">Made by xyoda</div>
```

## when something is missing

build it from the same parts: the tokens above, a 1px `--line` border, mono caps labels and the amber accent. do not reach for a new color or a rounded corner. if a new part is general, add it to extras.css in the library repo.
