view design_system/README.md @ 272:41a49c29a28f

polish JRPG conversation experience Integrate desktop conversations into the utility panel, simplify the mobile frame, add modal destinations and a reusable Zenbu composer lab, and preserve explicit conversation resume behavior. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Fri, 07 Aug 2026 16:05:29 -0700
parents 60a876c4587a
children
line wrap: on
line source

# Zenbu UI design system

Zenbu UI is a dependency-free set of light-DOM Web Components and CSS tokens.
It stays close to ordinary HTML: components wrap native controls and sectioning
elements instead of replacing their semantics.

The catalog includes native Zenbu component concepts and composition patterns.
They are original dependency-free Web Components using Zenbu tokens.
See
[`COMPONENTS.md`](COMPONENTS.md) for the complete mapping and HTML contracts.
Future HTML work follows the [`Zenbu UI wiki`](wiki/README.md).

## Catalog

Run the Seobeo-backed component catalog:

```bash
bazel run //design_system:dev
```

Open `http://127.0.0.1:6980`. Override the port with
`DESIGN_SYSTEM_PORT`.

The first-party catalog renders stories declared as HTML templates:

```html
<zen-story name="Primary button">
  <template>
    <zen-button>
      <button type="button">Save</button>
    </zen-button>
  </template>
</zen-story>
```

The story component renders the example and its source side by side.

## Reuse

Reusable assets are public Bazel targets:

```text
//design_system:components
//design_system:styles
//design_system:web_assets
```

Applications should copy the assets while preserving `components/` and
`styles/`, then load:

```html
<link rel="stylesheet" href="/design-system/styles/tokens.css">
<link rel="stylesheet" href="/design-system/styles/components.css">
<script type="module" src="/design-system/components/index.js"></script>
```

Canonical tokens use the layered
[`--zenbu-ref-*` / `--zenbu-sys-*` architecture](TOKENS.md) and can be
overridden at an application boundary; older `--zen-*` names remain
compatibility aliases. See [`COLORS.md`](COLORS.md) for color roles and theme
behavior.
Named [`themes`](THEMES.md) compose those tokens as Paper, Ink, and Playful
experiences in addition to automatic system light/dark behavior.
The [`sizing scale`](SIZING.md) defines shared `xs` through `xl` typography,
control, icon, gap, and padding primitives.

Use [`zen-icon`](ICONS.md) for all interface iconography. Design-system source
does not use emoji, ad hoc SVG, icon fonts, or third-party icon packages.

All exported JavaScript APIs use Google-style JSDoc. The policy target checks
the documentation contract along with token-only colors and first-party icons.

The catalog navigation is searchable with `/`, and every route is exercised at
desktop and mobile widths. Form controls reset browser chrome; date selection
uses Zenbu's first-party keyboard calendar.

## Native HTML contract

| Component family | Native content | Attributes | Events |
| --- | --- | --- | --- |
| `zen-button` | direct `button` or `a` | `appearance`, `variant`, `loading`, `disabled` | native click/form events |
| `zen-card` | direct `article` or `section` | `appearance`, `interactive` | native descendant events |
| `zen-link` | direct `a` | `effect` | native navigation events |
| `zen-alert` | message HTML | `tone`, `dismissible` | `zen-dismiss` |
| `zen-field` | direct `label`, form control, help text | `appearance`, native control attributes | native input/change/invalid |
| `zen-notifications` | descendant event producers | `aria-label`, `dismiss-label` | `zen-notification-action`, `zen-notification-removed` |
| `zen-stack` | any HTML | `direction`, `gap` | native descendant events |
| Disclosure and tabs | `details`, `summary`, buttons, sections | `multiple`, `activation` | `zen-change` |
| Dialogs and menus | native `dialog`, buttons, links | `placement`, native attributes | native click/close |
| Form controls | native input, select, textarea, fieldset | native control attributes | native form events |
| Collections | table, article, section, scroll containers | component-specific data hooks | `zen-change`, `zen-sort`, `zen-resize` |

Do not put business state into the design-system components. They provide
presentation, small accessibility wiring, and interaction affordances while
applications retain data and workflow ownership.

Use `appearance="plain"` when an application needs component behavior without
the Zenbu visual recipe. Plain buttons remove browser chrome, plain cards add
no surface treatment, and plain fields keep label/validity wiring while leaving
the application's control CSS untouched.

`zen-link effect="paw"` adds the first-party paw decoration and hover motion
while preserving the native anchor and all application-authored link styles.

### Notifications

See [`NOTIFICATIONS.md`](NOTIFICATIONS.md) for the complete event contract,
queue semantics, actions, timing, and accessibility behavior.

Place one scope around the part of the application that owns notifications:

```html
<zen-notifications aria-label="Notifications">
  <main id="application"></main>
</zen-notifications>
```

Any descendant can dispatch a non-composed bubbling event:

```js
source.dispatchEvent(new CustomEvent("zen-notify", {
  bubbles: true,
  composed: false,
  detail: {
    version: 1,
    id: "deployment-complete",
    tone: "success",
    message: "Deployment complete",
    announcement: "polite",
    durationMs: 5000,
  },
}));
```

Use `zen-dismiss-notification` with `{ version: 1, id }` to dismiss by ID.
Actions contain only an opaque token and label; clicking dispatches
`zen-notification-action`. Tokens are held in private component state and never
written to DOM attributes. The component renders three records and retains up
to 20 additional queued records.

## Tests

```bash
bazel test //design_system/test:catalog_test
bazel build //design_system:design_system_server_bundle
```