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
@@ -0,0 +1,300 @@
1
+ # Template manifest — `organization-service`
2
+
3
+ > The Free `organization-service` shape starter (#6757, roadmap § 6 Phase 2) — a company selling a service to clients anywhere, scaffolded keyless with no `--template` alias of its own. Generated file: the regions between `<!-- generated:begin <id> -->` and `<!-- generated:end -->` are produced by `scripts/build-template-manifest.mjs --template organization-service --check` from the composed layer stack (this tree → `_base` → the always-copied overlay), each roster row's MDX `sections[]`, and `component-catalog.json`. Everything outside the markers is written by hand.
4
+
5
+ | Field | Value |
6
+ | ---------------------- | ------------------------------------------------------------------------------- |
7
+ | Starter | `organization-service` (a `SHAPE_STARTERS` entry, not a `--template` alias) |
8
+ | Level | Free (derived from `requires` — `marketing` only; never declared) |
9
+ | `requires` | `[marketing]` |
10
+ | `extends` | `_base` — lineage only, never level |
11
+ | Delivery | keyless — ships in the tarball at `site-templates/shapes/organization-service/` |
12
+ | Sample content posture | every line of copy is a **placeholder**; no seed carries a price (D4) |
13
+
14
+ ## 1. Chrome
15
+
16
+ This starter declares **no `layout` block** — the default marketing chrome.
17
+
18
+ ### Layout knobs (#5612)
19
+
20
+ <!-- generated:begin layout -->
21
+
22
+ | Knob | Value |
23
+ | -------------------- | --------- |
24
+ | `nav` | `full` |
25
+ | `footer` | `columns` |
26
+ | `announcementBanner` | `false` |
27
+ | `home` | `default` |
28
+
29
+ <!-- generated:end -->
30
+
31
+ ### Theme (locked)
32
+
33
+ <!-- generated:begin theme -->
34
+
35
+ | Setting | Value |
36
+ | ------------------------ | ---------- |
37
+ | `corners` | `square` |
38
+ | `eyebrowCase` | `sentence` |
39
+ | `placeholders` | `fill` |
40
+ | `checkmarks` | `plain` |
41
+ | `colors.light.bg` | `#ffffff` |
42
+ | `colors.light.bgMuted` | `#ffffff` |
43
+ | `colors.light.surface` | `#ffffff` |
44
+ | `colors.light.border` | `#000000` |
45
+ | `colors.light.text` | `#000000` |
46
+ | `colors.light.textMuted` | `#333333` |
47
+ | `colors.light.primary` | `#000000` |
48
+ | `colors.light.primaryFg` | `#ffffff` |
49
+ | `colors.light.accent` | `#000000` |
50
+ | `colors.dark.bg` | `#000000` |
51
+ | `colors.dark.bgMuted` | `#000000` |
52
+ | `colors.dark.surface` | `#000000` |
53
+ | `colors.dark.border` | `#ffffff` |
54
+ | `colors.dark.text` | `#ffffff` |
55
+ | `colors.dark.textMuted` | `#cccccc` |
56
+ | `colors.dark.primary` | `#ffffff` |
57
+ | `colors.dark.primaryFg` | `#000000` |
58
+ | `colors.dark.accent` | `#ffffff` |
59
+
60
+ <!-- generated:end -->
61
+
62
+ ## 2. Pages
63
+
64
+ One `page=<route>` region per roster row, generated from the seed file the composed layer stack lands for that route.
65
+
66
+ `/`:
67
+
68
+ <!-- generated:begin page=/ -->
69
+
70
+ | # | Section | Component | Copy (first line) |
71
+ | --- | ----------------------------------------------------- | --------- | ------------------------------------------------- |
72
+ | 1 | `hero` (centered · eyebrow "{Your Company}" · 2 CTAs) | `Hero` | {One line on the outcome you deliver for clients} |
73
+ | 2 | `items` (columns=3 · items ×3) | `Items` | What we do |
74
+ | 3 | `cta` (minimal · 2 CTAs) | `CTA` | Ready to talk about your project? |
75
+
76
+ <!-- generated:end -->
77
+
78
+ `/about`:
79
+
80
+ <!-- generated:begin page=/about -->
81
+
82
+ | # | Section | Component | Copy (first line) |
83
+ | --- | ------------------------------------------ | -------------- | -------------------------------------------------------- |
84
+ | 1 | `content-block` (narrow · eyebrow "About") | `ContentBlock` | {A small team, a short client list, a long relationship} |
85
+ | 2 | `cta` (minimal · 2 CTAs) | `CTA` | Work with us |
86
+
87
+ <!-- generated:end -->
88
+
89
+ `/services`:
90
+
91
+ <!-- generated:begin page=/services -->
92
+
93
+ | # | Section | Component | Copy (first line) |
94
+ | --- | -------------------------------------- | --------- | --------------------------- |
95
+ | 1 | `hero` (centered · eyebrow "Services") | `Hero` | Three ways to work together |
96
+ | 2 | `items` (columns=3 · items ×3) | `Items` | Engagements |
97
+ | 3 | `cta` (minimal · 1 CTA) | `CTA` | Not sure which one? |
98
+
99
+ <!-- generated:end -->
100
+
101
+ `/services/[slug]`:
102
+
103
+ <!-- generated:begin page=/services/[slug] -->
104
+
105
+ _Detail route over `content/en/Service/` — 3 seed pages: `first-engagement.mdx`, `second-engagement.mdx`, `third-engagement.mdx`._
106
+ <!-- generated:end -->
107
+
108
+ `/contact` (always-copied overlay seed):
109
+
110
+ <!-- generated:begin page=/contact -->
111
+
112
+ | # | Section | Component | Copy (first line) |
113
+ | --- | --------------------------------------------------------- | --------- | ------------------------------------- |
114
+ | 1 | `hero` (split · eyebrow "Contact" · checklist ×3 · 1 CTA) | `Hero` | Get every message in your email, free |
115
+
116
+ <!-- generated:end -->
117
+
118
+ `/faq` (always-copied overlay seed):
119
+
120
+ <!-- generated:begin page=/faq -->
121
+
122
+ | # | Section | Component | Copy (first line) |
123
+ | --- | ------------------------------------------------------- | --------- | ---------------------------------------- |
124
+ | 1 | `hero` (gapBelow=tight · eyebrow "FAQ") | `Hero` | FAQs |
125
+ | 2 | `faq` (accordion · items ×5 · 1 CTA · initialOpen none) | `FAQ` | {A question your customers actually ask} |
126
+ | 3 | `faq` (accordion · items ×5 · 1 CTA · initialOpen none) | `FAQ` | {A second group of questions} |
127
+
128
+ <!-- generated:end -->
129
+
130
+ `/glossary`, `/newsletter`, `/book-a-call` (base-layer seeds every starter carries, #6658 D5 — `/newsletter` is this tree's own byte copy of the Free newsletter, D4/D9):
131
+
132
+ <!-- generated:begin page=/glossary -->
133
+
134
+ | # | Section | Component | Copy (first line) |
135
+ | --- | ----------------------------------- | --------------- | -------------------------------------------- |
136
+ | 1 | `hero` (eyebrow "Glossary" · 1 CTA) | `Hero` | {Glossary: the terms your customers look up} |
137
+ | 2 | `glossary-index` (columns) | `GlossaryIndex` | {Terms, A to Z} |
138
+
139
+ <!-- generated:end -->
140
+
141
+ <!-- generated:begin page=/newsletter -->
142
+
143
+ | # | Section | Component | Copy (first line) |
144
+ | --- | -------------------------------------- | --------- | --------------------------------------- |
145
+ | 1 | `hero` (eyebrow "Newsletter" · 2 CTAs) | `Hero` | {Start a free newsletter with Substack} |
146
+ | 2 | `faq` (expanded · items ×3) | `FAQ` | FAQs |
147
+
148
+ <!-- generated:end -->
149
+
150
+ <!-- generated:begin page=/book-a-call -->
151
+
152
+ | # | Section | Component | Copy (first line) |
153
+ | --- | -------------------------------------- | --------- | ------------------------------------------ |
154
+ | 1 | `hero` (eyebrow "Book a call" · 1 CTA) | `Hero` | {Book a call: what a visitor gets from it} |
155
+ | 2 | `items` (columns=3 · items ×3) | `Items` | What happens on the call? |
156
+
157
+ <!-- generated:end -->
158
+
159
+ `/privacy`, `/terms` (base-layer seeds):
160
+
161
+ <!-- generated:begin page=/privacy -->
162
+
163
+ | # | Section | Component | Copy (first line) |
164
+ | --- | ----------------------------------- | ----------------- | ----------------- |
165
+ | 1 | `document-chassis` (layout=article) | `DocumentChassis` | Privacy Policy |
166
+
167
+ <!-- generated:end -->
168
+
169
+ <!-- generated:begin page=/terms -->
170
+
171
+ | # | Section | Component | Copy (first line) |
172
+ | --- | ----------------------------------- | ----------------- | ----------------- |
173
+ | 1 | `document-chassis` (layout=article) | `DocumentChassis` | Terms of Service |
174
+
175
+ <!-- generated:end -->
176
+
177
+ `/purchase-policy` (this tree's own service-shape override — cancellation and refunds, D4):
178
+
179
+ <!-- generated:begin page=/purchase-policy -->
180
+
181
+ | # | Section | Component | Copy (first line) |
182
+ | --- | ----------------------------------- | ----------------- | ----------------- |
183
+ | 1 | `document-chassis` (layout=article) | `DocumentChassis` | Purchase Policy |
184
+
185
+ <!-- generated:end -->
186
+
187
+ `/blog` (the Free teaser row, § 1.8 — served by the generic `[slug]` route over the always-copied overlay's `BlogList/blog.mdx`):
188
+
189
+ <!-- generated:begin page=/blog -->
190
+
191
+ | # | Section | Component | Copy (first line) |
192
+ | --- | ------------------------------------------------------------ | -------------- | ----------------------------------------------------------------- |
193
+ | 1 | `hero` (centered · gapBelow=tight · eyebrow "Blog" · 2 CTAs) | `Hero` | Get free blog/docs from Fumadocs |
194
+ | 2 | `blog-list` (grid) | `BlogList` | |
195
+ | 3 | `logoCloud` (layout=inline · logos ×6) | `LogoCloud` | Don’t just take our word for it |
196
+ | 4 | `testimonials` (quote · items ×1) | `Testimonials` | {A customer quote, in their own words, about the result they got} |
197
+
198
+ <!-- generated:end -->
199
+
200
+ `/portfolio` (this tree's own override of the `_base` seed — both primary CTAs point at `/contact`, D4):
201
+
202
+ <!-- generated:begin page=/portfolio -->
203
+
204
+ | # | Section | Component | Copy (first line) |
205
+ | --- | ---------------------------------------------------------------------------------------------------------- | --------- | ------------------------------------------ |
206
+ | 1 | `hero` (default · gapBelow=tight · size=display · surface=wash-secondary · eyebrow "{Portfolio}" · 2 CTAs) | `Hero` | {The work, before and after.} |
207
+ | 2 | `items` (tile · surface=none · columns=2 · items ×4) | `Items` | |
208
+ | 3 | `cta` (beam · chips ×3 · 2 CTAs) | `CTA` | {Is your project the before or the after?} |
209
+ | 4 | `faq` (centered · surface=gray-100 · accordion · items ×3 · initialOpen first) | `FAQ` | Frequently Asked Questions |
210
+
211
+ <!-- generated:end -->
212
+
213
+ `/portfolio/[slug]`:
214
+
215
+ <!-- generated:begin page=/portfolio/[slug] -->
216
+
217
+ _Detail route over `content/en/PortfolioItem/` — 4 seed pages: `sample-four.mdx`, `sample-one.mdx`, `sample-three.mdx`, `sample-two.mdx`._
218
+ <!-- generated:end -->
219
+
220
+ ### 3a. Differences from the standard `organization-service` derivation
221
+
222
+ The standard page set for this shape (`derive-roster.py --shape organization-service --primary-goal generate-leads --registry packages/schema/src/registry/entries.ts`, harness commit `7bdaf148e1b0e639cd90a80008955e55cc4aa2b5`) is 33 rows, `mainEntity: Organization`. This starter's roster is that set minus the standard rows the table below drops, plus the rows the table after it adds, each with a reason.
223
+
224
+ **Standard rows dropped:**
225
+
226
+ | Standard row | Reason |
227
+ | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
228
+ | `TeamList` · `TeamMember` | a placeholder starter has no team to list; `/about` carries the people |
229
+ | `CareersList` · `JobPosting` | a placeholder starter has no open roles |
230
+ | `PartnersList` · `Partner` | a placeholder starter has no partners to list |
231
+ | `ProjectsList` · `Project` | the portfolio pair (`/portfolio`) is the proof of past work; `/projects` is the signal-collectors sample listing |
232
+ | `Pricing` | a service is priced on its own `Service` page (or quoted), not on a pricing table |
233
+ | `CaseStudiesList` · `CaseStudy` · `TestimonialsList` · `ClientsList` | proof pages need real customers (the #6658 reason) |
234
+ | `UseCasesList` · `UseCase` | each `Service` page names who it is for; the `_base` persona seeds are product copy that links `/pricing` |
235
+ | `EventsList` · `Event` · `DownloadsList` | a placeholder starter has no events or downloads |
236
+ | `ResourcesHub` · `ResourceDetail` · `HowTo` · `Whitepaper` | the Resources content system is the goal-driven default a site grows into, not a starter page |
237
+
238
+ **Rows added:**
239
+
240
+ | Row added | Reason |
241
+ | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
242
+ | `PurchasePolicyPage` | every shape carries one purchase policy with its shape's sections — service: cancellation and refunds (#6646 D3) |
243
+ | `PortfolioList` · `PortfolioItem` | the portfolio pair belongs to every shape's standard roster (operator, 2026-09-25; roadmap § 4) |
244
+ | `BlogList` | every Free scaffold's nav links `/blog` unconditionally (`renderNavConfig`, operator ruling 2026-09-23); the Free teaser serves it, as on organization-product (§ 1.8) |
245
+
246
+ `|S − D| = 11` and `|R| = 15`.
247
+
248
+ ## 4. Roster, as the registry declares it
249
+
250
+ `organization-service` is a `SHAPE_STARTERS` entry, not a declared `--template` alias: `TEMPLATE_MANIFESTS` and `RECOGNIZED_TEMPLATES` never carry its name (NFR-3). The merged roster, as the registry composes it:
251
+
252
+ <!-- generated:begin roster -->
253
+
254
+ ```
255
+ organization-service:
256
+ requires: [marketing]
257
+ categories: [accounting, legal, real-estate]
258
+ shape: organization-service
259
+ design: standard
260
+ roster:
261
+ - { route: "/", kind: page, content: ["content/en/HomePage/home.mdx"] }
262
+ - { route: "/about", kind: page, content: ["content/en/AboutPage/about.mdx"] }
263
+ - { route: "/services", kind: page, content: ["content/en/ServicesList/services.mdx"] }
264
+ - { route: "/services/[slug]", kind: page, contentDir: "content/en/Service" }
265
+ - { route: "/contact", kind: page, content: ["content/en/ContactPage/contact.mdx"] }
266
+ - { route: "/faq", kind: page, content: ["content/en/FAQPage/faq.mdx"] }
267
+ - { route: "/glossary", kind: page, content: ["content/en/GlossaryList/glossary.mdx"] }
268
+ - { route: "/newsletter", kind: page, content: ["content/en/NewsletterSignup/newsletter.mdx"] }
269
+ - { route: "/book-a-call", kind: page, content: ["content/en/BookCall/book-call.mdx"] }
270
+ - { route: "/privacy", kind: page, content: ["content/en/PrivacyPage/privacy.mdx"] }
271
+ - { route: "/terms", kind: page, content: ["content/en/TermsPage/terms.mdx"] }
272
+ - { route: "/purchase-policy", kind: page, content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"] }
273
+ - { route: "/blog", kind: page, content: ["content/en/BlogList/blog.mdx"] }
274
+ - { route: "/portfolio", kind: page, content: ["content/en/PortfolioList/portfolio.mdx"] }
275
+ - { route: "/portfolio/[slug]", kind: page, contentDir: "content/en/PortfolioItem" }
276
+ ```
277
+
278
+ <!-- generated:end -->
279
+
280
+ By source:
281
+
282
+ ```
283
+ starter: / · /about · /services · /services/<slug> · /contact · /faq
284
+ /glossary · /newsletter · /book-a-call · /privacy · /terms
285
+ /purchase-policy · /blog · /portfolio · /portfolio/<slug>
286
+ ```
287
+
288
+ Every row is module-less: `requires` is `[marketing]` alone, so `mergeRoster` contributes nothing beyond this tree's own fifteen rows.
289
+
290
+ ## 5. Component inventory
291
+
292
+ <!-- generated:begin inventory -->
293
+
294
+ | Tier | Used by this template |
295
+ | -------- | -------------------------------------------------------------------------------------------------------------------------- |
296
+ | Shell | `MarketingShell` |
297
+ | Chrome | `Nav`, `Footer`, `Banner` (+ `BannerConsentIsland`, `BannerDismissIsland`) |
298
+ | Sections | `BlogList`, `ContentBlock`, `CTA`, `DocumentChassis`, `FAQ`, `GlossaryIndex`, `Hero`, `Items`, `LogoCloud`, `Testimonials` |
299
+
300
+ <!-- generated:end -->
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "organization-service",
3
+ "requires": ["marketing"],
4
+ "extends": "_base",
5
+ "installMap": {
6
+ "provenance.json": ".ailk-template.json",
7
+ "TEMPLATE-MANIFEST.json": ".ailk-site-manifest.json"
8
+ },
9
+ "postInstall": "Starter organization-service installed. Its /faq, /contact and /blog seed pages came with the always-copied overlay; /glossary, /newsletter, /book-a-call, /privacy and /terms with the base layer it extends (content/en/). This tree's own /, /about, /services (+ three engagements), /purchase-policy and /portfolio pages are its own compositions. Every line of copy is a placeholder — replace it before you launch."
10
+ }
@@ -0,0 +1,38 @@
1
+ ---
2
+ type: "AboutPage"
3
+ slug: "about"
4
+ title: "About"
5
+ description: "The team behind {your company}. Placeholder copy — replace before you launch."
6
+ sections:
7
+ [
8
+ {
9
+ "id": "intro",
10
+ "type": "content-block",
11
+ "data":
12
+ {
13
+ "variant": "narrow",
14
+ "eyebrow": "About",
15
+ "headline": "{A small team, a short client list, a long relationship}",
16
+ "body": "{Two or three sentences on how the company started, who it works with, and what it will not take on. Keep it concrete rather than aspirational.}",
17
+ },
18
+ },
19
+ {
20
+ "id": "closing",
21
+ "type": "cta",
22
+ "data":
23
+ {
24
+ "variant": "minimal",
25
+ "headline": "Work with us",
26
+ "primaryCta": { "label": "Get in touch", "href": "/contact" },
27
+ "secondaryCta":
28
+ {
29
+ "label": "See services",
30
+ "href": "/services",
31
+ "variant": "outline",
32
+ },
33
+ },
34
+ },
35
+ ]
36
+ ---
37
+
38
+ Placeholder copy. This page overrides the always-copied overlay's `AboutPage/about.mdx`.
@@ -0,0 +1,85 @@
1
+ ---
2
+ type: "HomePage"
3
+ slug: "home"
4
+ title: "Your Company"
5
+ description: "Placeholder home for the organization-service starter — a company selling a service to clients anywhere. Replace every line before you launch."
6
+ sections:
7
+ [
8
+ {
9
+ "id": "hero",
10
+ "type": "hero",
11
+ "data":
12
+ {
13
+ "variant": "centered",
14
+ "eyebrow": "{Your Company}",
15
+ "headline": "{One line on the outcome you deliver for clients}",
16
+ "subheadline": "{One line on who you work with and what makes the engagement different.}",
17
+ "primaryCta": { "label": "Get in touch", "href": "/contact" },
18
+ "secondaryCta":
19
+ {
20
+ "label": "See services",
21
+ "href": "/services",
22
+ "variant": "outline",
23
+ },
24
+ },
25
+ },
26
+ {
27
+ "id": "services",
28
+ "type": "items",
29
+ "data":
30
+ {
31
+ "headline": "What we do",
32
+ "columns": 3,
33
+ "items":
34
+ [
35
+ {
36
+ "title": "{First engagement}",
37
+ "description": "{One line on what it is and who it suits.}",
38
+ "link":
39
+ {
40
+ "label": "Read more",
41
+ "href": "/services/first-engagement",
42
+ },
43
+ },
44
+ {
45
+ "title": "{Second engagement}",
46
+ "description": "{One line on what it is and who it suits.}",
47
+ "link":
48
+ {
49
+ "label": "Read more",
50
+ "href": "/services/second-engagement",
51
+ },
52
+ },
53
+ {
54
+ "title": "{Third engagement}",
55
+ "description": "{One line on what it is and who it suits.}",
56
+ "link":
57
+ {
58
+ "label": "Read more",
59
+ "href": "/services/third-engagement",
60
+ },
61
+ },
62
+ ],
63
+ },
64
+ },
65
+ {
66
+ "id": "closing",
67
+ "type": "cta",
68
+ "data":
69
+ {
70
+ "variant": "minimal",
71
+ "headline": "Ready to talk about your project?",
72
+ "description": "{One line inviting the reader to start the conversation.}",
73
+ "primaryCta": { "label": "Get in touch", "href": "/contact" },
74
+ "secondaryCta":
75
+ {
76
+ "label": "Read about us",
77
+ "href": "/about",
78
+ "variant": "outline",
79
+ },
80
+ },
81
+ },
82
+ ]
83
+ ---
84
+
85
+ Placeholder copy. Every headline, every line of body copy on this site is a placeholder — replace them before you launch.
@@ -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. */}
@@ -0,0 +1,171 @@
1
+ ---
2
+ type: "PortfolioList"
3
+ slug: "portfolio"
4
+ title: "{Before and after, compared} | {Company name}"
5
+ description: "{Every project shown as a comparison — what the client had, what they have now, and what changed in between.}"
6
+ sections:
7
+ [
8
+ {
9
+ "id": "cases-hero",
10
+ "type": "hero",
11
+ "data":
12
+ {
13
+ "variant": "default",
14
+ "size": "display",
15
+ "surface": "wash-secondary",
16
+ "gapBelow": "tight",
17
+ "eyebrow": "{Portfolio}",
18
+ "eyebrowTone": "brand",
19
+ "headline": "{The work, before and after.}",
20
+ "subheadline": "{Two or three sentences on why the comparison is the honest proof — what the before cost the client, what the after changed, and how a reader can check it.}",
21
+ "subtitleSize": "lead",
22
+ "ctaSize": "xl",
23
+ "primaryCta": { "label": "Get in touch", "href": "/contact" },
24
+ "secondaryCta": { "label": "{See services}", "href": "/services" },
25
+ },
26
+ },
27
+ {
28
+ "id": "cases-tiles",
29
+ "type": "items",
30
+ "data":
31
+ {
32
+ "variant": "tile",
33
+ "tileHover": "outline",
34
+ "columns": 2,
35
+ "surface": "none",
36
+ "items":
37
+ [
38
+ {
39
+ "title": "{Example one}: before and after",
40
+ "description": "{One sentence on what example one had, and what they have now}",
41
+ "rows":
42
+ [
43
+ {
44
+ "label": "THE CLIENT",
45
+ "body": "{Who they are and the market they sell into}",
46
+ },
47
+ {
48
+ "label": "WHAT CHANGED",
49
+ "body": "{The one thing the after does that the before could not}",
50
+ },
51
+ ],
52
+ "link":
53
+ {
54
+ "label": "See the comparison →",
55
+ "href": "/portfolio/sample-one",
56
+ },
57
+ },
58
+ {
59
+ "title": "{Example two}: before and after",
60
+ "description": "{One sentence on what example two had, and what they have now}",
61
+ "rows":
62
+ [
63
+ {
64
+ "label": "THE CLIENT",
65
+ "body": "{Who they are and the market they sell into}",
66
+ },
67
+ {
68
+ "label": "WHAT CHANGED",
69
+ "body": "{The one thing the after does that the before could not}",
70
+ },
71
+ ],
72
+ "link":
73
+ {
74
+ "label": "See the comparison →",
75
+ "href": "/portfolio/sample-two",
76
+ },
77
+ },
78
+ {
79
+ "title": "{Example three}: before and after",
80
+ "description": "{One sentence on what example three had, and what they have now}",
81
+ "rows":
82
+ [
83
+ {
84
+ "label": "THE CLIENT",
85
+ "body": "{Who they are and the market they sell into}",
86
+ },
87
+ {
88
+ "label": "WHAT CHANGED",
89
+ "body": "{The one thing the after does that the before could not}",
90
+ },
91
+ ],
92
+ "link":
93
+ {
94
+ "label": "See the comparison →",
95
+ "href": "/portfolio/sample-three",
96
+ },
97
+ },
98
+ {
99
+ "title": "{Example four}: before and after",
100
+ "description": "{One sentence on what example four had, and what they have now}",
101
+ "rows":
102
+ [
103
+ {
104
+ "label": "THE CLIENT",
105
+ "body": "{Who they are and the market they sell into}",
106
+ },
107
+ {
108
+ "label": "WHAT CHANGED",
109
+ "body": "{The one thing the after does that the before could not}",
110
+ },
111
+ ],
112
+ "link":
113
+ {
114
+ "label": "See the comparison →",
115
+ "href": "/portfolio/sample-four",
116
+ },
117
+ },
118
+ ],
119
+ },
120
+ },
121
+ {
122
+ "id": "cases-close",
123
+ "type": "cta",
124
+ "data":
125
+ {
126
+ "variant": "beam",
127
+ "headline": "{Is your project the before or the after?}",
128
+ "description": "{One line offering the reader the same comparison for their own project.}",
129
+ "primaryCta": { "label": "Get in touch", "href": "/contact" },
130
+ "secondaryCta": { "label": "{See services}", "href": "/services" },
131
+ "chips":
132
+ [
133
+ "{Proof you can check}",
134
+ "{Every project shown both ways}",
135
+ "{Re-checked every quarter}",
136
+ ],
137
+ },
138
+ },
139
+ {
140
+ "id": "cases-faq",
141
+ "type": "faq",
142
+ "data":
143
+ {
144
+ "headline": "Frequently Asked Questions",
145
+ "variant": "centered",
146
+ "presentation": "accordion",
147
+ "questionSize": "body-lg",
148
+ "initialOpen": "first",
149
+ "containerWidth": "default",
150
+ "surface": "gray-100",
151
+ "items":
152
+ [
153
+ {
154
+ "question": "{How do you pick which projects to show?}",
155
+ "answer": "{Two or three sentences.}",
156
+ },
157
+ {
158
+ "question": "{Are the before screenshots real?}",
159
+ "answer": "{Two or three sentences.}",
160
+ },
161
+ {
162
+ "question": "{Can I see the numbers behind a comparison?}",
163
+ "answer": "{Two or three sentences.}",
164
+ },
165
+ ],
166
+ },
167
+ },
168
+ ]
169
+ ---
170
+
171
+ {/* This tree's override of the `_base` PortfolioList page (D4): the `_base` page's two primary CTAs link `/pricing`, a route this shape does not serve, so this override keeps the same section types and four sample comparisons and points both primary CTAs at `/contact` instead. */}