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,199 @@
1
+ ---
2
+ type: "Pricing"
3
+ slug: "pricing"
4
+ title: "{Upgrade to Pro with Commerce}"
5
+ description: "{Checkout isn't included on the Free template. Upgrade to Pro with Commerce and take payments on your site with Stripe.}"
6
+ sections:
7
+ [
8
+ {
9
+ "id": "hero",
10
+ "type": "hero",
11
+ "data":
12
+ {
13
+ "variant": "centered",
14
+ "gapBelow": "tight",
15
+ "eyebrow": "Pricing",
16
+ "headline": "{Upgrade to Pro with Commerce}",
17
+ "subheadline": "{Checkout isn't included on the Free template. Upgrade to Pro with Commerce and take payments on your site with Stripe.}",
18
+ "primaryCta":
19
+ {
20
+ "label": "{Add Commerce for SMB}",
21
+ "href": "https://ailaunchkit.ai/pricing",
22
+ },
23
+ "secondaryCta":
24
+ {
25
+ "label": "{Add Commerce for SaaS}",
26
+ "href": "https://ailaunchkit.ai/pricing",
27
+ "variant": "outline",
28
+ },
29
+ },
30
+ },
31
+ {
32
+ "id": "plans",
33
+ "type": "pricing",
34
+ "data":
35
+ {
36
+ "variant": "three-tiers-with-toggle",
37
+ "billingToggle": true,
38
+ "toggleStyle": "switch",
39
+ "gapAbove": "tight",
40
+ "cardLayout": "centered",
41
+ "plans":
42
+ [
43
+ {
44
+ "name": "Basic plan",
45
+ "price": { "monthly": "{price}/mo", "annual": "{price}/yr" },
46
+ "features":
47
+ [
48
+ "{A feature this plan includes}",
49
+ "{A feature this plan includes}",
50
+ "{A feature this plan includes}",
51
+ ],
52
+ "cta": { "label": "{Primary CTA}", "href": "/contact" },
53
+ },
54
+ {
55
+ "name": "Business plan",
56
+ "price": { "monthly": "{price}/mo", "annual": "{price}/yr" },
57
+ "features":
58
+ [
59
+ "{A feature this plan adds}",
60
+ "{A feature this plan includes}",
61
+ "{A feature this plan includes}",
62
+ "{A feature this plan includes}",
63
+ ],
64
+ "cta": { "label": "{Primary CTA}", "href": "/contact" },
65
+ },
66
+ {
67
+ "name": "Enterprise plan",
68
+ "price": { "monthly": "{price}/mo", "annual": "{price}/yr" },
69
+ "features":
70
+ [
71
+ "{A feature this plan adds}",
72
+ "{A feature this plan includes}",
73
+ "{A feature this plan includes}",
74
+ "{A feature this plan includes}",
75
+ "{A feature this plan includes}",
76
+ ],
77
+ "cta": { "label": "{Primary CTA}", "href": "/contact" },
78
+ },
79
+ ],
80
+ },
81
+ },
82
+ {
83
+ "id": "logo-cloud",
84
+ "type": "logoCloud",
85
+ "data":
86
+ {
87
+ "headline": "{Don’t just take our word for it}",
88
+ "headlineStyle": "label",
89
+ "logos":
90
+ [
91
+ {
92
+ "name": "SalesSmyth",
93
+ "src": "/logos/salessmyth.svg",
94
+ "darkSrc": "/logos/salessmyth-light.svg",
95
+ "width": 1118,
96
+ "height": 147,
97
+ },
98
+ {
99
+ "name": "AI Launch Kit",
100
+ "src": "/logos/ai-launch-kit.svg",
101
+ "darkSrc": "/logos/ai-launch-kit-light.svg",
102
+ "width": 1248,
103
+ "height": 144,
104
+ },
105
+ {
106
+ "name": "Atomic Agent",
107
+ "src": "/logos/atomic-agent.svg",
108
+ "darkSrc": "/logos/atomic-agent-light.svg",
109
+ "width": 1320,
110
+ "height": 148,
111
+ },
112
+ ],
113
+ "layout": "inline",
114
+ "treatment": "monochrome",
115
+ },
116
+ },
117
+ {
118
+ "id": "testimonial",
119
+ "type": "testimonials",
120
+ "data":
121
+ {
122
+ "variant": "quote",
123
+ "items":
124
+ [
125
+ {
126
+ "quote": "{A customer quote, in their own words, about the result they got}",
127
+ "author": "{Customer name}",
128
+ "role": "{Their title, their company}",
129
+ },
130
+ ],
131
+ },
132
+ },
133
+ {
134
+ "id": "switch",
135
+ "type": "cta",
136
+ "data":
137
+ {
138
+ "variant": "box",
139
+ "headline": "{Switch to your product in time amount or less}",
140
+ "description": "{You shouldn't have to experience a painful problem. With your product, you can finally achieve a value outcome or get a big improvement.}",
141
+ "checklist":
142
+ ["No credit card required", "Cancel any time", "Live chat support"],
143
+ "primaryCta": { "label": "{Primary CTA}", "href": "/contact" },
144
+ "secondaryCta":
145
+ {
146
+ "label": "{Secondary CTA}",
147
+ "href": "/pricing",
148
+ "variant": "outline",
149
+ },
150
+ "closingLine": "{Social Proof goes here}",
151
+ },
152
+ },
153
+ {
154
+ "id": "faq",
155
+ "type": "faq",
156
+ "data":
157
+ {
158
+ "headline": "{FAQs}",
159
+ "description": "{One sentence that invites visitors to ask what this list does not answer}",
160
+ "actions":
161
+ [
162
+ {
163
+ "kind": "button",
164
+ "label": "Contact",
165
+ "href": "/contact",
166
+ "variant": "outline",
167
+ },
168
+ ],
169
+ "presentation": "accordion",
170
+ "initialOpen": "none",
171
+ "items":
172
+ [
173
+ {
174
+ "question": "{A question your customers actually ask}",
175
+ "answer": "{Answer the question in two or three plain sentences}",
176
+ },
177
+ {
178
+ "question": "{A question your customers actually ask}",
179
+ "answer": "{Answer the question in two or three plain sentences}",
180
+ },
181
+ {
182
+ "question": "{A question your customers actually ask}",
183
+ "answer": "{Answer the question in two or three plain sentences}",
184
+ },
185
+ {
186
+ "question": "{A question your customers actually ask}",
187
+ "answer": "{Answer the question in two or three plain sentences}",
188
+ },
189
+ {
190
+ "question": "{A question your customers actually ask}",
191
+ "answer": "{Answer the question in two or three plain sentences}",
192
+ },
193
+ ],
194
+ },
195
+ },
196
+ ]
197
+ ---
198
+
199
+ {/* Rendered from frontmatter `sections[]`. Seed content — replace the plan names, prices and features above with your own before you launch. */}
@@ -348,38 +348,26 @@ _Detail route over `content/en/Project/` — 2 seed pages: `fit-check-funnel.mdx
348
348
  _Detail route over `content/en/ThankYouPage/` — 3 seed pages: `apply.mdx`, `contact.mdx`, `newsletter.mdx`._
349
349
  <!-- generated:end -->
350
350
 
351
- ### 3a. Deviations from the standard roster (recorded, #6638)
352
-
353
- This template is the `organization-service` shape (`shape: organization-service`) rendered in the `minimalism` design (`design: minimalism`). The standard page set for that shape (`derive-roster.py` —
354
- `entityType=organization · offeringType=services · primaryGoal=generate-leads · scale=global`,
355
- `mainEntity: Organization`, 33 rows) is the baseline; the design adds no rows of its own —
356
- the deck home, the mark-only nav and the centered footer are layout, not pages. What this
357
- roster keeps from the standard set: `HomePage`, `AboutPage`, `ContactPage`, `FAQPage`,
358
- `PrivacyPage`, `TermsPage`, `ServicesList`, `Service`, and — since #6658, which gives every
359
- starter these three whatever its shape (`docs/decisions/starter-roster-page-set.md` D4, D7) —
360
- `GlossaryList`, `NewsletterSignup` and `BookCall` (its `/book-a-call` seed is this template's
361
- own, pointing at the `/meet` booker).
362
-
363
- | Row added | Why |
364
- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
365
- | `/reports` | the site is reports-first: the deck's landing CTA and slides 5–6 lead here, and it indexes the `signal-collectors` reader at `/reports/<slug>` (§ 2) |
366
- | `/referral` | the referral magnet — the pitch and what a referrer gets, opening the `referral` flow (§ 6); slide 3's action leads here. Both rows are `LandingPage` slugs, not new types |
367
-
368
- | Standard row omitted | Why |
369
- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
370
- | `TeamList` · `TeamMember` (entity spine) | the partners are one `team` slide on the deck and the `/about` page (§ 2, § 5), not a directory |
371
- | `CareersList` · `JobPosting` (entity spine) | not a hiring site; nothing to seed |
372
- | `PartnersList` · `Partner` (entity spine) | the partner/community strip is a `logoCloud` slide on the deck, not a page |
373
- | `ProjectsList` · `Project` (offering branch) | the proof is the reports, not a project portfolio |
374
- | `Pricing` (offering branch) | engagements are booked, not priced on the page; `/pricing` is unrostered, so its seed does not install (§ 4) |
375
-
376
- The lead-generation tier (CaseStudies, Testimonials, Clients, UseCases, Events, Downloads) and
377
- the Resources content system (ResourcesHub, ResourceDetail, HowTo, Whitepaper) are the
378
- goal-driven default a site prunes; the reports stand in for them here.
351
+ ### 3a. Differences from the organization-service shape roster
352
+
353
+ This template is the `organization-service` shape (`shape: organization-service`) rendered in the `minimalism` design (`design: minimalism`). Since #6757 that shape carries its own standard roster (fifteen rows: `HomePage`, `AboutPage`, `ServicesList`, `Service`, `ContactPage`, `FAQPage`, `GlossaryList`, `NewsletterSignup`, `BookCall`, `PrivacyPage`, `TermsPage`, `PurchasePolicyPage`, `BlogList`, `PortfolioList`, `PortfolioItem`) — its own deviations from the raw `derive-roster.py` derivation are recorded in `site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md` § 3a, not repeated here. This template's differences are additions and drops from THAT roster only:
354
+
355
+ | Row dropped | Why |
356
+ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
357
+ | `PortfolioList` · `PortfolioItem` | the reports are the proof, not a portfolio (§ 2) |
358
+ | `BlogList` | the `/blog` teaser upsells Pro and Fumadocs; a Pro alias does not carry an upsell to its own level (`marketing-site` and `saas-product` already drop the same row, #6753 D4, for the same reason of degree) |
359
+
360
+ | Row added | Why |
361
+ | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
362
+ | `/reports` | the site is reports-first: the deck's landing CTA and slides 5–6 lead here, and it indexes the `signal-collectors` reader at `/reports/<slug>` (§ 2) |
363
+ | `/referral` | the referral magnet — the pitch and what a referrer gets, opening the `referral` flow (§ 6); slide 3's action leads here. Both rows are `LandingPage` slugs, not new types |
364
+ | the three signal-collectors sample rows (`/projects`, `/projects/[slug]`, `/thanks/[slug]`) | the module's own sample content this template declares as its own rows (#6646) |
365
+
366
+ Every kept row of the shape roster (`HomePage`, `AboutPage`, `ServicesList`, `Service`, `ContactPage`, `FAQPage`, `GlossaryList`, `NewsletterSignup`, `BookCall`, `PrivacyPage`, `TermsPage`, `PurchasePolicyPage`) is unchanged: this template's own `/about`, `/contact` and `/book-a-call` seeds override the shared ones (its `/book-a-call` seed points at the `/meet` booker), and the rest ride the shared layers exactly as the shape roster declares them.
379
367
 
380
368
  ## 4. Roster, as the registry declares it
381
369
 
382
- `minimalism-site` is the one declared template that does not reuse `TEMPLATE_BASE_ROSTER`: the deck replaces the document-scroll home, and `/how-it-works`, the product page (`/software/product`), `/pricing` and `/sign-in` are not pages this site has. The roster is what the template IS, so an unrostered page has neither a route directory nor its seed: `scaffold()` installs a `_base` or overlay seed only for a row that names it (#6646), so `content/en/Pricing/pricing.mdx` does not land. The merged roster, as the registry composes it:
370
+ `minimalism-site` composes the `organization-service` shape roster plus the § 3a differences: the deck replaces the document-scroll home, and `/how-it-works`, the product page (`/software/product`), `/pricing` and `/sign-in` are not pages this site has. The roster is what the template IS, so an unrostered page has neither a route directory nor its seed: `scaffold()` installs a `_base` or overlay seed only for a row that names it (#6646), so `content/en/Pricing/pricing.mdx` does not land. The merged roster, as the registry composes it:
383
371
 
384
372
  <!-- generated:begin roster -->
385
373
 
@@ -3,7 +3,6 @@ type: "BookCall"
3
3
  slug: "book-call"
4
4
  title: "{Book a call: what a visitor gets from it}"
5
5
  description: "{One sentence on who the call is for and what they leave with}"
6
- placeholder: true
7
6
  schema:
8
7
  mainEntity:
9
8
  "@type": "Offer"
@@ -3,7 +3,6 @@ type: "PurchasePolicyPage"
3
3
  slug: "purchase-policy"
4
4
  title: "Purchase Policy"
5
5
  description: "How cancellations, reschedules and refunds work for bookings made on this site. Placeholder policy — replace every section before you launch."
6
- placeholder: true
7
6
  sections:
8
7
  [
9
8
  {
@@ -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.
@@ -22,13 +22,21 @@
22
22
 
23
23
  ## 2. Roster — the base rows, as the registry declares them
24
24
 
25
- `saas-product` reuses `TEMPLATE_BASE_ROSTER` (`template-manifest.ts`) and declares no rows of its own. The ten base routes:
25
+ `saas-product` reuses `TEMPLATE_BASE_ROSTER` (`template-manifest.ts`) plus the two portfolio rows every paid roster appends (`PORTFOLIO_ROWS`, #6687 — operator disposition 2026-09-24, Pro and up). The ten base routes:
26
26
 
27
27
  ```
28
28
  / · /how-it-works · /features · /pricing · /about
29
29
  /faq · /contact · /sign-in · /privacy · /terms
30
30
  ```
31
31
 
32
+ The portfolio rows — before/after project comparisons; the detail row's `contentDir` installs the seeds (#6646 D1):
33
+
34
+ ```
35
+ /portfolio PortfolioList · schema CollectionPage — the hub on the /alternatives stack
36
+ /portfolio/<slug> PortfolioItem · schema WebPage + CreativeWork — one `before-after` section per comparison
37
+ (seed pages sample-one · sample-two · sample-three · sample-four, `_base` layer)
38
+ ```
39
+
32
40
  Module-contributed rows arrive from `MODULE_SLICES[*].pageContributions` and are listed here so the page set reads as one:
33
41
 
34
42
  ```
@@ -1,10 +1,17 @@
1
1
  {
2
- "template": "simple-service",
3
- "requires": ["marketing", "scheduling", "commerce"],
4
- "categories": ["landscaping"],
2
+ "template": "local-business-service",
3
+ "requires": ["marketing"],
4
+ "categories": [
5
+ "hvac",
6
+ "roofing",
7
+ "plumbing",
8
+ "electrical",
9
+ "landscaping",
10
+ "auto-repair"
11
+ ],
5
12
  "shape": "local-business-service",
6
13
  "design": "standard",
7
- "generatedHash": "4aa55fe994472262e9e8f47566729699f3d9eff95267ecf9d8a7da5dcea5602a",
14
+ "generatedHash": "5a75067bc0b4f11911289cef648460e7fdb302b746900f7e1d37e004d0bd1188",
8
15
  "layout": {
9
16
  "nav": "full",
10
17
  "footer": "columns",
@@ -97,9 +104,9 @@
97
104
  "kind": "page",
98
105
  "contentDir": "content/en/Service",
99
106
  "seeds": [
100
- "content/en/Service/landscape-design.mdx",
101
- "content/en/Service/lawn-maintenance.mdx",
102
- "content/en/Service/seasonal-cleanup.mdx"
107
+ "content/en/Service/first-job.mdx",
108
+ "content/en/Service/second-job.mdx",
109
+ "content/en/Service/third-job.mdx"
103
110
  ],
104
111
  "pageType": "Service",
105
112
  "schema": "Service",
@@ -136,10 +143,6 @@
136
143
  {
137
144
  "type": "hero",
138
145
  "component": "Hero"
139
- },
140
- {
141
- "type": "cta",
142
- "component": "CTA"
143
146
  }
144
147
  ]
145
148
  },
@@ -151,13 +154,20 @@
151
154
  "shell": "MarketingShell",
152
155
  "chrome": "on",
153
156
  "sections": [
157
+ {
158
+ "type": "hero",
159
+ "component": "Hero",
160
+ "options": {
161
+ "gapBelow": "tight"
162
+ }
163
+ },
154
164
  {
155
165
  "type": "faq",
156
166
  "component": "FAQ"
157
167
  },
158
168
  {
159
- "type": "cta",
160
- "component": "CTA"
169
+ "type": "faq",
170
+ "component": "FAQ"
161
171
  }
162
172
  ]
163
173
  },
@@ -191,10 +201,6 @@
191
201
  "type": "hero",
192
202
  "component": "Hero"
193
203
  },
194
- {
195
- "type": "newsletter",
196
- "component": "Newsletter"
197
- },
198
204
  {
199
205
  "type": "faq",
200
206
  "component": "FAQ"
@@ -274,73 +280,87 @@
274
280
  ]
275
281
  },
276
282
  {
277
- "route": "/account",
278
- "kind": "route",
279
- "pageType": null,
280
- "schema": null,
281
- "shell": "MarketingShell",
282
- "chrome": "on",
283
- "sections": []
284
- },
285
- {
286
- "route": "/purchase/success",
287
- "kind": "route",
288
- "pageType": null,
289
- "schema": null,
290
- "shell": "MarketingShell",
291
- "chrome": "on",
292
- "sections": []
293
- },
294
- {
295
- "route": "/purchase/cancel",
296
- "kind": "route",
297
- "pageType": null,
298
- "schema": null,
299
- "shell": "MarketingShell",
300
- "chrome": "on",
301
- "sections": []
302
- },
303
- {
304
- "route": "/thanks/[slug]",
305
- "kind": "route",
306
- "pageType": null,
307
- "schema": null,
308
- "shell": "MarketingShell",
309
- "chrome": "on",
310
- "sections": []
311
- },
312
- {
313
- "route": "/meet",
314
- "kind": "route",
315
- "pageType": null,
316
- "schema": null,
317
- "shell": "MarketingShell",
318
- "chrome": "on",
319
- "sections": []
320
- },
321
- {
322
- "route": "/meet/[slug]",
323
- "kind": "route",
324
- "pageType": null,
325
- "schema": null,
283
+ "route": "/blog",
284
+ "kind": "page",
285
+ "pageType": "BlogList",
286
+ "schema": "BlogList",
326
287
  "shell": "MarketingShell",
327
288
  "chrome": "on",
328
- "sections": []
289
+ "sections": [
290
+ {
291
+ "type": "hero",
292
+ "component": "Hero",
293
+ "options": {
294
+ "gapBelow": "tight"
295
+ }
296
+ },
297
+ {
298
+ "type": "blog-list",
299
+ "component": "BlogList"
300
+ },
301
+ {
302
+ "type": "logoCloud",
303
+ "component": "LogoCloud",
304
+ "options": {
305
+ "layout": "inline"
306
+ }
307
+ },
308
+ {
309
+ "type": "testimonials",
310
+ "component": "Testimonials"
311
+ }
312
+ ]
329
313
  },
330
314
  {
331
- "route": "/meet/confirmed",
332
- "kind": "route",
333
- "pageType": null,
334
- "schema": null,
315
+ "route": "/portfolio",
316
+ "kind": "page",
317
+ "pageType": "PortfolioList",
318
+ "schema": "PortfolioList",
335
319
  "shell": "MarketingShell",
336
320
  "chrome": "on",
337
- "sections": []
321
+ "sections": [
322
+ {
323
+ "type": "hero",
324
+ "component": "Hero",
325
+ "options": {
326
+ "gapBelow": "tight",
327
+ "size": "display",
328
+ "surface": "wash-secondary"
329
+ }
330
+ },
331
+ {
332
+ "type": "items",
333
+ "component": "Items",
334
+ "options": {
335
+ "surface": "none",
336
+ "columns": 2
337
+ }
338
+ },
339
+ {
340
+ "type": "cta",
341
+ "component": "CTA"
342
+ },
343
+ {
344
+ "type": "faq",
345
+ "component": "FAQ",
346
+ "options": {
347
+ "surface": "gray-100"
348
+ }
349
+ }
350
+ ]
338
351
  },
339
352
  {
340
- "route": "/appointments",
341
- "kind": "route",
342
- "pageType": null,
343
- "schema": null,
353
+ "route": "/portfolio/[slug]",
354
+ "kind": "page",
355
+ "contentDir": "content/en/PortfolioItem",
356
+ "seeds": [
357
+ "content/en/PortfolioItem/sample-four.mdx",
358
+ "content/en/PortfolioItem/sample-one.mdx",
359
+ "content/en/PortfolioItem/sample-three.mdx",
360
+ "content/en/PortfolioItem/sample-two.mdx"
361
+ ],
362
+ "pageType": "PortfolioItem",
363
+ "schema": "PortfolioItem",
344
364
  "shell": "MarketingShell",
345
365
  "chrome": "on",
346
366
  "sections": []