# @opencode-ai/css OpenCode's design system as plain CSS. It has no JavaScript, framework, build tool, or runtime dependency. Use semantic HTML and `data-*` attributes. Native browser states such as `:hover`, `:focus-visible`, and `:disabled` work automatically; your JavaScript can represent application state with attributes such as `data-expanded`, `data-checked`, and `data-invalid`. ## Install ```sh npm install @opencode-ai/css ``` Load the complete design system from JavaScript: ```js import "@opencode-ai/css" ``` Or from CSS: ```css @import "@opencode-ai/css"; ``` For a static page with no package tooling: ```html ``` Add `data-oc-root` to the element that should receive the default page background, text color, and font. Set `data-color-scheme` to `light` or `dark` on that element or an ancestor. ```html ``` ## Selective imports The default export contains every component. Small pages can load only what they use: ```css @import "@opencode-ai/css/tokens.css"; @import "@opencode-ai/css/base.css"; @import "@opencode-ai/css/components/button.css"; @import "@opencode-ai/css/components/badge.css"; @import "@opencode-ai/css/components/table.css"; ``` `tokens.css` defines the color ramps and semantic theme variables. `base.css` is intentionally small and scoped: it only applies the full-page defaults to `[data-oc-root]` and normalization to design-system elements. ## Common components ### Button ```html ``` Variants: `neutral`, `contrast`, `outline`, `ghost`, `ghost-muted`, `danger`, `warning`, and `loading`. Sizes: `small`, `normal`, and `large`. ### Badge ```html Inactive Active ``` ### Internal-tool page ```html

Release control

Artifacts

Published builds

Newest first.

Name Status
cli@1.0.0 Active
``` ### JavaScript-owned state The package styles state; it does not implement behavior. Keep semantic HTML and ARIA as the source of truth, then mirror state to a `data-*` attribute when a component needs it. ```js const trigger = document.querySelector('[data-component="button"]') trigger.addEventListener("click", () => { const expanded = trigger.getAttribute("aria-expanded") !== "true" trigger.setAttribute("aria-expanded", String(expanded)) trigger.toggleAttribute("data-expanded", expanded) }) ``` ## Theme customization Override semantic tokens at your app root instead of editing component CSS: ```css [data-oc-root] { --oc-font-family-sans: Inter, system-ui, sans-serif; --oc-page-max-width: 1440px; --oc-bg-accent: #7152f4; --oc-border-focus: #8271f8; } ``` The low-level color ramps live in `colors.css`; light and dark semantic mappings live in `theme.css`. ## Component inventory The first release is intentionally focused on simple internal tools: - Layout: page, surface, and table - Actions and status: button and badge - Forms: field, input, select, textarea, and native checkbox/radio styling - Structure: divider Each stylesheet is available as `@opencode-ai/css/components/.css`. This small interface avoids publishing framework-specific DOM contracts for menus, dialogs, comboboxes, and other interactive widgets. ## Scope This package is styling only. It does not create DOM, manage focus, provide keyboard navigation, position overlays, or add ARIA attributes. Use native HTML for simple controls and a small behavior layer of your choice for menus, dialogs, comboboxes, and other interactive widgets. `@opencode-ai/ui` does not depend on this package yet. The CSS is intentionally isolated while its public interface settles.