create-ailk 0.7.0 → 0.8.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.
Files changed (169) hide show
  1. package/README.md +44 -10
  2. package/component-catalog.json +520 -5
  3. package/component-catalog.md +9 -6
  4. package/dist/cli.js +22 -24
  5. package/dist/lib/extract-module-bundle.js +5 -1
  6. package/dist/lib/module-license-gate.d.ts +79 -0
  7. package/dist/lib/module-license-gate.js +160 -12
  8. package/dist/lib/module-tier.d.ts +45 -16
  9. package/dist/lib/module-tier.js +76 -0
  10. package/dist/lib/pro-callout.js +10 -2
  11. package/dist/parse-args.d.ts +78 -10
  12. package/dist/parse-args.js +204 -14
  13. package/dist/programmatic.d.ts +39 -9
  14. package/dist/programmatic.js +163 -25
  15. package/dist/site-roster.js +11 -6
  16. package/dist/starter-grid.d.ts +216 -0
  17. package/dist/starter-grid.js +449 -0
  18. package/dist/surfaces.d.ts +4 -4
  19. package/dist/surfaces.js +102 -43
  20. package/dist/template-manifest.d.ts +36 -17
  21. package/dist/template-manifest.js +121 -367
  22. package/dist/template-names.d.ts +14 -12
  23. package/dist/template-names.js +13 -17
  24. package/package.json +3 -3
  25. package/site-templates/_base/content/en/BookCall/book-call.mdx +0 -1
  26. package/site-templates/_base/content/en/Feature/feature-1.mdx +69 -0
  27. package/site-templates/_base/content/en/Feature/feature-2.mdx +69 -0
  28. package/site-templates/_base/content/en/Feature/feature-3.mdx +69 -0
  29. package/site-templates/_base/content/en/FeaturesList/features.mdx +91 -0
  30. package/site-templates/_base/content/en/GlossaryList/glossary.mdx +0 -1
  31. package/site-templates/_base/content/en/NewsletterSignup/newsletter.mdx +0 -1
  32. package/site-templates/_base/content/en/PortfolioItem/sample-four.mdx +105 -0
  33. package/site-templates/_base/content/en/PortfolioItem/sample-one.mdx +34 -0
  34. package/site-templates/_base/content/en/PortfolioItem/sample-three.mdx +94 -0
  35. package/site-templates/_base/content/en/PortfolioItem/sample-two.mdx +45 -0
  36. package/site-templates/_base/content/en/PortfolioList/portfolio.mdx +169 -0
  37. package/site-templates/_base/content/en/PrivacyPage/privacy.mdx +15 -0
  38. package/site-templates/_base/content/en/UseCase/persona-1.mdx +69 -0
  39. package/site-templates/_base/content/en/UseCase/persona-2.mdx +69 -0
  40. package/site-templates/_base/content/en/UseCase/persona-3.mdx +69 -0
  41. package/site-templates/designs/standard/DESIGN.md +5 -0
  42. package/site-templates/marketing-site/DESIGN.md +5 -0
  43. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +89 -25
  44. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +35 -14
  45. package/site-templates/marketing-site-free/DESIGN.md +5 -0
  46. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +95 -29
  47. package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +74 -44
  48. package/site-templates/marketing-site-free/content/en/NewsletterSignup/newsletter.mdx +59 -0
  49. package/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +199 -0
  50. package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +17 -29
  51. package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +0 -1
  52. package/site-templates/minimalism-site/content/en/PurchasePolicyPage/purchase-policy.mdx +0 -1
  53. package/site-templates/saas-product/DESIGN.md +5 -0
  54. package/site-templates/saas-product/TEMPLATE-MANIFEST.md +9 -1
  55. package/site-templates/{simple-service → shapes/local-business-service}/TEMPLATE-MANIFEST.json +96 -76
  56. package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +302 -0
  57. package/site-templates/shapes/local-business-service/ailk-template.json +10 -0
  58. package/site-templates/{simple-service → shapes/local-business-service}/content/en/AboutPage/about.mdx +4 -4
  59. package/site-templates/shapes/local-business-service/content/en/HomePage/home.mdx +70 -0
  60. package/site-templates/shapes/local-business-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
  61. package/site-templates/shapes/local-business-service/content/en/PortfolioList/portfolio.mdx +171 -0
  62. package/site-templates/{simple-service → shapes/local-business-service}/content/en/PurchasePolicyPage/purchase-policy.mdx +7 -8
  63. package/site-templates/shapes/local-business-service/content/en/Service/first-job.mdx +39 -0
  64. package/site-templates/shapes/local-business-service/content/en/Service/second-job.mdx +39 -0
  65. package/site-templates/shapes/local-business-service/content/en/Service/third-job.mdx +39 -0
  66. package/site-templates/shapes/local-business-service/content/en/ServicesList/services.mdx +61 -0
  67. package/site-templates/shapes/local-business-service/provenance.json +4 -0
  68. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +362 -0
  69. package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +300 -0
  70. package/site-templates/shapes/organization-service/ailk-template.json +10 -0
  71. package/site-templates/shapes/organization-service/content/en/AboutPage/about.mdx +38 -0
  72. package/site-templates/shapes/organization-service/content/en/HomePage/home.mdx +85 -0
  73. package/site-templates/shapes/organization-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
  74. package/site-templates/shapes/organization-service/content/en/PortfolioList/portfolio.mdx +171 -0
  75. package/site-templates/shapes/organization-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
  76. package/site-templates/shapes/organization-service/content/en/Service/first-engagement.mdx +38 -0
  77. package/site-templates/shapes/organization-service/content/en/Service/second-engagement.mdx +38 -0
  78. package/site-templates/shapes/organization-service/content/en/Service/third-engagement.mdx +38 -0
  79. package/site-templates/shapes/organization-service/content/en/ServicesList/services.mdx +72 -0
  80. package/site-templates/shapes/organization-service/provenance.json +4 -0
  81. package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +369 -0
  82. package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +299 -0
  83. package/site-templates/shapes/person-service/ailk-template.json +10 -0
  84. package/site-templates/shapes/person-service/content/_site.mdx +85 -0
  85. package/site-templates/shapes/person-service/content/en/AboutPage/about.mdx +39 -0
  86. package/site-templates/shapes/person-service/content/en/HomePage/home.mdx +97 -0
  87. package/site-templates/shapes/person-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
  88. package/site-templates/shapes/person-service/content/en/PortfolioList/portfolio.mdx +169 -0
  89. package/site-templates/shapes/person-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
  90. package/site-templates/shapes/person-service/content/en/Service/first-engagement.mdx +38 -0
  91. package/site-templates/shapes/person-service/content/en/Service/second-engagement.mdx +38 -0
  92. package/site-templates/shapes/person-service/content/en/Service/third-engagement.mdx +38 -0
  93. package/site-templates/{simple-service → shapes/person-service}/content/en/ServicesList/services.mdx +16 -16
  94. package/site-templates/shapes/person-service/provenance.json +4 -0
  95. package/templates/.claude/skills/README.md +3 -2
  96. package/templates/.claude/skills/add-page/references/page-types.md +4 -0
  97. package/templates/.claude/skills/setup-database/SKILL.md +156 -0
  98. package/templates/.claude/skills/setup-database/scripts/verify-inbox.ts +154 -0
  99. package/templates/.claude/skills/setup-deploy/SKILL.md +64 -32
  100. package/templates/.claude/skills/setup-deploy/references/env-vars-template.md +19 -28
  101. package/templates/.claude/skills/setup-deploy/references/runbook-template.md +58 -102
  102. package/templates/DESIGN.md +5 -0
  103. package/templates/README.md +46 -38
  104. package/templates/apps/api/CLAUDE.md +3 -2
  105. package/templates/apps/api/src/config/__tests__/index.test.ts +115 -14
  106. package/templates/apps/api/src/config/index.ts +35 -16
  107. package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +30 -0
  108. package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +96 -0
  109. package/templates/apps/api/src/lib/lead-capture-store.ts +12 -0
  110. package/templates/apps/api/src/lib/lead-delivery.ts +52 -0
  111. package/templates/apps/api/src/openapi/spec.ts +63 -12
  112. package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +88 -0
  113. package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +100 -0
  114. package/templates/apps/api/src/routes/leads/index.ts +46 -1
  115. package/templates/apps/api/src/server.ts +7 -0
  116. package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +194 -0
  117. package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +124 -0
  118. package/templates/apps/api/src/services/lead-routing.ts +140 -30
  119. package/templates/apps/api/src/services/leads-inbox.ts +48 -11
  120. package/templates/apps/mcp/__tests__/parity.test.ts +5 -4
  121. package/templates/apps/mcp/src/tools/create_project.ts +21 -6
  122. package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +14 -6
  123. package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +10 -9
  124. package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-text.test.ts +32 -0
  125. package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +129 -0
  126. package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +227 -84
  127. package/templates/apps/web/app/[locale]/contact/contact-form-text.ts +50 -0
  128. package/templates/apps/web/app/[locale]/contact/contact.actions.ts +73 -20
  129. package/templates/apps/web/app/[locale]/contact/page.tsx +105 -15
  130. package/templates/apps/web/app/[locale]/contact/site-contact-email.ts +54 -0
  131. package/templates/apps/web/app/[locale]/features/[slug]/page.tsx +64 -0
  132. package/templates/apps/web/app/[locale]/features/page.tsx +52 -0
  133. package/templates/apps/web/app/[locale]/layout.tsx +37 -5
  134. package/templates/apps/web/app/[locale]/newsletter/__tests__/newsletter.actions.test.ts +75 -0
  135. package/templates/apps/web/app/[locale]/newsletter/__tests__/page.test.tsx +163 -0
  136. package/templates/apps/web/app/[locale]/newsletter/newsletter.actions.ts +66 -0
  137. package/templates/apps/web/app/[locale]/newsletter/page.tsx +106 -14
  138. package/templates/apps/web/app/[locale]/portfolio/[slug]/page.tsx +59 -0
  139. package/templates/apps/web/app/[locale]/portfolio/page.tsx +49 -0
  140. package/templates/apps/web/app/[locale]/use-cases/[slug]/page.tsx +18 -3
  141. package/templates/apps/web/lib/nav-config.ts +48 -36
  142. package/templates/apps/web/lib/site-identity.ts +14 -0
  143. package/templates/apps/web/messages/en.json +28 -2
  144. package/templates/content/_site.mdx +4 -2
  145. package/templates/content/en/BlogList/blog.mdx +37 -16
  146. package/templates/content/en/ContactPage/contact.mdx +14 -44
  147. package/templates/content/en/HomePage/home.mdx +8 -16
  148. package/templates/content/en/PurchasePolicyPage/purchase-policy.mdx +0 -1
  149. package/templates/content/en/UseCasesList/use-cases.mdx +6 -6
  150. package/templates/database/CHANGELOG.md +7 -0
  151. package/templates/database/package.json +1 -1
  152. package/versions.json +33 -33
  153. package/site-templates/_base/content/en/UseCase/first-use-case.mdx +0 -23
  154. package/site-templates/_base/content/en/UseCase/second-use-case.mdx +0 -23
  155. package/site-templates/_base/content/en/UseCase/third-use-case.mdx +0 -23
  156. package/site-templates/simple-service/DESIGN.md +0 -162
  157. package/site-templates/simple-service/TEMPLATE-MANIFEST.md +0 -333
  158. package/site-templates/simple-service/ailk-template.json +0 -11
  159. package/site-templates/simple-service/content/en/BookCall/book-call.mdx +0 -53
  160. package/site-templates/simple-service/content/en/ContactPage/contact.mdx +0 -32
  161. package/site-templates/simple-service/content/en/FAQPage/faq.mdx +0 -56
  162. package/site-templates/simple-service/content/en/HomePage/home.mdx +0 -85
  163. package/site-templates/simple-service/content/en/Service/landscape-design.mdx +0 -40
  164. package/site-templates/simple-service/content/en/Service/lawn-maintenance.mdx +0 -40
  165. package/site-templates/simple-service/content/en/Service/seasonal-cleanup.mdx +0 -40
  166. package/site-templates/simple-service/provenance.json +0 -4
  167. package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +0 -211
  168. package/templates/apps/web/app/[locale]/contact/__tests__/ContactForm.test.tsx +0 -96
  169. package/templates/content/en/SoftwareProduct/product.mdx +0 -175
@@ -111,21 +111,26 @@ The base rows come first, exactly as the base layer and the always-copied overla
111
111
 
112
112
  <!-- generated:begin page=/use-cases/[slug] -->
113
113
 
114
- _Detail route over `content/en/UseCase/` — 3 seed pages: `first-use-case.mdx`, `second-use-case.mdx`, `third-use-case.mdx`._
114
+ _Detail route over `content/en/UseCase/` — 3 seed pages: `persona-1.mdx`, `persona-2.mdx`, `persona-3.mdx`._
115
115
  <!-- generated:end -->
116
116
 
117
117
  `/software` (code route — the product listing, core since #6658):
118
118
 
119
- <!-- generated:begin page=/software -->
119
+ <!-- generated:begin page=/features -->
120
+
121
+ | # | Section | Component | Copy (first line) |
122
+ | --- | ------------------------------------------------- | --------- | ----------------------------------------------- |
123
+ | 1 | `hero` (eyebrow "Features" · 2 CTAs) | `Hero` | {Features: what your product does} |
124
+ | 2 | `items` (columns=3 · items ×3) | `Items` | {Everything your product does for the customer} |
125
+ | 3 | `cta` (box · checklist ×3 · 2 CTAs · closingLine) | `CTA` | {Switch to your product in time amount or less} |
120
126
 
121
- _Code route — no content, no sections._
122
127
  <!-- generated:end -->
123
128
 
124
- `/software/[slug]` (the product's own page, `/software/product` — #6658 D3):
129
+ `/features/[slug]` (one page per feature — #6721, reversing #6658 D3's single product page):
125
130
 
126
- <!-- generated:begin page=/software/[slug] -->
131
+ <!-- generated:begin page=/features/[slug] -->
127
132
 
128
- _Detail route over `content/en/SoftwareProduct/` — 1 seed page: `product.mdx`._
133
+ _Detail route over `content/en/Feature/` — 3 seed pages: `feature-1.mdx`, `feature-2.mdx`, `feature-3.mdx`._
129
134
  <!-- generated:end -->
130
135
 
131
136
  `/pricing`:
@@ -172,11 +177,9 @@ _Detail route over `content/en/SoftwareProduct/` — 1 seed page: `product.mdx`.
172
177
 
173
178
  <!-- generated:begin page=/contact -->
174
179
 
175
- | # | Section | Component | Copy (first line) |
176
- | --- | ----------------------------------------------------- | -------------- | ----------------------------------------------------------------- |
177
- | 1 | `hero` (split · eyebrow "Book a Demo" · checklist ×3) | `Hero` | {Ready to achieve a valuable outcome?} |
178
- | 2 | `logoCloud` (layout=inline · logos ×6) | `LogoCloud` | Don’t just take our word for it |
179
- | 3 | `testimonials` (quote · items ×1) | `Testimonials` | {A customer quote, in their own words, about the result they got} |
180
+ | # | Section | Component | Copy (first line) |
181
+ | --- | --------------------------------------------------------- | --------- | ------------------------------------- |
182
+ | 1 | `hero` (split · eyebrow "Contact" · checklist ×3 · 1 CTA) | `Hero` | Get every message in your email, free |
180
183
 
181
184
  <!-- generated:end -->
182
185
 
@@ -412,6 +415,22 @@ Authored per form (#3960): `contact` (if the Pro contact form redirects), `newsl
412
415
  _Detail route over `content/en/ThankYouPage/` — 3 seed pages: `apply.mdx`, `contact.mdx`, `newsletter.mdx`._
413
416
  <!-- generated:end -->
414
417
 
418
+ <!-- generated:begin page=/portfolio -->
419
+
420
+ | # | Section | Component | Copy (first line) |
421
+ | --- | ---------------------------------------------------------------------------------------------------------- | --------- | --------------------------------------- |
422
+ | 1 | `hero` (default · gapBelow=tight · size=display · surface=wash-secondary · eyebrow "{Portfolio}" · 2 CTAs) | `Hero` | {The work, before and after.} |
423
+ | 2 | `items` (tile · surface=none · columns=2 · items ×4) | `Items` | |
424
+ | 3 | `cta` (beam · chips ×3 · 2 CTAs) | `CTA` | {Is your site the before or the after?} |
425
+ | 4 | `faq` (centered · surface=gray-100 · accordion · items ×3 · initialOpen first) | `FAQ` | Frequently Asked Questions |
426
+
427
+ <!-- generated:end -->
428
+
429
+ <!-- generated:begin page=/portfolio/[slug] -->
430
+
431
+ _Detail route over `content/en/PortfolioItem/` — 4 seed pages: `sample-four.mdx`, `sample-one.mdx`, `sample-three.mdx`, `sample-two.mdx`._
432
+ <!-- generated:end -->
433
+
415
434
  ## 2a. State and persistence — Pro delta
416
435
 
417
436
  Everything in the Free manifest § 2a applies. Pro adds:
@@ -436,13 +455,13 @@ Everything in the Free manifest § 2a applies. Pro adds:
436
455
  ```
437
456
  marketing-site:
438
457
  requires: [marketing, docs-blog, scheduling, signal-collectors]
439
- categories: [accounting, legal, hvac, roofing, plumbing, electrical, landscaping, auto-repair, real-estate, technology, medical-specialty]
458
+ categories: [accounting, legal, consulting, hvac, roofing, plumbing, electrical, landscaping, auto-repair, real-estate, technology, medical-specialty]
440
459
  shape: organization-product
441
460
  design: standard
442
461
  roster:
443
462
  - { route: "/", kind: page, content: ["content/en/HomePage/home.mdx"] }
444
- - { route: "/software", kind: route }
445
- - { route: "/software/[slug]", kind: page, contentDir: "content/en/SoftwareProduct" }
463
+ - { route: "/features", kind: page, content: ["content/en/FeaturesList/features.mdx"] }
464
+ - { route: "/features/[slug]", kind: page, contentDir: "content/en/Feature" }
446
465
  - { route: "/use-cases", kind: page, content: ["content/en/UseCasesList/use-cases.mdx"] }
447
466
  - { route: "/use-cases/[slug]", kind: page, contentDir: "content/en/UseCase" }
448
467
  - { route: "/pricing", kind: page, content: ["content/en/Pricing/pricing.mdx"] }
@@ -460,6 +479,8 @@ marketing-site:
460
479
  - { route: "/projects", kind: page, content: ["content/en/ProjectsList/projects.mdx"] }
461
480
  - { route: "/projects/[slug]", kind: page, contentDir: "content/en/Project" }
462
481
  - { route: "/thanks/[slug]", kind: page, contentDir: "content/en/ThankYouPage" }
482
+ - { route: "/portfolio", kind: page, content: ["content/en/PortfolioList/portfolio.mdx"] }
483
+ - { route: "/portfolio/[slug]", kind: page, contentDir: "content/en/PortfolioItem" }
463
484
  - { route: "/blog", kind: page, content: ["apps/web/content/en/blog/index.mdx", "apps/web/content/en/blog/01-8-things-that-prove-coding-skills-are-directly-linked-to-successfully-assembling-ikea-furniture.mdx", "apps/web/content/en/blog/02-5-ways-to-guarantee-your-startup-goes-nowhere-fast.mdx", "apps/web/content/en/blog/03-10-ideas-that-will-guarantee-1000x-growth.mdx", "apps/web/content/en/blog/04-7-keys-to-saas-success-the-elite-doesnt-want-you-to-know.mdx", "apps/web/content/en/blog/launching-ailk.mdx"] }
464
485
  - { route: "/docs", kind: page, content: ["apps/web/content/en/docs/getting-started.mdx", "apps/web/content/en/docs/configure.mdx", "apps/web/content/en/docs/deploy.mdx"] }
465
486
  - { route: "/meet", kind: route }
@@ -160,3 +160,8 @@ The foundation's pinned direction is the pacing of a classic wireframe marketing
160
160
  - **Don't** add a colour accent. The foundation's one idea is black on white; a brand pass adds colour deliberately, through the theme.
161
161
  - **Don't** replace a black rule with a shadow or a grey fill.
162
162
  - **Don't** hard-code the "heading toward" values above into a page. They arrive through the platform, or not at all.
163
+
164
+ ## Revisions
165
+
166
+ - **2026-09-24 — tile hover is outline-only (operator ruling, /build-starter live pass, #6687).** A comparison tile (`items` in `variant: tile`) hovers by shifting its border to the accent only — no lift, no glow — matching the Positionary `/alternatives` ruling of 2026-08-29. Expressed as the bounded `tileHover: "outline"` option (Card `wash-outline`); the library default `lift` is unchanged for every other site.
167
+ - **2026-09-25 — the before-after section's rulings (operator, /build-starter live pass, #6687).** One layout, not two variants: a panel body is an image or rows of content under the same label bar. The label bar is the tone's fill (brand → black bar, white text) at the heading-4 role; a `neutral` panel keeps a white bar. The view selector is underline tabs with the underline under the current tab only (no full-width baseline), active black, inactive muted, black on hover. The pager is a ghost "‹ Previous" at the left edge and "Next ›" at the right edge. The catalyst column carries no icon tile — it starts at the arrow, or at an image when one is set. No back-to-all link and no tag chips on the seed pages.
@@ -4,7 +4,7 @@
4
4
  "categories": ["accounting", "legal", "technology"],
5
5
  "shape": "organization-product",
6
6
  "design": "standard",
7
- "generatedHash": "94f2cb77c5d2d72493fbf73e7599836557d44d77d48e0746896d370cdd371b4b",
7
+ "generatedHash": "e7d2b343d863a1b095dff583c61421b6fc95a4a55e10796568435672a209abfb",
8
8
  "layout": {
9
9
  "nav": "full",
10
10
  "footer": "columns",
@@ -120,21 +120,41 @@
120
120
  ]
121
121
  },
122
122
  {
123
- "route": "/software",
124
- "kind": "route",
125
- "pageType": null,
126
- "schema": null,
123
+ "route": "/features",
124
+ "kind": "page",
125
+ "pageType": "FeaturesList",
126
+ "schema": "FeaturesList",
127
127
  "shell": "MarketingShell",
128
128
  "chrome": "on",
129
- "sections": []
129
+ "sections": [
130
+ {
131
+ "type": "hero",
132
+ "component": "Hero"
133
+ },
134
+ {
135
+ "type": "items",
136
+ "component": "Items",
137
+ "options": {
138
+ "columns": 3
139
+ }
140
+ },
141
+ {
142
+ "type": "cta",
143
+ "component": "CTA"
144
+ }
145
+ ]
130
146
  },
131
147
  {
132
- "route": "/software/[slug]",
148
+ "route": "/features/[slug]",
133
149
  "kind": "page",
134
- "contentDir": "content/en/SoftwareProduct",
135
- "seeds": ["content/en/SoftwareProduct/product.mdx"],
136
- "pageType": "SoftwareProduct",
137
- "schema": "SoftwareProduct",
150
+ "contentDir": "content/en/Feature",
151
+ "seeds": [
152
+ "content/en/Feature/feature-1.mdx",
153
+ "content/en/Feature/feature-2.mdx",
154
+ "content/en/Feature/feature-3.mdx"
155
+ ],
156
+ "pageType": "Feature",
157
+ "schema": "Feature",
138
158
  "shell": "MarketingShell",
139
159
  "chrome": "on",
140
160
  "sections": []
@@ -184,9 +204,9 @@
184
204
  "kind": "page",
185
205
  "contentDir": "content/en/UseCase",
186
206
  "seeds": [
187
- "content/en/UseCase/first-use-case.mdx",
188
- "content/en/UseCase/second-use-case.mdx",
189
- "content/en/UseCase/third-use-case.mdx"
207
+ "content/en/UseCase/persona-1.mdx",
208
+ "content/en/UseCase/persona-2.mdx",
209
+ "content/en/UseCase/persona-3.mdx"
190
210
  ],
191
211
  "pageType": "UseCase",
192
212
  "schema": "UseCase",
@@ -202,6 +222,13 @@
202
222
  "shell": "MarketingShell",
203
223
  "chrome": "on",
204
224
  "sections": [
225
+ {
226
+ "type": "hero",
227
+ "component": "Hero",
228
+ "options": {
229
+ "gapBelow": "tight"
230
+ }
231
+ },
205
232
  {
206
233
  "type": "pricing",
207
234
  "component": "Pricing",
@@ -302,17 +329,6 @@
302
329
  {
303
330
  "type": "hero",
304
331
  "component": "Hero"
305
- },
306
- {
307
- "type": "logoCloud",
308
- "component": "LogoCloud",
309
- "options": {
310
- "layout": "inline"
311
- }
312
- },
313
- {
314
- "type": "testimonials",
315
- "component": "Testimonials"
316
332
  }
317
333
  ]
318
334
  },
@@ -346,10 +362,6 @@
346
362
  "type": "hero",
347
363
  "component": "Hero"
348
364
  },
349
- {
350
- "type": "newsletter",
351
- "component": "Newsletter"
352
- },
353
365
  {
354
366
  "type": "faq",
355
367
  "component": "FAQ"
@@ -477,6 +489,60 @@
477
489
  "component": "Testimonials"
478
490
  }
479
491
  ]
492
+ },
493
+ {
494
+ "route": "/portfolio",
495
+ "kind": "page",
496
+ "pageType": "PortfolioList",
497
+ "schema": "PortfolioList",
498
+ "shell": "MarketingShell",
499
+ "chrome": "on",
500
+ "sections": [
501
+ {
502
+ "type": "hero",
503
+ "component": "Hero",
504
+ "options": {
505
+ "gapBelow": "tight",
506
+ "size": "display",
507
+ "surface": "wash-secondary"
508
+ }
509
+ },
510
+ {
511
+ "type": "items",
512
+ "component": "Items",
513
+ "options": {
514
+ "surface": "none",
515
+ "columns": 2
516
+ }
517
+ },
518
+ {
519
+ "type": "cta",
520
+ "component": "CTA"
521
+ },
522
+ {
523
+ "type": "faq",
524
+ "component": "FAQ",
525
+ "options": {
526
+ "surface": "gray-100"
527
+ }
528
+ }
529
+ ]
530
+ },
531
+ {
532
+ "route": "/portfolio/[slug]",
533
+ "kind": "page",
534
+ "contentDir": "content/en/PortfolioItem",
535
+ "seeds": [
536
+ "content/en/PortfolioItem/sample-four.mdx",
537
+ "content/en/PortfolioItem/sample-one.mdx",
538
+ "content/en/PortfolioItem/sample-three.mdx",
539
+ "content/en/PortfolioItem/sample-two.mdx"
540
+ ],
541
+ "pageType": "PortfolioItem",
542
+ "schema": "PortfolioItem",
543
+ "shell": "MarketingShell",
544
+ "chrome": "on",
545
+ "sections": []
480
546
  }
481
547
  ]
482
548
  }
@@ -122,25 +122,30 @@ Three placeholder use cases from the base layer (#6658 D4): `first-use-case`, `s
122
122
 
123
123
  <!-- generated:begin page=/use-cases/[slug] -->
124
124
 
125
- _Detail route over `content/en/UseCase/` — 3 seed pages: `first-use-case.mdx`, `second-use-case.mdx`, `third-use-case.mdx`._
125
+ _Detail route over `content/en/UseCase/` — 3 seed pages: `persona-1.mdx`, `persona-2.mdx`, `persona-3.mdx`._
126
126
  <!-- generated:end -->
127
127
 
128
128
  ### `/software` — code route (the product listing) · chrome on
129
129
 
130
130
  Lists every `SoftwareProduct` page by slug. The route is core since #6658: the product's own page replaced the `/features` stand-in, so every scaffold carries it.
131
131
 
132
- <!-- generated:begin page=/software -->
132
+ <!-- generated:begin page=/features -->
133
+
134
+ | # | Section | Component | Copy (first line) |
135
+ | --- | ------------------------------------------------- | --------- | ----------------------------------------------- |
136
+ | 1 | `hero` (eyebrow "Features" · 2 CTAs) | `Hero` | {Features: what your product does} |
137
+ | 2 | `items` (columns=3 · items ×3) | `Items` | {Everything your product does for the customer} |
138
+ | 3 | `cta` (box · checklist ×3 · 2 CTAs · closingLine) | `CTA` | {Switch to your product in time amount or less} |
133
139
 
134
- _Code route — no content, no sections._
135
140
  <!-- generated:end -->
136
141
 
137
- ### `/software/<slug>` (seed: `/software/product`) — SoftwareProduct · schema `WebPage` → `SoftwareApplication` · chrome on
142
+ ### `/features/<slug>` (seeds: `feature-1` · `feature-2` · `feature-3`) — Feature · schema `WebPage` → `SoftwareApplication` (named for the feature, `featureList: [it]`) · chrome on
138
143
 
139
- Reference: `screenshots/features.png`, `copy/features.txt`, plus the how-it-works steps. The product's own detail page (#6658 D3), rendered by the `/software/[slug]` route over `content/en/SoftwareProduct/product.mdx`. Its JSON-LD is a `WebPage` whose `mainEntity` is a `SoftwareApplication` named by the page title; its feature titles become the site's `featureList` when `_site.mdx` declares a `SoftwareApplication` secondary. It carries the former `/features` sections, with their links re-pointed to in-page anchors, and the how-it-works steps that moved off `/use-cases` (the brief's "how-it-works folds into the product page"). The nav's Features links and the home page's feature links point here.
144
+ Reference: `screenshots/features.png`, `copy/features.txt`, plus the how-it-works steps. One page per feature (#6721, reversing #6658 D5), rendered by the `/features/[slug]` route over `content/en/Feature/<slug>.mdx`; the `/features` hub (`FeaturesList`) lists them. Its JSON-LD is a `WebPage` whose `mainEntity` is a `SoftwareApplication` named by the page title; its feature titles become the site's `featureList` when `_site.mdx` declares a `SoftwareApplication` secondary. It carries the former `/features` sections, with their links re-pointed to in-page anchors, and the how-it-works steps that moved off `/use-cases` (the brief's "how-it-works folds into the product page"). The nav's Features links and the home page's feature links point here.
140
145
 
141
- <!-- generated:begin page=/software/[slug] -->
146
+ <!-- generated:begin page=/features/[slug] -->
142
147
 
143
- _Detail route over `content/en/SoftwareProduct/` — 1 seed page: `product.mdx`._
148
+ _Detail route over `content/en/Feature/` — 3 seed pages: `feature-1.mdx`, `feature-2.mdx`, `feature-3.mdx`._
144
149
  <!-- generated:end -->
145
150
 
146
151
  ### `/pricing` — Pricing · schema `Pricing` · chrome on
@@ -149,13 +154,14 @@ Reference: `screenshots/pricing.png`, `copy/pricing.txt`. The reference opens on
149
154
 
150
155
  <!-- generated:begin page=/pricing -->
151
156
 
152
- | # | Section | Component | Copy (first line) |
153
- | --- | -------------------------------------------------------------------------------------------------------- | -------------- | ----------------------------------------------------------------- |
154
- | 1 | `pricing` (three-tiers-with-toggle · cardLayout=centered · eyebrow "Pricing" · plans ×3 · billingToggle) | `Pricing` | {Pays for itself in tangible value or outcome} |
155
- | 2 | `logoCloud` (layout=inline · logos ×3) | `LogoCloud` | Don’t just take our word for it |
156
- | 3 | `testimonials` (quote · items ×1) | `Testimonials` | {A customer quote, in their own words, about the result they got} |
157
- | 4 | `cta` (box · checklist ×3 · 2 CTAs · closingLine) | `CTA` | {Switch to your product in time amount or less} |
158
- | 5 | `faq` (accordion · items ×5 · 1 CTA · initialOpen none) | `FAQ` | FAQs |
157
+ | # | Section | Component | Copy (first line) |
158
+ | --- | ------------------------------------------------------------------------------------ | -------------- | ----------------------------------------------------------------- |
159
+ | 1 | `hero` (centered · gapBelow=tight · eyebrow "Pricing" · 2 CTAs) | `Hero` | {Upgrade to Pro with Commerce} |
160
+ | 2 | `pricing` (three-tiers-with-toggle · cardLayout=centered · plans ×3 · billingToggle) | `Pricing` | Basic plan |
161
+ | 3 | `logoCloud` (layout=inline · logos ×3) | `LogoCloud` | {Don’t just take our word for it} |
162
+ | 4 | `testimonials` (quote · items ×1) | `Testimonials` | {A customer quote, in their own words, about the result they got} |
163
+ | 5 | `cta` (box · checklist ×3 · 2 CTAs · closingLine) | `CTA` | {Switch to your product in time amount or less} |
164
+ | 6 | `faq` (accordion · items ×5 · 1 CTA · initialOpen none) | `FAQ` | {FAQs} |
159
165
 
160
166
  <!-- generated:end -->
161
167
 
@@ -195,11 +201,9 @@ Reference: `screenshots/contact.png`, `copy/contact.txt`. The reference is a spl
195
201
 
196
202
  <!-- generated:begin page=/contact -->
197
203
 
198
- | # | Section | Component | Copy (first line) |
199
- | --- | ----------------------------------------------------- | -------------- | ----------------------------------------------------------------- |
200
- | 1 | `hero` (split · eyebrow "Book a Demo" · checklist ×3) | `Hero` | {Ready to achieve a valuable outcome?} |
201
- | 2 | `logoCloud` (layout=inline · logos ×6) | `LogoCloud` | Don’t just take our word for it |
202
- | 3 | `testimonials` (quote · items ×1) | `Testimonials` | {A customer quote, in their own words, about the result they got} |
204
+ | # | Section | Component | Copy (first line) |
205
+ | --- | --------------------------------------------------------- | --------- | ------------------------------------- |
206
+ | 1 | `hero` (split · eyebrow "Contact" · checklist ×3 · 1 CTA) | `Hero` | Get every message in your email, free |
203
207
 
204
208
  <!-- generated:end -->
205
209
 
@@ -222,11 +226,10 @@ A base-layer seed every starter carries (#6658 D5). The form posts to lead captu
222
226
 
223
227
  <!-- generated:begin page=/newsletter -->
224
228
 
225
- | # | Section | Component | Copy (first line) |
226
- | --- | ------------------------------------- | ------------ | ------------------------------------------------ |
227
- | 1 | `hero` (eyebrow "Newsletter" · 1 CTA) | `Hero` | {Newsletter: what subscribers get and how often} |
228
- | 2 | `newsletter` | `Newsletter` | Subscribe |
229
- | 3 | `faq` (expanded · items ×3) | `FAQ` | FAQs |
229
+ | # | Section | Component | Copy (first line) |
230
+ | --- | -------------------------------------- | --------- | --------------------------------------- |
231
+ | 1 | `hero` (eyebrow "Newsletter" · 2 CTAs) | `Hero` | {Start a free newsletter with Substack} |
232
+ | 2 | `faq` (expanded · items ×3) | `FAQ` | FAQs |
230
233
 
231
234
  <!-- generated:end -->
232
235
 
@@ -249,12 +252,12 @@ Reference: `screenshots/blog.png`, `copy/blog.txt` for the opener and the newsle
249
252
 
250
253
  <!-- generated:begin page=/blog -->
251
254
 
252
- | # | Section | Component | Copy (first line) |
253
- | --- | --------------------------------------------------- | -------------- | ----------------------------------------------------------------- |
254
- | 1 | `hero` (centered · gapBelow=tight · eyebrow "Blog") | `Hero` | {Resources for customer profile} |
255
- | 2 | `blog-list` (grid) | `BlogList` | |
256
- | 3 | `logoCloud` (layout=inline · logos ×6) | `LogoCloud` | Don’t just take our word for it |
257
- | 4 | `testimonials` (quote · items ×1) | `Testimonials` | {A customer quote, in their own words, about the result they got} |
255
+ | # | Section | Component | Copy (first line) |
256
+ | --- | ------------------------------------------------------------ | -------------- | ----------------------------------------------------------------- |
257
+ | 1 | `hero` (centered · gapBelow=tight · eyebrow "Blog" · 2 CTAs) | `Hero` | Get free blog/docs from Fumadocs |
258
+ | 2 | `blog-list` (grid) | `BlogList` | |
259
+ | 3 | `logoCloud` (layout=inline · logos ×6) | `LogoCloud` | Don’t just take our word for it |
260
+ | 4 | `testimonials` (quote · items ×1) | `Testimonials` | {A customer quote, in their own words, about the result they got} |
258
261
 
259
262
  <!-- generated:end -->
260
263
 
@@ -312,6 +315,30 @@ One document-chassis page with the shape's policy sections — returns, shipping
312
315
 
313
316
  <!-- generated:end -->
314
317
 
318
+ ### `/portfolio` — PortfolioList · chrome on
319
+
320
+ The before/after portfolio hub (#6687). A shape row since #6753: portfolio belongs to the `organization-product` shape, Free included (operator 2026-09-25).
321
+
322
+ <!-- generated:begin page=/portfolio -->
323
+
324
+ | # | Section | Component | Copy (first line) |
325
+ | --- | ---------------------------------------------------------------------------------------------------------- | --------- | --------------------------------------- |
326
+ | 1 | `hero` (default · gapBelow=tight · size=display · surface=wash-secondary · eyebrow "{Portfolio}" · 2 CTAs) | `Hero` | {The work, before and after.} |
327
+ | 2 | `items` (tile · surface=none · columns=2 · items ×4) | `Items` | |
328
+ | 3 | `cta` (beam · chips ×3 · 2 CTAs) | `CTA` | {Is your site the before or the after?} |
329
+ | 4 | `faq` (centered · surface=gray-100 · accordion · items ×3 · initialOpen first) | `FAQ` | Frequently Asked Questions |
330
+
331
+ <!-- generated:end -->
332
+
333
+ ### `/portfolio/<slug>` (seeds: `sample-one` … `sample-four`) — PortfolioItem · chrome on
334
+
335
+ One `before-after` comparison per page, seeded from `site-templates/_base/content/en/PortfolioItem/` (#6687, #6753).
336
+
337
+ <!-- generated:begin page=/portfolio/[slug] -->
338
+
339
+ _Detail route over `content/en/PortfolioItem/` — 4 seed pages: `sample-four.mdx`, `sample-one.mdx`, `sample-three.mdx`, `sample-two.mdx`._
340
+ <!-- generated:end -->
341
+
315
342
  ### `/thanks/<slug>` — per-form confirmation (InstrumentDeliveryPage) · chrome on
316
343
 
317
344
  Not a hub page by design (#3960). Free ships none because the contact form confirms inline. Listed so nobody re-files it.
@@ -360,8 +387,8 @@ marketing-site-free:
360
387
  design: standard
361
388
  roster:
362
389
  - { route: "/", kind: page, content: ["content/en/HomePage/home.mdx"] }
363
- - { route: "/software", kind: route }
364
- - { route: "/software/[slug]", kind: page, contentDir: "content/en/SoftwareProduct" }
390
+ - { route: "/features", kind: page, content: ["content/en/FeaturesList/features.mdx"] }
391
+ - { route: "/features/[slug]", kind: page, contentDir: "content/en/Feature" }
365
392
  - { route: "/use-cases", kind: page, content: ["content/en/UseCasesList/use-cases.mdx"] }
366
393
  - { route: "/use-cases/[slug]", kind: page, contentDir: "content/en/UseCase" }
367
394
  - { route: "/pricing", kind: page, content: ["content/en/Pricing/pricing.mdx"] }
@@ -377,11 +404,13 @@ marketing-site-free:
377
404
  - { route: "/terms", kind: page, content: ["content/en/TermsPage/terms.mdx"] }
378
405
  - { route: "/purchase-policy", kind: page, content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"] }
379
406
  - { route: "/blog", kind: page, content: ["content/en/BlogList/blog.mdx"] }
407
+ - { route: "/portfolio", kind: page, content: ["content/en/PortfolioList/portfolio.mdx"] }
408
+ - { route: "/portfolio/[slug]", kind: page, contentDir: "content/en/PortfolioItem" }
380
409
  ```
381
410
 
382
411
  <!-- generated:end -->
383
412
 
384
- All eighteen rows are declared on the registry (`TEMPLATE_BASE_ROSTER` + the Free `/blog` teaser row, #5469 D3/D4, re-derived by #6658), so the template is one declared page set whichever mechanism scaffolds each: the always-copied overlay for the core pages, `site-templates/_base/content/**` for the module-less ones and the three use cases. The scaffold carries this roster as `.ailk-site-manifest.json` at its root (#6658 D7); this Markdown stays in the template.
413
+ All twenty rows are declared on the registry — the `organization-product` shape roster in `src/starter-grid.ts`: `TEMPLATE_BASE_ROSTER` + the `/blog` teaser row + the two portfolio rows (#5469 D3/D4, re-derived by #6658, portfolio added by #6753), so the template is one declared page set whichever mechanism scaffolds each: the always-copied overlay for the core pages, `site-templates/_base/content/**` for the module-less ones and the three use cases. The scaffold carries this roster as `.ailk-site-manifest.json` at its root (#6658 D7); this Markdown stays in the template.
385
414
 
386
415
  ### 3a. Deviations from the standard roster (recorded, #6658)
387
416
 
@@ -410,12 +439,13 @@ reversed (`docs/decisions/starter-roster-page-set.md` D4, D7).
410
439
 
411
440
  **Rows added:**
412
441
 
413
- | Added row | Reason |
414
- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
415
- | `SoftwareProduct` | the single product's own detail page — the standard's multi-product opt-in, taken by the one product |
416
- | `PurchasePolicyPage` | the product-shape purchase policy every shape carries (#6646 D3) |
417
- | `BlogList` (the `/blog` teaser) | the standard's `convert` goal carries no blog (`blog_enabled: false`); the Free teaser stays by operator ruling 2026-09-24, and where the docs-blog module is present its own `BlogList` serves `/blog` instead |
418
- | `/software`, `/sign-in`, `/sign-up` | code routes (`kind: route`): the product listing and the two auth pages carry no page type of their own |
442
+ | Added row | Reason |
443
+ | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
444
+ | `SoftwareProduct` | the single product's own detail page — the standard's multi-product opt-in, taken by the one product |
445
+ | `PurchasePolicyPage` | the product-shape purchase policy every shape carries (#6646 D3) |
446
+ | `BlogList` (the `/blog` teaser) | the standard's `convert` goal carries no blog (`blog_enabled: false`); the Free teaser stays by operator ruling 2026-09-24, and where the docs-blog module is present its own `BlogList` serves `/blog` instead |
447
+ | `/software`, `/sign-in`, `/sign-up` | code routes (`kind: route`): the product listing and the two auth pages carry no page type of their own |
448
+ | `PortfolioList`, `PortfolioItem` (`/portfolio`, `/portfolio/[slug]`) | portfolio belongs to the shape, Free included (roadmap § 4, operator 2026-09-25, reversing #6687's "Pro and up"; #6753). `pnpm starter:check` R3.2 counts two more missing anchor captures for these routes — the pre-existing, non-CI anchor gap, now 14 |
419
449
 
420
450
  ### 3b. Site entity (operator-disposed 2026-09-24)
421
451
 
@@ -425,11 +455,11 @@ reversed (`docs/decisions/starter-roster-page-set.md` D4, D7).
425
455
 
426
456
  <!-- generated:begin inventory -->
427
457
 
428
- | Tier | Used by this template |
429
- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
430
- | Shell | `MarketingShell` |
431
- | Chrome | `Nav`, `Footer`, `Banner` (+ `BannerConsentIsland`, `BannerDismissIsland`) |
432
- | Sections | `BlogList`, `ContentBlock`, `CTA`, `DecisionSplit`, `DocumentChassis`, `FAQ`, `Feature`, `GlossaryIndex`, `Hero`, `Items`, `LogoCloud`, `MediaBand`, `Newsletter`, `Pricing`, `Team`, `Testimonials` |
458
+ | Tier | Used by this template |
459
+ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
460
+ | Shell | `MarketingShell` |
461
+ | Chrome | `Nav`, `Footer`, `Banner` (+ `BannerConsentIsland`, `BannerDismissIsland`) |
462
+ | Sections | `BlogList`, `ContentBlock`, `CTA`, `DecisionSplit`, `DocumentChassis`, `FAQ`, `Feature`, `GlossaryIndex`, `Hero`, `Items`, `LogoCloud`, `MediaBand`, `Pricing`, `Team`, `Testimonials` |
433
463
 
434
464
  <!-- generated:end -->
435
465
 
@@ -0,0 +1,59 @@
1
+ ---
2
+ type: "NewsletterSignup"
3
+ slug: "newsletter"
4
+ title: "{Start a free newsletter with Substack}"
5
+ description: "{Or upgrade to Pro to capture every subscriber and build your own marketing database.}"
6
+ schema:
7
+ mainEntity:
8
+ "@type": "Offer"
9
+ name: "{Your newsletter name}"
10
+ price: 0
11
+ priceCurrency: "USD"
12
+ sections:
13
+ [
14
+ {
15
+ "id": "hero",
16
+ "type": "hero",
17
+ "data":
18
+ {
19
+ "eyebrow": "Newsletter",
20
+ "headline": "{Start a free newsletter with Substack}",
21
+ "subheadline": "{Or upgrade to Pro to capture every subscriber and build your own marketing database.}",
22
+ "primaryCta":
23
+ { "label": "{Connect Substack}", "href": "https://substack.com" },
24
+ "secondaryCta":
25
+ {
26
+ "label": "{Upgrade to Pro}",
27
+ "href": "https://ailaunchkit.ai/pricing",
28
+ "variant": "outline",
29
+ },
30
+ },
31
+ },
32
+ {
33
+ "id": "faq",
34
+ "type": "faq",
35
+ "data":
36
+ {
37
+ "headline": "FAQs",
38
+ "presentation": "expanded",
39
+ "items":
40
+ [
41
+ {
42
+ "question": "{How often will I hear from you?}",
43
+ "answer": "{Answer in one or two plain sentences}",
44
+ },
45
+ {
46
+ "question": "{What will I get?}",
47
+ "answer": "{Answer in one or two plain sentences}",
48
+ },
49
+ {
50
+ "question": "{Can I unsubscribe?}",
51
+ "answer": "{Answer in one or two plain sentences}",
52
+ },
53
+ ],
54
+ },
55
+ },
56
+ ]
57
+ ---
58
+
59
+ {/* Rendered from frontmatter `sections[]` by the /newsletter route. The Free template has no signup form: the hero points the owner to Substack, or to Pro for subscriber capture. The `schema:` Offer is the page's JSON-LD main entity — a free subscription. Placeholder copy — replace every {brace} with your own words before you launch. */}