• Status:
    • Decided plan, written before the Storybook build exists; deployment and browser verification will follow.
    • Option D will define the first delivery; Option C will provide its composition mechanism.
    • Included means the named subset, not whole-application coverage. Direct imports, adapted components, and page embeds are different claims.
  • Evidence:

Option A - One instance with per-framework builders

Mechanism

  • Hoped-for configuration:
    • Put @storybook/svelte-vite, @storybook/vue3-vite, and @storybook/react-vite together in one main.ts; expect their builders to select the correct renderer for each story.
    • That is not a supported native configuration. The framework field accepts one framework name or one object containing that name and its options. Multiple builders do not compose into one renderer.
  • Actual boundary:
    • A builder compiles the preview; a renderer mounts and updates stories using a particular component model.
    • The version-pinned framework presets explicitly bind the same Vite builder to different renderers: Svelte, Vue 3, React.
  • Supported limited form:
    • One Vite builder can run multiple compatible transform plugins in one Vite preview configuration; Vite’s plugin array is not restricted to one transform.
    • A single Svelte instance can therefore compile several compatible Svelte projects, including their CSS processing, provided dependency resolution, aliases, source scanning, and global styles are reconciled.
    • The renderer stays Svelte. Adding Vue or React compilation plugins does not turn it into a native Vue or React story renderer. Project count is not renderer count.

Cost

  • Supported Svelte-only form: one configuration, dependency resolution policy, build, and navigation shell; external-source integration still needs deliberate configuration.
  • Hoped-for multi-renderer form: unsupported configuration, not a cheap implementation option. Custom mounting bridges would be separately authored integrations with their own controls and lifecycle contracts, not the proposed native package combination.

Sacrifice

  • A valid single-instance choice must give up native coverage of other renderers.
  • For this comparison, the Svelte instance would use the daisyUI regime. Choosing the bits skin instead would reverse the CSS trade-off, not remove it.
  • Page embedding could display other applications, but would not provide native component reuse or establish their props and interaction contracts.

Included projects

  • sflw: direct imports of the selected Svelte components.
  • svelte-chat: source-attributed Svelte adaptations, not imports of a nonexistent reusable component library.

Excluded projects

  • bits: renderer-compatible, but its unmodified global skin would conflict with the selected daisyUI preview.
  • airi: native Vue 3 requires @storybook/vue3-vite in a separate instance.
  • iconmania: native React requires @storybook/react-vite in a separate instance.
  • click2punch: standalone prototype pages, deliberately deferred to an HTML page-embed lane rather than counted as Svelte components.
  • wrdp: PHP/WordPress templates cannot become native Svelte stories by choosing another builder; its vanilla DOM-factory exception remains separate scope.

Verdict

  • Reject the advertised multi-renderer mechanism; retain its valid observation that multiple compatible Svelte projects can share one instance.
  • Insufficient for this first delivery because preserving bits requires a second CSS regime even before adding another renderer.

Option B - One instance per framework

Mechanism

  • Create independent native instances:
    • Svelte: @storybook/svelte-vite.
    • Vue 3: @storybook/vue3-vite.
    • React: @storybook/react-vite.
  • Each instance will own its story index, preview document, framework configuration, and published output. No separate repository is inherently required.
  • The evaluated Svelte lane will use daisyUI. One instance per framework does not by itself isolate incompatible styles within that framework.

Cost

  • For N instances: N configurations, N independently resolvable dependency trees, N builds, N deployments, and N navigation shells.
    • Compatible dependencies may deduplicate; deployment artifacts may share a host and static server. N instances does not require N machines or daemons.
    • Each artifact still needs a working URL, version ownership, and verification.
  • No single entry point unless the instances are composed or a separate directory of links is maintained.

Sacrifice

  • Browsing and comparison would span separate shells.
  • A strict one-per-framework rule would either drop the bits skin, reconcile conflicting CSS through adaptations, or exclude bits from the daisyUI Svelte lane. A second Svelte instance would abandon that strict rule for a sound reason.

Included projects

  • sflw: selected imports in the Svelte/daisyUI instance.
  • svelte-chat: attributed adaptations in that Svelte instance.
  • airi: selected Vue components in the Vue/UnoCSS instance, after its dependency and preview setup is resolved.
  • iconmania: selected React components in the React instance with its handwritten stylesheet and any required image fixtures.

Excluded projects

  • bits: excluded from the evaluated daisyUI Svelte preview if its original skin must be preserved; a second Svelte Storybook is the chosen remedy, not a claim of renderer incompatibility.
  • click2punch: excluded from these three native lanes; an additional @storybook/html-vite lane could host isolated page embeds.
  • wrdp: PHP templates excluded; an HTML lane could later cover the existing vanilla player factories without rewriting PHP.

Verdict

  • A valid modular baseline when separate explorers are acceptable.
  • Not the chosen topology: framework-only partitioning is too coarse for the observed CSS, and disconnected navigation is unnecessary once composition is available.

Option C - Composition via refs

Mechanism

  • The root instance’s main.ts will declare refs pointing to the URLs of other independently built Storybooks.
  • The shell will fetch each referenced index.json and present federated story trees; selected stories will render through their owning instance’s preview.
  • Composition solves the navigation problem, not the renderer problem. The root will remain a native Svelte instance; a referenced Vue instance would still use Vue, and a referenced React instance would still use React.
  • Separate instances may also share a renderer while isolating CSS. That is how the two Svelte regimes will coexist.

Cost

  • All referenced builds must be served, versioned, and kept compatible with their published indexes and assets. A refs entry does not build or deploy its target.
  • The root manager provides federated search over local and referenced indexes; search and deep links must be verified against each ref.
    • Referenced previews retain their own CSS, decorators and theme implementation.
    • Story args have ref-aware routing, but the root globals/theme toolbar is not a shared cross-instance theme controller.
    • Any promised referenced Controls behavior must be verified against the selected preview; other addon behavior is not assumed to match an uncomposed Storybook.
  • A broken or inaccessible ref degrades the shell with a missing or failing branch. A working root page is not proof that its refs work.

Sacrifice

  • One browsable entry point will not create one renderer, one dependency tree, one visual language, or uniform addon behavior.
  • Full native breadth now would require at least two Svelte builds for CSS isolation, one Vue build, and one React build, plus their source-specific setup.

Included projects

  • Broad candidate scope, conditional on implementing and verifying each lane:
    • sflw: native Svelte imports in the daisyUI root.
    • svelte-chat: attributed Svelte adaptations in that root.
    • bits: native Svelte demo imports in a separate ink-skin ref.
    • airi: native Vue components in a Vue/UnoCSS ref.
    • iconmania: native React components in a handwritten-CSS ref.

Excluded projects

  • click2punch: excluded from this native-component candidate scope; later @storybook/html-vite iframe stories would be page embeds, not reusable component imports.
  • wrdp: PHP/WordPress templates excluded from native execution; later HTML stories could use the existing JavaScript factories. Composition does not provide PHP execution.

Verdict

  • Choose this mechanism for navigation and isolation.
  • Do not confuse selecting composition with approving every possible referenced build. First-delivery scope will remain Option D.

Option D - Deliberately narrower first target

Mechanism

  • Build two native Svelte instances using @storybook/svelte-vite:
    • fleet: root instance at /, with the daisyUI regime, direct sflw imports, and attributed svelte-chat adaptations.
    • bits: independent build at /bits/, with the bits Tailwind ink skin; federated into fleet through refs.
  • Keep every existing fleet project byte-unchanged. Imports will point to real source files where their dependency graph permits; adaptations will be authored inside stbk with exact source-file and line-range provenance.

Cost

  • Two preview configurations, two builds, two published output trees, and a ref whose assets and deep links must work under a sub-path.
  • External-source compilation and CSS discovery, dependency resolution, source theme reproduction, a real XYFlow fixture, and continuing maintenance of the chat adaptations.
  • The fleet preview will replicate the four source theme definitions with attribution and use one deliberate neutral base rather than concatenate both application resets. That is adaptation work, not zero-configuration source fidelity.

Sacrifice

  • The phrase “three Svelte projects” overstates reusable-component coverage.
    • svelte-chat exposes no reusable Svelte component files; its UI is inline in svelte-chat/src/routes/r/[room]/+page.svelte, roughly 1,575 lines in the scout inventory.
    • Its representation must be adapted copies with provenance. These copies will not automatically receive upstream markup or behavior changes, and their existence will not prove the room application works in isolation.
  • The neutral fleet base will differ from each application’s full-page baseline. Source themes and component states will be preserved and checked, but whole-page pixel identity will not be claimed.
  • Native Vue, React, HTML prototypes, PHP templates, and full Svelte application flows will remain deferred. Two small import sets and three adaptations are not fleet-wide coverage.

Included projects

  • sflw:
    • sflw/src/lib/components/Icon.svelte:1-59: directly imported SVG; public name, size, and stroke props, no imports.
    • sflw/src/lib/components/SourcePanel.svelte:1-40: directly imported string-prop surface using source and filename, native disclosure, and component-local clipboard feedback; its only import is ./Icon.svelte.
    • sflw/src/lib/components/StudioNode.svelte:1-46: directly imported and registered through nodeTypes in a real SvelteFlow fixture, not rendered bare. Its Handle usage needs node and Flow context; the $lib/flow/graph dependency is type-only. Existing registration: sflw/src/routes/demo/nodes/+page.svelte:10-16,161-168; context requirement: sflw/node_modules/@xyflow/svelte/dist/lib/components/Handle/Handle.svelte:38-48.
  • bits:
    • bits/src/lib/demos/dialog/BasicDemo.svelte.
    • bits/src/lib/demos/combobox/MultipleDemo.svelte.
    • bits/src/lib/demos/checkbox/IndeterminateDemo.svelte.
    • All three will be directly imported existing demo compositions. Their only imports are bits-ui and @lucide/svelte at lines 2-3 of each file; bits-ui resolves to 2.19.0 in bits/package-lock.json:1609-1611. Their internal state will not be misrepresented as a public scalar-prop API.
  • svelte-chat:
    • MessageBubble display/body adaptation: svelte-chat/src/routes/r/[room]/+page.svelte:1079-1143, with new stbk closure/state glue. The complete upstream snippet is 1079-1200; its footer at 1144-1197 is excluded. This is not full-bubble coverage.
    • Attachment presentation adaptation: the same source file at :1054-1077.
    • Toast stack adaptation: the same source file at :1564-1575, with local state and dismissal at :1025-1035.
    • Each new component will be labeled adapted, never imported, and will carry those source ranges in its provenance header.

Excluded projects

  • airi:
    • Vue 3 requires a separate @storybook/vue3-vite instance; styling is UnoCSS, not Tailwind (airi/uno.config.ts:141-193).
    • The declared workspace workflow pins pnpm 11.24.0 and invokes pnpm from postinstall (airi/package.json:6,15); catalogs and patches are present (airi/pnpm-workspace.yaml:20-53). The 2026-09-15 scout recorded no pnpm binary on PATH. A package-manager bootstrap is additional work, not a story-file edit.
    • This is not proof that every Vue leaf requires installing the whole workspace; a minimal preview could reproduce a leaf’s dependencies. That path still requires an explicit implementation and verification decision.
    • An existing Histoire explorer already has real stories (airi/packages/stage-ui/package.json:64-67; airi/packages/stage-ui/src/components/misc/button.story.vue:1-60). Its presence is a reason to price duplication honestly.
  • iconmania:
    • React 19.1.1 is pinned in iconmania/package.json:20-21; native stories require @storybook/react-vite and the handwritten iconmania/src/styles.css.
    • Gallery art uses /api/gallery/... URLs for SVG and PNG files (iconmania/src/app/workspace-data.ts:162-172). Faithful gallery stories need real image fixture responses, not generic JSON mocks. Simpler controlled leaves exist, but the additional renderer is still outside this delivery.
  • click2punch:
    • Standalone HTML prototype documents load daisyUI @5 and @tailwindcss/browser@4 from CDN at floating major versions (click2punch/prototypes/2026-09-15-punch-ui/deck.html:8-10; the scout records the same imports in board.html and focus.html).
    • Later representation will use @storybook/html-vite iframe page embeds with their assets; it will not be called native component import coverage.
  • wrdp:
    • No root package.json was found by the scout; this does not mean no nested manifest exists.
    • PHP/WordPress templates require a rewrite for native browser-story execution; wrdp/wp/wp-content/plugins/quizwizz/templates/single-qw_quiz.php:8-34 depends on WordPress functions and plugin rendering.
    • Narrow exception: wrdp/wp/wp-content/plugins/quizwizz/assets/js/qwizz-player-renderer.js exposes DOM factories through window.QuizWizzPlayerRenderer at :380-391. Its status, failure, and progress surfaces at :20-38,70-81 could become later HTML stories without rewriting PHP.

Verdict

  • Chosen first-delivery scope, using Option C’s supported composition mechanism.
  • It accepts a second Svelte build to preserve incompatible CSS and accepts disclosed chat adaptations rather than inventing reusable source components.
  • Exact story and interaction acceptance: 30-first-delivery.

Why a CSS regime is a second boundary

  • Observed regimes:
    • sflw and svelte-chat: Tailwind 4.3.3 plus daisyUI 5.7.38, with CSS-first custom @plugin 'daisyui/theme' blocks.
      • Styles: sflw/src/app.css:1-73; svelte-chat/src/app.css:1-84.
      • Locked versions: sflw/package-lock.json:1618-1619,2481-2482; svelte-chat/package-lock.json:1932-1933,2987-2988.
    • bits: Tailwind 4.3.3 with a handwritten ink/brand skin, not daisyUI.
      • Version: bits/package-lock.json:2573-2575.
      • Tokens: bits/src/app.css:8-34; global dark base and focus styling: :79-96; local btn, card, panel, and input utilities: :100-176.
  • Concrete collision:
    • daisyUI defines .btn in sflw/node_modules/daisyui/components/button/object.js:1.
    • bits/src/app.css:100-123 defines its own @utility btn, producing the same class name with its own dimensions, border, background, and state rules.
    • Global collisions extend beyond that selector: bits/src/app.css:79-96 and sflw/src/app.css:145-195 both affect the document, body, selection, and focus treatment; Tailwind processing also brings document-wide reset rules.
  • Consequence:
    • Imported global CSS is injected into a Storybook preview document, not isolated by source project or sidebar folder; see Storybook’s CSS contract.
    • Layers choose cascade winners rather than isolate skins; selector scoping, per-story stylesheet ownership and a dedicated iframe are possible but add portal/lifecycle/Docs or interaction integration. Renaming one class alone would not isolate the global rules or portalled content.
    • A renderer boundary is mandatory for native framework support; a CSS-regime boundary is the chosen source-fidelity policy for incompatible global styles. CSS rewriting is possible, but its maintenance cost and visual divergence are not free. Do not claim those unprototyped alternatives are cheaper overall.
flowchart LR
  R["Native renderer"] --> S["Svelte"]
  R --> V["Vue 3"]
  R --> X["React"]
  S --> D["CSS regime: daisyUI"]
  S --> K["CSS regime: bits ink"]
  V --> U["CSS regime: UnoCSS"]
  X --> H["CSS regime: handwritten CSS"]
  D --> F["Chosen: fleet at /; sflw and adapted chat"]
  K --> B["Chosen: bits at /bits/"]
  U --> A["Deferred: airi"]
  H --> I["Deferred: iconmania"]
  F -->|"refs; separate preview document"| B
  • Sharing daisyUI does not mean sharing one palette or safely concatenating two application stylesheets:
    • fleet will preserve the source sflw-light and sflw-dark theme definitions, plus chat’s custom light and dark definitions; these are not stock themes.
    • Attributed preview CSS will reconcile the base deliberately. The single neutral base is a disclosed fidelity divergence and a future verification target, not evidence that the source resets were compatible.
    • bits will keep its separate ink skin and global dark base.

Decision

  • Execute Option D on Option C’s mechanism:
    • One root Svelte/daisyUI instance, one referenced Svelte/ink instance, two independently built previews.
    • Direct source imports for the selected sflw and bits files; attributed adaptations only where svelte-chat lacks reusable component files.
    • No existing fleet source, dependency tree, service, or configuration will be changed by this work.
  • Growth path:
    • Add a Vue instance for airi and a React instance for iconmania as refs later, when their dependency, CSS, fixture, and verification costs are accepted.
    • Nothing in the first delivery blocks those additions; no renderer merger or replacement of the two Svelte instances is required.
    • HTML page embeds and the vanilla wrdp exception will remain a separately approved HTML lane. PHP execution will not be implied.
  • Proof still required after implementation:
    • Root and referenced indexes, assets, direct story links, and federated navigation must work.
    • Browser checks must exercise the actual preview documents, source themes, keyboard interactions, and network isolation; a successful static build alone will not establish these claims.
    • Acceptance: 30-first-delivery. Owner-only publication and hosting boundary: 40-runtime-and-hosting.

What would change the decision

  • Additional bits-skin project:
    • Trigger: another in-scope Svelte project is source-verified to use the same ink skin and compatible dependencies.
    • Change: add its eligible imports to the bits instance rather than create an instance solely because the project name differs.
  • AIRI dependency prerequisite resolved:
    • Trigger: the pinned pnpm becomes available with working lifecycle-script resolution, or the operator explicitly approves a stbk-local package-manager bootstrap; alternatively, a minimal Vue preview proves the selected leaf dependencies without installing the workspace.
    • Change: price and approve the Vue ref. Availability alone will not count as successful AIRI coverage.
  • React expansion approved:
    • Trigger: the operator accepts a React lane and its selected components pass isolated interaction checks; gallery inclusion additionally requires actual SVG/PNG fixture responses.
    • Change: add the iconmania ref without merging its renderer or CSS into fleet.
  • Real chat component boundaries appear upstream:
    • Trigger: svelte-chat independently gains reusable files whose import graphs and contracts match the represented surfaces.
    • Change: replace the attributed copies with direct imports and retire the superseded adaptations; this project will not edit the fleet to manufacture that prerequisite.
  • Shared daisyUI preview fails source-fidelity checks:
    • Trigger: matched source-versus-story checks demonstrate that the neutral base or theme switching changes a required component state, focus treatment, or layout.
    • Change: split sflw and chat into separate Svelte refs, or obtain explicit acceptance of the measured divergence. Do not preserve the two-instance count by concealing a styling regression.