# Multi-Framework Support
> How to consume `@whynot/design` from React, Django, Vue, Svelte, or plain HTML — without forking, restyling, or re-implementing components per framework.
---
## TL;DR
`whynot-design` ships **Web Components** (custom elements built with Lit) as the canonical component layer. They render to **light DOM** — meaning the global stylesheets style them — and work identically in any HTML context.
```html
Promote prototype
```
That tag is valid in:
- A Django template
- A React JSX file
- A Vue Single-File Component
- A Svelte component
- `index.html` with no JS framework at all
- An HTMX `hx-get` fragment response
You do not write a different component per framework. You write the same custom element. The framework decides how to pass props (`variant="primary"` in HTML, `variant="primary"` in JSX, `:variant="…"` in Vue).
---
## Architecture recap
```
┌─────────────────────────────────────────────────────────────┐
│ Layer 3 — Framework adapters (optional) │
│ Django {% include %} partials, Vue/React typed wrappers │
├─────────────────────────────────────────────────────────────┤
│ Layer 2 — Custom elements (canonical) │
│ , , , … │
│ Lit-based, light DOM, ~5kb gzipped runtime total │
├─────────────────────────────────────────────────────────────┤
│ Layer 1 — Tokens + CSS │
│ colors_and_type.css + components.css │
└─────────────────────────────────────────────────────────────┘
```
Most consumers need only Layer 1 + Layer 2. Layer 3 is sugar.
---
## How light DOM rendering works
A Lit component normally renders into a **shadow root** — its own isolated DOM tree with style encapsulation. That's wrong for a design system: it would prevent the global CSS from styling components, force every component to ship its own copy of the rules, and break server-side rendering.
`whynot-design` components override the render root to be light DOM:
```js
class WnButton extends LitElement {
createRenderRoot() { return this; } // ← light DOM
render() { return html``; }
}
```
Consequences:
1. **Global stylesheets style them.** Your `components.css` rules for `.wn-btn` apply to the button inside ``. No `::part`, no `::slotted`, no CSS variables-as-API.
2. **SSR is trivial.** The server renders the same `` HTML it would render for any tag. The browser later "upgrades" the element to add behaviour, but the HTML is already there — no FOUC, no hydration mismatch.
3. **Form participation works.** `` containing a real `` participates in `