create-ailk 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/component-catalog.json +11939 -0
- package/component-catalog.md +176 -64
- package/dist/cli.js +29 -1
- package/dist/derive-architecture.js +5 -2
- package/dist/lib/extract-module-bundle.d.ts +50 -2
- package/dist/lib/extract-module-bundle.js +223 -15
- package/dist/lib/fetch-guard.d.ts +28 -0
- package/dist/lib/fetch-guard.js +101 -0
- package/dist/lib/fetch-module.js +4 -0
- package/dist/lib/fetch-template.js +4 -0
- package/dist/module-architecture.d.ts +59 -8
- package/dist/module-architecture.js +334 -115
- package/dist/parse-args.js +6 -2
- package/dist/programmatic.d.ts +10 -0
- package/dist/programmatic.js +134 -19
- package/dist/site-chrome.d.ts +80 -0
- package/dist/site-chrome.js +135 -0
- package/dist/surfaces.d.ts +21 -6
- package/dist/surfaces.js +107 -32
- package/dist/template-manifest.d.ts +55 -3
- package/dist/template-manifest.js +181 -12
- package/dist/template-names.d.ts +1 -1
- package/dist/template-names.js +1 -0
- package/package.json +9 -2
- package/site-templates/_base/ailk-template.json +6 -0
- package/site-templates/_base/content/en/Pricing/pricing.mdx +169 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +331 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +393 -0
- package/site-templates/marketing-site/ailk-template.json +11 -0
- package/site-templates/marketing-site/content/en/blog/05-this-vc-morning-routine-will-make-you-super-annoying.mdx +36 -0
- package/site-templates/marketing-site/provenance.json +4 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +288 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +285 -0
- package/site-templates/marketing-site-free/ailk-template.json +2 -1
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.json +271 -0
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +324 -0
- package/site-templates/minimalism-site/ailk-template.json +21 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-1.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-2.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-3.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-4.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-5.svg +7 -0
- package/site-templates/minimalism-site/assets/avatar-placeholder-6.svg +7 -0
- package/site-templates/minimalism-site/assets/hero-backdrop.svg +17 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-1.svg +6 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-2.svg +6 -0
- package/site-templates/minimalism-site/assets/logo-placeholder-3.svg +6 -0
- package/site-templates/minimalism-site/content/en/AboutPage/about.mdx +110 -0
- package/site-templates/minimalism-site/content/en/ContactPage/contact.mdx +68 -0
- package/site-templates/minimalism-site/content/en/FAQPage/faq.mdx +57 -0
- package/site-templates/minimalism-site/content/en/HomePage/home.mdx +214 -0
- package/site-templates/minimalism-site/content/en/LandingPage/referral.mdx +77 -0
- package/site-templates/minimalism-site/content/en/LandingPage/reports.mdx +73 -0
- package/site-templates/minimalism-site/content/en/ReportPage/annual-letter-2024.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/field-notes-2023.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/platform-shift-2025.mdx +52 -0
- package/site-templates/minimalism-site/content/en/ReportPage/state-of-the-market-2026.mdx +52 -0
- package/site-templates/minimalism-site/content/en/Service/first-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/Service/second-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/Service/third-engagement.mdx +38 -0
- package/site-templates/minimalism-site/content/en/ServicesList/services.mdx +73 -0
- package/site-templates/minimalism-site/flows/referral.flow.json +71 -0
- package/site-templates/minimalism-site/provenance.json +4 -0
- package/site-templates/saas-product/TEMPLATE-MANIFEST.md +61 -0
- package/site-templates/saas-product/ailk-template.json +16 -0
- package/site-templates/saas-product/provenance.json +10 -0
- package/templates/.claude/skills/README.md +16 -25
- package/templates/.env.example +32 -7
- package/templates/.github/workflows/ci.yml +48 -0
- package/templates/README.md +3 -1
- package/templates/apps/api/CLAUDE.md +4 -1
- package/templates/apps/api/eslint.config.mjs +69 -0
- package/templates/apps/api/package.json +6 -2
- package/templates/apps/api/src/__tests__/module-exclusion.test.ts +6 -2
- package/templates/apps/api/src/__tests__/review-surface-registration.test.ts +167 -0
- package/templates/apps/api/src/__tests__/workspace-module-registration.test.ts +8 -1
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -0
- package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +339 -0
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +108 -0
- package/templates/apps/api/src/middleware/default-tenant.ts +136 -0
- package/templates/apps/api/src/routes/leads/__tests__/list.test.ts +171 -0
- package/templates/apps/api/src/routes/leads/list.ts +104 -0
- package/templates/apps/api/src/server.ts +82 -6
- package/templates/apps/api/src/services/__tests__/lead-promotion.test.ts +408 -0
- package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +329 -0
- package/templates/apps/api/src/services/default-tenant.ts +261 -0
- package/templates/apps/api/src/services/lead-promotion.ts +161 -0
- package/templates/apps/api/src/services/leads-inbox.ts +263 -0
- package/templates/apps/api/src/services/owner-workspaces.ts +132 -0
- package/templates/apps/mcp/CLAUDE.md +1 -1
- package/templates/apps/mcp/__tests__/parity.test.ts +2 -2
- package/templates/apps/mcp/__tests__/tools/{scaffold.test.ts → create_project.test.ts} +23 -23
- package/templates/apps/mcp/eslint.config.mjs +69 -0
- package/templates/apps/mcp/package.json +6 -2
- package/templates/apps/mcp/src/server.ts +2 -2
- package/templates/apps/mcp/src/tools/{scaffold.ts → create_project.ts} +3 -3
- package/templates/apps/mcp/src/tools/index.ts +2 -2
- package/templates/apps/web/.env.example +3 -3
- package/templates/apps/web/CLAUDE.md +2 -0
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +4 -6
- package/templates/apps/web/app/[locale]/(authed)/layout.tsx +1 -1
- package/templates/apps/web/app/[locale]/(authed)/leads/__tests__/page.test.tsx +181 -0
- package/templates/apps/web/app/[locale]/(authed)/leads/components/LeadsTable.tsx +137 -0
- package/templates/apps/web/app/[locale]/(authed)/leads/page.tsx +111 -0
- package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +1 -1
- package/templates/apps/web/app/[locale]/[slug]/__tests__/page.test.tsx +111 -0
- package/templates/apps/web/app/[locale]/[slug]/page.tsx +65 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.permalink.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.test.tsx +6 -5
- package/templates/apps/web/app/[locale]/flows/[slug]/flow.actions.ts +1 -1
- package/templates/apps/web/app/[locale]/layout.tsx +214 -17
- package/templates/apps/web/components/google-analytics.tsx +18 -1
- package/templates/apps/web/eslint.config.mjs +69 -0
- package/templates/apps/web/jest.config.cjs +7 -15
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +32 -5
- package/templates/apps/web/lib/nav-config.ts +27 -7
- package/templates/apps/web/lib/server-api.ts +1 -1
- package/templates/apps/web/lib/site-chrome.ts +29 -0
- package/templates/apps/web/lib/telemetry-scrub.ts +46 -0
- package/templates/apps/web/messages/en.json +29 -2
- package/templates/apps/web/next.config.mjs +20 -0
- package/templates/apps/web/package.json +6 -2
- package/templates/apps/web/sentry.client.config.ts +131 -0
- package/templates/apps/web/sentry.edge.config.ts +72 -0
- package/templates/apps/web/sentry.server.config.ts +72 -0
- package/templates/apps/web/src/lib/routes.ts +13 -18
- package/templates/brand_assets/README.md +24 -0
- package/templates/content/en/AboutPage/about.mdx +160 -15
- package/templates/content/en/ContactPage/contact.mdx +90 -13
- package/templates/content/en/FAQPage/faq.mdx +62 -22
- package/templates/content/en/HomePage/home.mdx +244 -20
- package/templates/content/en/LandingPage/blog.mdx +83 -0
- package/templates/content/en/LandingPage/features.mdx +103 -0
- package/templates/content/en/LandingPage/how-it-works.mdx +143 -0
- package/templates/database/CHANGELOG.md +7 -0
- package/templates/database/__tests__/seed.test.ts +1 -1
- package/templates/database/eslint.config.mjs +69 -0
- package/templates/database/package.json +7 -3
- package/templates/database/seed.ts +1 -1
- package/templates/package.json +1 -14
- package/versions.json +52 -0
- package/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +0 -103
- /package/site-templates/{marketing-site-free → _base}/content/en/PrivacyPage/privacy.mdx +0 -0
- /package/site-templates/{marketing-site-free → _base}/content/en/TermsPage/terms.mdx +0 -0
- /package/templates/apps/web/{src/components → components}/SiteNav.tsx +0 -0
package/component-catalog.md
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
The component inventory of `@working-theory/ui` and the shells of `@working-theory/templates` — the library an AI Launch Kit site is built from. It exists because a name search fails: a site rebuilt five components AILK already had, because it searched for the names IT would have used and AILK uses different ones — `ContactOverlay`→`FormLightbox`, `SearchOverlay`→`SpotlightPanel`/`NavSearchTrigger`, `SiteRail`→`SidebarNav`, `FunnelNav`→`Nav`, `NumberedWorkList`→`Steps`/`StairSteps`.
|
|
6
6
|
|
|
7
|
-
**What this file does NOT cover.** All six component tiers are indexed — Sections, Blocks, Chrome, Primitives, Panels and Shells —
|
|
7
|
+
**What this file does NOT cover.** All six component tiers are indexed — Sections, Blocks, Chrome, Primitives, Panels and Shells — for `@working-theory/ui` and `@working-theory/templates` AND for each of the four paid `@working-theory/ui-*` packages, which carry their own entry per tier they populate. A component absent from these tables is genuinely absent from the library. Outside the file: the **design tokens** (tier 0 — colors, spacing, typography, radius and the rest are values in `@working-theory/theme`, not components; `packages/ui/src/tokens/` holds their Storybook stories and the small display components those stories use); the **page compositions** in `packages/ui/src/pages/` and `packages/templates/src/pages/`, which assemble whole pages from the tiers below; and every non-component module (hooks, `utils/`, `.ts` helpers).
|
|
8
8
|
|
|
9
|
-
**Two things a listing does not promise.** First, the tables index every component file in
|
|
9
|
+
**Two things a listing does not promise.** First, the tables index every component file in every tier of every package, **including the paid module packages** — the `Booker` family is here, under `Scheduling Sections` and `Scheduling Blocks`, and a build with the scheduling module switched off will not contain it. Listed is not the same as present in your tree; check the modules your site was scaffolded with. Second, this file carries no **props or data shapes**: it says what a component is FOR, never what it accepts. For a section's accepted `data` fields, read its Zod schema, or the `component-catalog.json` manifest the AILK source repo generates alongside this file.
|
|
10
10
|
|
|
11
11
|
**Before you build a component, search this file for what it DOES.**
|
|
12
12
|
|
|
@@ -15,13 +15,13 @@ The component inventory of `@working-theory/ui` and the shells of `@working-theo
|
|
|
15
15
|
3. Check the Primitives, Panels and Shells tables too — a low-level control, a collapsible layout container, or a route-level frame lives there, not under Sections or Blocks.
|
|
16
16
|
4. Only then build. If you do build, you are declaring the capability is genuinely absent.
|
|
17
17
|
|
|
18
|
-
Inventory: **
|
|
18
|
+
Inventory: **286 component files** across 16 tiers — 54 sections, 86 blocks, 17 chrome, 79 primitives, 6 panels, 3 shells, 5 docs-blog-blocks, 1 docs-blog-chrome, 2 docs-blog-shells, 2 scheduling-sections, 5 scheduling-blocks, 3 signal-collectors-sections, 8 signal-collectors-blocks, 2 commerce-sections, 12 commerce-blocks, 1 commerce-panels. 283 distinct names: `SchedulerEmbed`, `Separator`, `Tabs` exist in more than one tier as genuinely different components, listed once per tier with its own source path.
|
|
19
19
|
|
|
20
|
-
Description coverage: **
|
|
20
|
+
Description coverage: **282/286** components carry a capability description derived from source — 43 from the section registry's hand-authored when-to-use text, 213 from the component's own doc-comment header, 26 from its tier barrel's roster line. **4** have none; they are listed under [Undescribed components](#undescribed-components) rather than given a sentence invented from their name.
|
|
21
21
|
|
|
22
|
-
Of those, **
|
|
22
|
+
Of those, **253** are *strong* — a capability sentence you could match a requirement against — and **29** are *weak*: either one short clause, or a long one that spends itself on wiring (client boundaries, class names, which primitives it composes) instead of on what the thing is for. Weak rows are marked `(weak)` and listed in full under [Weak descriptions](#weak-descriptions). Coverage is 99%, but **findable-without-luck coverage is 88%**.
|
|
23
23
|
|
|
24
|
-
Per tier, strong out of total: **Sections**
|
|
24
|
+
Per tier, strong out of total: **Sections** 53/54 · **Blocks** 81/86 · **Chrome** 10/17 · **Primitives** 64/79 (4 undescribed) · **Panels** 5/6 · **Shells** 2/3 · **Docs + Blog Blocks** 5/5 · **Docs + Blog Chrome** 1/1 · **Docs + Blog Shells** 0/2 · **Scheduling Sections** 2/2 · **Scheduling Blocks** 5/5 · **Signal-Collectors Sections** 3/3 · **Signal-Collectors Blocks** 7/8 · **Commerce Sections** 2/2 · **Commerce Blocks** 12/12 · **Commerce Panels** 1/1. A tier low on this line is a tier where a capability search is most likely to come up empty on something that exists.
|
|
25
25
|
|
|
26
26
|
That grade is **mechanical**. It counts what it can measure — how much a description adds beyond the component's own name, how much of it is spent on wiring, whether the extraction came out damaged — and it cannot tell a fluent paragraph about the wrong subject from a useful one. A person reading these tables will find more rows unusable than the weak count admits. Treat it as a floor on the problem, not a measurement of it, and read the source before concluding a capability is absent.
|
|
27
27
|
|
|
@@ -35,15 +35,15 @@ The left column is search vocabulary — how a person phrases the need. It is ha
|
|
|
35
35
|
| --- | --- | --- |
|
|
36
36
|
| contact overlay · modal form · popup form · form in a dialog · form on a dimmed backdrop · lightbox form | `FormLightbox` (sections) · `VideoLightbox` (blocks) · `SpotlightPanel` (sections) · `ContactForm` (sections) | FormLightbox is the modal-form one: a trigger opens a multi-step form inside a Radix Dialog on a dimmed/blurred backdrop (focus trap, ESC/backdrop close, scroll lock, lazy mount). ContactForm is the INLINE form — do not mistake it for the overlay and rebuild the overlay. |
|
|
37
37
|
| search overlay · command palette · cmd-K · ⌘K search · spotlight · quick find | `NavSearchTrigger` (blocks) · `AskAiCommandGroup` (blocks) · `SpotlightPanel` (sections) | Read this one carefully: AILK does NOT ship a site-wide ⌘K palette. It ships the PARTS — NavSearchTrigger (the ⌘K trigger pill), AskAiCommandGroup (a CommandGroup you drop into your own dialog), and the Command/CommandDialog primitives in `packages/ui/src/primitives`. Composing a site palette from these is expected; forking the dialog is not. SpotlightPanel is the dimmed-backdrop centered-card band — it hosts a form/flow, not a search index. |
|
|
38
|
-
| site rail · vertical nav column · left rail · app sidebar · icon rail · dashboard sidebar | `SidebarNav` (chrome) · `SidebarNavRailItems` (chrome) · `SidePanel` (chrome) | Pick by context: SidebarNav is the DASHBOARD rail (it hardcodes a teams section and a user footer, and is the `sidebar` prop of
|
|
38
|
+
| site rail · vertical nav column · left rail · app sidebar · icon rail · dashboard sidebar | `SidebarNav` (chrome) · `SidebarNavRailItems` (chrome) · `SidePanel` (chrome) | Pick by context: SidebarNav is the DASHBOARD rail (it hardcodes a teams section and a user footer, and is the `sidebar` prop of AdminShell) — fighting it into a marketing site is the wrong call; SidebarNavRailItems is SidebarNav's collapsed icon-rail row. SidePanel is the RIGHT edge, not a left rail. |
|
|
39
39
|
| funnel nav · minimal chrome with one CTA · stripped-down header · landing-page nav · one-action header · sticky CTA | `Nav` (chrome) · `SectionNav` (chrome) · `FloatingCta` (chrome) | There is no separate funnel-nav component, and there does not need to be: this is a CONFIGURATION of Nav — pass it one action and no link list. SectionNav is the in-page section jump nav; FloatingCta is the persistent floating single-action affordance. |
|
|
40
|
-
| numbered work list · ordered steps · process list · how it works · 1-2-3 steps · staircase | `Steps` (blocks) · `StepFlow` (sections) · `StairSteps` (sections) · `FlowStepper` (sections) | For a numbered LIST you want Steps (presentational block) or StairSteps (staggered staircase section). StepFlow
|
|
40
|
+
| numbered work list · ordered steps · process list · how it works · 1-2-3 steps · staircase | `Steps` (blocks) · `StepFlow` (sections) · `StairSteps` (sections) · `FlowStepper` (signal-collectors-sections) | For a numbered LIST you want Steps (presentational block) or StairSteps (staggered staircase section). StepFlow is listed because the phrase collides, but it is the interactive multi-step FORM — not a work list. FlowStepper is its progress indicator; #5581 U4 moved it into the paid `@working-theory/ui-signal-collectors` package, so it is indexed here but present only in a build with that module. |
|
|
41
41
|
| accordion · collapsible · expand/collapse · show more · disclosure | `Accordion` (primitives) · `Collapsible` (primitives) · `FaqItem` (blocks) · `FAQ` (sections) · `Objection` (sections) | `Accordion` is the standalone primitive (Radix, multi-panel) and `Collapsible` is the single show/hide — reach for those for generic disclosure. FaqItem and the FAQ/Objection sections carry their own expand/collapse and are the right choice for question-and-answer CONTENT, because they also feed the page's JSON-LD. |
|
|
42
42
|
| banner · announcement bar · cookie consent · notification strip | `Banner` (chrome) · `AlertSection` (sections) | Banner is chrome (announcement + consent, with dismiss/consent islands); AlertSection is the in-page dismissible strip. |
|
|
43
43
|
| logo wall · client logos · trusted by · partner marks | `LogoCloud` (sections) · `Awards` (sections) | |
|
|
44
44
|
| pricing table · plan comparison · feature matrix · tier cards | `Pricing` (sections) · `PricingTierCard` (blocks) · `ComparisonMatrix` (blocks) · `ComparisonTable` (sections) · `BillingToggle` (blocks) | |
|
|
45
45
|
| avatar stack · people grid · about-us team · bios | `Team` (sections) · `TeamMemberCard` (blocks) | |
|
|
46
|
-
| booking · scheduling · calendar · pick a time · appointment | `Booker` (sections) · `SchedulerEmbed` (blocks) | Booker is the in-page day-strip/slot-grid transaction; SchedulerEmbed is the third-party provider iframe. |
|
|
46
|
+
| booking · scheduling · calendar · pick a time · appointment | `Booker` (scheduling-sections) · `SchedulerEmbed` (blocks) | Booker is the in-page day-strip/slot-grid transaction; SchedulerEmbed is the third-party provider iframe. |
|
|
47
47
|
| sign in · sign up · login form · oauth buttons · account menu | `AuthPanel` (sections) · `AuthCard` (blocks) · `AccountMenu` (chrome) | |
|
|
48
48
|
| email capture · newsletter signup · subscribe box | `Newsletter` (sections) · `NewsletterFormInline` (blocks) · `NewsletterDetail` (blocks) | |
|
|
49
49
|
| video player · embedded video · video modal | `VideoSection` (sections) · `VideoEmbed` (blocks) · `VideoLightbox` (blocks) | |
|
|
@@ -53,7 +53,7 @@ The left column is search vocabulary — how a person phrases the need. It is ha
|
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
|
-
## Sections (
|
|
56
|
+
## Sections (54)
|
|
57
57
|
|
|
58
58
|
Page-level content bands. Most are MDX-driven (authored by `type` in page frontmatter and dispatched by `SectionRenderer`); a few are composed directly in a route.
|
|
59
59
|
|
|
@@ -69,8 +69,6 @@ Import: `import { X } from "@working-theory/ui/sections";` (or from the `@workin
|
|
|
69
69
|
| `BentoGrid` | A mixed-span mosaic of feature cards — use for a visually varied capability overview. | MDX `type: bento-grid` · `import { BentoGrid } from "@working-theory/ui/sections"` |
|
|
70
70
|
| `BlogList` | A blog post list with pagination — use for the blog index page only. | MDX `type: blog-list` · `import { BlogList } from "@working-theory/ui/sections"` |
|
|
71
71
|
| `BlogPost` | A single blog post body with TOC and related posts — use only on the blog-post chassis. | MDX `type: blog-post` · `import { BlogPost } from "@working-theory/ui/sections"` |
|
|
72
|
-
| `Booker` | The custom booker — use on a scheduling page where the whole see-days/pick-slot/confirm transaction should land in the page itself rather than a provider iframe (the `scheduler-embed` alternative). Authors supply only `calLink` plus optional eyebrow/headline framing; duration, meeting type, and timezone are DERIVED from the calendar via /v1/schedule/availability and can never be typed into content. | MDX `type: booker` |
|
|
73
|
-
| `BookerIsland` | The island owns exactly two things: the state machine, and the two calls across the scheduling seam. It talks to `/v1/schedule/availability` and `/v1/schedule/book` — never to a provider — so the day this deploy flips to the self-hosted engine, nothing in this file changes. | internal — compose from `packages/ui/src/sections/BookerIsland.tsx` |
|
|
74
72
|
| `Carousel` | An image carousel/slider — use for a sequential set of visual items in constrained space. | MDX `type: carousel` · `import { Carousel } from "@working-theory/ui/sections"` |
|
|
75
73
|
| `ComparisonTable` | A general-purpose entity-vs-entity comparison — use for /vs pages, not tied to pricing plans. | MDX `type: comparison-table` |
|
|
76
74
|
| `ContactChannels` | A support channel directory — use to list alternate ways to reach the team (icon + title + description + CTA). | MDX `type: contact-channels` · `import { ContactChannels } from "@working-theory/ui/sections"` |
|
|
@@ -85,7 +83,6 @@ Import: `import { X } from "@working-theory/ui/sections";` (or from the `@workin
|
|
|
85
83
|
| `DocumentViewerClient` | The interactive shell for DocumentViewer. Split out of DocumentViewer.tsx (which stays RSC) for the same reason AlertSection composes AlertSectionDismissIsland: interactivity is contained to one client island. *(weak)* | internal — compose from `packages/ui/src/sections/DocumentViewerClient.tsx` |
|
|
86
84
|
| `FAQ` | Question-and-answer pairs — use to pre-empt buyer objections that are naturally phrased as questions. | MDX `type: faq` · `import { FAQ } from "@working-theory/ui/sections"` |
|
|
87
85
|
| `Feature` | A multi-item benefit/feature highlight grid — use to walk through several product capabilities. | MDX `type: feature` |
|
|
88
|
-
| `FlowStepper` | Rendering a served flow config as a real multi-step form. | internal — compose from `packages/ui/src/sections/FlowStepper.tsx` |
|
|
89
86
|
| `FormLightbox` | The VideoLightbox dialog shell hosting a StepFlow instead of a video: a trigger (e.g. a "Let's Start" Button — any focusable element the caller supplies) opens the SAME StepFlow inside a Radix Dialog on the dimmed/blurred backdrop shared with VideoLightbox/SpotlightPanel. | `import { FormLightbox } from "@working-theory/ui/sections"` |
|
|
90
87
|
| `Gallery` | An image gallery — use to showcase product screenshots or visual work. | MDX `type: gallery` · `import { Gallery } from "@working-theory/ui/sections"` |
|
|
91
88
|
| `GlossaryIndex` | An A-Z glossary index — use for a browsable list of defined terms. | MDX `type: glossary-index` · `import { GlossaryIndex } from "@working-theory/ui/sections"` |
|
|
@@ -95,17 +92,15 @@ Import: `import { X } from "@working-theory/ui/sections";` (or from the `@workin
|
|
|
95
92
|
| `HeroPromptCapture` | The Hero `promptCapture` opt-in's wiring. Composes the two new blocks — `PromptCaptureCard` (the chat-style card) and `SuggestionChipCarousel` (the one-expanded-slot chip row) — and owns the ONE piece of state they share: the typed text. A chip click writes into it; the card renders and edits it; submit carries it onward. | `import { HeroPromptCapture } from "@working-theory/ui/sections"` |
|
|
96
93
|
| `HeroQuickSearch` | Surfaces the existing ⌘K quick-search as an inline trigger inside the hero CTA cluster (Chassis 2). It does NOT re-roll a search input: it composes the SearchInputTrigger primitive (an input-style control at CTA height) plus the Command palette primitive, so there is ONE search mechanism. The nav's compact 24px ⌘K pill stays as-is — the hero reads as a search INPUT, matching the 44px "Get Started" CTA. | internal — compose from `packages/ui/src/sections/HeroQuickSearch.tsx` |
|
|
97
94
|
| `Items` | A general-purpose card/items grid — use for services, use cases, or any homogeneous list of cards. | MDX `type: items` · `import { Items } from "@working-theory/ui/sections"` |
|
|
98
|
-
| `ListingApplicationFlow` | This is the thing a consuming site mounts INSTEAD of hand-writing three proxy routes, a save-on-advance form, and a decision about where a bearer token lives. | internal — compose from `packages/ui/src/sections/ListingApplicationFlow.tsx` |
|
|
99
95
|
| `LogoCloud` | A customer/partner logo wall — use for trust-by-association social proof. | MDX `type: logoCloud` · `import { LogoCloud } from "@working-theory/ui/sections"` |
|
|
100
96
|
| `MDXContent` | The keystone the docs route and blog both render their compiled MDX through. | `import { MDXContent } from "@working-theory/ui/sections"` |
|
|
101
97
|
| `MediaBand` | A single full-width image band — use for the 1-up visual moment Gallery's 2-column minimum can't express (e.g. between pricing plan columns); renders a labeled placeholder until a real image is supplied. | MDX `type: media-band` · `import { MediaBand } from "@working-theory/ui/sections"` |
|
|
102
98
|
| `ModuleAbsent` | What a slice section renders when its module is not here. The oss dispatch table must name a component for every `SectionName`, and `booker`'s real component strips with the scheduling slice. This is the entry it names instead; a slice that IS installed registers over it through `registerSliceRenderer`. | internal — compose from `packages/ui/src/sections/ModuleAbsent.tsx` |
|
|
103
99
|
| `Newsletter` | An email signup form — use for a low-commitment conversion ask. | MDX `type: newsletter` · `import { Newsletter } from "@working-theory/ui/sections"` |
|
|
104
100
|
| `Objection` | Objection-and-response pairs — use for you-might-think rhetoric that isn't phrased as a question. | MDX `type: objection` |
|
|
105
|
-
| `PaymentReceipt` | A checkout payment outcome — use only on a checkout Delivery/confirmation page to show status + receipt details. | MDX `type: payment-receipt` |
|
|
106
101
|
| `Pricing` | A plan comparison — the page's pricing decision surface; six variants cover tables, toggles, single-price offers, and add-on grids. | MDX `type: pricing` · `import { Pricing } from "@working-theory/ui/sections"` |
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
102
|
+
| `ReportHeader` | The tiny header the chrome-off report reader puts above the document — a back arrow and the report's title, nothing else. Use it ONLY with `document-viewer` on a /reports/<slug> page; it is not a hero and has no description, CTA or media slot. `backHref` is optional: a reader who arrived from an emailed link has nowhere to go back to, and the header renders the title alone rather than a dead control. | MDX `type: report-header` |
|
|
103
|
+
| `ReportsList` | A listing of reports, each linking to /reports/<slug>. Two variants over one data shape: `cards` (default) is a titled grid with cover, date and a Read link — the home or resources listing; `list` is centered titles with dates and no covers, for a full-bleed slide (set `tone: "on-dark"` on a dark surface). Not for blog posts — that is `blog-list`. | MDX `type: reports-list` |
|
|
109
104
|
| `SchedulerEmbed` | A declarative third-party booking iframe (e.g. Google Calendar Appointment Schedules) — use for a booking/scheduling moment; sets the provider's cookies on load, so a site classifying it as non-essential may wrap it in a consent gate. | MDX `type: scheduler-embed` · `import { SchedulerEmbed } from "@working-theory/ui/sections"` · `packages/ui/src/sections/SchedulerEmbed.tsx` |
|
|
110
105
|
| `SectionEmpty` | The shared empty-state body every section's `*Empty` variant delegates to. | `import { SectionEmpty } from "@working-theory/ui/sections"` |
|
|
111
106
|
| `SectionRenderer` | Typed dispatch table. Maps a section's `type` discriminant to its React component. | `import { SectionRenderer } from "@working-theory/ui/sections"` |
|
|
@@ -123,7 +118,7 @@ Import: `import { X } from "@working-theory/ui/sections";` (or from the `@workin
|
|
|
123
118
|
|
|
124
119
|
---
|
|
125
120
|
|
|
126
|
-
## Blocks (
|
|
121
|
+
## Blocks (86)
|
|
127
122
|
|
|
128
123
|
Intermediate composition tiles — the pieces sections are built from. Compose primitives and panels; never import a section.
|
|
129
124
|
|
|
@@ -144,15 +139,8 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
144
139
|
| `BadgeRow` | Horizontal cluster of static badge labels used by Hero and Feature section families for `data.badge` and tag-list patterns. | `import { BadgeRow } from "@working-theory/ui/blocks"` |
|
|
145
140
|
| `BillingToggle` | Monthly / Annual billing period toggle for the Pricing section. Purely presentational — click handlers come from the parent (Pricing section). No "use client" needed at the block level; the parent Pricing section is "use client" and passes the callbacks down. | `import { BillingToggle } from "@working-theory/ui/blocks"` |
|
|
146
141
|
| `BlogPostHeader` | Layout: the better-auth sticky left rail — eyebrow ← back-link · decorative title · author byline · date/reading-time meta · tags. Per the title here is DECORATIVE (aria-hidden): the semantic `<h1>` is rendered atop the right content column by `BlogPost` (bodyOnly), so the page keeps exactly one heading. | `import { BlogPostHeader } from "@working-theory/ui/blocks"` |
|
|
147
|
-
| `BookerAttendeeFields` | TWO FIELDS. A booking needs somewhere to send the invite and a name to put on it; every additional field is one more reason to abandon a transaction the user had already decided to complete. Notes, phone, and company are deliberately absent — the provider collects them after the invite lands, if the operator wants them at all. | internal — compose from `packages/ui/src/blocks/BookerAttendeeFields.tsx` |
|
|
148
|
-
| `BookerDateStrip` | ONLY DAYS THAT HAVE OPEN SLOTS APPEAR. That is the structural argument this block makes, and the reason the composition is a horizontal strip rather than the month grid every booking widget reaches for: a month grid spends its whole area rendering the ~24 days you cannot book, then needs a second interaction to reveal which of the remaining six are live. | internal — compose from `packages/ui/src/blocks/BookerDateStrip.tsx` |
|
|
149
|
-
| `BookerEventHeader` | TWO KINDS OF TEXT, AND THE DIFFERENCE MATTERS. `eyebrow` and `headline` are AUTHORED: the operator's words about why someone would book. Everything in the meta row — duration, meeting type, timezone — is DERIVED from the calendar on the availability read, which is why the section schema has no field for any of it. | internal — compose from `packages/ui/src/blocks/BookerEventHeader.tsx` |
|
|
150
|
-
| `BookerPanel` | The booking card, fully controlled. One chassis, five views, ONE FOOTER. | internal — compose from `packages/ui/src/blocks/BookerPanel.tsx` |
|
|
151
|
-
| `BookerSlotGrid` | The selected day's open times. Two columns at 48px on mobile — the measured pixel target — widening to three at `lg` so the desktop variant shows more of the day without scrolling. Two columns is not an arbitrary density: at 390px it is the widest grid where a time still reads at a glance, and it puts eight times (a full working day's openings) inside one thumb-reachable block. | internal — compose from `packages/ui/src/blocks/BookerSlotGrid.tsx` |
|
|
152
142
|
| `BrandLogo` | Brand identity lockup (mark + wordmark + badge slot) as a home link. Brand identity lockup for Nav, Footer, and other surfaces. | `import { BrandLogo } from "@working-theory/ui/blocks"` |
|
|
153
143
|
| `Card` | The base surface-chrome block the section tier composes instead of hand-rolling `rounded + hairline border + surface + p-card` (7× duplicated at time). A block owns its visual identity: it looks the same everywhere it is composed, and a higher tier SELECTS a look via `variant` — it never patches via className. | `import { Card } from "@working-theory/ui/blocks"` |
|
|
154
|
-
| `CheckoutForm` | Product/amount selection + checkout submit for the one-time checkout surface. | internal — compose from `packages/ui/src/blocks/CheckoutForm.tsx` |
|
|
155
|
-
| `CheckoutPriceCard` | DESIGN 's checkout price card: the panel's fourth view once it flips to the right and becomes an order summary — eyebrow, offer name + description, seat/credit line items, an optional caller-supplied add-credits row, and the total + due-today. | internal — compose from `packages/ui/src/blocks/CheckoutPriceCard.tsx` |
|
|
156
144
|
| `ChoiceCard` | Onboarding "Is this you?" disambiguation card — reimplements the ploy.ai persona-disambiguation capture: a researched candidate option vs a "none of these are me" option, confirmed by the user ("a human-input seam the user answers to orient the agent"). Purely presentational and props-driven: renders options + an optional "none of these" option + a confirm action, disabled until a selection is made. | `import { ChoiceCard } from "@working-theory/ui/blocks"` |
|
|
157
145
|
| `CodeBlock` | Read-only code display with syntax highlighting. Modeled on the Claude docs code-block pattern. | `import { CodeBlock } from "@working-theory/ui/blocks"` |
|
|
158
146
|
| `ComparisonMatrix` | Full feature × tier comparison matrix for the Pricing 'with-comparison-table' variant. Renders N collapsible ComparisonGroups, each containing M feature rows with per-tier values. | `import { ComparisonMatrix } from "@working-theory/ui/blocks"` |
|
|
@@ -162,36 +150,25 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
162
150
|
| `ContactChannelItem` | Renders one support channel entry: colored icon square + headline + description paragraph + CTA link (with trailing arrow icon). | `import { ContactChannelItem } from "@working-theory/ui/blocks"` |
|
|
163
151
|
| `ContactFormFields` | Renders the form field grid (Input / Textarea / Select primitives) + submit Button + optional consent text footer. | `import { ContactFormFields } from "@working-theory/ui/blocks"` |
|
|
164
152
|
| `ContactInfoAside` | For ContactForm 'split-with-pattern' variant. Renders address / phone / email contact info rows. Each row: sr-only <dt> label + visible <dd> with Icon + Text. Phone and email render as tel:/mailto: links (click-to-call / click-to-email). | `import { ContactInfoAside } from "@working-theory/ui/blocks"` |
|
|
165
|
-
| `ConversationalIntake` | The UI half of the conversational-intake feature: renders the transcript, closed-question answer pills, a free-text form, a thinking indicator, and Skip — driven entirely through the `NextTurn` interface exported by `./engine` (merged). |
|
|
153
|
+
| `ConversationalIntake` | The UI half of the conversational-intake feature: renders the transcript, closed-question answer pills, a free-text form, a thinking indicator, and Skip — driven entirely through the `NextTurn` interface exported by `./engine` (merged). | `import { ConversationalIntake } from "@working-theory/ui/blocks"` |
|
|
166
154
|
| `DescriptionList` | Semantic <dl> of aligned term/definition rows (rows + inline layouts). A semantic <dl> rendering label/value rows from an `items` prop. Each item is a <dt> (muted, min-width-aligned term) paired with a <dd> (value). The value is a ReactNode, so callers compose richer values (spans, lists, mono text) inside it. | `import { DescriptionList } from "@working-theory/ui/blocks"` |
|
|
167
155
|
| `DetailCard` | The collapsible console / data-panel card: a composable card with a header (title + optional actions + collapse toggle), an optional tab bar, a body slot, and an optional footer. The "deferred SidePanel DetailCard" from, built as a general content card any console / detail view can compose without inventing its own card structure. | `import { DetailCard } from "@working-theory/ui/blocks"` |
|
|
168
156
|
| `DetailHeader` | The entity-bearing sibling of PageHeader: a Breadcrumb wayfinding trail above an EntityHeader identity row, plus a forwarded actions slot. | `import { DetailHeader } from "@working-theory/ui/blocks"` |
|
|
169
157
|
| `DistributionList` | Per-option answer-share list over the Progress primitive. One question's answer distribution: a title, an "answered" count line, and one row per declared option (a label, a pre-formatted share `display` string, and a `Progress` bar). `display` is pre-formatted by the caller (Rule 10 — this block never formats numbers itself); `share` drives the `Progress` fill, scaled to the primitive's 0–100 range. | `import { DistributionList } from "@working-theory/ui/blocks"` |
|
|
170
|
-
| `DocsActionBar` | The agent-facing article toolbar that lands in the DocsArticleHeader `actionBar` slot, presented as the Claude-docs **"Copy page ▾" split button**. The in-page rendered↔markdown toggle is NOT reimplemented here — that is the existing MarkdownViewToggle block, which the route mounts around the article body. This bar only adds the copy + open-in affordances. | internal — compose from `packages/ui/src/blocks/DocsActionBar.tsx` |
|
|
171
|
-
| `DocsArticleHeader` | The article header: a breadcrumb trail (with the TOC popover button at its inline-end), the page title (the single <h1>), an optional lead description, and an "updated" meta line. Leaves an `actionBar` slot for the Phase-5 DocsActionBar (markdown toggle / copy / share) — empty until then. | internal — compose from `packages/ui/src/blocks/DocsArticleHeader.tsx` |
|
|
172
|
-
| `DocsFeedback` | The article-footer feedback widget: a "Was this helpful?" thumbs yes/no pair plus an "Edit this page on GitHub" link. Clicking a thumb records the answer (fires a `gtag` analytics event when the site's GA is present) and, on "no", reveals an optional free-text note. After answering, the prompt is replaced with a thank-you line. | internal — compose from `packages/ui/src/blocks/DocsFeedback.tsx` |
|
|
173
|
-
| `DocsSearch` | The cmd-K documentation search: a ⌘K trigger pill (NavSearchTrigger) that opens a CommandDialog over a passed-in search index. Typing filters the index by title/description (cmdk's built-in filter, fed a `value` that bundles both); selecting a result navigates there. | internal — compose from `packages/ui/src/blocks/DocsSearch.tsx` |
|
|
174
|
-
| `DocsTocButton` | Clicking the `List`-icon button opens a Popover rendering the shared `TableOfContents` (styling preserved). Esc / outside-click closes it (Radix default); in-page anchor jumps work as they do in the rail. The button renders nothing when there are no TOC entries, so the breadcrumb row stays clean on heading-less / `wide` pages. | internal — compose from `packages/ui/src/blocks/DocsTocButton.tsx` |
|
|
175
158
|
| `EntityHeader` | The single identity-row source: an optional leading avatar, a title/name (Heading), an optional subtitle/meta line (Text), an optional type-badge slot above the title, and an optional trailing actions slot. | `import { EntityHeader } from "@working-theory/ui/blocks"` |
|
|
176
159
|
| `FaqItem` | Q&A pair block for FAQ section families (expanded + accordion). Defaults reproduce the current render except the deliberate item-spacing-asymmetry fix. | `import { FaqItem } from "@working-theory/ui/blocks"` |
|
|
177
160
|
| `FeatureCard` | Icon badge + title + a short check-list + an optional "Learn more" link — the card used in HubSpot's right-hand product grid. Generalizes the inline card markup currently hand-rolled in sections/Feature.tsx. | `import { FeatureCard } from "@working-theory/ui/blocks"` |
|
|
178
161
|
| `FeatureCardGrid` | Responsive column schedule (mobile-first, uniform cells): base. Uniform responsive grid of FeatureCard tiles. Strictly equal-span cells at every breakpoint; use BentoGrid for variable-span layouts. | `import { FeatureCardGrid } from "@working-theory/ui/blocks"` |
|
|
179
162
|
| `FloatingBar` | Z-40 (spec) — the same rung Nav's sticky bar and FloatingCta already occupy; no new z-index token. The same-slot takeover works by DOM ORDER, not a higher z: a `position="sticky"` FloatingBar rendered later in the document (inside body content, after the nav) paints over a `fixed` FloatingBar at equal z-40 once it sticks, given an `opaque` surface. | internal — compose from `packages/ui/src/blocks/FloatingBar.tsx` |
|
|
180
|
-
| `FlowSidePanel` | The per-view side panel of the flow/recommender surface. ONE CHASSIS, THREE VIEWS. | internal — compose from `packages/ui/src/blocks/FlowSidePanel.tsx` |
|
|
181
163
|
| `FooterBottomBar` | Separator + copyright line (+ optional trailing social). Bottom bar with a single top divider + copyright line. | `import { FooterBottomBar } from "@working-theory/ui/blocks"` |
|
|
182
164
|
| `FooterNav` | Data-driven footer nav: flat row or titled columns (row/columns layout). These two renderings of the same footer-link data were used mutually-exclusively by the chrome `Footer`'s `layout` switch — collapsing them removes a real either/or the parent managed. | `import { FooterNav } from "@working-theory/ui/blocks"` |
|
|
183
165
|
| `FormCard` | Stateless, centered max-w-md form-card chassis: a Card wrapping an optional title + description header, a field-stack body (children), and a footer slot for the primary action + a secondary line below it. The SHARED look composed by both the contact-form section's 'card' variant and the auth-panel section — this block owns none of their field/state machinery, only the surrounding chrome. | `import { FormCard } from "@working-theory/ui/blocks"` |
|
|
184
166
|
| `InviteMemberDialog` | The invite modal — reimplements the ploy.ai "Invite Team Member" capture (Email textbox + Role select, default Member, options Member/Admin, helper "Admins can invite and remove members." + Send Invitation). | `import { InviteMemberDialog } from "@working-theory/ui/blocks"` |
|
|
185
|
-
| `InvoiceForm` | Creates a draft invoice (single line item), for the invoice surface (U4). | internal — compose from `packages/ui/src/blocks/InvoiceForm.tsx` |
|
|
186
|
-
| `InvoiceList` | A customer's invoice rows, shared by the invoice surface (U4). Capability-bearing: binds a schema.org `Invoice` resource-payload fragment per row (imported from `@working-theory/schema`) — so a co-located `.text.ts` + `.text.test.ts` renderer is required and gated by `scripts/check-ax-parity.sh`. | internal — compose from `packages/ui/src/blocks/InvoiceList.tsx` |
|
|
187
167
|
| `KeyPointsPanel` | ONE shared block composed by two consumers: Hero's `panel` variant (text-left / panel-right) and Pricing's `band-hero` arrangement (header-left / panel-right, tiers below). | internal — compose from `packages/ui/src/blocks/KeyPointsPanel.tsx` |
|
|
188
168
|
| `LinkCard` | A whole-tile link card: the entire tile IS the anchor (Claude-docs link-card anatomy). Optional leading icon, a title heading, and an optional description paragraph. Hover fill + chrome are intrinsic to the block — never props. | `import { LinkCard } from "@working-theory/ui/blocks"` |
|
|
189
169
|
| `LinkListItem` | Hub-page spoke list row: prose Link + optional description, enlarged to the 44px touch-target floor. Fix: the enlarged-hit-area pattern (same idiom as ShortcutTrigger, SegmentedControl's touchTargetFloor) — `min-h-(control-height-big)` clamps the anchor's clickable box to 44px while `inline-flex items-center` keeps the visible text at its normal prose size. | `import { LinkListItem } from "@working-theory/ui/blocks"` |
|
|
190
|
-
| `ListingFullPreview` | The full-page-preview `custom` step renderer. The founder's assembled application, rendered as a page, with an edit link back to the step that owns each rendered part. Purely presentational: every entry's label and formatted value arrive pre-built on `entries` (this block does no formatting of its own), and `onEdit` is the only way it ever changes anything — it never mutates, saves, or fetches. | internal — compose from `packages/ui/src/blocks/ListingFullPreview.tsx` |
|
|
191
|
-
| `ListingPrivacyNotice` | The per-listing privacy notice. It names the FOUNDER — not the platform — as the party collecting a visitor's personal data, and it renders ON THE FLOW (where a visitor submits answers), not on the listing page. | internal — compose from `packages/ui/src/blocks/ListingPrivacyNotice.tsx` |
|
|
192
|
-
| `ListingQuestionReview` | The edit-only question-review `custom` step renderer. The founder is refining a diagnostic template the SITE authored, not composing one from nothing (`projectListingQuestionsSchema`, `packages/validation/src/schemas/project-listings.ts`). | internal — compose from `packages/ui/src/blocks/ListingQuestionReview.tsx` |
|
|
193
|
-
| `ListingTilePreview` | The founder's tile, as it will look, updating as they type. | internal — compose from `packages/ui/src/blocks/ListingTilePreview.tsx` |
|
|
194
170
|
| `LocaleSwitcher` | Compact globe + locale dropdown. Extracts the "🌐 English ▾" affordance that lived as an inline node in the chrome Footer story into a reusable block. Composes the `Select` primitive (NOT a raw <select>): a leading globe icon, the current locale label (via SelectValue), and the trigger's built-in chevron. | `import { LocaleSwitcher } from "@working-theory/ui/blocks"` |
|
|
171
|
+
| `LocaleSwitcherNav` | Composes the controlled `LocaleSwitcher` block and owns the navigation side-effect that block deliberately leaves to its consumer: on a locale change it writes the `NEXT_LOCALE` cookie and navigates to the as-needed prefixed path (default locale unprefixed, every other locale `/<code>` + path — mirroring `apps/web/middleware.ts`'s `localePrefix: "as-needed"`). | `import { LocaleSwitcherNav } from "@working-theory/ui/blocks"` |
|
|
195
172
|
| `LogoRow` | The ONE logo-strip implementation; bounded layout/treatment/logoSize plus an opt-in motion-safe marquee; composed by the LogoCloud section and the Hero logoStrip opt-in. | `import { LogoRow } from "@working-theory/ui/blocks"` |
|
|
196
173
|
| `MarkdownViewToggle` | 2-state rendered ↔ markdown view toggle for content pages. The human complement to the agent-facing /llms.txt surface. Mirrors the Claude-docs "view/copy as markdown" affordance. Ships at Tier 3 (Block) because it is an interactive view-toggle control composing the SegmentedControl primitive with the CodeBlock block — not a page-level layout shell. | `import { MarkdownViewToggle } from "@working-theory/ui/blocks"` |
|
|
197
174
|
| `MediaFigure` | The reusable *frame* for the visual half of a split section: an `Image` constrained by an optional `AspectRatio`, with consistent rounding, an optional caption, an optional decorative frame, and an optional overlay slot + scrim for text/badges/play-buttons over media. | `import { MediaFigure } from "@working-theory/ui/blocks"` |
|
|
@@ -204,27 +181,18 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
204
181
|
| `NewsletterDetail` | One "why subscribe" detail item: colored icon square + headline + description. Vertically arranged (icon top, heading + description below). Used in the right-column 2-up grid of the 'side-by-side-with-details' variant. | `import { NewsletterDetail } from "@working-theory/ui/blocks"` |
|
|
205
182
|
| `NewsletterFormInline` | Inline email signup form: email Input + submit Button side-by-side at sm+, stacked on mobile (input full-width on its own row, Subscribe below). Manages its own submit state so the parent Newsletter section can remain RSC-oriented (only this block needs the client boundary). | `import { NewsletterFormInline } from "@working-theory/ui/blocks"` |
|
|
206
183
|
| `OnboardingChecklist` | Global onboarding launcher: floating "N/5" bubble expanding into a Popover (lg+) / bottom Sheet (<lg) checklist with SegmentedProgress + item rows (ploy-capture recomposition). The global onboarding launcher captured off ploy.ai's app frame (behavior spec: `post-ftu-checklist` — "global onboarding launcher (floating, all pages)"). | `import { OnboardingChecklist } from "@working-theory/ui/blocks"` |
|
|
207
|
-
| `PageHeader` | RSC. Page-level header composing the Breadcrumb primitive for the left-side wayfinding trail, a generic right-side `actions` slot, and an optional `switcher` slot for header-owned segment switching. Fills AppShell's `header` slot (
|
|
184
|
+
| `PageHeader` | RSC. Page-level header composing the Breadcrumb primitive for the left-side wayfinding trail, a generic right-side `actions` slot, and an optional `switcher` slot for header-owned segment switching. Fills AppShell's `header` slot (AdminShell and similar). No accent bar. No tab API. No named action props — the caller assembles whatever button/menu nodes it needs and passes them as `actions`. *(weak)* | `import { PageHeader } from "@working-theory/ui/blocks"` |
|
|
208
185
|
| `PageHeaderSwitcher` | Header-owned context-switcher island (DropdownMenu-backed). Header-owned segment switcher rendered inside PageHeader's `switcher` slot. Composes DropdownMenu (Radix-backed — positioning, click-outside, Escape, focus management, and roving keyboard nav all come for free). | `import { PageHeaderSwitcher } from "@working-theory/ui/blocks"` |
|
|
209
186
|
| `PairingCard` | Quiet card naming a matched WaitlistRecommendation pairing: both resolved offer names + the resolved reason, joined against a caller-supplied offers[] by key. | `import { PairingCard } from "@working-theory/ui/blocks"` |
|
|
210
|
-
| `PaymentLinkCard` | A single shareable Stripe Payment Link (pay-by-link surface). Renders the link's offer name, active-status chip, optional amount, and the hosted URL with a one-click copy action. | internal — compose from `packages/ui/src/blocks/PaymentLinkCard.tsx` |
|
|
211
|
-
| `PaymentLinkForm` | Product selection + "create link" submit for the pay-by-link surface. | internal — compose from `packages/ui/src/blocks/PaymentLinkForm.tsx` |
|
|
212
|
-
| `PaymentLinkList` | A site owner's shareable payment links (pay-by-link surface). Composes one `PaymentLinkCard` per link. | internal — compose from `packages/ui/src/blocks/PaymentLinkList.tsx` |
|
|
213
|
-
| `PaymentResult` | Success/cancel result state for the one-time checkout surface — the terminal render a consumer's success/cancel return-URL page shows after the Stripe-hosted Checkout redirect. | internal — compose from `packages/ui/src/blocks/PaymentResult.tsx` |
|
|
214
|
-
| `PaymentStatusBadge` | Payment-state chip shared by the invoice-status (U4) and subscription-status (U5) surfaces. | internal — compose from `packages/ui/src/blocks/PaymentStatusBadge.tsx` |
|
|
215
187
|
| `PhoneNumberField` | Single-box combo phone input for the "tel" field kind (supersedes the two-segment country-Select + number-Input layout). | `import { PhoneNumberField } from "@working-theory/ui/blocks"` |
|
|
216
|
-
| `PortalEntry` | A standalone "Manage billing" entry point into Stripe's hosted Customer Portal — the smallest surface (spec: AILK owns only the entry; Stripe hosts the portal itself). | internal — compose from `packages/ui/src/blocks/PortalEntry.tsx` |
|
|
217
188
|
| `PostRow` | A single horizontal row in the two-column blog index: a landscape cover thumbnail (left) followed by the post's title · excerpt · author+date meta · tag list. The WHOLE row is one link (aria-labelled by the title, so screen readers announce the post title rather than the concatenated row content). | `import { PostRow } from "@working-theory/ui/blocks"` |
|
|
218
189
|
| `PricingExtraTierRow` | Compact horizontal extra-tier row for the Pricing 'two-tiers-with-extra-tier' variant. Renders plan name + description on the left and a CTA on the right. Structurally different from PricingTierCard (no price display in this variant). | `import { PricingExtraTierRow } from "@working-theory/ui/blocks"` |
|
|
219
190
|
| `PricingTierCard` | Single pricing tier card (all 4 Pricing variants). Renders a single pricing tier: plan name + optional badge, description, price display, CTA button, and feature checklist. | `import { PricingTierCard } from "@working-theory/ui/blocks"` |
|
|
220
191
|
| `PricingTierCardFeaturesDisclosure` | Phone-breakpoint (<md, 768px — the same phone/tablet step CardGrid's own mobile-stacking ramp uses) presentation of a tier card's feature list: collapsed behind a disclosure button so price + CTA (which render ABOVE this row, see PricingTierCard's row-slot ordering) fit the first card view on a phone — the wisprflow.ai/pricing pattern. `md` and up renders the SAME feature list, always expanded, in a second, non-interactive tree — desktop/tablet is unaffected by the collapse. | `import { PricingTierCardFeaturesDisclosure } from "@working-theory/ui/blocks"` |
|
|
221
192
|
| `PricingTierCardSeatControl` | Seat-count range picker for the Team tier card. Renders a Select primitive that lets the user choose an "Up to N seats" option from a caller-supplied list of numbers. The parent PricingTierCard stays a pure RSC; only this tiny island is hydrated. Pattern mirrors PageHeaderSwitcher.tsx: small "use client" island imported by an otherwise-server-rendered parent, keeping the client bundle minimal. *(weak)* | `import { PricingTierCardSeatControl } from "@working-theory/ui/blocks"` |
|
|
222
|
-
| `ProjectListingCard` | The tile for one listing on a shelf (`ProjectListingShelves`). The whole tile is a single anchor (LinkCard's bespoke-by-semantics precedent: Card renders a <div> and cannot satisfy a whole-tile-link contract, so this composes Link directly rather than Card). | internal — compose from `packages/ui/src/blocks/ProjectListingCard.tsx` |
|
|
223
193
|
| `PromptCaptureCard` | The chat-style prompt card: a multiline field carrying the authored placeholder, with a circular arrow submit control pinned bottom-right that stays muted (disabled) until the visitor has typed something. Enter submits; Shift+Enter inserts a newline — the chat-composer convention. | `import { PromptCaptureCard } from "@working-theory/ui/blocks"` |
|
|
224
194
|
| `Prose` | The single typography wrapper both the docs route and blog render their compiled-MDX body inside. It styles every RAW markdown element a compiled document emits — h2–h6, p, ul/ol/li, blockquote, table parts, hr, a, inline code, pre, img, kbd, strong/em — via `@working-theory/theme` semantic tokens and type roles. No raw color or spacing literals; dark mode rides the semantic tokens (no `dark:` variants needed). | `import { Prose } from "@working-theory/ui/blocks"` |
|
|
225
195
|
| `RecommendationCard` | "For you" proactive-recommendation tile: status + title + description + "Why this?" disclosure + context chip + action + dismiss (ploy-capture recomposition). The "For you" proactive-recommendation card captured off ploy.ai's Overview page (behavior spec: -2, — `overview-page` "For you" feed / rebuild-triage row "For you" recommendation card"). | `import { RecommendationCard } from "@working-theory/ui/blocks"` |
|
|
226
|
-
| `ResponseChart` | The single-question aggregate chart of the diagnostic's results reveal. Renders exactly ONE `FlowAggregateQuestion`. The chart type is FIXED by `question.answerType` — a closed `single \| multi` union — and there is no `chartType`/`variant` prop: an author cannot request a doughnut for a multi-select question, because there is no prop through which to ask. | internal — compose from `packages/ui/src/blocks/ResponseChart.tsx` |
|
|
227
|
-
| `ResultsReveal` | The results-reveal active-region composition: one ResponseChart per resultsReveal-flagged, aggregate-matched segmentation step, in served order. | internal — compose from `packages/ui/src/blocks/ResultsReveal.tsx` |
|
|
228
196
|
| `SchedulerEmbed` | A declarative third-party booking iframe. Renders a full-width, border-0, lazy-loaded <iframe> at `src` with a graceful loading skeleton (shown until the iframe's own `load` event fires) and a timeout-gated plain-link fallback beneath it — for environments that block third-party frames (ad blockers, a strict CSP `frame-src`) where the iframe may load blank or never load at all. | `import { SchedulerEmbed } from "@working-theory/ui/blocks"` · `packages/ui/src/blocks/SchedulerEmbed.tsx` |
|
|
229
197
|
| `SectionHeader` | Alignment-parameterized section header (eyebrow/subtitle/description/supportLink). The same component serves two ranks (headingLevel="section" \| "subsection") and three alignments (align="start" \| "center" \| "end"). It knows nothing about columns/splits/carousels — it is width-flexible and fills whatever container the section places it in. | `import { SectionHeader } from "@working-theory/ui/blocks"` |
|
|
230
198
|
| `ShareBar` | The reader-facing counterpart to DocsActionBar. Both surfaces share the same SplitButton *affordance + slot* (outline variant, right-justified on the post title row) but fill it with different actions: DocsActionBar carries the AI-ingestion set (Copy page + Open in …), ShareBar carries the social-share set (X · LinkedIn · Bluesky · Copy link). One primitive, two configs. | `import { ShareBar } from "@working-theory/ui/blocks"` |
|
|
@@ -233,8 +201,6 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
233
201
|
| `StatTicker` | Static, horizontally overflow-scrollable workspace stat strip with an optional trailing CTA; no auto-scroll marquee (ploy-capture recomposition). The Overview stat strip captured off ploy.ai (behavior spec: -2, — `overview-ticker` "-viewport"/"-track"/"-segment"/"-value"/"-cta"). | `import { StatTicker } from "@working-theory/ui/blocks"` |
|
|
234
202
|
| `Steps` | The numbered install/guide walkthrough: an ordered list of `Step` items, each a zero-padded number marker + an optional per-step heading + body, joined top-to-bottom by a connecting vertical rule. The classic docs "follow these steps" surface, rendered from `@working-theory/ui` so docs pages stay design-system citizens. | `import { Steps } from "@working-theory/ui/blocks"` |
|
|
235
203
|
| `StreamingMessage` | One chat turn's message rendering, per the ploy.ai capture contract. | `import { StreamingMessage } from "@working-theory/ui/blocks"` |
|
|
236
|
-
| `StripeActionButton` | The checkout/portal entry-point action button shared by the checkout (U2) and billing-portal (U6) surfaces. | internal — compose from `packages/ui/src/blocks/StripeActionButton.tsx` |
|
|
237
|
-
| `SubscriptionStatus` | Current plan + lifecycle state for the subscriptions surface — shows state via U1's `PaymentStatusBadge` plus a portal "Manage" action. | internal — compose from `packages/ui/src/blocks/SubscriptionStatus.tsx` |
|
|
238
204
|
| `SuggestionChipCarousel` | A 3-6 icon-chip row with exactly one chip expanded (muted category + bold prompt), auto-rotating motion-safe with hover/focus pause; a click hands the chip's prompt to the host. A row of 3-6 icon chips in which exactly ONE is expanded at a time. | `import { SuggestionChipCarousel } from "@working-theory/ui/blocks"` |
|
|
239
205
|
| `TableOfContents` | The shared "On this page" rail consumed by the docs shell and the blog post layout (do not couple it to docs-only context). Renders a flat list of heading anchors and scroll-spies the heading currently in view, highlighting the matching item. | `import { TableOfContents } from "@working-theory/ui/blocks"` |
|
|
240
206
|
| `TeamMemberCard` | Renders one team member in either of two layout modes: 'inline' — small circular avatar left + name/role right (with-small-images variant) 'stacked' — large circular avatar top + name/role/social-links below (with-large-images variant). | `import { TeamMemberCard } from "@working-theory/ui/blocks"` |
|
|
@@ -249,7 +215,7 @@ Import: `import { X } from "@working-theory/ui/blocks";` (or from the `@working-
|
|
|
249
215
|
|
|
250
216
|
---
|
|
251
217
|
|
|
252
|
-
## Chrome (
|
|
218
|
+
## Chrome (17)
|
|
253
219
|
|
|
254
220
|
Persistent framing UI that wraps page content — navigation, footers, sidebars, banners. Not MDX-driven.
|
|
255
221
|
|
|
@@ -262,7 +228,6 @@ Import: `import { X } from "@working-theory/ui/chrome";` (or from the `@working-
|
|
|
262
228
|
| `Banner` | Site-wide announcement and consent banner chrome. *(weak)* | `import { Banner } from "@working-theory/ui/chrome"` |
|
|
263
229
|
| `BannerConsentIsland` | Accept / Reject action cluster for the consent Banner. Isolated to "use client" so Banner stays RSC. The onAccept / onReject callbacks must be Server Actions when used inside an RSC tree; they may be regular functions in client contexts (Storybook, testing). *(weak)* | internal — compose from `packages/ui/src/chrome/BannerConsentIsland.tsx` |
|
|
264
230
|
| `BannerDismissIsland` | Isolated to "use client" so Banner (Server Component) stays RSC. Mirrors the Nav / NavMobileMenu split: interactivity is contained here. Rendering: wraps its children in a relative-positioned div and absolutely places the × dismiss button at the end (RTL-safe: `end-4`) of the bar. *(weak)* | internal — compose from `packages/ui/src/chrome/BannerDismissIsland.tsx` |
|
|
265
|
-
| `DocsSidebar` | The left documentation rail. Consumes a `tree` prop (structurally a Fumadocs `source.pageTree` Root) and renders its folders (static section groups), pages (links), and separators (section captions / dividers). The current page is highlighted via `aria-current="page"`. Kept repo-agnostic: the route passes `docsSource.pageTree`; no nav data is hardcoded here, so a fork reuses it unchanged. | internal — compose from `packages/ui/src/chrome/DocsSidebar.tsx` |
|
|
266
231
|
| `FacetNav` | Chrome-tier faceted secondary navigation (ploy-capture recomposition). One reusable component servicing THREE captured consumers: Settings' grouped Org/Workspace nav, Assets' All + tag-facet counts, and Docs' All + folder tree + tag facets. | `import { FacetNav } from "@working-theory/ui/chrome"` |
|
|
267
232
|
| `FloatingCta` | Persistent fixed corner action pill. *(weak)* | `import { FloatingCta } from "@working-theory/ui/chrome"` |
|
|
268
233
|
| `Footer` | Site footer server component with secondary nav links. Label resolution order for navItems labels. Resolved labels are passed into FooterNav as pre-resolved strings — no duplicated resolution logic across variants. | `import { Footer } from "@working-theory/ui/chrome"` |
|
|
@@ -271,7 +236,7 @@ Import: `import { X } from "@working-theory/ui/chrome";` (or from the `@working-
|
|
|
271
236
|
| `NavOverflowMenu` | The Nav row's per-breakpoint link-overflow disclosure. The desktop link row never wraps: a fixed per-breakpoint inline-link budget (4 at md, 6 at lg+) is enforced by the caller (Nav), which splits `navItems` into an inline slice and an overflow slice. This component renders ONLY the overflow slice, behind a disclosure trigger, in source order — it never computes the budget itself. | internal — compose from `packages/ui/src/chrome/NavOverflowMenu.tsx` |
|
|
272
237
|
| `NotificationsMenu` | Bell trigger + notifications popover chrome (ploy-capture app-frame). Presentational, props-driven. The unread count and row list arrive entirely via props — this component carries NO fetch/polling logic of its own. Rows are pre-formatted at the call site (relative time, heading, empty copy) per the AILK i18n/formatting convention (design-system-rules Rule 10). | `import { NotificationsMenu } from "@working-theory/ui/chrome"` |
|
|
273
238
|
| `SectionNav` | Chrome-tier route-aware section navigation. A horizontal, tab-styled section nav promoting Working Theory's bespoke `UnifiedTabs`/`TheoriesTabs` to a tokenized, tier-correct AILK component. | `import { SectionNav } from "@working-theory/ui/chrome"` |
|
|
274
|
-
| `SidebarNav` | Application sidebar rail (nav + teams + user) for dashboard shells. Server Component (RSC). Renders the vertical sidebar rail for application-shell layouts. Used as the `sidebar` prop of
|
|
239
|
+
| `SidebarNav` | Application sidebar rail (nav + teams + user) for dashboard shells. Server Component (RSC). Renders the vertical sidebar rail for application-shell layouts. Used as the `sidebar` prop of AdminShell. Wrap in a FixedPanel (panels tier) to get the expanded ↔ rail ↔ hidden state machinery. Independently reusable in future shells (settings, analytics, etc.). *(weak)* | `import { SidebarNav } from "@working-theory/ui/chrome"` |
|
|
275
240
|
| `SidebarNavRailItems` | Client boundary for the collapsed rail tooltip affordance. Isolated "use client" boundary so SidebarNav itself stays a Server Component. Renders icon-only nav links with Tooltip labels when the rail is collapsed. *(weak)* | internal — compose from `packages/ui/src/chrome/SidebarNavRailItems.tsx` |
|
|
276
241
|
| `SidePanel` | Chrome-tier right-edge content panel. Fills the ResizablePanel right-edge slot in AppShell. Provides a rich header (title / subtitle / type-badge / avatar / actions / close), a scrollable body, and an optional footer. Mirrors how SidebarNav fills the left edge. | `import { SidePanel } from "@working-theory/ui/chrome"` |
|
|
277
242
|
| `WorkspaceSwitcher` | Org/workspace switcher chrome (ploy-capture app-frame). Presentational, props-driven. Tenancy data (org, user, workspace list, credit meters, actions) arrives entirely via the optional `tenancy` prop — this component carries NO fetch/session logic of its own. When `tenancy` is absent it degrades cleanly to a static, non-interactive single-tenant identity row: no popover, no chevron, no menu semantics. | `import { WorkspaceSwitcher } from "@working-theory/ui/chrome"` |
|
|
@@ -368,7 +333,7 @@ Import: `import { X } from "@working-theory/ui/primitives";` (or from the `@work
|
|
|
368
333
|
|
|
369
334
|
---
|
|
370
335
|
|
|
371
|
-
## Panels (
|
|
336
|
+
## Panels (6)
|
|
372
337
|
|
|
373
338
|
Reusable layout containers that own their own interaction state (collapse, rail, drag-to-resize, off-canvas drawer below `lg`). Not page shells — composable containers that sit between primitives and blocks.
|
|
374
339
|
|
|
@@ -379,14 +344,13 @@ Import: `import { X } from "@working-theory/ui/panels";` (or from the `@working-
|
|
|
379
344
|
| `CardGrid` | The shared owner of how card-grid cells are arranged and separated — columns, gap, and the inter-cell SEPARATION treatment. Seven sections (BentoGrid, Items, Pricing, SocialProof, Stats, Testimonials, Team) currently hand-roll `grid gap-grid grid-cols-*`; this panel is the foundation they compose instead, the direct analogue of how `SectionFrame` collapsed 23× frame duplication. | `import { CardGrid } from "@working-theory/ui/panels"` |
|
|
380
345
|
| `FixedPanel` | Collapsible layout-container primitive (Tier 2 — Panels). A three-state panel: expanded ↔ rail ↔ hidden. Controlled only — callers manage state via `state` + `onStateChange`. | `import { FixedPanel } from "@working-theory/ui/panels"` |
|
|
381
346
|
| `FlowFrame` | The // frame: a full-viewport ground on the site `bg` token, two 50/50 regions (a persistent side panel + an active region) that stack below `md:` (side panel first, in DOM and visual order), and a bottom bar pinned to the VISIBLE viewport (`position: fixed`, safe-area aware) carrying a single continuous accent progress line, `leading` / `label` (center) / `trailing` slots, and a prop-controlled "Powered by Working Theory" line. *(weak)* | `import { FlowFrame } from "@working-theory/ui/panels"` |
|
|
382
|
-
| `InvoiceDetail` | A single invoice's detail view, for the invoice surface (U4). Capability-bearing: binds a schema.org `Invoice` resource-payload fragment (imported from `@working-theory/schema`) — so a co-located `.text.ts` + `.text.test.ts` renderer is required and gated by `scripts/check-ax-parity.sh`. | internal — compose from `packages/ui/src/panels/InvoiceDetail.tsx` |
|
|
383
347
|
| `ResizablePanel` | Drag-resizable layout-container primitive (Panels tier, Tier 2). Provides a resizable side panel container for layout composition. The panel width is controlled by the parent via `width` + `onWidthChange`/`onWidthChangeEnd`. The panel itself manages the drag interaction; the parent persists the committed width (e.g. via localStorage or server state). | `import { ResizablePanel } from "@working-theory/ui/panels"` |
|
|
384
348
|
| `SectionFrame` | The shared frame the section tier composes instead of hand-rolling the `SectionErrorBoundary` + `<section className="py-section bg-bg">` + `Container` plumbing (23× duplicated at time). | `import { SectionFrame } from "@working-theory/ui/panels"` |
|
|
385
349
|
| `StickyColumn` | Makes one column of a two-column layout stick (`lg:sticky` with a top offset) while the sibling column scrolls — the HubSpot "left header sticks, right content scrolls" pattern. `lg`-only: below `lg` it is NOT sticky (normal flow, stacks). Consumed by SplitContentMedia; reusable by any two-column layout. | `import { StickyColumn } from "@working-theory/ui/panels"` |
|
|
386
350
|
|
|
387
351
|
---
|
|
388
352
|
|
|
389
|
-
## Shells (
|
|
353
|
+
## Shells (3)
|
|
390
354
|
|
|
391
355
|
Route-level slot-frames — the outermost layout a page is placed into. They supply geometry and slots (nav / sidebar / main / footer), not content: you inject the real Nav, Footer and sidebar. A different package from every tier above: `@working-theory/templates`.
|
|
392
356
|
|
|
@@ -395,11 +359,159 @@ Import: `import { X } from "@working-theory/templates/shells";` (or from the `@w
|
|
|
395
359
|
| Component | What it does | How to use it |
|
|
396
360
|
| --- | --- | --- |
|
|
397
361
|
| `AppShell` | Shared authed-app base frame. Layout ownership: AppShell is the SINGLE owner of the authed sidebar frame layout. The `sidebar` prop is CONTENT (e.g. a <SidebarNav>), never a layout component. Do NOT pass SidebarShell or FixedPanel as the sidebar — that nests two incompatible layout systems (a fixed-width shell vs a variable-width panel). | `import { AppShell } from "@working-theory/templates/shells"` |
|
|
398
|
-
| `BlogShell` | Blog reading **slot-frame** (DOCS-UI-8). Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* and *where content goes*, owning **geometry only**. Chrome (Nav/Footer) and content (the post meta rail + the reconciled BlogPost body) **fill** the slots — nothing is baked in. Peer to MarketingShell / DocsShell; see. *(weak)* | internal — compose from `packages/templates/src/shells/BlogShell.tsx` |
|
|
399
362
|
| `DeckHeroObserver` | Internal client island for MarketingShell's `deckHero` option. | internal — compose from `packages/templates/src/shells/DeckHeroObserver.tsx` |
|
|
400
|
-
| `DocsShell` | Documentation reading **slot-frame** (DOCS-UI-4). Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* and *where content goes*, owning **geometry only**. Chrome (DocsSidebar) and content (DocsArticleHeader + MDXContent + ArticlePager + DocsFeedback) **fill** the slots — nothing is baked in. Peer to MarketingShell; see. *(weak)* | internal — compose from `packages/templates/src/shells/DocsShell.tsx` |
|
|
401
363
|
| `MarketingShell` | Public-facing marketing site **slot-frame**. Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* (top + bottom) and *where sections go* (the body), owning **geometry only**. Chrome (Nav/Footer) and sections **fill** the slots — nothing is baked into the component. See (first instance). *(weak)* | `import { MarketingShell } from "@working-theory/templates/shells"` |
|
|
402
|
-
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Docs + Blog Blocks (5)
|
|
368
|
+
|
|
369
|
+
Paid — delivered by the `docs-blog` module bundle, not present in a Free scaffold. Composition tiles for documentation and blog surfaces — search, page navigation, article furniture.
|
|
370
|
+
|
|
371
|
+
Import: `import { X } from "@working-theory/ui-docs-blog";` (or from the `@working-theory/ui-docs-blog` root barrel). Components marked *internal* are not re-exported — they are implementation details of a sibling in the same tier.
|
|
372
|
+
|
|
373
|
+
| Component | What it does | How to use it |
|
|
374
|
+
| --- | --- | --- |
|
|
375
|
+
| `DocsActionBar` | The agent-facing article toolbar that lands in the DocsArticleHeader `actionBar` slot, presented as the Claude-docs **"Copy page ▾" split button**. The in-page rendered↔markdown toggle is NOT reimplemented here — that is the existing MarkdownViewToggle block, which the route mounts around the article body. This bar only adds the copy + open-in affordances. | `import { DocsActionBar } from "@working-theory/ui-docs-blog"` |
|
|
376
|
+
| `DocsArticleHeader` | The article header: a breadcrumb trail (with the TOC popover button at its inline-end), the page title (the single <h1>), an optional lead description, and an "updated" meta line. Leaves an `actionBar` slot for the Phase-5 DocsActionBar (markdown toggle / copy / share) — empty until then. | `import { DocsArticleHeader } from "@working-theory/ui-docs-blog"` |
|
|
377
|
+
| `DocsFeedback` | The article-footer feedback widget: a "Was this helpful?" thumbs yes/no pair plus an "Edit this page on GitHub" link. Clicking a thumb records the answer (fires a `gtag` analytics event when the site's GA is present) and, on "no", reveals an optional free-text note. After answering, the prompt is replaced with a thank-you line. | `import { DocsFeedback } from "@working-theory/ui-docs-blog"` |
|
|
378
|
+
| `DocsSearch` | The cmd-K documentation search: a ⌘K trigger pill (NavSearchTrigger) that opens a CommandDialog over a passed-in search index. Typing filters the index by title/description (cmdk's built-in filter, fed a `value` that bundles both); selecting a result navigates there. | `import { DocsSearch } from "@working-theory/ui-docs-blog"` |
|
|
379
|
+
| `DocsTocButton` | Clicking the `List`-icon button opens a Popover rendering the shared `TableOfContents` (styling preserved). Esc / outside-click closes it (Radix default); in-page anchor jumps work as they do in the rail. The button renders nothing when there are no TOC entries, so the breadcrumb row stays clean on heading-less / `wide` pages. | `import { DocsTocButton } from "@working-theory/ui-docs-blog"` |
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Docs + Blog Chrome (1)
|
|
384
|
+
|
|
385
|
+
Paid — delivered by the `docs-blog` module bundle, not present in a Free scaffold. Persistent framing UI for the docs surface — the docs sidebar and its rail.
|
|
386
|
+
|
|
387
|
+
Import: `import { X } from "@working-theory/ui-docs-blog";` (or from the `@working-theory/ui-docs-blog` root barrel). Components marked *internal* are not re-exported — they are implementation details of a sibling in the same tier.
|
|
388
|
+
|
|
389
|
+
| Component | What it does | How to use it |
|
|
390
|
+
| --- | --- | --- |
|
|
391
|
+
| `DocsSidebar` | The left documentation rail. Consumes a `tree` prop (structurally a Fumadocs `source.pageTree` Root) and renders its folders (static section groups), pages (links), and separators (section captions / dividers). The current page is highlighted via `aria-current="page"`. Kept repo-agnostic: the route passes `docsSource.pageTree`; no nav data is hardcoded here, so a fork reuses it unchanged. | `import { DocsSidebar } from "@working-theory/ui-docs-blog"` |
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## Docs + Blog Shells (2)
|
|
396
|
+
|
|
397
|
+
Paid — delivered by the `docs-blog` module bundle, not present in a Free scaffold. Route-level slot-frames for the blog and docs surfaces. Same contract as the Shells tier above, a different package.
|
|
398
|
+
|
|
399
|
+
Import: `import { X } from "@working-theory/ui-docs-blog";` (or from the `@working-theory/ui-docs-blog` root barrel). Components marked *internal* are not re-exported — they are implementation details of a sibling in the same tier.
|
|
400
|
+
|
|
401
|
+
| Component | What it does | How to use it |
|
|
402
|
+
| --- | --- | --- |
|
|
403
|
+
| `BlogShell` | Blog reading **slot-frame** (DOCS-UI-8). Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* and *where content goes*, owning **geometry only**. Chrome (Nav/Footer) and content (the post meta rail + the reconciled BlogPost body) **fill** the slots — nothing is baked in. Peer to MarketingShell / DocsShell; see. *(weak)* | `import { BlogShell } from "@working-theory/ui-docs-blog"` |
|
|
404
|
+
| `DocsShell` | Documentation reading **slot-frame** (DOCS-UI-4). Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* and *where content goes*, owning **geometry only**. Chrome (DocsSidebar) and content (DocsArticleHeader + MDXContent + ArticlePager + DocsFeedback) **fill** the slots — nothing is baked in. Peer to MarketingShell; see. *(weak)* | `import { DocsShell } from "@working-theory/ui-docs-blog"` |
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Scheduling Sections (2)
|
|
409
|
+
|
|
410
|
+
Paid — delivered by the `scheduling` module bundle, not present in a Free scaffold. The `booker` section type, registered into `SectionRenderer` by the package's entry point rather than by the Free dispatch table.
|
|
411
|
+
|
|
412
|
+
Import: `import { X } from "@working-theory/ui-scheduling";` (or from the `@working-theory/ui-scheduling` root barrel). Components marked *internal* are not re-exported — they are implementation details of a sibling in the same tier.
|
|
413
|
+
|
|
414
|
+
| Component | What it does | How to use it |
|
|
415
|
+
| --- | --- | --- |
|
|
416
|
+
| `Booker` | The custom booker — use on a scheduling page where the whole see-days/pick-slot/confirm transaction should land in the page itself rather than a provider iframe (the `scheduler-embed` alternative). Authors supply only `calLink` plus optional eyebrow/headline framing; duration, meeting type, and timezone are DERIVED from the calendar via /v1/schedule/availability and can never be typed into content. | MDX `type: booker` · `import { Booker } from "@working-theory/ui-scheduling"` |
|
|
417
|
+
| `BookerIsland` | The island owns exactly two things: the state machine, and the two calls across the scheduling seam. It talks to `/v1/schedule/availability` and `/v1/schedule/book` — never to a provider — so the day this deploy flips to the self-hosted engine, nothing in this file changes. | internal — compose from `packages-paid/ui-scheduling/src/sections/BookerIsland.tsx` |
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Scheduling Blocks (5)
|
|
422
|
+
|
|
423
|
+
Paid — delivered by the `scheduling` module bundle, not present in a Free scaffold. The pieces the booker section is built from — slot pickers, timezone and confirmation furniture.
|
|
424
|
+
|
|
425
|
+
Import: `import { X } from "@working-theory/ui-scheduling";` (or from the `@working-theory/ui-scheduling` root barrel). Components marked *internal* are not re-exported — they are implementation details of a sibling in the same tier.
|
|
426
|
+
|
|
427
|
+
| Component | What it does | How to use it |
|
|
428
|
+
| --- | --- | --- |
|
|
429
|
+
| `BookerAttendeeFields` | TWO FIELDS. A booking needs somewhere to send the invite and a name to put on it; every additional field is one more reason to abandon a transaction the user had already decided to complete. Notes, phone, and company are deliberately absent — the provider collects them after the invite lands, if the operator wants them at all. | internal — compose from `packages-paid/ui-scheduling/src/blocks/BookerAttendeeFields.tsx` |
|
|
430
|
+
| `BookerDateStrip` | ONLY DAYS THAT HAVE OPEN SLOTS APPEAR. That is the structural argument this block makes, and the reason the composition is a horizontal strip rather than the month grid every booking widget reaches for: a month grid spends its whole area rendering the ~24 days you cannot book, then needs a second interaction to reveal which of the remaining six are live. | internal — compose from `packages-paid/ui-scheduling/src/blocks/BookerDateStrip.tsx` |
|
|
431
|
+
| `BookerEventHeader` | TWO KINDS OF TEXT, AND THE DIFFERENCE MATTERS. `eyebrow` and `headline` are AUTHORED: the operator's words about why someone would book. Everything in the meta row — duration, meeting type, timezone — is DERIVED from the calendar on the availability read, which is why the section schema has no field for any of it. | internal — compose from `packages-paid/ui-scheduling/src/blocks/BookerEventHeader.tsx` |
|
|
432
|
+
| `BookerPanel` | The booking card, fully controlled. One chassis, five views, ONE FOOTER. | internal — compose from `packages-paid/ui-scheduling/src/blocks/BookerPanel.tsx` |
|
|
433
|
+
| `BookerSlotGrid` | The selected day's open times. Two columns at 48px on mobile — the measured pixel target — widening to three at `lg` so the desktop variant shows more of the day without scrolling. Two columns is not an arbitrary density: at 390px it is the widest grid where a time still reads at a glance, and it puts eight times (a full working day's openings) inside one thumb-reachable block. | internal — compose from `packages-paid/ui-scheduling/src/blocks/BookerSlotGrid.tsx` |
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
## Signal-Collectors Sections (3)
|
|
438
|
+
|
|
439
|
+
Paid — delivered by the `signal-collectors` module bundle, not present in a Free scaffold. Multi-step flow and listing surfaces — the page-level bands a signal-collection route is assembled from.
|
|
440
|
+
|
|
441
|
+
Import: `import { X } from "@working-theory/ui-signal-collectors";` (or from the `@working-theory/ui-signal-collectors` root barrel). Components marked *internal* are not re-exported — they are implementation details of a sibling in the same tier.
|
|
442
|
+
|
|
443
|
+
| Component | What it does | How to use it |
|
|
444
|
+
| --- | --- | --- |
|
|
445
|
+
| `FlowStepper` | Rendering a served flow config as a real multi-step form. | `import { FlowStepper } from "@working-theory/ui-signal-collectors"` |
|
|
446
|
+
| `ListingApplicationFlow` | This is the thing a consuming site mounts INSTEAD of hand-writing three proxy routes, a save-on-advance form, and a decision about where a bearer token lives. | `import { ListingApplicationFlow } from "@working-theory/ui-signal-collectors"` |
|
|
447
|
+
| `ProjectListingShelves` | Two shelves of ProjectListingCards partitioned from ONE list of public listing rows: `status === "active"` on one shelf, `status === "closed"` on the other. `closed` is COMPUTED by the API read (the window-end check lives server-side, / D6b) — this component never recomputes it, it only reads the field. | `import { ProjectListingShelves } from "@working-theory/ui-signal-collectors"` |
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Signal-Collectors Blocks (8)
|
|
452
|
+
|
|
453
|
+
Paid — delivered by the `signal-collectors` module bundle, not present in a Free scaffold. Flow step, listing card, response chart and results-reveal tiles the sections above compose.
|
|
454
|
+
|
|
455
|
+
Import: `import { X } from "@working-theory/ui-signal-collectors";` (or from the `@working-theory/ui-signal-collectors` root barrel). Components marked *internal* are not re-exported — they are implementation details of a sibling in the same tier.
|
|
456
|
+
|
|
457
|
+
| Component | What it does | How to use it |
|
|
458
|
+
| --- | --- | --- |
|
|
459
|
+
| `FlowSidePanel` | The per-view side panel of the flow/recommender surface. ONE CHASSIS, THREE VIEWS. | `import { FlowSidePanel } from "@working-theory/ui-signal-collectors"` |
|
|
460
|
+
| `ListingFullPreview` | The full-page-preview `custom` step renderer. The founder's assembled application, rendered as a page, with an edit link back to the step that owns each rendered part. Purely presentational: every entry's label and formatted value arrive pre-built on `entries` (this block does no formatting of its own), and `onEdit` is the only way it ever changes anything — it never mutates, saves, or fetches. | internal — compose from `packages-paid/ui-signal-collectors/src/blocks/ListingFullPreview.tsx` |
|
|
461
|
+
| `ListingPrivacyNotice` | The per-listing privacy notice. It names the FOUNDER — not the platform — as the party collecting a visitor's personal data, and it renders ON THE FLOW (where a visitor submits answers), not on the listing page. | `import { ListingPrivacyNotice } from "@working-theory/ui-signal-collectors"` |
|
|
462
|
+
| `ListingQuestionReview` | The edit-only question-review `custom` step renderer. The founder is refining a diagnostic template the SITE authored, not composing one from nothing (`projectListingQuestionsSchema`, `packages/validation/src/schemas/project-listings.ts`). | internal — compose from `packages-paid/ui-signal-collectors/src/blocks/ListingQuestionReview.tsx` |
|
|
463
|
+
| `ListingTilePreview` | The founder's tile, as it will look, updating as they type. | internal — compose from `packages-paid/ui-signal-collectors/src/blocks/ListingTilePreview.tsx` |
|
|
464
|
+
| `ProjectListingCard` | The tile for one listing on a shelf (`ProjectListingShelves`). The whole tile is a single anchor (LinkCard's bespoke-by-semantics precedent: Card renders a <div> and cannot satisfy a whole-tile-link contract, so this composes Link directly rather than Card). | `import { ProjectListingCard } from "@working-theory/ui-signal-collectors"` |
|
|
465
|
+
| `ResponseChart` | The single-question aggregate chart of the diagnostic's results reveal. Renders exactly ONE `FlowAggregateQuestion`. The chart type is FIXED by `question.answerType` — a closed `single \| multi` union — and there is no `chartType`/`variant` prop: an author cannot request a doughnut for a multi-select question, because there is no prop through which to ask. | internal — compose from `packages-paid/ui-signal-collectors/src/blocks/ResponseChart.tsx` |
|
|
466
|
+
| `ResultsReveal` | The active-region composition of the diagnostic's results reveal. *(weak)* | internal — compose from `packages-paid/ui-signal-collectors/src/blocks/ResultsReveal.tsx` |
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## Commerce Sections (2)
|
|
471
|
+
|
|
472
|
+
Paid — delivered by the `commerce` module bundle, not present in a Free scaffold. The `payment-receipt` section type and the pricing table — registered into `SectionRenderer` by the package's entry point.
|
|
473
|
+
|
|
474
|
+
Import: `import { X } from "@working-theory/ui-commerce";` (or from the `@working-theory/ui-commerce` root barrel). Components marked *internal* are not re-exported — they are implementation details of a sibling in the same tier.
|
|
475
|
+
|
|
476
|
+
| Component | What it does | How to use it |
|
|
477
|
+
| --- | --- | --- |
|
|
478
|
+
| `PaymentReceipt` | A checkout payment outcome — use only on a checkout Delivery/confirmation page to show status + receipt details. | MDX `type: payment-receipt` · `import { PaymentReceipt } from "@working-theory/ui-commerce"` |
|
|
479
|
+
| `PricingTable` | A grid of subscription plan tiers that SUBSCRIBE — the capability-bearing twin of the `Pricing` CMS section (which renders href-based marketing tier CTAs, no live Stripe call). `PricingTable` is scaffolded by `scaffold-commerce` (not registered in `SectionRenderer`'s CMS dispatch table) and each tier's action POSTs to the subscription surface's `subscribeHandler` route + redirects to the returned Stripe Checkout URL — the same `onCheckout`-callback shape `CheckoutForm` uses for one-time products. | internal — compose from `packages-paid/ui-commerce/src/sections/PricingTable.tsx` |
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## Commerce Blocks (12)
|
|
484
|
+
|
|
485
|
+
Paid — delivered by the `commerce` module bundle, not present in a Free scaffold. Checkout, payment, invoice, subscription and customer-portal tiles. Search here before hand-rolling any Stripe-facing UI.
|
|
486
|
+
|
|
487
|
+
Import: `import { X } from "@working-theory/ui-commerce";` (or from the `@working-theory/ui-commerce` root barrel). Components marked *internal* are not re-exported — they are implementation details of a sibling in the same tier.
|
|
488
|
+
|
|
489
|
+
| Component | What it does | How to use it |
|
|
490
|
+
| --- | --- | --- |
|
|
491
|
+
| `CheckoutForm` | Product/amount selection + checkout submit for the one-time checkout surface. | internal — compose from `packages-paid/ui-commerce/src/blocks/CheckoutForm.tsx` |
|
|
492
|
+
| `CheckoutPriceCard` | DESIGN 's checkout price card: the panel's fourth view once it flips to the right and becomes an order summary — eyebrow, offer name + description, seat/credit line items, an optional caller-supplied add-credits row, and the total + due-today. | `import { CheckoutPriceCard } from "@working-theory/ui-commerce"` |
|
|
493
|
+
| `InvoiceForm` | Creates a draft invoice (single line item), for the invoice surface (U4). | internal — compose from `packages-paid/ui-commerce/src/blocks/InvoiceForm.tsx` |
|
|
494
|
+
| `InvoiceList` | A customer's invoice rows, shared by the invoice surface (U4). Capability-bearing: binds a schema.org `Invoice` resource-payload fragment per row (imported from `@working-theory/schema`) — so a co-located `.text.ts` + `.text.test.ts` renderer is required and gated by `scripts/check-ax-parity.sh`. | internal — compose from `packages-paid/ui-commerce/src/blocks/InvoiceList.tsx` |
|
|
495
|
+
| `PaymentLinkCard` | A single shareable Stripe Payment Link (pay-by-link surface). Renders the link's offer name, active-status chip, optional amount, and the hosted URL with a one-click copy action. | internal — compose from `packages-paid/ui-commerce/src/blocks/PaymentLinkCard.tsx` |
|
|
496
|
+
| `PaymentLinkForm` | Product selection + "create link" submit for the pay-by-link surface. | internal — compose from `packages-paid/ui-commerce/src/blocks/PaymentLinkForm.tsx` |
|
|
497
|
+
| `PaymentLinkList` | A site owner's shareable payment links (pay-by-link surface). Composes one `PaymentLinkCard` per link. | internal — compose from `packages-paid/ui-commerce/src/blocks/PaymentLinkList.tsx` |
|
|
498
|
+
| `PaymentResult` | Success/cancel result state for the one-time checkout surface — the terminal render a consumer's success/cancel return-URL page shows after the Stripe-hosted Checkout redirect. | internal — compose from `packages-paid/ui-commerce/src/blocks/PaymentResult.tsx` |
|
|
499
|
+
| `PaymentStatusBadge` | Payment-state chip shared by the invoice-status (U4) and subscription-status (U5) surfaces. | internal — compose from `packages-paid/ui-commerce/src/blocks/PaymentStatusBadge.tsx` |
|
|
500
|
+
| `PortalEntry` | A standalone "Manage billing" entry point into Stripe's hosted Customer Portal — the smallest surface (spec: AILK owns only the entry; Stripe hosts the portal itself). | internal — compose from `packages-paid/ui-commerce/src/blocks/PortalEntry.tsx` |
|
|
501
|
+
| `StripeActionButton` | The checkout/portal entry-point action button shared by the checkout (U2) and billing-portal (U6) surfaces. | internal — compose from `packages-paid/ui-commerce/src/blocks/StripeActionButton.tsx` |
|
|
502
|
+
| `SubscriptionStatus` | Current plan + lifecycle state for the subscriptions surface — shows state via U1's `PaymentStatusBadge` plus a portal "Manage" action. | internal — compose from `packages-paid/ui-commerce/src/blocks/SubscriptionStatus.tsx` |
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## Commerce Panels (1)
|
|
507
|
+
|
|
508
|
+
Paid — delivered by the `commerce` module bundle, not present in a Free scaffold. Layout containers owning their own interaction state for commerce detail surfaces.
|
|
509
|
+
|
|
510
|
+
Import: `import { X } from "@working-theory/ui-commerce";` (or from the `@working-theory/ui-commerce` root barrel). Components marked *internal* are not re-exported — they are implementation details of a sibling in the same tier.
|
|
511
|
+
|
|
512
|
+
| Component | What it does | How to use it |
|
|
513
|
+
| --- | --- | --- |
|
|
514
|
+
| `InvoiceDetail` | A single invoice's detail view, for the invoice surface (U4). Capability-bearing: binds a schema.org `Invoice` resource-payload fragment (imported from `@working-theory/schema`) — so a co-located `.text.ts` + `.text.test.ts` renderer is required and gated by `scripts/check-ax-parity.sh`. | internal — compose from `packages-paid/ui-commerce/src/panels/InvoiceDetail.tsx` |
|
|
403
515
|
|
|
404
516
|
---
|
|
405
517
|
|
|
@@ -411,7 +523,7 @@ These 29 components have a description that is accurate but does not do the job
|
|
|
411
523
|
| --- | --- | --- |
|
|
412
524
|
| `DocumentViewerClient` | sections | The interactive shell for DocumentViewer. Split out of DocumentViewer.tsx (which stays RSC) for the same reason AlertSection composes AlertSectionDismissIsland: interactivity is contained to one client island. |
|
|
413
525
|
| `AgentContextCard` | blocks | Capability-bearing block that renders agent provenance. RSC note: no hooks or browser APIs — server-renderable by default. |
|
|
414
|
-
| `PageHeader` | blocks | RSC. Page-level header composing the Breadcrumb primitive for the left-side wayfinding trail, a generic right-side `actions` slot, and an optional `switcher` slot for header-owned segment switching. Fills AppShell's `header` slot (
|
|
526
|
+
| `PageHeader` | blocks | RSC. Page-level header composing the Breadcrumb primitive for the left-side wayfinding trail, a generic right-side `actions` slot, and an optional `switcher` slot for header-owned segment switching. Fills AppShell's `header` slot (AdminShell and similar). No accent bar. No tab API. No named action props — the caller assembles whatever button/menu nodes it needs and passes them as `actions`. |
|
|
415
527
|
| `PricingTierCardSeatControl` | blocks | Seat-count range picker for the Team tier card. Renders a Select primitive that lets the user choose an "Up to N seats" option from a caller-supplied list of numbers. The parent PricingTierCard stays a pure RSC; only this tiny island is hydrated. Pattern mirrors PageHeaderSwitcher.tsx: small "use client" island imported by an otherwise-server-rendered parent, keeping the client bundle minimal. |
|
|
416
528
|
| `SinglePriceCard` | blocks | 2-column split card for the Pricing 'single-price-with-details' variant. |
|
|
417
529
|
| `SocialIcons` | blocks | Horizontal row of social icon links. Renders brand icons (via Icon primitive + simple-icons paths) inside accessible Link primitives. Each platform link gets an aria-label. Shared by company-mission, simple-centered, and newsletter-below footer variants, and composed by TeamMemberCard for member social links. |
|
|
@@ -420,7 +532,7 @@ These 29 components have a description that is accurate but does not do the job
|
|
|
420
532
|
| `BannerDismissIsland` | chrome | Isolated to "use client" so Banner (Server Component) stays RSC. Mirrors the Nav / NavMobileMenu split: interactivity is contained here. Rendering: wraps its children in a relative-positioned div and absolutely places the × dismiss button at the end (RTL-safe: `end-4`) of the bar. |
|
|
421
533
|
| `FloatingCta` | chrome | Persistent fixed corner action pill. |
|
|
422
534
|
| `NavMobileMenu` | chrome | Client subcomponent for mobile hamburger state. Isolates "use client" to this narrow component so Nav (Server Component) stays clean. Renders a hamburger button + collapsible link list. Closes the menu automatically when the pathname changes (route navigation). |
|
|
423
|
-
| `SidebarNav` | chrome | Application sidebar rail (nav + teams + user) for dashboard shells. Server Component (RSC). Renders the vertical sidebar rail for application-shell layouts. Used as the `sidebar` prop of
|
|
535
|
+
| `SidebarNav` | chrome | Application sidebar rail (nav + teams + user) for dashboard shells. Server Component (RSC). Renders the vertical sidebar rail for application-shell layouts. Used as the `sidebar` prop of AdminShell. Wrap in a FixedPanel (panels tier) to get the expanded ↔ rail ↔ hidden state machinery. Independently reusable in future shells (settings, analytics, etc.). |
|
|
424
536
|
| `SidebarNavRailItems` | chrome | Client boundary for the collapsed rail tooltip affordance. Isolated "use client" boundary so SidebarNav itself stays a Server Component. Renders icon-only nav links with Tooltip labels when the rail is collapsed. |
|
|
425
537
|
| `AspectRatio` | primitives | Constrains content to a given width/height ratio. Thin re-export of @radix-ui/react-aspect-ratio. RSC-safe: no hooks or browser APIs — default server component. |
|
|
426
538
|
| `CopyButton` | primitives | CopyButton Primitive. |
|
|
@@ -434,10 +546,10 @@ These 29 components have a description that is accurate but does not do the job
|
|
|
434
546
|
| `Toggle` | primitives | Toggle Primitive. |
|
|
435
547
|
| `VisuallyHidden` | primitives | Renders its children so they are present in the DOM and the accessibility tree but visually hidden. Standardizes the ad-hoc `sr-only` className pattern previously hand-rolled across primitives (Dialog/Sheet/Toast close labels) and section headers. |
|
|
436
548
|
| `FlowFrame` | panels | The // frame: a full-viewport ground on the site `bg` token, two 50/50 regions (a persistent side panel + an active region) that stack below `md:` (side panel first, in DOM and visual order), and a bottom bar pinned to the VISIBLE viewport (`position: fixed`, safe-area aware) carrying a single continuous accent progress line, `leading` / `label` (center) / `trailing` slots, and a prop-controlled "Powered by Working Theory" line. |
|
|
437
|
-
| `BlogShell` | shells | Blog reading **slot-frame** (DOCS-UI-8). Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* and *where content goes*, owning **geometry only**. Chrome (Nav/Footer) and content (the post meta rail + the reconciled BlogPost body) **fill** the slots — nothing is baked in. Peer to MarketingShell / DocsShell; see. |
|
|
438
|
-
| `DocsShell` | shells | Documentation reading **slot-frame** (DOCS-UI-4). Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* and *where content goes*, owning **geometry only**. Chrome (DocsSidebar) and content (DocsArticleHeader + MDXContent + ArticlePager + DocsFeedback) **fill** the slots — nothing is baked in. Peer to MarketingShell; see. |
|
|
439
549
|
| `MarketingShell` | shells | Public-facing marketing site **slot-frame**. Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* (top + bottom) and *where sections go* (the body), owning **geometry only**. Chrome (Nav/Footer) and sections **fill** the slots — nothing is baked into the component. See (first instance). |
|
|
440
|
-
| `
|
|
550
|
+
| `BlogShell` | docs-blog-shells | Blog reading **slot-frame** (DOCS-UI-8). Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* and *where content goes*, owning **geometry only**. Chrome (Nav/Footer) and content (the post meta rail + the reconciled BlogPost body) **fill** the slots — nothing is baked in. Peer to MarketingShell / DocsShell; see. |
|
|
551
|
+
| `DocsShell` | docs-blog-shells | Documentation reading **slot-frame** (DOCS-UI-4). Server Component (RSC default). A shell is a slot-defining frame: it carves out *where chrome goes* and *where content goes*, owning **geometry only**. Chrome (DocsSidebar) and content (DocsArticleHeader + MDXContent + ArticlePager + DocsFeedback) **fill** the slots — nothing is baked in. Peer to MarketingShell; see. |
|
|
552
|
+
| `ResultsReveal` | signal-collectors-blocks | The active-region composition of the diagnostic's results reveal. |
|
|
441
553
|
|
|
442
554
|
---
|
|
443
555
|
|