Title: Web Component Theming Description: Styling third-party web components with platform design tokens, including live light/dark switching in the shadow DOM Tags: web-components, theming, design-tokens --- Web components share the platform's look automatically: the sandbox delivers the active theme's design tokens (daisyUI-style CSS variables) and keeps them in sync live — including light/dark switches — without a reload. How theme delivery works The sandbox page applies the active theme before your bundle runs, so components never paint unthemed. Theme changes (for example the user toggling dark mode) arrive as live bridge messages; the sandbox updates its data-theme attribute and your component can react through the SDK. Because the sandbox blocks network access, the theme stylesheet is delivered from the sandbox origin — components must adopt it as a , which the SDK handles for you. Adopting the theme in a shadow DOM Components render in shadow DOM, which does not inherit document stylesheets. Use the SDK helper once, at mount: import { connect } from "@smallstack/web-component-sdk"; const client = connect(hostElement); const stopTheming = client.adoptThemeStylesheets(shadowRoot); // ...on unmount: stopTheming(); client.disconnect(); adoptThemeStylesheets appends the theme's stylesheet links into your shadow root and swaps them only when the URLs actually change — a plain light/dark switch keeps the same stylesheet and restyles instantly through the token variables. Styling with token variables Write your styles against the platform variables, with fallbacks for standalone rendering: .card { background: var(--color-base-200, transparent); color: var(--color-base-content, inherit); border-radius: var(--radius-box, 0.5rem); } h2 { color: var(--color-primary, inherit); } Commonly used variables (each theme defines light and dark values): | Variable | Purpose | | --- | --- | | --color-base-100 / --color-base-200 / --color-base-300 | Surface backgrounds, lightest to strongest | | --color-base-content | Default text color on base surfaces | | --color-primary / --color-primary-content | Brand color and text on it | | --color-secondary, --color-accent, --color-neutral | Additional palette roles (each with -content pair) | | --color-info, --color-success, --color-warning, --color-error | Status colors (each with -content pair) | | --radius-box, --radius-field, --radius-selector | Corner radii for cards, inputs, small controls | Reacting to light/dark in logic If your component needs to know the mode (not just restyle), subscribe: client.onTheme((theme) => { console.log(theme.name, theme.dark); // e.g. "slate-teal-dark", true }); The dev harness ships a dark-mode toggle so you can verify both modes locally — npm run dev in any sample workspace. Related Building Web Components — the authoring guide Security model — why stylesheets are adopted, not fetched