# TVU UX Design System — build conventions

These components are React wrappers around TVU's `<tvu-*>` web components. Build only with components from this library (import them from the package / `window.TvuDS`) — never hand-build an equivalent of a component that exists here. Read each component's `<Name>.d.ts` (`<Name>Props`) for its exact prop enums and `<Name>.prompt.md` for usage.

## Setup & theming
- The DS stylesheet is imported once at the app root; it defines the design tokens at `:root`. Tokens are CSS custom properties inherited into the components' shadow DOM, so they MUST live at `:root` — never inject them per-component.
- **Dark is the default** (`:root`). Light mode = set `data-theme="light"` on `<html>`. Never show both themes at once (no dark/light side-by-side).
- The web components self-register when the bundle loads — no provider/wrapper is needed.
- Tokens are presented **grouped by semantic category** (Neutrals, Brand & status, …) in `variables.css`, ordered within each group. Keep that categorized ordering whenever tokens are regenerated, synced, or exported — never flatten to arbitrary or alphabetical order (readability + cross-surface consistency). Source of truth: repo `docs/meta-rules.md` §1 "分类型真源 / 派生产物按分类分组展示" sub-rule.

## Styling idiom — props + tokens, never CSS classes
- Each component carries its own look. Style it via its **enum props** (`color`, `variant`, `size`, `status`, `theme`, `kind`, `type`, `darkTheme`…), NOT by adding CSS classes to it. The exact enums are in each `<Name>Props`.
- For YOUR OWN layout glue (surfaces, spacing, backgrounds) use DS tokens as `var(--*)` — never hardcoded hex/px:
  - Accent: `var(--brand)` (green — primary actions/key emphasis only, use sparingly). Danger: `var(--red)`.
  - Surfaces bottom→top: `var(--bg-layer1)` … `var(--bg-layer4)`.
  - Text: `var(--text-body)`, `var(--text-2)` (secondary). Dividers/borders: `var(--line-border)`.
  - Fonts: `var(--font-family-base)` for all text and data (IPs, bitrates, counts). `var(--font-family-clock)` (7-segment LED) ONLY for the top-bar clock readout.

## Which component for what (do not improvise)
- **Dialogs / confirmations / alerts → `Notification` with `form="dialog"`** (`type`: success / danger / error / info / warning; title + description + action buttons). Do NOT hand-build a confirmation inside `PopupBox`. **`PopupBox` is only for large custom-content modals** (forms, wizards) that need a full-screen backdrop — not for confirmations.
- **Inline feedback banners → `Message`** (status success/info/error/warning). **Status pills → `PillStatus`** (On-air/Preview/Analyzing/Inactive); **count pills → `PillCounter`**.
- **Charts / data-viz → `Chart`** (`type`: pie / donut / line / bar / bar-horizontal / line-bar; pass `labels` + `datasets`).
- **Tabular data → `Table`**; **paged lists → `Pagination`**; **wizards/flows → `Steps` + `StepItem`**.
- **Forms** compose `FormItem` around `Input` / `InputBoxFilled` / `InputNumber` / `SelectBoxLine` / `SelectBoxFilled` / `CheckBox` / `Radio` / `Switch` / `Slider`. Disable inputs via `enable="off"` (not a bool); `InputNumber` uses a real `disabled` bool.
- **Top bar → `TopBar`** (`tag="After Login"` / `"Before Login"`). Fill its named-slot props, don't rebuild the bar: `logo` (a `Logo`), `menu` (a `MenuList orientation="horizontal"`), `rightContent`. Set `showMenu`/`showSearchBox` to reveal those regions.
- **Brand mark → `Logo`** (`type`: tvu / ts). NEVER hand-draw a logo (no green square + letter, no CSS/`<div>` equivalent). The `logo` slot / brand leading position always takes a real `Logo`.
- **Menus → `MenuList`** (`orientation`: `horizontal` = topbar nav with brand underline / `vertical` = dropdown & panel bodies with brand color + trailing check). NEVER hand-build `<a>`/`<li>`+flex navigation or a bespoke dropdown row.
- **After-login account menu → `UserMenu`** (REQUIRED as the `TopBar` `rightContent` when `tag="After Login"`). Solid-color avatar (initials from `name`, or `image`/`color`) → panel with `role` badge + email, custom `actions`, inline language toggle, sign-out. **Bilingual = the in-menu language toggle (`languages`/`lang`/`onLanguageChange`), NEVER side-by-side dual-language text.** Its panel body is a `MenuList`; never hand-draw the avatar circle or account popup.

## Example
```jsx
<div style={{ background: 'var(--bg-layer1)', padding: 20, display: 'flex', gap: 12, alignItems: 'center' }}>
  <Button color="green" variant="filling" size="M">Go Live</Button>
  <Notification form="dialog" type="success" title="Stream started"
    description="Channel 1 is now live." confirmText="View monitor" cancelText="Dismiss" />
</div>
```
