Reference doc for the next build phase. Supersedes the studio view list in §4.3 of BUILD-PLAN.md; extends §10 (self-serve). Written 2026-07-07.
| Surface | Package | Audience | Purpose |
|---|---|---|---|
| Design Studio | studio/ (exists, restructure) |
Internal (design + dev) | Living docs + QA for @departmnt/ui |
| Portal Builder | app/ = @departmnt/portal-builder (new workspace) |
Clients (self-serve) | Part of Core — the brand dashboard |
Foundations (@departmnt/ui: tokens, primitives, components, modules) stay untouched and are the
single render source for both. Anything both surfaces need (module registry, field schemas,
editors, portal preview) moves to a shared layer — see §5 Refactors.
Replace the current 6 phase-based views (Foundations / Theme Lab / Lookbook / Flow Map / Module Preview / Builder) with product-shaped views:
Single reading destination. Content:
--module-* / --page-fg semantic slots).classic, arrows/radius canon)./docs/*.md — today they're repo-only).Source: absorb Foundations page content + docs/*.md. Markdown-rendered in-app so docs stop
drifting from the repo.
Per brand: logo, seed colours (accent + gray), the generated 12-step scales (light/dark), colour profile assignment. Absorbs: Foundations scales + Theme Lab profile/radius/scaling controls. Theme Lab's custom-profile builder stays here (it becomes the model for Portal Builder → Theme).
The Lookbook, evolved: colour-profile switcher + variant selector tabs (done) + colour breakdown (done). Add: per-component doc link into Docs.
Module Preview, evolved:
--module-* slots it consumes).layers.ts).Unchanged for now. It is the prototype for Portal Builder → Portal; freeze features here and pour new effort into the Portal Builder app.
Retired: Flow Map as a top view (fold the flow graph into Docs), phase-numbered nav (P1–P6),
views.ts phase/status fields.
app/) — Core brand dashboardProduct name: Portal Builder, a section of Core (the brand dashboard). Dashboard IA (⭐ = build first):
Build order: Portal → Theme → Modules → Products → Events → Audience → (Tags, Logic, Analytics).
A first-class mobile view — as easy as posting to Instagram:
PortalConfig + field schemas; the editor surface is what shrinks.Per BUILD-PLAN §10: mock/localStorage first, Supabase in P1. Config model = PortalConfig
(already JSON-serialisable).
| Module | Notes |
|---|---|
| User directory + DMs | Member list, profiles, 1:1 threads. Needs realtime backend later; build presentational modules + mock store now. |
| Community chat | Global chat room. Same chat primitives as DMs. |
| Group chats + channels | Membership gated by NFC claim or audience segment — ties into Audience segments. |
| File download | Gated file delivery (artefact unlock target). |
| Page lock & Drop | Lock external pages/content (e.g. Shopify product or collection page); access only through this module. Needs a redirect/token mechanism — document as a backend contract, mock in UI. |
Chat family shares primitives: MessageList, MessageInput, ThreadRow, PresenceDot — build once in
modules/shared/, compose three modules from them.
Audited: studio/lib/*, studio/components/*, studio/app/*, modules/*, docs/*.
renderers.tsx (module registry + SAMPLE_PROPS), fields.ts
(field schemas), builder.ts (PortalConfig), portal-preview.tsx, content-editor.tsx,
social-editor.tsx, fields-editor.tsx all live in studio/. Portal Builder needs every one.
→ Refactor: extract to a shared workspace package (e.g. builder-kit/ =
@departmnt/builder-kit) consumed by both apps. Do this before app/ scaffolding.builder/page.tsx is a 712-line monolith — screen nav, slot editing, module picker, fields
rail, preview all in one file. → Split into components as part of the extraction; Portal
Builder must not import a page.PreviewChrome lives in studio but is portal UI (used it for --page-fg work). → Move to
modules/shared/ or builder-kit so the public runtime renders the same chrome.flows.ts couples screen graph + slot defs + toggles). Tabs,
slot-valid module types, and mobile editing need a screen schema: slots[] { id, accepts[], max }, tabs[] { id, source: moduleQuery }. → Version PortalConfig (add version: 2) when
this lands; write a v1→v2 migration for localStorage configs.modules.ts has tier/category/blurb but nothing machine-
readable for "slot-valid", "tab source", "artefact-unlockable", "mobile-editable". → Extend the
registry entry: capabilities: string[], slotTypes: string[], mobileFields?: string[].FieldType is
text/toggle/select/aspect-ratio; content/social needed bespoke editors. → Add 'list' (typed
item arrays — generalise ContentEditor/SocialEditor's drag-reorder pattern) and 'media'
(upload slot, data-URL now / storage later) before building the new modules.layers.ts is hand-maintained (390 lines) and will drift as modules grow — it's also the
source for "full Radix usage" in Studio Modules. → Acceptable short-term; note as debt.
Long-term: generate from module source (ts-morph pass in scripts/).docs/*.md aren't rendered anywhere — the Docs view needs an in-app markdown renderer
(next-mdx-remote or a build step). Keep files as the source of truth.views.ts is phase-based — rewrite for the 5-view IA; home page cards read from it.color="gray" text sitting directly on the accent page bg under the background profile stays
muted-dark (needs literal per-appearance restores).generate-scale.ts is a v1 perceptual generator — revisit contrast guarantees when Theme
editing goes client-facing (clients will pick arbitrary seeds; validate contrast in the Theme UI).icon.svg has a pre-existing lint error (empty <title>).New docs/PATTERNS.md, rendered in Studio → Docs. Sections:
builder-kit (registry, fields, config model, editors, portal preview + chrome). (§5.1)docs/PATTERNS.md. (§2, §6)accepts, tabs, module capabilities. (§5.2)app/ Portal Builder — dashboard shell + ⭐ Portal / Theme / Modules on mock data.