theme.css and Theme Tokens
Usage
import '@patab/widget-sdk/theme.css'
The stylesheet defines semantic classes on top of the host-injected --pt-* tokens and includes a global @media (prefers-reduced-motion: reduce) rule for reduced motion. Importing it is optional — you can also reference var(--pt-*) directly in your own CSS.
Semantic Classes
| Class name | Purpose |
|---|---|
.pt-surface | Regular container background and text color |
.pt-surface-strong | Emphasized container (a higher-contrast surface) |
.pt-text | Body text color |
.pt-text-strong | Heading/emphasis text color |
.pt-text-muted | Secondary/de-emphasized text color |
.pt-button | Button (including hover/active states) |
.pt-input | Input field |
.pt-focus-ring | Focus ring |
.pt-danger | Danger/destructive action color |
The above are all the contract classes provided by theme.css. The pt-card, pt-title, and pt-muted class names that appear in the official examples are not part of the SDK contract (they do not exist in theme.css); use contract classes such as .pt-surface or define your own styles if you need card styling.
Component Style Showcase
The showcase below renders every contract class from theme.css and all 20 theme tokens (demo values come from the host fallback theme table, matching the real runtime environment). Hover, active, and focus-ring states are fully interactive:
Semantic classes
.pt-surfaceBody .pt-text
Muted text .pt-text-muted
.pt-surface-strongHeading text .pt-text-strong
.pt-text / .pt-text-strong / .pt-text-mutedHeading text .pt-text-strong
Body text .pt-text
Secondary text .pt-text-muted
.pt-button(hover / active / focus-visible).pt-input.pt-focus-ringClick me, or press Tab to see the focus ring.pt-dangerDestructive action text.pt-surfaceBody .pt-text
Muted text .pt-text-muted
.pt-surface-strongHeading text .pt-text-strong
.pt-text / .pt-text-strong / .pt-text-mutedHeading text .pt-text-strong
Body text .pt-text
Secondary text .pt-text-muted
.pt-button(hover / active / focus-visible).pt-input.pt-focus-ringClick me, or press Tab to see the focus ring.pt-dangerDestructive action textTheme token values
| Token | Purpose | Preview | Light value | Dark value |
|---|---|---|---|---|
--pt-surface | Regular surface background | rgb(255 255 255 / 0.45) | rgb(255 255 255 / 0.08) | |
--pt-surface-strong | Emphasized surface background | rgb(255 255 255 / 0.8) | rgb(24 24 27 / 0.88) | |
--pt-text | Body text | rgb(64 64 64) | rgb(229 229 229) | |
--pt-text-strong | Emphasized text | rgb(38 38 38) | rgb(245 245 245) | |
--pt-text-muted | De-emphasized text | rgb(115 115 115) | rgb(161 161 170) | |
--pt-accent | Theme accent color | rgb(2 132 199) | rgb(56 189 248) | |
--pt-accent-contrast | Contrasting text on the accent color | rgb(255 255 255) | rgb(8 47 73) | |
--pt-accent-hover | Accent color hover state | rgb(3 105 161) | rgb(125 211 252) | |
--pt-border | Border | rgb(255 255 255 / 0.45) | rgb(255 255 255 / 0.14) | |
--pt-input | Input control background | rgb(255 255 255 / 0.7) | rgb(255 255 255 / 0.14) | |
--pt-danger | Danger color | rgb(220 38 38) | rgb(252 165 165) | |
--pt-focus-ring | Focus ring | rgb(2 132 199) | rgb(125 211 252) | |
--pt-radius-sm | Border radius (small) | 0.75rem | 0.75rem | |
--pt-radius-md | Border radius (medium) | 1rem | 1rem | |
--pt-radius-lg | Border radius (large) | 1.5rem | 1.5rem | |
--pt-shadow | Shadow | 0 10px 15px -3px rgb(0 0 0 / 0.1) | 0 10px 15px -3px rgb(0 0 0 / 0.32) | |
--pt-font-sans | Body font family | Font sample Aa 中文字体 | Inter, PingFang SC, Microsoft YaHei, system-ui, sans-serif | Inter, PingFang SC, Microsoft YaHei, system-ui, sans-serif |
--pt-motion-duration | Motion duration | — | 150ms | 150ms |
--pt-motion-easing | Motion easing | — | ease | ease |
--pt-color-scheme | color-scheme value | — | light | dark |
The showcase stays in sync with the SDK source: the semantic class rules mirror packages/widget-sdk/src/theme.css, and the token values mirror the host's createFallbackTokens. Completeness is verified automatically by pnpm --filter docs-site verify:theme-css.
Theme Tokens (20)
Token names are part of the API v1 contract. The host injects them into the sandbox document's :root and updates them in sync when the theme changes:
| Token | Purpose |
|---|---|
--pt-surface | Regular surface background |
--pt-surface-strong | Emphasized surface background |
--pt-text | Body text |
--pt-text-strong | Emphasized text |
--pt-text-muted | De-emphasized text |
--pt-accent | Theme accent color |
--pt-accent-contrast | Contrasting text color on the accent color |
--pt-accent-hover | Accent color hover state |
--pt-border | Border |
--pt-input | Input control background |
--pt-danger | Danger color |
--pt-focus-ring | Focus ring |
--pt-radius-sm / --pt-radius-md / --pt-radius-lg | Border radii |
--pt-shadow | Shadow |
--pt-font-sans | Body font family |
--pt-motion-duration / --pt-motion-easing | Motion duration and easing |
--pt-color-scheme | color-scheme value (light/dark) |
The corresponding TypeScript union type is WidgetThemeTokenName; the themeChanged event may carry a WidgetThemeTokens ({ version: 1; values: Record<WidgetThemeTokenName, string> }) snapshot.
Do not reference the host's internal --theme-* variables or the host UI framework's utility classes — they are not part of the public contract. The host translates internal variables into --pt-* through an explicit mapping table; unmapped internal variables are never exposed to widgets.