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.
- package/README.md +44 -10
- package/component-catalog.json +520 -5
- package/component-catalog.md +9 -6
- package/dist/cli.js +22 -24
- package/dist/lib/extract-module-bundle.js +5 -1
- package/dist/lib/module-license-gate.d.ts +79 -0
- package/dist/lib/module-license-gate.js +160 -12
- package/dist/lib/module-tier.d.ts +45 -16
- package/dist/lib/module-tier.js +76 -0
- package/dist/lib/pro-callout.js +10 -2
- package/dist/parse-args.d.ts +78 -10
- package/dist/parse-args.js +204 -14
- package/dist/programmatic.d.ts +39 -9
- package/dist/programmatic.js +163 -25
- package/dist/site-roster.js +11 -6
- package/dist/starter-grid.d.ts +216 -0
- package/dist/starter-grid.js +449 -0
- package/dist/surfaces.d.ts +4 -4
- package/dist/surfaces.js +102 -43
- package/dist/template-manifest.d.ts +36 -17
- package/dist/template-manifest.js +121 -367
- package/dist/template-names.d.ts +14 -12
- package/dist/template-names.js +13 -17
- package/package.json +3 -3
- package/site-templates/_base/content/en/BookCall/book-call.mdx +0 -1
- package/site-templates/_base/content/en/Feature/feature-1.mdx +69 -0
- package/site-templates/_base/content/en/Feature/feature-2.mdx +69 -0
- package/site-templates/_base/content/en/Feature/feature-3.mdx +69 -0
- package/site-templates/_base/content/en/FeaturesList/features.mdx +91 -0
- package/site-templates/_base/content/en/GlossaryList/glossary.mdx +0 -1
- package/site-templates/_base/content/en/NewsletterSignup/newsletter.mdx +0 -1
- package/site-templates/_base/content/en/PortfolioItem/sample-four.mdx +105 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-one.mdx +34 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-three.mdx +94 -0
- package/site-templates/_base/content/en/PortfolioItem/sample-two.mdx +45 -0
- package/site-templates/_base/content/en/PortfolioList/portfolio.mdx +169 -0
- package/site-templates/_base/content/en/PrivacyPage/privacy.mdx +15 -0
- package/site-templates/_base/content/en/UseCase/persona-1.mdx +69 -0
- package/site-templates/_base/content/en/UseCase/persona-2.mdx +69 -0
- package/site-templates/_base/content/en/UseCase/persona-3.mdx +69 -0
- package/site-templates/designs/standard/DESIGN.md +5 -0
- package/site-templates/marketing-site/DESIGN.md +5 -0
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +89 -25
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +35 -14
- package/site-templates/marketing-site-free/DESIGN.md +5 -0
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +95 -29
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +74 -44
- package/site-templates/marketing-site-free/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +199 -0
- package/site-templates/minimalism-site/TEMPLATE-MANIFEST.md +17 -29
- package/site-templates/minimalism-site/content/en/BookCall/book-call.mdx +0 -1
- package/site-templates/minimalism-site/content/en/PurchasePolicyPage/purchase-policy.mdx +0 -1
- package/site-templates/saas-product/DESIGN.md +5 -0
- package/site-templates/saas-product/TEMPLATE-MANIFEST.md +9 -1
- package/site-templates/{simple-service → shapes/local-business-service}/TEMPLATE-MANIFEST.json +96 -76
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +302 -0
- package/site-templates/shapes/local-business-service/ailk-template.json +10 -0
- package/site-templates/{simple-service → shapes/local-business-service}/content/en/AboutPage/about.mdx +4 -4
- package/site-templates/shapes/local-business-service/content/en/HomePage/home.mdx +70 -0
- package/site-templates/shapes/local-business-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/shapes/local-business-service/content/en/PortfolioList/portfolio.mdx +171 -0
- package/site-templates/{simple-service → shapes/local-business-service}/content/en/PurchasePolicyPage/purchase-policy.mdx +7 -8
- package/site-templates/shapes/local-business-service/content/en/Service/first-job.mdx +39 -0
- package/site-templates/shapes/local-business-service/content/en/Service/second-job.mdx +39 -0
- package/site-templates/shapes/local-business-service/content/en/Service/third-job.mdx +39 -0
- package/site-templates/shapes/local-business-service/content/en/ServicesList/services.mdx +61 -0
- package/site-templates/shapes/local-business-service/provenance.json +4 -0
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +362 -0
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +300 -0
- package/site-templates/shapes/organization-service/ailk-template.json +10 -0
- package/site-templates/shapes/organization-service/content/en/AboutPage/about.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/HomePage/home.mdx +85 -0
- package/site-templates/shapes/organization-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/shapes/organization-service/content/en/PortfolioList/portfolio.mdx +171 -0
- package/site-templates/shapes/organization-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
- package/site-templates/shapes/organization-service/content/en/Service/first-engagement.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/Service/second-engagement.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/Service/third-engagement.mdx +38 -0
- package/site-templates/shapes/organization-service/content/en/ServicesList/services.mdx +72 -0
- package/site-templates/shapes/organization-service/provenance.json +4 -0
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +369 -0
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +299 -0
- package/site-templates/shapes/person-service/ailk-template.json +10 -0
- package/site-templates/shapes/person-service/content/_site.mdx +85 -0
- package/site-templates/shapes/person-service/content/en/AboutPage/about.mdx +39 -0
- package/site-templates/shapes/person-service/content/en/HomePage/home.mdx +97 -0
- package/site-templates/shapes/person-service/content/en/NewsletterSignup/newsletter.mdx +59 -0
- package/site-templates/shapes/person-service/content/en/PortfolioList/portfolio.mdx +169 -0
- package/site-templates/shapes/person-service/content/en/PurchasePolicyPage/purchase-policy.mdx +123 -0
- package/site-templates/shapes/person-service/content/en/Service/first-engagement.mdx +38 -0
- package/site-templates/shapes/person-service/content/en/Service/second-engagement.mdx +38 -0
- package/site-templates/shapes/person-service/content/en/Service/third-engagement.mdx +38 -0
- package/site-templates/{simple-service → shapes/person-service}/content/en/ServicesList/services.mdx +16 -16
- package/site-templates/shapes/person-service/provenance.json +4 -0
- package/templates/.claude/skills/README.md +3 -2
- package/templates/.claude/skills/add-page/references/page-types.md +4 -0
- package/templates/.claude/skills/setup-database/SKILL.md +156 -0
- package/templates/.claude/skills/setup-database/scripts/verify-inbox.ts +154 -0
- package/templates/.claude/skills/setup-deploy/SKILL.md +64 -32
- package/templates/.claude/skills/setup-deploy/references/env-vars-template.md +19 -28
- package/templates/.claude/skills/setup-deploy/references/runbook-template.md +58 -102
- package/templates/DESIGN.md +5 -0
- package/templates/README.md +46 -38
- package/templates/apps/api/CLAUDE.md +3 -2
- package/templates/apps/api/src/config/__tests__/index.test.ts +115 -14
- package/templates/apps/api/src/config/index.ts +35 -16
- package/templates/apps/api/src/lib/__tests__/lead-capture-store.test.ts +30 -0
- package/templates/apps/api/src/lib/__tests__/lead-delivery.test.ts +96 -0
- package/templates/apps/api/src/lib/lead-capture-store.ts +12 -0
- package/templates/apps/api/src/lib/lead-delivery.ts +52 -0
- package/templates/apps/api/src/openapi/spec.ts +63 -12
- package/templates/apps/api/src/routes/leads/__tests__/capture.test.ts +88 -0
- package/templates/apps/api/src/routes/leads/__tests__/index.test.ts +100 -0
- package/templates/apps/api/src/routes/leads/index.ts +46 -1
- package/templates/apps/api/src/server.ts +7 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +194 -0
- package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +124 -0
- package/templates/apps/api/src/services/lead-routing.ts +140 -30
- package/templates/apps/api/src/services/leads-inbox.ts +48 -11
- package/templates/apps/mcp/__tests__/parity.test.ts +5 -4
- package/templates/apps/mcp/src/tools/create_project.ts +21 -6
- package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +14 -6
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +10 -9
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-form-text.test.ts +32 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +129 -0
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +227 -84
- package/templates/apps/web/app/[locale]/contact/contact-form-text.ts +50 -0
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +73 -20
- package/templates/apps/web/app/[locale]/contact/page.tsx +105 -15
- package/templates/apps/web/app/[locale]/contact/site-contact-email.ts +54 -0
- package/templates/apps/web/app/[locale]/features/[slug]/page.tsx +64 -0
- package/templates/apps/web/app/[locale]/features/page.tsx +52 -0
- package/templates/apps/web/app/[locale]/layout.tsx +37 -5
- package/templates/apps/web/app/[locale]/newsletter/__tests__/newsletter.actions.test.ts +75 -0
- package/templates/apps/web/app/[locale]/newsletter/__tests__/page.test.tsx +163 -0
- package/templates/apps/web/app/[locale]/newsletter/newsletter.actions.ts +66 -0
- package/templates/apps/web/app/[locale]/newsletter/page.tsx +106 -14
- package/templates/apps/web/app/[locale]/portfolio/[slug]/page.tsx +59 -0
- package/templates/apps/web/app/[locale]/portfolio/page.tsx +49 -0
- package/templates/apps/web/app/[locale]/use-cases/[slug]/page.tsx +18 -3
- package/templates/apps/web/lib/nav-config.ts +48 -36
- package/templates/apps/web/lib/site-identity.ts +14 -0
- package/templates/apps/web/messages/en.json +28 -2
- package/templates/content/_site.mdx +4 -2
- package/templates/content/en/BlogList/blog.mdx +37 -16
- package/templates/content/en/ContactPage/contact.mdx +14 -44
- package/templates/content/en/HomePage/home.mdx +8 -16
- package/templates/content/en/PurchasePolicyPage/purchase-policy.mdx +0 -1
- package/templates/content/en/UseCasesList/use-cases.mdx +6 -6
- package/templates/database/CHANGELOG.md +7 -0
- package/templates/database/package.json +1 -1
- package/versions.json +33 -33
- package/site-templates/_base/content/en/UseCase/first-use-case.mdx +0 -23
- package/site-templates/_base/content/en/UseCase/second-use-case.mdx +0 -23
- package/site-templates/_base/content/en/UseCase/third-use-case.mdx +0 -23
- package/site-templates/simple-service/DESIGN.md +0 -162
- package/site-templates/simple-service/TEMPLATE-MANIFEST.md +0 -333
- package/site-templates/simple-service/ailk-template.json +0 -11
- package/site-templates/simple-service/content/en/BookCall/book-call.mdx +0 -53
- package/site-templates/simple-service/content/en/ContactPage/contact.mdx +0 -32
- package/site-templates/simple-service/content/en/FAQPage/faq.mdx +0 -56
- package/site-templates/simple-service/content/en/HomePage/home.mdx +0 -85
- package/site-templates/simple-service/content/en/Service/landscape-design.mdx +0 -40
- package/site-templates/simple-service/content/en/Service/lawn-maintenance.mdx +0 -40
- package/site-templates/simple-service/content/en/Service/seasonal-cleanup.mdx +0 -40
- package/site-templates/simple-service/provenance.json +0 -4
- package/templates/apps/web/app/[locale]/contact/ContactForm.tsx +0 -211
- package/templates/apps/web/app/[locale]/contact/__tests__/ContactForm.test.tsx +0 -96
- package/templates/content/en/SoftwareProduct/product.mdx +0 -175
|
@@ -1,333 +0,0 @@
|
|
|
1
|
-
# Template manifest — `simple-service`
|
|
2
|
-
|
|
3
|
-
> The T1 lawn-care template (#6087, Epic #5778) — the first site shape that composes `scheduling` and `commerce`: three priced services, a booker, a checkout return pair and a purchase policy (cancellation and refunds, #6646). Generated file: the regions between `<!-- generated:begin <id> -->` and `<!-- generated:end -->` are produced by `scripts/build-template-manifest.mjs --template simple-service` from the composed layer stack (this tree → its required modules → `_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
|
-
| Template | `simple-service` |
|
|
8
|
-
| Level | Pro (derived from `requires` — `scheduling` and `commerce` are paid; never declared) |
|
|
9
|
-
| `requires` | `[marketing, scheduling, commerce]` — the first template to take `commerce` |
|
|
10
|
-
| `extends` | `_base` — lineage only, never level |
|
|
11
|
-
| Delivery | licence-checked module bundle (#5441); never in the Free tarball |
|
|
12
|
-
| Sample content posture | every line of copy, and all three service prices, are **placeholders** — and the prices are PUBLISHED as JSON-LD `Offer`s |
|
|
13
|
-
|
|
14
|
-
## 1. Chrome
|
|
15
|
-
|
|
16
|
-
This template declares **no `layout` block**. The default marketing-site chrome is what a lawn-care site wants — a nav row a reader can reach `/services` from, the four-column footer, and the document-scroll home — and the issue's STOP boundary excludes layout knobs the spec does not name.
|
|
17
|
-
|
|
18
|
-
### Layout knobs (#5612)
|
|
19
|
-
|
|
20
|
-
The template's `layout` block — resolved with `resolveSiteChrome`, defaults filled.
|
|
21
|
-
|
|
22
|
-
<!-- generated:begin layout -->
|
|
23
|
-
|
|
24
|
-
| Knob | Value |
|
|
25
|
-
| -------------------- | --------- |
|
|
26
|
-
| `nav` | `full` |
|
|
27
|
-
| `footer` | `columns` |
|
|
28
|
-
| `announcementBanner` | `false` |
|
|
29
|
-
| `home` | `default` |
|
|
30
|
-
|
|
31
|
-
<!-- generated:end -->
|
|
32
|
-
|
|
33
|
-
### Theme (locked)
|
|
34
|
-
|
|
35
|
-
The template's `theme:` block as `_site.mdx` declares it — the shape knobs and the colour overlay. Generated, so a change to a locked template's look is a red `manifest:check`, not a silent drift (starter-template contract R3.5).
|
|
36
|
-
|
|
37
|
-
<!-- generated:begin theme -->
|
|
38
|
-
|
|
39
|
-
| Setting | Value |
|
|
40
|
-
| ------------------------ | ---------- |
|
|
41
|
-
| `corners` | `square` |
|
|
42
|
-
| `eyebrowCase` | `sentence` |
|
|
43
|
-
| `placeholders` | `fill` |
|
|
44
|
-
| `checkmarks` | `plain` |
|
|
45
|
-
| `colors.light.bg` | `#ffffff` |
|
|
46
|
-
| `colors.light.bgMuted` | `#ffffff` |
|
|
47
|
-
| `colors.light.surface` | `#ffffff` |
|
|
48
|
-
| `colors.light.border` | `#000000` |
|
|
49
|
-
| `colors.light.text` | `#000000` |
|
|
50
|
-
| `colors.light.textMuted` | `#333333` |
|
|
51
|
-
| `colors.light.primary` | `#000000` |
|
|
52
|
-
| `colors.light.primaryFg` | `#ffffff` |
|
|
53
|
-
| `colors.light.accent` | `#000000` |
|
|
54
|
-
| `colors.dark.bg` | `#000000` |
|
|
55
|
-
| `colors.dark.bgMuted` | `#000000` |
|
|
56
|
-
| `colors.dark.surface` | `#000000` |
|
|
57
|
-
| `colors.dark.border` | `#ffffff` |
|
|
58
|
-
| `colors.dark.text` | `#ffffff` |
|
|
59
|
-
| `colors.dark.textMuted` | `#cccccc` |
|
|
60
|
-
| `colors.dark.primary` | `#ffffff` |
|
|
61
|
-
| `colors.dark.primaryFg` | `#000000` |
|
|
62
|
-
| `colors.dark.accent` | `#ffffff` |
|
|
63
|
-
|
|
64
|
-
<!-- generated:end -->
|
|
65
|
-
|
|
66
|
-
## 2. The money path
|
|
67
|
-
|
|
68
|
-
The whole point of this template is the first roster that takes a booking **and** the payment for it:
|
|
69
|
-
|
|
70
|
-
| Step | Where it lives |
|
|
71
|
-
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
72
|
-
| Discovery | `/services` and the three `/services/<slug>` pages. Each detail page's top-level `price` + `priceCurrency` + `provider` become one schema.org `Offer` in its JSON-LD (#5838) — the free discovery floor. |
|
|
73
|
-
| Booking | `/meet`, `/meet/<slug>`, `/meet/confirmed` — the `scheduling` module's own contributed rows; `/appointments` is the site owner's own list (#6086). |
|
|
74
|
-
| Payment | a provider-hosted page on the seller's own Stripe account. Nothing on this site renders a card form. |
|
|
75
|
-
| Return | `/purchase/success` and `/purchase/cancel` — base tree under #6084 D12's shape-2 disposition, gated at request time on the `commerce` licence claim. |
|
|
76
|
-
| Policies | `/purchase-policy` (#6646) — cancellation and refunds sections, this template's service-shape override of the overlay's product-shape seed. |
|
|
77
|
-
|
|
78
|
-
## 3. Pages
|
|
79
|
-
|
|
80
|
-
One `page=<route>` region per roster row, generated from the seed file the composed layer stack lands for that route.
|
|
81
|
-
|
|
82
|
-
`/`:
|
|
83
|
-
|
|
84
|
-
<!-- generated:begin page=/ -->
|
|
85
|
-
|
|
86
|
-
| # | Section | Component | Copy (first line) |
|
|
87
|
-
| --- | ---------------------------------------------------------- | --------- | ---------------------------------------------- |
|
|
88
|
-
| 1 | `hero` (centered · eyebrow "{Your service area}" · 2 CTAs) | `Hero` | {Lawn care that turns up when it says it will} |
|
|
89
|
-
| 2 | `items` (columns=3 · items ×3) | `Items` | What we do |
|
|
90
|
-
| 3 | `cta` (minimal · 2 CTAs) | `CTA` | Ready for a tidier yard? |
|
|
91
|
-
|
|
92
|
-
<!-- generated:end -->
|
|
93
|
-
|
|
94
|
-
`/services`:
|
|
95
|
-
|
|
96
|
-
<!-- generated:begin page=/services -->
|
|
97
|
-
|
|
98
|
-
| # | Section | Component | Copy (first line) |
|
|
99
|
-
| --- | -------------------------------------- | --------- | ------------------------ |
|
|
100
|
-
| 1 | `hero` (centered · eyebrow "Services") | `Hero` | Three jobs, three prices |
|
|
101
|
-
| 2 | `items` (columns=3 · items ×3) | `Items` | What we do |
|
|
102
|
-
| 3 | `cta` (minimal · 1 CTA) | `CTA` | Not sure which one? |
|
|
103
|
-
|
|
104
|
-
<!-- generated:end -->
|
|
105
|
-
|
|
106
|
-
`/services/[slug]`:
|
|
107
|
-
|
|
108
|
-
<!-- generated:begin page=/services/[slug] -->
|
|
109
|
-
|
|
110
|
-
_Detail route over `content/en/Service/` — 3 seed pages: `landscape-design.mdx`, `lawn-maintenance.mdx`, `seasonal-cleanup.mdx`._
|
|
111
|
-
<!-- generated:end -->
|
|
112
|
-
|
|
113
|
-
`/about`:
|
|
114
|
-
|
|
115
|
-
<!-- generated:begin page=/about -->
|
|
116
|
-
|
|
117
|
-
| # | Section | Component | Copy (first line) |
|
|
118
|
-
| --- | ------------------------------------------ | -------------- | ------------------------------------------ |
|
|
119
|
-
| 1 | `content-block` (narrow · eyebrow "About") | `ContentBlock` | {A small crew, the same yards, every week} |
|
|
120
|
-
| 2 | `cta` (minimal · 2 CTAs) | `CTA` | Want us to take a look? |
|
|
121
|
-
|
|
122
|
-
<!-- generated:end -->
|
|
123
|
-
|
|
124
|
-
`/contact`:
|
|
125
|
-
|
|
126
|
-
<!-- generated:begin page=/contact -->
|
|
127
|
-
|
|
128
|
-
| # | Section | Component | Copy (first line) |
|
|
129
|
-
| --- | ------------------------------------- | --------- | ------------------------ |
|
|
130
|
-
| 1 | `hero` (centered · eyebrow "Contact") | `Hero` | Tell us about the yard |
|
|
131
|
-
| 2 | `cta` (minimal · 1 CTA) | `CTA` | Would a visit be faster? |
|
|
132
|
-
|
|
133
|
-
<!-- generated:end -->
|
|
134
|
-
|
|
135
|
-
`/faq`:
|
|
136
|
-
|
|
137
|
-
<!-- generated:begin page=/faq -->
|
|
138
|
-
|
|
139
|
-
| # | Section | Component | Copy (first line) |
|
|
140
|
-
| --- | ------------------------------------------------------------- | --------- | ---------------------- |
|
|
141
|
-
| 1 | `faq` (centered · items ×5 · supportLink · initialOpen first) | `FAQ` | Questions |
|
|
142
|
-
| 2 | `cta` (minimal · 1 CTA) | `CTA` | Still have a question? |
|
|
143
|
-
|
|
144
|
-
<!-- generated:end -->
|
|
145
|
-
|
|
146
|
-
`/glossary`, `/newsletter` (base-layer seeds every starter carries, #6658 D5):
|
|
147
|
-
|
|
148
|
-
<!-- generated:begin page=/glossary -->
|
|
149
|
-
|
|
150
|
-
| # | Section | Component | Copy (first line) |
|
|
151
|
-
| --- | ----------------------------------- | --------------- | -------------------------------------------- |
|
|
152
|
-
| 1 | `hero` (eyebrow "Glossary" · 1 CTA) | `Hero` | {Glossary: the terms your customers look up} |
|
|
153
|
-
| 2 | `glossary-index` (columns) | `GlossaryIndex` | {Terms, A to Z} |
|
|
154
|
-
|
|
155
|
-
<!-- generated:end -->
|
|
156
|
-
|
|
157
|
-
<!-- generated:begin page=/newsletter -->
|
|
158
|
-
|
|
159
|
-
| # | Section | Component | Copy (first line) |
|
|
160
|
-
| --- | ------------------------------------- | ------------ | ------------------------------------------------ |
|
|
161
|
-
| 1 | `hero` (eyebrow "Newsletter" · 1 CTA) | `Hero` | {Newsletter: what subscribers get and how often} |
|
|
162
|
-
| 2 | `newsletter` | `Newsletter` | Subscribe |
|
|
163
|
-
| 3 | `faq` (expanded · items ×3) | `FAQ` | FAQs |
|
|
164
|
-
|
|
165
|
-
<!-- generated:end -->
|
|
166
|
-
|
|
167
|
-
`/book-a-call` (this template's own override of the base seed — the call to action opens the `/meet` booker the scheduling module supplies, not `/contact`):
|
|
168
|
-
|
|
169
|
-
<!-- generated:begin page=/book-a-call -->
|
|
170
|
-
|
|
171
|
-
| # | Section | Component | Copy (first line) |
|
|
172
|
-
| --- | -------------------------------------- | --------- | ------------------------------------------ |
|
|
173
|
-
| 1 | `hero` (eyebrow "Book a call" · 1 CTA) | `Hero` | {Book a call: what a visitor gets from it} |
|
|
174
|
-
| 2 | `items` (columns=3 · items ×3) | `Items` | What happens on the call? |
|
|
175
|
-
|
|
176
|
-
<!-- generated:end -->
|
|
177
|
-
|
|
178
|
-
`/purchase-policy`:
|
|
179
|
-
|
|
180
|
-
<!-- generated:begin page=/purchase-policy -->
|
|
181
|
-
|
|
182
|
-
| # | Section | Component | Copy (first line) |
|
|
183
|
-
| --- | ----------------------------------- | ----------------- | ----------------- |
|
|
184
|
-
| 1 | `document-chassis` (layout=article) | `DocumentChassis` | Purchase Policy |
|
|
185
|
-
|
|
186
|
-
<!-- generated:end -->
|
|
187
|
-
|
|
188
|
-
`/privacy`:
|
|
189
|
-
|
|
190
|
-
<!-- generated:begin page=/privacy -->
|
|
191
|
-
|
|
192
|
-
| # | Section | Component | Copy (first line) |
|
|
193
|
-
| --- | ----------------------------------- | ----------------- | ----------------- |
|
|
194
|
-
| 1 | `document-chassis` (layout=article) | `DocumentChassis` | Privacy Policy |
|
|
195
|
-
|
|
196
|
-
<!-- generated:end -->
|
|
197
|
-
|
|
198
|
-
`/terms`:
|
|
199
|
-
|
|
200
|
-
<!-- generated:begin page=/terms -->
|
|
201
|
-
|
|
202
|
-
| # | Section | Component | Copy (first line) |
|
|
203
|
-
| --- | ----------------------------------- | ----------------- | ----------------- |
|
|
204
|
-
| 1 | `document-chassis` (layout=article) | `DocumentChassis` | Terms of Service |
|
|
205
|
-
|
|
206
|
-
<!-- generated:end -->
|
|
207
|
-
|
|
208
|
-
`/account`:
|
|
209
|
-
|
|
210
|
-
<!-- generated:begin page=/account -->
|
|
211
|
-
|
|
212
|
-
_Code route — no content, no sections._
|
|
213
|
-
<!-- generated:end -->
|
|
214
|
-
|
|
215
|
-
`/purchase/success`:
|
|
216
|
-
|
|
217
|
-
<!-- generated:begin page=/purchase/success -->
|
|
218
|
-
|
|
219
|
-
_Code route — no content, no sections._
|
|
220
|
-
<!-- generated:end -->
|
|
221
|
-
|
|
222
|
-
`/purchase/cancel`:
|
|
223
|
-
|
|
224
|
-
<!-- generated:begin page=/purchase/cancel -->
|
|
225
|
-
|
|
226
|
-
_Code route — no content, no sections._
|
|
227
|
-
<!-- generated:end -->
|
|
228
|
-
|
|
229
|
-
`/thanks/[slug]`:
|
|
230
|
-
|
|
231
|
-
<!-- generated:begin page=/thanks/[slug] -->
|
|
232
|
-
|
|
233
|
-
_Code route — no content, no sections._
|
|
234
|
-
<!-- generated:end -->
|
|
235
|
-
|
|
236
|
-
`/meet`:
|
|
237
|
-
|
|
238
|
-
<!-- generated:begin page=/meet -->
|
|
239
|
-
|
|
240
|
-
_Code route — no content, no sections._
|
|
241
|
-
<!-- generated:end -->
|
|
242
|
-
|
|
243
|
-
`/meet/[slug]`:
|
|
244
|
-
|
|
245
|
-
<!-- generated:begin page=/meet/[slug] -->
|
|
246
|
-
|
|
247
|
-
_Code route — no content, no sections._
|
|
248
|
-
<!-- generated:end -->
|
|
249
|
-
|
|
250
|
-
`/meet/confirmed`:
|
|
251
|
-
|
|
252
|
-
<!-- generated:begin page=/meet/confirmed -->
|
|
253
|
-
|
|
254
|
-
_Code route — no content, no sections._
|
|
255
|
-
<!-- generated:end -->
|
|
256
|
-
|
|
257
|
-
`/appointments`:
|
|
258
|
-
|
|
259
|
-
<!-- generated:begin page=/appointments -->
|
|
260
|
-
|
|
261
|
-
_Code route — no content, no sections._
|
|
262
|
-
<!-- generated:end -->
|
|
263
|
-
|
|
264
|
-
## 4. Roster, as the registry declares it
|
|
265
|
-
|
|
266
|
-
`simple-service` is the second declared template that does not reuse `TEMPLATE_BASE_ROSTER`: a lawn-care site sells three named services from `/services`, not from a pricing table, so `/how-it-works`, the product page (`/software/product`) and `/pricing` 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:
|
|
267
|
-
|
|
268
|
-
<!-- generated:begin roster -->
|
|
269
|
-
|
|
270
|
-
```
|
|
271
|
-
simple-service:
|
|
272
|
-
requires: [marketing, scheduling, commerce]
|
|
273
|
-
categories: [landscaping]
|
|
274
|
-
shape: local-business-service
|
|
275
|
-
design: standard
|
|
276
|
-
roster:
|
|
277
|
-
- { route: "/", kind: page, content: ["content/en/HomePage/home.mdx"] }
|
|
278
|
-
- { route: "/services", kind: page, content: ["content/en/ServicesList/services.mdx"] }
|
|
279
|
-
- { route: "/services/[slug]", kind: page, contentDir: "content/en/Service" }
|
|
280
|
-
- { route: "/about", kind: page, content: ["content/en/AboutPage/about.mdx"] }
|
|
281
|
-
- { route: "/contact", kind: page, content: ["content/en/ContactPage/contact.mdx"] }
|
|
282
|
-
- { route: "/faq", kind: page, content: ["content/en/FAQPage/faq.mdx"] }
|
|
283
|
-
- { route: "/glossary", kind: page, content: ["content/en/GlossaryList/glossary.mdx"] }
|
|
284
|
-
- { route: "/newsletter", kind: page, content: ["content/en/NewsletterSignup/newsletter.mdx"] }
|
|
285
|
-
- { route: "/book-a-call", kind: page, content: ["content/en/BookCall/book-call.mdx"] }
|
|
286
|
-
- { route: "/purchase-policy", kind: page, content: ["content/en/PurchasePolicyPage/purchase-policy.mdx"] }
|
|
287
|
-
- { route: "/privacy", kind: page, content: ["content/en/PrivacyPage/privacy.mdx"] }
|
|
288
|
-
- { route: "/terms", kind: page, content: ["content/en/TermsPage/terms.mdx"] }
|
|
289
|
-
- { route: "/account", kind: route }
|
|
290
|
-
- { route: "/purchase/success", kind: route }
|
|
291
|
-
- { route: "/purchase/cancel", kind: route }
|
|
292
|
-
- { route: "/thanks/[slug]", kind: route }
|
|
293
|
-
- { route: "/meet", kind: route }
|
|
294
|
-
- { route: "/meet/[slug]", kind: route }
|
|
295
|
-
- { route: "/meet/confirmed", kind: route }
|
|
296
|
-
- { route: "/appointments", kind: route }
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
<!-- generated:end -->
|
|
300
|
-
|
|
301
|
-
By source:
|
|
302
|
-
|
|
303
|
-
```
|
|
304
|
-
template: / · /services · /services/<slug> · /about · /contact · /faq
|
|
305
|
-
/purchase-policy · /privacy · /terms · /account
|
|
306
|
-
/purchase/success · /purchase/cancel · /thanks/<slug>
|
|
307
|
-
scheduling: /meet · /meet/<slug> · /meet/confirmed · /appointments
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
**Why the two `/purchase/*` rows are the TEMPLATE's and not the `commerce` module's.** #6084 landed the checkout return pair under the operator's shape-2 disposition (#6084 D12): `CORE_ROUTE_DIRS` carries `[locale]/purchase`, and neither `GATEABLE_SURFACES` nor `MODULE_SURFACES.commerce` gained an entry, so `MODULE_SLICES.commerce` contributes **no** `pageContributions` at all. Nothing else claims the two routes, so declaring them here trips no both-claimants refusal — and the issue's AC-1 requires the merged roster to carry them. The four scheduling rows, by contrast, **are** the module's, and declaring one here would make `mergeRoster` refuse this template outright.
|
|
311
|
-
|
|
312
|
-
`/account` and `/purchase-policy` carry no `GATEABLE_SURFACES` entry and need none: `(authed)` ships unconditionally, and `/purchase-policy` has no gateable surface at all, so it is always copied. The six module-less surfaces this roster enables are `book-a-call`, `glossary`, `newsletter`, `privacy`, `services` and `terms`.
|
|
313
|
-
|
|
314
|
-
## 5. Component inventory
|
|
315
|
-
|
|
316
|
-
Every component the roster rows' seed content composes today (generated):
|
|
317
|
-
|
|
318
|
-
<!-- generated:begin inventory -->
|
|
319
|
-
|
|
320
|
-
| Tier | Used by this template |
|
|
321
|
-
| -------- | ----------------------------------------------------------------------------------------------- |
|
|
322
|
-
| Shell | `MarketingShell` |
|
|
323
|
-
| Chrome | `Nav`, `Footer`, `Banner` (+ `BannerConsentIsland`, `BannerDismissIsland`) |
|
|
324
|
-
| Sections | `ContentBlock`, `CTA`, `DocumentChassis`, `FAQ`, `GlossaryIndex`, `Hero`, `Items`, `Newsletter` |
|
|
325
|
-
|
|
326
|
-
<!-- generated:end -->
|
|
327
|
-
|
|
328
|
-
## 6. Known gaps this manifest depends on
|
|
329
|
-
|
|
330
|
-
| Gap | Issue |
|
|
331
|
-
| -------------------------------------------------------------------------------------------- | ----- |
|
|
332
|
-
| No routes-map row for `/account`, `/appointments` or `/purchase/*`, so those rows show blank | #5572 |
|
|
333
|
-
| The Pro demo host `simple-service.ailaunchkit.ai` — provisioning is the runbook's act | #5778 |
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "simple-service",
|
|
3
|
-
"requires": ["marketing", "scheduling", "commerce"],
|
|
4
|
-
"extends": "_base",
|
|
5
|
-
"$comment": "The T1 lawn-care template (#6087, Epic #5778) — the first site shape that composes scheduling and commerce. Composed base -> modules -> template: /privacy and /terms arrive with the _base layer this extends (its unrostered /pricing seed does not install, #6646), and /purchase-policy is this tree's own service-shape override of the overlay's product-shape seed (#6646 — cancellation and refunds sections); /meet, /meet/<slug>, /meet/confirmed and /appointments with the scheduling bundle; /purchase/success and /purchase/cancel are BASE TREE (#6084 D12 shape 2 — CORE_ROUTE_DIRS carries [locale]/purchase and the commerce licence claim, not the scaffold, decides whether they serve); the Free about/contact/faq compositions with the overlay, which this template's own /about, /contact and /faq files then override; the overlay's other seeds (/use-cases, the /software/product page, the /blog teaser) are unrostered here and do not install (#6646). This tree holds ONLY its own compositions and its placeholder copy. It declares no layout block — the default marketing-site chrome is what this template renders with, and the code registry (TEMPLATE_MANIFESTS) is authoritative for a template create-ailk ships, so a duplicate block here would be a second authority for one fact. installMap: bundle-relative source -> scaffold-relative destination; the stager reads only installMap/postInstall/patches. Unmapped content/en/** lands at the scaffold root's content/, exactly as marketing-site-free's does.",
|
|
6
|
-
"installMap": {
|
|
7
|
-
"provenance.json": ".ailk-template.json",
|
|
8
|
-
"TEMPLATE-MANIFEST.json": ".ailk-site-manifest.json"
|
|
9
|
-
},
|
|
10
|
-
"postInstall": "Template simple-service installed. This is the lawn-care shape: three priced services at /services (content/en/Service/), a booker at /meet from the scheduling module, the site owner's own list at /appointments, and the checkout return pair at /purchase/success and /purchase/cancel. /privacy, /terms, /glossary and /newsletter came with the base layer, and /book-a-call is this template's own override of the base seed, its call to action opening the /meet booker. This template adds the home page, /services and its three detail pages, /about, /contact, /faq and /purchase-policy (cancellation and refunds). THE THREE PRICES ARE PLACEHOLDERS AND THEY ARE PUBLISHED: each service page's top-level price and priceCurrency become a schema.org Offer in that page's JSON-LD, which is what an agent reading your site quotes back to a buyer — replace all three, and the provider name with them, before you launch. Taking money needs the commerce licence claim and your own Stripe account: without the claim the return pages 404 by design. EVERY line of copy on this site is a placeholder too — replace it before you launch."
|
|
11
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: "BookCall"
|
|
3
|
-
slug: "book-call"
|
|
4
|
-
title: "{Book a call: what a visitor gets from it}"
|
|
5
|
-
description: "{One sentence on who the call is for and what they leave with}"
|
|
6
|
-
placeholder: true
|
|
7
|
-
schema:
|
|
8
|
-
mainEntity:
|
|
9
|
-
"@type": "Offer"
|
|
10
|
-
name: "{Your call name}"
|
|
11
|
-
price: 0
|
|
12
|
-
priceCurrency: "USD"
|
|
13
|
-
sections:
|
|
14
|
-
[
|
|
15
|
-
{
|
|
16
|
-
"id": "hero",
|
|
17
|
-
"type": "hero",
|
|
18
|
-
"data":
|
|
19
|
-
{
|
|
20
|
-
"eyebrow": "Book a call",
|
|
21
|
-
"headline": "{Book a call: what a visitor gets from it}",
|
|
22
|
-
"subheadline": "{One sentence on who the call is for and what they leave with}",
|
|
23
|
-
"primaryCta": { "label": "Book a time", "href": "/meet" },
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"id": "what-happens-on-the-call",
|
|
28
|
-
"type": "items",
|
|
29
|
-
"data":
|
|
30
|
-
{
|
|
31
|
-
"headline": "What happens on the call?",
|
|
32
|
-
"columns": 3,
|
|
33
|
-
"items":
|
|
34
|
-
[
|
|
35
|
-
{
|
|
36
|
-
"title": "{The first thing you cover}",
|
|
37
|
-
"description": "{One or two sentences on what the visitor learns or decides here}",
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"title": "{The second thing you cover}",
|
|
41
|
-
"description": "{One or two sentences on what the visitor learns or decides here}",
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"title": "{The next step you agree}",
|
|
45
|
-
"description": "{One or two sentences on what happens after the call}",
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
]
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
{/* Rendered from frontmatter `sections[]` by the /book-a-call route. This template carries the scheduling module, so the call to action opens the /meet booker. It overrides the base layer's copy, which points at /contact. The `schema:` Offer is the page's JSON-LD main entity — a free call. Placeholder copy — replace every {brace} with your own words before you launch. */}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: "ContactPage"
|
|
3
|
-
slug: "contact"
|
|
4
|
-
title: "Contact"
|
|
5
|
-
description: "One form, three fields, an inline confirmation. Placeholder copy — replace before you launch."
|
|
6
|
-
sections:
|
|
7
|
-
[
|
|
8
|
-
{
|
|
9
|
-
"id": "hero",
|
|
10
|
-
"type": "hero",
|
|
11
|
-
"data":
|
|
12
|
-
{
|
|
13
|
-
"variant": "centered",
|
|
14
|
-
"eyebrow": "Contact",
|
|
15
|
-
"headline": "Tell us about the yard",
|
|
16
|
-
"subheadline": "{One line on what happens after you send this, and how long it takes. If a call is faster, say so.}",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"id": "closing",
|
|
21
|
-
"type": "cta",
|
|
22
|
-
"data":
|
|
23
|
-
{
|
|
24
|
-
"variant": "minimal",
|
|
25
|
-
"headline": "Would a visit be faster?",
|
|
26
|
-
"primaryCta": { "label": "Book a visit →", "href": "/meet" },
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
]
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
The /contact route mounts the page's one contact surface — the guided intake, with its fallback form — which posts to the site's own API (`/v1/leads/submit`) and confirms inline. Placeholder copy.
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: "FAQPage"
|
|
3
|
-
slug: "faq"
|
|
4
|
-
title: "FAQ"
|
|
5
|
-
description: "The questions people ask before they book. Placeholder copy — replace every answer before you launch."
|
|
6
|
-
sections:
|
|
7
|
-
[
|
|
8
|
-
{
|
|
9
|
-
"id": "faq",
|
|
10
|
-
"type": "faq",
|
|
11
|
-
"data":
|
|
12
|
-
{
|
|
13
|
-
"headline": "Questions",
|
|
14
|
-
"variant": "centered",
|
|
15
|
-
"initialOpen": "first",
|
|
16
|
-
"items":
|
|
17
|
-
[
|
|
18
|
-
{
|
|
19
|
-
"question": "{Which areas do you cover?}",
|
|
20
|
-
"answer": "{Name the towns, the radius or the postcodes. A reader outside them should know it here.}",
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
"question": "{How often do you visit?}",
|
|
24
|
-
"answer": "{Give the real cadence for the recurring job, and say what happens in winter.}",
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"question": "{What does it cost?}",
|
|
28
|
-
"answer": "{The three service pages carry the prices. Say here what moves them — yard size, access, waste removal.}",
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"question": "{How do I pay?}",
|
|
32
|
-
"answer": "{Say when payment is taken and how. Checkout runs on your own Stripe account; the card details never touch this site.}",
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"question": "{What if I need to cancel?}",
|
|
36
|
-
"answer": "{Point at the cancellation policy and give the notice period in one line.}",
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
"supportLink":
|
|
40
|
-
{ "label": "Still stuck? Get in touch", "href": "/contact" },
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"id": "closing",
|
|
45
|
-
"type": "cta",
|
|
46
|
-
"data":
|
|
47
|
-
{
|
|
48
|
-
"variant": "minimal",
|
|
49
|
-
"headline": "Still have a question?",
|
|
50
|
-
"primaryCta": { "label": "Contact us →", "href": "/contact" },
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
]
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
Placeholder copy. Replace every answer before you launch.
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: "HomePage"
|
|
3
|
-
slug: "home"
|
|
4
|
-
title: "Your Company"
|
|
5
|
-
description: "Placeholder home for the simple-service template — a lawn-care site that books a visit and takes the payment. 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 service area}",
|
|
15
|
-
"headline": "{Lawn care that turns up when it says it will}",
|
|
16
|
-
"subheadline": "{One line on who you serve and what they get. Name the street, the town or the county — a local reader is looking for their own.}",
|
|
17
|
-
"primaryCta": { "label": "Book a visit →", "href": "/meet" },
|
|
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": "{Lawn maintenance}",
|
|
37
|
-
"description": "{One line on the recurring visit — what it includes and how often it runs.}",
|
|
38
|
-
"link":
|
|
39
|
-
{
|
|
40
|
-
"label": "Read more",
|
|
41
|
-
"href": "/services/lawn-maintenance",
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"title": "{Seasonal cleanup}",
|
|
46
|
-
"description": "{One line on the spring and autumn clear-down.}",
|
|
47
|
-
"link":
|
|
48
|
-
{
|
|
49
|
-
"label": "Read more",
|
|
50
|
-
"href": "/services/seasonal-cleanup",
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"title": "{Landscape design}",
|
|
55
|
-
"description": "{One line on the design-and-plant job, and what a customer ends up with.}",
|
|
56
|
-
"link":
|
|
57
|
-
{
|
|
58
|
-
"label": "Read more",
|
|
59
|
-
"href": "/services/landscape-design",
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"id": "closing",
|
|
67
|
-
"type": "cta",
|
|
68
|
-
"data":
|
|
69
|
-
{
|
|
70
|
-
"variant": "minimal",
|
|
71
|
-
"headline": "Ready for a tidier yard?",
|
|
72
|
-
"description": "{One line inviting the reader to pick a time rather than fill in a form.}",
|
|
73
|
-
"primaryCta": { "label": "Book a visit →", "href": "/meet" },
|
|
74
|
-
"secondaryCta":
|
|
75
|
-
{
|
|
76
|
-
"label": "Ask a question",
|
|
77
|
-
"href": "/contact",
|
|
78
|
-
"variant": "outline",
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
]
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
Placeholder copy. Every headline, every line of body copy and every price on this site is a placeholder — replace them before you launch.
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: "Service"
|
|
3
|
-
slug: "landscape-design"
|
|
4
|
-
title: "{Landscape design}"
|
|
5
|
-
description: "{One line on what this job is and who it suits. Replace before you launch.}"
|
|
6
|
-
price: 1250
|
|
7
|
-
priceCurrency: "USD"
|
|
8
|
-
provider:
|
|
9
|
-
name: "{Your Company}"
|
|
10
|
-
schema:
|
|
11
|
-
serviceType: "{Landscape design}"
|
|
12
|
-
areaServed: "{Your service area}"
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
# \{Landscape design\}
|
|
16
|
-
|
|
17
|
-
\{Open with the situation a reader is in when they come looking for this. Two or
|
|
18
|
-
three sentences, no more — the detail belongs under the headings below.\}
|
|
19
|
-
|
|
20
|
-
## What it covers
|
|
21
|
-
|
|
22
|
-
- \{The first thing you actually do\}
|
|
23
|
-
- \{The second thing you actually do\}
|
|
24
|
-
- \{The third thing you actually do\}
|
|
25
|
-
|
|
26
|
-
## How it runs
|
|
27
|
-
|
|
28
|
-
\{One paragraph on the shape of the visit: how it is scheduled, how long it
|
|
29
|
-
takes, who turns up, and what you need from the customer beforehand.\}
|
|
30
|
-
|
|
31
|
-
## What you end up with
|
|
32
|
-
|
|
33
|
-
\{One paragraph on the result. Be concrete — describe the yard when the crew
|
|
34
|
-
drives away.\}
|
|
35
|
-
|
|
36
|
-
## What it costs
|
|
37
|
-
|
|
38
|
-
\{The price in this page's frontmatter is a PLACEHOLDER. It is what the site
|
|
39
|
-
publishes as a schema.org `Offer`, so an agent reading this page quotes it —
|
|
40
|
-
replace it with your real number before you launch.\}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: "Service"
|
|
3
|
-
slug: "lawn-maintenance"
|
|
4
|
-
title: "{Lawn maintenance}"
|
|
5
|
-
description: "{One line on what this job is and who it suits. Replace before you launch.}"
|
|
6
|
-
price: 149
|
|
7
|
-
priceCurrency: "USD"
|
|
8
|
-
provider:
|
|
9
|
-
name: "{Your Company}"
|
|
10
|
-
schema:
|
|
11
|
-
serviceType: "{Lawn maintenance}"
|
|
12
|
-
areaServed: "{Your service area}"
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
# \{Lawn maintenance\}
|
|
16
|
-
|
|
17
|
-
\{Open with the situation a reader is in when they come looking for this. Two or
|
|
18
|
-
three sentences, no more — the detail belongs under the headings below.\}
|
|
19
|
-
|
|
20
|
-
## What it covers
|
|
21
|
-
|
|
22
|
-
- \{The first thing you actually do\}
|
|
23
|
-
- \{The second thing you actually do\}
|
|
24
|
-
- \{The third thing you actually do\}
|
|
25
|
-
|
|
26
|
-
## How it runs
|
|
27
|
-
|
|
28
|
-
\{One paragraph on the shape of the visit: how it is scheduled, how long it
|
|
29
|
-
takes, who turns up, and what you need from the customer beforehand.\}
|
|
30
|
-
|
|
31
|
-
## What you end up with
|
|
32
|
-
|
|
33
|
-
\{One paragraph on the result. Be concrete — describe the yard when the crew
|
|
34
|
-
drives away.\}
|
|
35
|
-
|
|
36
|
-
## What it costs
|
|
37
|
-
|
|
38
|
-
\{The price in this page's frontmatter is a PLACEHOLDER. It is what the site
|
|
39
|
-
publishes as a schema.org `Offer`, so an agent reading this page quotes it —
|
|
40
|
-
replace it with your real number before you launch.\}
|