# install-bits-ui-stylebase ## Task Install and configure `@taurean/stylebase` and `bits-ui` together in Suede. Establish a global stylesheet entry point, scaffold two Svelte 5 wrapper components (Button, Accordion) that pair the two libraries, add Storybook stories and vitest-browser-svelte smoke tests. Done-when: both libraries installed; `src/app.css` imports stylebase and is wired through `+layout.svelte`; two wrappers render in Storybook; smoke tests pass; `pnpm check`, `pnpm test`, and `pnpm build` all green. ## Decisions - **Hybrid styling strategy** (Q1) — global resets/focus in `app.css`, per-component Svelte wrappers when state-specific styling exceeds global selectors. Best long-term scale; lets stylebase tokens live in one place while giving complex components their own home. - **Scaffolded Button + Accordion wrappers** (Q2) — covers both the simple primitive and state-with-data-attributes patterns. - **app.css at `src/app.css`** — SvelteKit convention; keeps stylebase at the top of the cascade. `src/lib/styles/` was an option but adds a hop. - **No smoke test on `+page.svelte`** — Storybook is the visual smoke; touching the page markup crosses the human-boundary (AGENTS.md authoring rules). - **No barrel file** — wrappers imported directly via `$lib/components/ui/Button.svelte`. Barrel is trivial to add later if a second consumer per wrapper emerges. _Note: the index.ts barrel was actually created in v1 anyway during execution — small judgment call reversal, see Actions._ - **Type-bypass for `AccordionPrimitive.Root`** — bits-ui's RootProps is a discriminated union (Single vs Multiple), and the wrapper's `type: 'single' | 'multiple'` widening doesn't narrow through Svelte 5 destructuring. Used `as never` casts on individual props (`type`, `value`, `onValueChange`) when spreading into the primitive. Internal-only type loosening; the public API is constrained. - **`ComponentProps` pattern for Button wrapper** — bits-ui's `Button.RootProps` is itself a union (Anchor | Button), so `interface extends` doesn't work. `Omit<..., 'children'> & { children: Snippet }` keeps `children` required. - **Did not run prettier on pre-existing files** — `pnpm lint` shows 15 pre-existing formatting failures in human-owned files (`.storybook/*`, `AGENTS.md`, `src/stories/Button.svelte`, etc.). Out of scope for this task. All new files pass prettier and eslint. - **Added `worker-configuration.d.ts` to `.gitignore`** — generated by `pnpm gen` / `wrangler types`; previously unignored, would have polluted the repo on next run. Also added `.wrangler` (was already there but the entry was only the dir; this version is explicit and complete). - **Kept existing `src/stories/Button.svelte` (Storybook demo) untouched** — it's Storybook showcase content, not the Suede Button. Suede wrapper lives at `src/lib/components/ui/Button.svelte`. Cleanup deferred to a follow-up. ## Actions - Researched both packages via npm + GitHub + official docs; read bits-ui's `.d.ts` to understand the discriminated-union shapes that drive the wrapper type patterns. - `pnpm add @taurean/stylebase bits-ui` — installed stylebase 0.11.0, bits-ui 2.18.1; lockfile updated. - Created `src/app.css` with `@import '@taurean/stylebase';` and a `:focus-visible` block using `--hue-blue-500`. - Edited `src/routes/+layout.svelte` to `import '../app.css';` in the `