create-ailk 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/component-catalog.json +186 -8
- package/component-catalog.md +9 -7
- package/dist/add-module.js +20 -14
- package/dist/add-route.d.ts +55 -1
- package/dist/add-route.js +294 -12
- package/dist/cli.js +27 -10
- package/dist/derive-architecture.d.ts +12 -3
- package/dist/derive-architecture.js +20 -8
- package/dist/design-package.js +7 -2
- package/dist/lib/design-checks.js +4 -2
- package/dist/lib/env-catalog.js +5 -5
- package/dist/lib/npm-auth.d.ts +9 -0
- package/dist/lib/npm-auth.js +48 -0
- package/dist/lib/scaffold-render-sweep.d.ts +3 -2
- package/dist/lib/scaffold-render-sweep.js +5 -8
- package/dist/module-architecture.js +99 -9
- package/dist/paid-sections.d.ts +21 -2
- package/dist/paid-sections.js +69 -7
- package/dist/programmatic.js +19 -5
- package/dist/seed-flows.d.ts +4 -1
- package/dist/seed-flows.js +50 -4
- package/dist/site-chrome.d.ts +8 -0
- package/dist/site-chrome.js +17 -1
- package/dist/spoke-checkout.d.ts +65 -41
- package/dist/spoke-checkout.js +208 -430
- package/dist/starter-grid.d.ts +0 -3
- package/dist/starter-grid.js +24 -14
- package/dist/surfaces.js +52 -26
- package/dist/sync-routes.d.ts +38 -1
- package/dist/sync-routes.js +187 -13
- package/dist/template-record.d.ts +4 -3
- package/dist/template-record.js +8 -4
- package/dist/topology.js +25 -1
- package/dist/update.js +15 -0
- package/package.json +3 -3
- package/site-templates/_base/content/en/NewsletterSignup/newsletter.mdx +4 -49
- package/site-templates/_base/content/en/Pricing/pricing.mdx +3 -21
- package/site-templates/designs/minimalism/DESIGN.md +1 -1
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +23 -20
- package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +28 -14
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.json +15 -39
- package/site-templates/marketing-site-free/TEMPLATE-MANIFEST.md +38 -34
- package/site-templates/marketing-site-free/content/en/NewsletterSignup/newsletter.mdx +6 -43
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.json +14 -31
- package/site-templates/shapes/local-business-service/TEMPLATE-MANIFEST.md +26 -25
- package/site-templates/shapes/local-business-service/content/en/NewsletterSignup/newsletter.mdx +6 -43
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.json +14 -31
- package/site-templates/shapes/organization-service/TEMPLATE-MANIFEST.md +26 -25
- package/site-templates/shapes/organization-service/content/en/NewsletterSignup/newsletter.mdx +6 -43
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.json +14 -31
- package/site-templates/shapes/person-service/TEMPLATE-MANIFEST.md +26 -25
- package/site-templates/shapes/person-service/content/en/NewsletterSignup/newsletter.mdx +6 -43
- package/templates/.env.example +9 -7
- package/templates/.github/workflows/ci.yml +13 -0
- package/templates/README.md +1 -0
- package/templates/_gitignore +4 -0
- package/templates/apps/api/.env.example +27 -0
- package/templates/apps/api/CLAUDE.md +87 -17
- package/templates/apps/api/package.json +1 -0
- package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +2 -0
- package/templates/apps/api/src/bin/stripe-connections-rekey.ts +45 -0
- package/templates/apps/api/src/config/__tests__/stripe-connection-key.test.ts +185 -0
- package/templates/apps/api/src/config/index.ts +109 -0
- package/templates/apps/api/src/lib/__mocks__/prisma.ts +3 -0
- package/templates/apps/api/src/lib/__tests__/consent-store.test.ts +19 -0
- package/templates/apps/api/src/lib/__tests__/flow-completion-store.test.ts +149 -0
- package/templates/apps/api/src/lib/__tests__/flow-rename-race.db.test.ts +116 -0
- package/templates/apps/api/src/lib/consent-store.ts +28 -0
- package/templates/apps/api/src/lib/error-serializer.ts +74 -7
- package/templates/apps/api/src/lib/flow-completion-store.ts +136 -0
- package/templates/apps/api/src/lib/hub-sign-in-store.ts +38 -2
- package/templates/apps/api/src/lib/proposal-paid-store.ts +21 -4
- package/templates/apps/api/src/lib/stripe.ts +74 -4
- package/templates/apps/api/src/lib/webhook-idempotency.ts +66 -2
- package/templates/apps/api/src/middleware/__tests__/auth.hub-session-path.test.ts +14 -3
- package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +218 -0
- package/templates/apps/api/src/middleware/__tests__/write-budget.test.ts +174 -0
- package/templates/apps/api/src/middleware/auth.ts +13 -6
- package/templates/apps/api/src/middleware/rate-limit.ts +226 -4
- package/templates/apps/api/src/openapi/spec.ts +33 -3
- package/templates/apps/api/src/routes/auth/__tests__/hub-sign-in.test.ts +49 -0
- package/templates/apps/api/src/routes/auth/hub-sign-in.ts +41 -0
- package/templates/apps/api/src/routes/billing/plan-checkout.ts +325 -0
- package/templates/apps/api/src/routes/checkout/__tests__/live-key.test.ts +11 -0
- package/templates/apps/api/src/routes/checkout/__tests__/offerings-authorization.test.ts +1300 -0
- package/templates/apps/api/src/routes/checkout/__tests__/session.test.ts +11 -0
- package/templates/apps/api/src/routes/checkout/__tests__/sessions.test.ts +49 -0
- package/templates/apps/api/src/routes/checkout/session.ts +57 -25
- package/templates/apps/api/src/routes/checkout/sessions.ts +232 -82
- package/templates/apps/api/src/routes/consent/__tests__/account.test.ts +386 -0
- package/templates/apps/api/src/routes/consent/__tests__/sign-up-rate-limit.test.ts +160 -0
- package/templates/apps/api/src/routes/consent/account.ts +268 -0
- package/templates/apps/api/src/routes/consent/index.ts +15 -7
- package/templates/apps/api/src/routes/content/__tests__/get-page.test.ts +36 -0
- package/templates/apps/api/src/routes/content/__tests__/offerings.test.ts +731 -0
- package/templates/apps/api/src/routes/content/__tests__/pricing.test.ts +753 -0
- package/templates/apps/api/src/routes/content/__tests__/shown-offerings.test.ts +762 -0
- package/templates/apps/api/src/routes/content/get-page.ts +4 -0
- package/templates/apps/api/src/routes/content/index.ts +16 -2
- package/templates/apps/api/src/routes/content/offerings.ts +184 -0
- package/templates/apps/api/src/routes/content/pricing.ts +176 -0
- package/templates/apps/api/src/routes/content/shown-offerings.ts +229 -0
- package/templates/apps/api/src/routes/leads/__tests__/magnet-completion.test.ts +515 -0
- package/templates/apps/api/src/routes/leads/index.ts +164 -7
- package/templates/apps/api/src/routes/webhooks/README.md +66 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-checkout-consent.test.ts +649 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-offerings.test.ts +814 -0
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-org-billing.test.ts +80 -68
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe-site-filter.test.ts +5 -5
- package/templates/apps/api/src/routes/webhooks/__tests__/stripe.test.ts +8 -2
- package/templates/apps/api/src/routes/webhooks/index.ts +23 -0
- package/templates/apps/api/src/routes/webhooks/stripe-offerings.ts +384 -0
- package/templates/apps/api/src/routes/webhooks/stripe.ts +245 -36
- package/templates/apps/api/src/server.ts +163 -46
- package/templates/apps/api/src/services/__tests__/checkout-plan.test.ts +313 -0
- package/templates/apps/api/src/services/__tests__/deliverable-fulfillment.test.ts +51 -2
- package/templates/apps/api/src/services/__tests__/keyless-workspace-predicate.test.ts +234 -0
- package/templates/apps/api/src/services/__tests__/lead-routing.test.ts +1383 -133
- package/templates/apps/api/src/services/__tests__/magnet-completion.test.ts +389 -0
- package/templates/apps/api/src/services/__tests__/person.test.ts +232 -1
- package/templates/apps/api/src/services/__tests__/plan-offerings.test.ts +444 -0
- package/templates/apps/api/src/services/checkout-buyer.ts +100 -4
- package/templates/apps/api/src/services/consent.ts +95 -0
- package/templates/apps/api/src/services/deliverable-fulfillment.ts +13 -5
- package/templates/apps/api/src/services/entitlements.ts +157 -1
- package/templates/apps/api/src/services/lead-routing.ts +431 -47
- package/templates/apps/api/src/services/magnet-completion.ts +242 -0
- package/templates/apps/api/src/services/offerings/__tests__/catalog.test.ts +295 -0
- package/templates/apps/api/src/services/offerings/__tests__/checkout-session-record.test.ts +268 -0
- package/templates/apps/api/src/services/offerings/__tests__/connection.test.ts +868 -0
- package/templates/apps/api/src/services/offerings/__tests__/fixtures.ts +416 -0
- package/templates/apps/api/src/services/offerings/__tests__/org-products.test.ts +396 -0
- package/templates/apps/api/src/services/offerings/__tests__/readers.test.ts +681 -0
- package/templates/apps/api/src/services/offerings/__tests__/source.test.ts +231 -0
- package/templates/apps/api/src/services/offerings/catalog.ts +308 -0
- package/templates/apps/api/src/services/offerings/checkout-authorization.ts +385 -0
- package/templates/apps/api/src/services/offerings/checkout-session-record.ts +192 -0
- package/templates/apps/api/src/services/offerings/connection.ts +1003 -0
- package/templates/apps/api/src/services/offerings/index.ts +614 -0
- package/templates/apps/api/src/services/offerings/source.ts +140 -0
- package/templates/apps/api/src/services/offerings/store.ts +150 -0
- package/templates/apps/api/src/services/person.ts +164 -17
- package/templates/apps/api/src/services/plan-offerings.ts +125 -0
- package/templates/apps/api/src/services/public-site-resolver.ts +27 -15
- package/templates/apps/mcp/CLAUDE.md +22 -14
- package/templates/apps/mcp/__tests__/catalog-drift.test.ts +9 -4
- package/templates/apps/mcp/__tests__/get_offerings.test.ts +358 -0
- package/templates/apps/mcp/__tests__/get_pricing.test.ts +364 -0
- package/templates/apps/mcp/__tests__/http-transport.test.ts +4 -4
- package/templates/apps/mcp/__tests__/module-exclusion.test.ts +2 -2
- package/templates/apps/mcp/__tests__/server.test.ts +13 -11
- package/templates/apps/mcp/__tests__/start_purchase.test.ts +208 -12
- package/templates/apps/mcp/__tests__/tools/purchase.test.ts +11 -11
- package/templates/apps/mcp/src/lib/shown-offerings.ts +105 -0
- package/templates/apps/mcp/src/server.ts +5 -0
- package/templates/apps/mcp/src/tools/get_offerings.ts +47 -30
- package/templates/apps/mcp/src/tools/get_pricing.ts +40 -40
- package/templates/apps/mcp/src/tools/purchase.ts +30 -2
- package/templates/apps/mcp/src/workspace-server.ts +15 -0
- package/templates/apps/web/.env.example +24 -31
- package/templates/apps/web/CLAUDE.md +393 -9
- package/templates/apps/web/__tests__/__mocks__/next-intl-server.ts +6 -2
- package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +5 -4
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/forgot-password-card.tsx +5 -1
- package/templates/apps/web/app/[locale]/(auth)/forgot-password/page.tsx +2 -0
- package/templates/apps/web/app/[locale]/(auth)/layout.tsx +3 -14
- package/templates/apps/web/app/[locale]/(auth)/reset-password/page.tsx +2 -0
- package/templates/apps/web/app/[locale]/(auth)/reset-password/reset-password-card.tsx +5 -1
- package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/page.test.tsx +160 -8
- package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/sign-in-card.test.tsx +12 -9
- package/templates/apps/web/app/[locale]/(auth)/sign-in/page.tsx +105 -2
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +36 -3
- package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-text.ts +47 -1
- package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/sign-up-card.test.tsx +60 -22
- package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +16 -8
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +85 -31
- package/templates/apps/web/app/[locale]/(auth)/use-auth-card-flow.ts +18 -4
- package/templates/apps/web/app/[locale]/(auth)/verify-email/page.tsx +3 -1
- package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +7 -4
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/agreements-prompt.test.tsx +227 -207
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/layout-sign-out.test.tsx +17 -1
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/layout.test.tsx +143 -1
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/new-menu.test.tsx +4 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/page.test.tsx +385 -89
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/popups.test.tsx +5 -0
- package/templates/apps/web/app/[locale]/(authed)/account/__tests__/privacy.test.tsx +44 -5
- package/templates/apps/web/app/[locale]/(authed)/account/account-frame.tsx +68 -34
- package/templates/apps/web/app/[locale]/(authed)/account/actions.ts +0 -8
- package/templates/apps/web/app/[locale]/(authed)/account/agreements-actions.ts +39 -151
- package/templates/apps/web/app/[locale]/(authed)/account/agreements-gate.ts +61 -0
- package/templates/apps/web/app/[locale]/(authed)/account/agreements-prompt.tsx +143 -140
- package/templates/apps/web/app/[locale]/(authed)/account/layout.tsx +40 -6
- package/templates/apps/web/app/[locale]/(authed)/account/page.tsx +68 -54
- package/templates/apps/web/app/[locale]/(authed)/account/privacy/page.tsx +5 -1
- package/templates/apps/web/app/[locale]/careers/[slug]/[action]/page.tsx +189 -0
- package/templates/apps/web/app/[locale]/careers/[slug]/apply.actions.ts +295 -0
- package/templates/apps/web/app/[locale]/careers/[slug]/job-application-form.ts +120 -0
- package/templates/apps/web/app/[locale]/careers/[slug]/page.tsx +23 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/apply.actions.test.ts +319 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/careers-hub.test.tsx +172 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/careers-set.test.tsx +149 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/job-application-form.test.ts +141 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/job-apply-page.test.tsx +424 -0
- package/templates/apps/web/app/[locale]/careers/__tests__/page-renderer-migration.test.tsx +72 -11
- package/templates/apps/web/app/[locale]/careers/page.tsx +129 -5
- package/templates/apps/web/app/[locale]/case-studies/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/checkout/__tests__/pages.test.tsx +139 -0
- package/templates/apps/web/app/[locale]/checkout/__tests__/thank-you-account.test.tsx +136 -0
- package/templates/apps/web/app/[locale]/checkout/thank-you/page.tsx +114 -0
- package/templates/apps/web/app/[locale]/checkout/unavailable/page.tsx +51 -0
- package/templates/apps/web/app/[locale]/clients/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/contact/ConversationalIntakeWrapper.tsx +17 -1
- package/templates/apps/web/app/[locale]/contact/__tests__/ConversationalIntakeWrapper.test.tsx +79 -4
- package/templates/apps/web/app/[locale]/contact/__tests__/contact-magnet-page.test.tsx +160 -13
- package/templates/apps/web/app/[locale]/contact/__tests__/contact.actions.test.ts +466 -36
- package/templates/apps/web/app/[locale]/contact/__tests__/page-renderer-migration.test.tsx +7 -0
- package/templates/apps/web/app/[locale]/contact/contact.actions.ts +172 -57
- package/templates/apps/web/app/[locale]/contact/intake-script.ts +26 -0
- package/templates/apps/web/app/[locale]/contact/page.tsx +99 -60
- package/templates/apps/web/app/[locale]/courses/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/events/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/flows/[slug]/FlowStepperClient.tsx +341 -4
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.count.test.tsx +43 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.deliverable.test.tsx +200 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.ending.test.tsx +197 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/FlowStepperClient.invite.test.tsx +257 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/account-invite.actions.test.ts +69 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/magnet-page.test.tsx +430 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/__tests__/two-route-tool.test.tsx +21 -9
- package/templates/apps/web/app/[locale]/flows/[slug]/account-invite.actions.ts +35 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/magnet-page.tsx +352 -0
- package/templates/apps/web/app/[locale]/flows/[slug]/page.tsx +12 -73
- package/templates/apps/web/app/[locale]/flows/[slug]/start/page.tsx +10 -31
- package/templates/apps/web/app/[locale]/for/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/how-to/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/integrations/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/layout.tsx +55 -4
- package/templates/apps/web/app/[locale]/newsletter/__tests__/page.test.tsx +174 -104
- package/templates/apps/web/app/[locale]/newsletter/page.tsx +95 -58
- package/templates/apps/web/app/[locale]/page.tsx +13 -1
- package/templates/apps/web/app/[locale]/partners/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/pricing/__tests__/__snapshots__/unconnected.test.tsx.snap +7 -0
- package/templates/apps/web/app/[locale]/pricing/__tests__/offerings.test.tsx +599 -0
- package/templates/apps/web/app/[locale]/pricing/__tests__/page.test.tsx +216 -0
- package/templates/apps/web/app/[locale]/pricing/__tests__/unconnected.test.tsx +236 -0
- package/templates/apps/web/app/[locale]/pricing/page.tsx +367 -6
- package/templates/apps/web/app/[locale]/products/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/resources/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/services/__tests__/page-renderer-migration.test.tsx +2 -2
- package/templates/apps/web/app/[locale]/software/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/team/__tests__/team-routes.test.tsx +4 -1
- package/templates/apps/web/app/[locale]/tech-articles/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/testimonials/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/[locale]/thanks/[slug]/AccountInviteLink.tsx +89 -0
- package/templates/apps/web/app/[locale]/thanks/[slug]/__tests__/AccountInviteLink.test.tsx +104 -0
- package/templates/apps/web/app/[locale]/thanks/[slug]/__tests__/page.test.tsx +38 -0
- package/templates/apps/web/app/[locale]/thanks/[slug]/page.tsx +9 -0
- package/templates/apps/web/app/[locale]/unsubscribe/__tests__/unsubscribe-rsc-boundary.test.tsx +17 -0
- package/templates/apps/web/app/[locale]/unsubscribe/__tests__/unsubscribe.test.tsx +62 -3
- package/templates/apps/web/app/[locale]/unsubscribe/page.tsx +70 -18
- package/templates/apps/web/app/[locale]/unsubscribe/unsubscribe-button.tsx +30 -9
- package/templates/apps/web/app/[locale]/whitepapers/__tests__/page-renderer-migration.test.tsx +1 -1
- package/templates/apps/web/app/api/auth/hub/authorize/__tests__/route.test.ts +114 -0
- package/templates/apps/web/app/api/auth/hub/authorize/route.ts +20 -3
- package/templates/apps/web/app/api/hub-session/__tests__/routes.test.ts +44 -1
- package/templates/apps/web/app/api/hub-session/sign-in/route.ts +22 -3
- package/templates/apps/web/app/api/offerings/checkout/[lookupKey]/route.ts +316 -0
- package/templates/apps/web/app/api/offerings/checkout/__tests__/route.test.ts +810 -0
- package/templates/apps/web/auth.ts +28 -2
- package/templates/apps/web/lib/__tests__/account-invite.test.ts +63 -0
- package/templates/apps/web/lib/__tests__/auth-routes.test.ts +27 -1
- package/templates/apps/web/lib/__tests__/consent-policies.test.ts +23 -0
- package/templates/apps/web/lib/__tests__/deck-page.test.ts +7 -1
- package/templates/apps/web/lib/__tests__/in-page-magnet.test.ts +265 -0
- package/templates/apps/web/lib/__tests__/magnet-routes.test.ts +57 -0
- package/templates/apps/web/lib/__tests__/newsletter.actions.test.ts +293 -0
- package/templates/apps/web/lib/__tests__/offerings-pricing.test.ts +601 -0
- package/templates/apps/web/lib/__tests__/structured-data.test.tsx +101 -25
- package/templates/apps/web/lib/account-invite.ts +37 -0
- package/templates/apps/web/lib/auth-routes.ts +36 -2
- package/templates/apps/web/lib/checkout-config.ts +16 -0
- package/templates/apps/web/lib/consent-policies.ts +22 -0
- package/templates/apps/web/lib/deck-page.ts +7 -0
- package/templates/apps/web/lib/deliverable-grant.ts +18 -0
- package/templates/apps/web/lib/hub-session/__tests__/sign-in-gate.test.tsx +111 -0
- package/templates/apps/web/lib/hub-session/sign-in-gate.tsx +88 -32
- package/templates/apps/web/lib/in-page-magnet.ts +416 -0
- package/templates/apps/web/lib/magnet-routes.ts +42 -0
- package/templates/apps/web/lib/modules.generated.ts +9 -0
- package/templates/apps/web/lib/newsletter.actions.ts +202 -0
- package/templates/apps/web/lib/offerings-pricing.ts +326 -0
- package/templates/apps/web/lib/posting-title.ts +17 -0
- package/templates/apps/web/lib/prisma-for-auth.ts +8 -0
- package/templates/apps/web/lib/sign-up-agreements.ts +449 -0
- package/templates/apps/web/lib/site-chrome.ts +2 -0
- package/templates/apps/web/lib/telemetry-scrub.ts +5 -1
- package/templates/apps/web/messages/en.json +71 -20
- package/templates/apps/web/middleware.ts +12 -2
- package/templates/apps/web/package.json +1 -0
- package/templates/apps/web/security-headers.config.ts +17 -0
- package/templates/apps/web/src/lib/__tests__/lead-write.test.ts +187 -0
- package/templates/apps/web/src/lib/__tests__/rate-limit.test.ts +67 -0
- package/templates/apps/web/src/lib/lead-write.ts +90 -0
- package/templates/apps/web/src/lib/rate-limit.ts +79 -0
- package/templates/content/en/BlogList/blog.mdx +4 -71
- package/templates/content/en/BookCall/book-a-call.mdx +1 -41
- package/templates/content/en/BookCall/onsite-estimate.mdx +1 -17
- package/templates/content/en/BookCall/onsite-service.mdx +1 -17
- package/templates/content/en/BookCall/start-project.mdx +1 -17
- package/templates/content/en/ContactPage/contact.mdx +6 -63
- package/templates/content/en/HomePage/home.mdx +3 -21
- package/templates/database/CHANGELOG.md +69 -0
- package/templates/database/__tests__/consent-source-checkout-migration.test.ts +79 -0
- package/templates/database/__tests__/flow-completion-migration.test.ts +115 -0
- package/templates/database/__tests__/flow-completion.db.test.ts +136 -0
- package/templates/database/__tests__/in-page-magnets-migration.test.ts +161 -0
- package/templates/database/__tests__/offerings-checkout-session.db.test.ts +270 -0
- package/templates/database/__tests__/offerings-migration.test.ts +197 -0
- package/templates/database/__tests__/offerings-shown-price-ids-migration.test.ts +86 -0
- package/templates/database/__tests__/offerings.db.test.ts +303 -0
- package/templates/database/__tests__/seed.test.ts +64 -1
- package/templates/database/auth/schema.prisma +4 -0
- package/templates/database/config/schema.prisma +91 -0
- package/templates/database/inbox/schema.prisma +17 -2
- package/templates/database/migrations/20261018120000_flow_completion/migration.sql +52 -0
- package/templates/database/migrations/20261019120000_consent_source_checkout/migration.sql +27 -0
- package/templates/database/migrations/20261020120000_offerings_data_model/migration.sql +146 -0
- package/templates/database/migrations/20261021120000_offerings_checkout_session/migration.sql +77 -0
- package/templates/database/migrations/20261022120000_in_page_magnets/migration.sql +45 -0
- package/templates/database/migrations/20261023120000_offerings_shown_price_ids/migration.sql +47 -0
- package/templates/database/migrations/20261024120000_organization_plan_checkout_session/migration.sql +16 -0
- package/templates/database/package.json +1 -1
- package/templates/database/seed.ts +62 -3
- package/versions.json +35 -35
- package/site-templates/marketing-site-free/content/en/Pricing/pricing.mdx +0 -199
- package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up.actions.ts +0 -125
- package/templates/apps/web/app/[locale]/downloads/__tests__/page-renderer-migration.test.tsx +0 -93
- package/templates/apps/web/app/[locale]/downloads/page.tsx +0 -37
- package/templates/apps/web/app/[locale]/newsletter/__tests__/newsletter.actions.test.ts +0 -139
- package/templates/apps/web/app/[locale]/newsletter/newsletter.actions.ts +0 -93
- package/templates/apps/web/lib/__tests__/meeting-slugs.test.ts +0 -120
- package/templates/apps/web/lib/meeting-slugs.ts +0 -63
package/dist/topology.js
CHANGED
|
@@ -174,6 +174,29 @@ export function isRemovableClosureMember(path, opts = {}) {
|
|
|
174
174
|
return (p.split("/").includes("__tests__") ||
|
|
175
175
|
prefixes.some((prefix) => underPrefix(p, prefix)));
|
|
176
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* The relative module specifiers a file reaches that are NOT static imports:
|
|
179
|
+
* a jest module reference (`jest.mock("../auth")`, `doMock`, `unmock`,
|
|
180
|
+
* `setMock`, `requireActual`, `requireMock`, `createMockFromModule`) or a
|
|
181
|
+
* `require(...)`. A suite that mocks a seed by path ships a dangling
|
|
182
|
+
* reference on a spoke exactly as one that imports it would (#8758), yet the
|
|
183
|
+
* shared import walk (`relativeImportsOf`) sees only `import`/`export ... from`
|
|
184
|
+
* and `import()` — it is shared with the module-slice lints, so the extra
|
|
185
|
+
* forms are read here rather than widening it for them.
|
|
186
|
+
*/
|
|
187
|
+
function referencedModulesOf(absPath) {
|
|
188
|
+
const specs = relativeImportsOf(absPath);
|
|
189
|
+
let src;
|
|
190
|
+
try {
|
|
191
|
+
src = readFileSync(absPath, "utf8");
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
return specs;
|
|
195
|
+
}
|
|
196
|
+
for (const m of src.matchAll(/\b(?:jest\s*\.\s*(?:mock|doMock|unmock|setMock|requireActual|requireMock|createMockFromModule)|require)\s*\(\s*["'`](\.[^"'`]*)["'`]/g))
|
|
197
|
+
specs.push(m[1]);
|
|
198
|
+
return specs;
|
|
199
|
+
}
|
|
177
200
|
/**
|
|
178
201
|
* Every path a spoke does not carry, computed over the built `templates/`
|
|
179
202
|
* tree: the removed roots, the seeds that apply, and every source file under
|
|
@@ -209,7 +232,7 @@ export function spokeExclusions(templatesDir, opts) {
|
|
|
209
232
|
for (const file of candidates) {
|
|
210
233
|
if (closed.has(file))
|
|
211
234
|
continue;
|
|
212
|
-
for (const spec of
|
|
235
|
+
for (const spec of referencedModulesOf(join(templatesDir, file))) {
|
|
213
236
|
const target = resolveRelativeImport(file, spec, candidates);
|
|
214
237
|
if (target !== undefined && closed.has(target)) {
|
|
215
238
|
closed.add(file);
|
|
@@ -899,6 +922,7 @@ export function renderSpokeHardFloors(opts) {
|
|
|
899
922
|
" reason: Stripe webhook route — payment state requires human review",
|
|
900
923
|
" - paths:",
|
|
901
924
|
' - "apps/web/app/api/checkout/**"',
|
|
925
|
+
' - "apps/web/lib/checkout.ts"',
|
|
902
926
|
' - "apps/web/lib/checkout-config.ts"',
|
|
903
927
|
' - ".github/workflows/checkout-e2e.yml"',
|
|
904
928
|
" reason: Spoke checkout — the buy route, the price map and the checkout e2e workflow require human review",
|
package/dist/update.js
CHANGED
|
@@ -26,8 +26,10 @@ import { AddModuleRefusedError, readArchitectureHeader } from "./add-module-core
|
|
|
26
26
|
import { buildScaffoldMarkers, isExcluded, isTextFile, renderTemplateFile, templateDestination } from "./copy.js";
|
|
27
27
|
import { fetchTemplateSnapshot } from "./lib/fetch-template-snapshot.js";
|
|
28
28
|
import { mergeThreeWay } from "./lib/merge-three-way.js";
|
|
29
|
+
import { MODULE_FLAGS_PATH, writeModuleFlags } from "./paid-sections.js";
|
|
29
30
|
import { ParseError } from "./parse-args.js";
|
|
30
31
|
import { SITE_ROSTER_PATH } from "./site-roster.js";
|
|
32
|
+
import { SPOKE_CHECKOUT_TEMPLATE_PATHS } from "./spoke-checkout.js";
|
|
31
33
|
import { excludedRoutePaths } from "./surfaces.js";
|
|
32
34
|
import { TEMPLATE_RECORD_PATH, isRecordable, parseTemplateRecord, serializeTemplateRecord, sha256Hex, } from "./template-record.js";
|
|
33
35
|
import { TopologyError, isSpokeExcluded, readSpokeShape, spokeExclusions, } from "./topology.js";
|
|
@@ -248,9 +250,13 @@ export async function updateSite(opts) {
|
|
|
248
250
|
}
|
|
249
251
|
const excludedRoutes = excludedRoutePaths(header.surfaces);
|
|
250
252
|
const spokeExclusionList = spoke !== undefined ? spokeExclusions(opts.templatesDir, spoke) : undefined;
|
|
253
|
+
// #8748 D3 — the standard spoke checkout is a commerce spoke's alone.
|
|
254
|
+
const sellsAsSpoke = spoke !== undefined && header.modules.includes("commerce");
|
|
251
255
|
const outOfScope = (destRel) => {
|
|
252
256
|
if (isExcluded(destRel, excludedRoutes))
|
|
253
257
|
return true;
|
|
258
|
+
if (!sellsAsSpoke && isExcluded(destRel, SPOKE_CHECKOUT_TEMPLATE_PATHS))
|
|
259
|
+
return true;
|
|
254
260
|
if (spoke !== undefined && spokeExclusionList !== undefined) {
|
|
255
261
|
return isSpokeExcluded(destRel, { ...spoke, exclusions: spokeExclusionList });
|
|
256
262
|
}
|
|
@@ -509,6 +515,15 @@ export async function updateSite(opts) {
|
|
|
509
515
|
if (recordChanged) {
|
|
510
516
|
writeFileSync(recordPath, serializeTemplateRecord({ schema: 1, projectName: record.projectName, files: nextFiles }));
|
|
511
517
|
}
|
|
518
|
+
// #8843 D10 — the module-presence flags are generated, never copied
|
|
519
|
+
// (REGENERATED_APP_PATHS): render them from this site's own
|
|
520
|
+
// apps/web/package.json on every run, so a site updated onto a layout
|
|
521
|
+
// that imports them has them before it builds. Not recorded.
|
|
522
|
+
const flags = writeModuleFlags(targetDir);
|
|
523
|
+
if (flags === "added")
|
|
524
|
+
moved.added.push(MODULE_FLAGS_PATH);
|
|
525
|
+
else if (flags === "updated")
|
|
526
|
+
moved.updated.push(MODULE_FLAGS_PATH);
|
|
512
527
|
return {
|
|
513
528
|
targetDir,
|
|
514
529
|
version,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-ailk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Scaffolder for AI Launch Kit — `pnpm create ailk@latest <dir>` produces a starter repo consuming @working-theory/* from npm (per ADR 0007).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"tar": "^7.5.21"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@working-theory/schema": "0.
|
|
32
|
-
"@working-theory/templates": "0.
|
|
31
|
+
"@working-theory/schema": "0.44.0",
|
|
32
|
+
"@working-theory/templates": "0.44.0"
|
|
33
33
|
},
|
|
34
34
|
"repository": {
|
|
35
35
|
"type": "git",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
type: "NewsletterSignup"
|
|
3
3
|
slug: "newsletter"
|
|
4
|
-
title: "
|
|
4
|
+
title: "Get the newsletter"
|
|
5
5
|
description: "{One sentence on what this newsletter covers and who it is for}"
|
|
6
6
|
schema:
|
|
7
7
|
mainEntity:
|
|
@@ -11,57 +11,12 @@ schema:
|
|
|
11
11
|
priceCurrency: "USD"
|
|
12
12
|
sections:
|
|
13
13
|
[
|
|
14
|
-
{
|
|
15
|
-
"id": "hero",
|
|
16
|
-
"type": "hero",
|
|
17
|
-
"data":
|
|
18
|
-
{
|
|
19
|
-
"eyebrow": "Newsletter",
|
|
20
|
-
"headline": "{Newsletter: what subscribers get and how often}",
|
|
21
|
-
"subheadline": "{One sentence on what this newsletter covers and who it is for}",
|
|
22
|
-
"primaryCta": { "label": "Subscribe", "href": "#signup" },
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
14
|
{
|
|
26
15
|
"id": "signup",
|
|
27
|
-
"type": "
|
|
28
|
-
"data":
|
|
29
|
-
{
|
|
30
|
-
"headline": "Subscribe",
|
|
31
|
-
"description": "{One sentence on what lands in the inbox}",
|
|
32
|
-
"action": "/v1/leads/subscribe",
|
|
33
|
-
"source": "newsletter",
|
|
34
|
-
"placeholder": "you@example.com",
|
|
35
|
-
"submitLabel": "Subscribe",
|
|
36
|
-
"consentText": "{One line on how you use the address, and that readers can unsubscribe any time}",
|
|
37
|
-
"pattern": "none",
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"id": "faq",
|
|
42
|
-
"type": "faq",
|
|
43
|
-
"data":
|
|
44
|
-
{
|
|
45
|
-
"headline": "FAQs",
|
|
46
|
-
"presentation": "expanded",
|
|
47
|
-
"items":
|
|
48
|
-
[
|
|
49
|
-
{
|
|
50
|
-
"question": "{How often will I hear from you?}",
|
|
51
|
-
"answer": "{Answer in one or two plain sentences}",
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"question": "{What will I get?}",
|
|
55
|
-
"answer": "{Answer in one or two plain sentences}",
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
"question": "{Can I unsubscribe?}",
|
|
59
|
-
"answer": "{Answer in one or two plain sentences}",
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
},
|
|
16
|
+
"type": "contact-form",
|
|
17
|
+
"data": { "variant": "column", "fields": [] },
|
|
63
18
|
},
|
|
64
19
|
]
|
|
65
20
|
---
|
|
66
21
|
|
|
67
|
-
{/* Rendered from frontmatter `sections[]` by the /newsletter route. The
|
|
22
|
+
{/* Rendered from frontmatter `sections[]` by the /newsletter route. The page's one signup surface is the workspace's Newsletter magnet: its heading, sentence, field, consent, button and ending all come from the magnet, mounted by the route in this section's slot. To change the signup, change the magnet in Admin → Magnets. The `schema:` Offer is the page's JSON-LD main entity — a free subscription. Replace every {brace} with your own words before you launch. */}
|
|
@@ -67,27 +67,9 @@ sections:
|
|
|
67
67
|
"headlineStyle": "label",
|
|
68
68
|
"logos":
|
|
69
69
|
[
|
|
70
|
-
{
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"darkSrc": "/logos/salessmyth-light.svg",
|
|
74
|
-
"width": 1118,
|
|
75
|
-
"height": 147,
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"name": "AI Launch Kit",
|
|
79
|
-
"src": "/logos/ai-launch-kit.svg",
|
|
80
|
-
"darkSrc": "/logos/ai-launch-kit-light.svg",
|
|
81
|
-
"width": 1248,
|
|
82
|
-
"height": 144,
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
"name": "Atomic Agent",
|
|
86
|
-
"src": "/logos/atomic-agent.svg",
|
|
87
|
-
"darkSrc": "/logos/atomic-agent-light.svg",
|
|
88
|
-
"width": 1320,
|
|
89
|
-
"height": 148,
|
|
90
|
-
},
|
|
70
|
+
{ "name": "Placeholder logo", "src": "/logomark.svg" },
|
|
71
|
+
{ "name": "Placeholder logo", "src": "/logomark.svg" },
|
|
72
|
+
{ "name": "Placeholder logo", "src": "/logomark.svg" },
|
|
91
73
|
],
|
|
92
74
|
"layout": "inline",
|
|
93
75
|
"treatment": "monochrome",
|
|
@@ -183,7 +183,7 @@ spacing:
|
|
|
183
183
|
|
|
184
184
|
The minimalism design is the standard foundation — the same black-on-white wireframe, the same type and the same components — presented as a deck. The home page is a deck: each home section is one slide, snapping one slide per scroll, and the landing hero carries the brand, so the site reads like a presentation before it reads like a website; the rest of the site is quiet and document-like. Its character comes from structure, not a palette: it carries no theme of its own.
|
|
185
185
|
|
|
186
|
-
The deck presents slide by slide (`layout.deckPresentation: true`). Each slide fits the screen, and a slide with more to say scrolls inside itself, with its down chevron after its last line. The pinned mark takes the ground of the slide under it, so it shows its dark variant over a dark slide. Each slide has its own link, `#slide-<name>`, which the address bar follows as the reader moves without adding a history entry. Slides fade in as they arrive, unless the reader has asked for reduced motion. Every slide's header is centred, and feature cards stack in one column on phones.
|
|
186
|
+
The deck presents slide by slide (`layout.deckPresentation: true`). Each slide fits the screen, and a slide with more to say scrolls inside itself, with its down chevron after its last line. The pinned mark takes the ground of the slide under it, so it shows its dark variant over a dark slide. Each slide has its own link, `#slide-<name>`, which the address bar follows as the reader moves without adding a history entry. A site may choose bare links instead, `#<name>`, by setting `layout.deckAnchors: bare` (it applies only with `deckPresentation: true`; minimalism leaves it unset, so its links stay `#slide-<name>`): a slide keeps the `slide-` name only where its bare name would collide, with another slide, a JSON-LD `@id` fragment on the page or an element id on the page (the page renderer checks `main` and the ids it is given; the deck checks every bare name against the live page when it loads, and the closing slide is `contact` unless an element or a JSON-LD node already has that id, else `slide-contact`), so a link never lands on a different element than its slide. Slides fade in as they arrive, unless the reader has asked for reduced motion. Every slide's header is centred, and feature cards stack in one column on phones. From 1024px up the slides after the landing share three lines, so a reader moving from slide to slide sees nothing jump: a **label heading** (the heading of a logo wall, a list or the portraits, each set in the section-label role above, smaller than the statement size) hangs from the **top line**, `--spacing-deck-label-line` below the top of the slide (7rem); the slide's content centres on the **middle line**, midway between the label zone and the action zone, whatever its height; and a slide's **action** (a statement slide's button, the logo wall's and the portraits' action row, the closing slide's buttons) ends on the **button line**, `--spacing-deck-action-line` above the foot of the slide (7.5rem, plus the consent bar's height while it shows), which is the landing's own button line. The landing sets that line; the other slides read it. Below 1024px a slide is one stacked flow and the lines do not apply. The action is seated on the line while its slide's content fits the zone; a slide that outgrows the zone scrolls inside itself, and the action, which is part of the scrolled content, no longer sits on the line (keep a slide's content within the zone, or put the action in the content). A list taller than its slide's content zone (five display-size titles at 1440×727) scrolls inside the slide, and its down chevron comes after its last line.
|
|
187
187
|
|
|
188
188
|
Every page is composed from the AI Launch Kit component library (`@working-theory/ui`). Nothing is hand-built: a page is a list of registered sections, each with a bounded set of variants.
|
|
189
189
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
],
|
|
18
18
|
"shape": "organization-product",
|
|
19
19
|
"design": "standard",
|
|
20
|
-
"generatedHash": "
|
|
20
|
+
"generatedHash": "f4a8f11aba42a071794585c4563015bd1c99cbe6917a36ee0629d37c6f5f476c",
|
|
21
21
|
"layout": {
|
|
22
22
|
"nav": "full",
|
|
23
23
|
"footer": "columns",
|
|
@@ -333,15 +333,8 @@
|
|
|
333
333
|
"chrome": "on",
|
|
334
334
|
"sections": [
|
|
335
335
|
{
|
|
336
|
-
"type": "
|
|
337
|
-
"component": "
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
"type": "items",
|
|
341
|
-
"component": "Items",
|
|
342
|
-
"options": {
|
|
343
|
-
"columns": 2
|
|
344
|
-
}
|
|
336
|
+
"type": "contact-form",
|
|
337
|
+
"component": "ContactForm"
|
|
345
338
|
}
|
|
346
339
|
]
|
|
347
340
|
},
|
|
@@ -372,19 +365,20 @@
|
|
|
372
365
|
"chrome": "on",
|
|
373
366
|
"sections": [
|
|
374
367
|
{
|
|
375
|
-
"type": "
|
|
376
|
-
"component": "
|
|
377
|
-
},
|
|
378
|
-
{
|
|
379
|
-
"type": "newsletter",
|
|
380
|
-
"component": "Newsletter"
|
|
381
|
-
},
|
|
382
|
-
{
|
|
383
|
-
"type": "faq",
|
|
384
|
-
"component": "FAQ"
|
|
368
|
+
"type": "contact-form",
|
|
369
|
+
"component": "ContactForm"
|
|
385
370
|
}
|
|
386
371
|
]
|
|
387
372
|
},
|
|
373
|
+
{
|
|
374
|
+
"route": "/unsubscribe",
|
|
375
|
+
"kind": "route",
|
|
376
|
+
"pageType": null,
|
|
377
|
+
"schema": null,
|
|
378
|
+
"shell": "MarketingShell",
|
|
379
|
+
"chrome": "on",
|
|
380
|
+
"sections": []
|
|
381
|
+
},
|
|
388
382
|
{
|
|
389
383
|
"route": "/sign-in",
|
|
390
384
|
"kind": "route",
|
|
@@ -697,6 +691,15 @@
|
|
|
697
691
|
"chrome": "on",
|
|
698
692
|
"sections": []
|
|
699
693
|
},
|
|
694
|
+
{
|
|
695
|
+
"route": "/private",
|
|
696
|
+
"kind": "route",
|
|
697
|
+
"pageType": null,
|
|
698
|
+
"schema": null,
|
|
699
|
+
"shell": "MarketingShell",
|
|
700
|
+
"chrome": "on",
|
|
701
|
+
"sections": []
|
|
702
|
+
},
|
|
700
703
|
{
|
|
701
704
|
"route": "/appointments",
|
|
702
705
|
"kind": "route",
|
|
@@ -177,10 +177,9 @@ _Detail route over `content/en/Feature/` — 3 seed pages: `feature-1.mdx`, `fea
|
|
|
177
177
|
|
|
178
178
|
<!-- generated:begin page=/contact -->
|
|
179
179
|
|
|
180
|
-
| # | Section
|
|
181
|
-
| --- |
|
|
182
|
-
| 1 | `
|
|
183
|
-
| 2 | `items` (tiles · columns=2 · items ×4) | `Items` | {Add appointment scheduling to your site} |
|
|
180
|
+
| # | Section | Component | Copy (first line) |
|
|
181
|
+
| --- | ----------------------------------- | ------------- | ----------------- |
|
|
182
|
+
| 1 | `contact-form` (column · fields ×0) | `ContactForm` | |
|
|
184
183
|
|
|
185
184
|
<!-- generated:end -->
|
|
186
185
|
|
|
@@ -197,14 +196,17 @@ _Detail route over `content/en/Feature/` — 3 seed pages: `feature-1.mdx`, `fea
|
|
|
197
196
|
|
|
198
197
|
<!-- generated:begin page=/newsletter -->
|
|
199
198
|
|
|
200
|
-
| # | Section
|
|
201
|
-
| --- |
|
|
202
|
-
| 1 | `
|
|
203
|
-
| 2 | `newsletter` | `Newsletter` | Subscribe |
|
|
204
|
-
| 3 | `faq` (expanded · items ×3) | `FAQ` | FAQs |
|
|
199
|
+
| # | Section | Component | Copy (first line) |
|
|
200
|
+
| --- | ----------------------------------- | ------------- | ----------------- |
|
|
201
|
+
| 1 | `contact-form` (column · fields ×0) | `ContactForm` | |
|
|
205
202
|
|
|
206
203
|
<!-- generated:end -->
|
|
207
204
|
|
|
205
|
+
<!-- generated:begin page=/unsubscribe -->
|
|
206
|
+
|
|
207
|
+
_Code route — no content, no sections._
|
|
208
|
+
<!-- generated:end -->
|
|
209
|
+
|
|
208
210
|
`/sign-in`:
|
|
209
211
|
|
|
210
212
|
<!-- generated:begin page=/sign-in -->
|
|
@@ -342,6 +344,16 @@ Target composition (deferred to **#5670**, same as `/meet` above):
|
|
|
342
344
|
_Code route — no content, no sections._
|
|
343
345
|
<!-- generated:end -->
|
|
344
346
|
|
|
347
|
+
### `/private` — the private meeting index · scheduling
|
|
348
|
+
|
|
349
|
+
The same booking frame as `/meet`, listing the workspace's private meetings
|
|
350
|
+
(#8843 D8); `noindex`, unlinked, no seed.
|
|
351
|
+
|
|
352
|
+
<!-- generated:begin page=/private -->
|
|
353
|
+
|
|
354
|
+
_Code route — no content, no sections._
|
|
355
|
+
<!-- generated:end -->
|
|
356
|
+
|
|
345
357
|
`/appointments`:
|
|
346
358
|
|
|
347
359
|
<!-- generated:begin page=/appointments -->
|
|
@@ -517,6 +529,7 @@ marketing-site:
|
|
|
517
529
|
- { route: "/contact", kind: page, content: ["content/en/ContactPage/contact.mdx"] }
|
|
518
530
|
- { route: "/glossary", kind: page, content: ["content/en/GlossaryList/glossary.mdx"] }
|
|
519
531
|
- { route: "/newsletter", kind: page, content: ["content/en/NewsletterSignup/newsletter.mdx"] }
|
|
532
|
+
- { route: "/unsubscribe", kind: route }
|
|
520
533
|
- { route: "/sign-in", kind: route }
|
|
521
534
|
- { route: "/sign-up", kind: route }
|
|
522
535
|
- { route: "/privacy", kind: page, content: ["content/en/PrivacyPage/privacy.mdx"] }
|
|
@@ -537,6 +550,7 @@ marketing-site:
|
|
|
537
550
|
- { route: "/meet", kind: route }
|
|
538
551
|
- { route: "/meet/[slug]", kind: route }
|
|
539
552
|
- { route: "/meet/confirmed", kind: route }
|
|
553
|
+
- { route: "/private", kind: route }
|
|
540
554
|
- { route: "/appointments", kind: route }
|
|
541
555
|
- { route: "/flows/[slug]", kind: route }
|
|
542
556
|
- { route: "/flows/[slug]/start", kind: route }
|
|
@@ -563,11 +577,11 @@ Every component the roster rows' seed content composes today (generated):
|
|
|
563
577
|
|
|
564
578
|
<!-- generated:begin inventory -->
|
|
565
579
|
|
|
566
|
-
| Tier | Used by this template
|
|
567
|
-
| -------- |
|
|
568
|
-
| Shell | `MarketingShell`
|
|
569
|
-
| Chrome | `Nav`, `Footer`, `Banner` (+ `BannerConsentIsland`, `BannerDismissIsland`)
|
|
570
|
-
| Sections | `ContentBlock`, `CTA`, `DecisionSplit`, `DocumentChassis`, `FAQ`, `Feature`, `GlossaryIndex`, `Hero`, `Items`, `LogoCloud`, `MediaBand`, `
|
|
580
|
+
| Tier | Used by this template |
|
|
581
|
+
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
582
|
+
| Shell | `MarketingShell` |
|
|
583
|
+
| Chrome | `Nav`, `Footer`, `Banner` (+ `BannerConsentIsland`, `BannerDismissIsland`) |
|
|
584
|
+
| Sections | `ContactForm`, `ContentBlock`, `CTA`, `DecisionSplit`, `DocumentChassis`, `FAQ`, `Feature`, `GlossaryIndex`, `Hero`, `Items`, `LogoCloud`, `MediaBand`, `Pricing`, `StairSteps`, `Team`, `Testimonials` |
|
|
571
585
|
|
|
572
586
|
<!-- generated:end -->
|
|
573
587
|
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
"categories": ["accounting", "legal", "technology"],
|
|
5
5
|
"shape": "organization-product",
|
|
6
6
|
"design": "standard",
|
|
7
|
-
"generatedHash": "
|
|
7
|
+
"generatedHash": "69b9e9d31dba7bc9d556deb74bf88969c0be778e81cc96fa6966387d728317fa",
|
|
8
8
|
"layout": {
|
|
9
9
|
"nav": "full",
|
|
10
10
|
"footer": "columns",
|
|
11
|
-
"announcementBanner":
|
|
11
|
+
"announcementBanner": false,
|
|
12
12
|
"home": "default"
|
|
13
13
|
},
|
|
14
14
|
"theme": {
|
|
@@ -222,13 +222,6 @@
|
|
|
222
222
|
"shell": "MarketingShell",
|
|
223
223
|
"chrome": "on",
|
|
224
224
|
"sections": [
|
|
225
|
-
{
|
|
226
|
-
"type": "hero",
|
|
227
|
-
"component": "Hero",
|
|
228
|
-
"options": {
|
|
229
|
-
"gapBelow": "tight"
|
|
230
|
-
}
|
|
231
|
-
},
|
|
232
225
|
{
|
|
233
226
|
"type": "pricing",
|
|
234
227
|
"component": "Pricing",
|
|
@@ -327,15 +320,8 @@
|
|
|
327
320
|
"chrome": "on",
|
|
328
321
|
"sections": [
|
|
329
322
|
{
|
|
330
|
-
"type": "
|
|
331
|
-
"component": "
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
"type": "items",
|
|
335
|
-
"component": "Items",
|
|
336
|
-
"options": {
|
|
337
|
-
"columns": 2
|
|
338
|
-
}
|
|
323
|
+
"type": "contact-form",
|
|
324
|
+
"component": "ContactForm"
|
|
339
325
|
}
|
|
340
326
|
]
|
|
341
327
|
},
|
|
@@ -366,15 +352,20 @@
|
|
|
366
352
|
"chrome": "on",
|
|
367
353
|
"sections": [
|
|
368
354
|
{
|
|
369
|
-
"type": "
|
|
370
|
-
"component": "
|
|
371
|
-
},
|
|
372
|
-
{
|
|
373
|
-
"type": "faq",
|
|
374
|
-
"component": "FAQ"
|
|
355
|
+
"type": "contact-form",
|
|
356
|
+
"component": "ContactForm"
|
|
375
357
|
}
|
|
376
358
|
]
|
|
377
359
|
},
|
|
360
|
+
{
|
|
361
|
+
"route": "/unsubscribe",
|
|
362
|
+
"kind": "route",
|
|
363
|
+
"pageType": null,
|
|
364
|
+
"schema": null,
|
|
365
|
+
"shell": "MarketingShell",
|
|
366
|
+
"chrome": "on",
|
|
367
|
+
"sections": []
|
|
368
|
+
},
|
|
378
369
|
{
|
|
379
370
|
"route": "/sign-in",
|
|
380
371
|
"kind": "route",
|
|
@@ -476,10 +467,6 @@
|
|
|
476
467
|
"gapBelow": "tight"
|
|
477
468
|
}
|
|
478
469
|
},
|
|
479
|
-
{
|
|
480
|
-
"type": "blog-list",
|
|
481
|
-
"component": "BlogList"
|
|
482
|
-
},
|
|
483
470
|
{
|
|
484
471
|
"type": "logoCloud",
|
|
485
472
|
"component": "LogoCloud",
|
|
@@ -526,17 +513,6 @@
|
|
|
526
513
|
"type": "hero",
|
|
527
514
|
"component": "Hero"
|
|
528
515
|
},
|
|
529
|
-
{
|
|
530
|
-
"type": "cta",
|
|
531
|
-
"component": "CTA"
|
|
532
|
-
},
|
|
533
|
-
{
|
|
534
|
-
"type": "items",
|
|
535
|
-
"component": "Items",
|
|
536
|
-
"options": {
|
|
537
|
-
"columns": 3
|
|
538
|
-
}
|
|
539
|
-
},
|
|
540
516
|
{
|
|
541
517
|
"type": "content-block",
|
|
542
518
|
"component": "ContentBlock"
|
|
@@ -34,7 +34,7 @@ The template's `layout` block — resolved with `resolveSiteChrome`, defaults fi
|
|
|
34
34
|
| -------------------- | --------- |
|
|
35
35
|
| `nav` | `full` |
|
|
36
36
|
| `footer` | `columns` |
|
|
37
|
-
| `announcementBanner` | `
|
|
37
|
+
| `announcementBanner` | `false` |
|
|
38
38
|
| `home` | `default` |
|
|
39
39
|
|
|
40
40
|
<!-- generated:end -->
|
|
@@ -154,14 +154,13 @@ Reference: `screenshots/pricing.png`, `copy/pricing.txt`. The reference opens on
|
|
|
154
154
|
|
|
155
155
|
<!-- generated:begin page=/pricing -->
|
|
156
156
|
|
|
157
|
-
| # | Section
|
|
158
|
-
| --- |
|
|
159
|
-
| 1 | `
|
|
160
|
-
| 2 | `
|
|
161
|
-
| 3 | `
|
|
162
|
-
| 4 | `
|
|
163
|
-
| 5 | `
|
|
164
|
-
| 6 | `faq` (accordion · items ×5 · 1 CTA · initialOpen none) | `FAQ` | {FAQs} |
|
|
157
|
+
| # | Section | Component | Copy (first line) |
|
|
158
|
+
| --- | -------------------------------------------------------------------------------------------------------- | -------------- | ----------------------------------------------------------------- |
|
|
159
|
+
| 1 | `pricing` (three-tiers-with-toggle · cardLayout=centered · eyebrow "Pricing" · plans ×3 · billingToggle) | `Pricing` | {Pays for itself in tangible value or outcome} |
|
|
160
|
+
| 2 | `logoCloud` (layout=inline · logos ×3) | `LogoCloud` | Don’t just take our word for it |
|
|
161
|
+
| 3 | `testimonials` (quote · items ×1) | `Testimonials` | {A customer quote, in their own words, about the result they got} |
|
|
162
|
+
| 4 | `cta` (box · checklist ×3 · 2 CTAs · closingLine) | `CTA` | {Switch to your product in time amount or less} |
|
|
163
|
+
| 5 | `faq` (accordion · items ×5 · 1 CTA · initialOpen none) | `FAQ` | FAQs |
|
|
165
164
|
|
|
166
165
|
<!-- generated:end -->
|
|
167
166
|
|
|
@@ -201,10 +200,9 @@ Reference: `screenshots/contact.png`, `copy/contact.txt`. The reference is a spl
|
|
|
201
200
|
|
|
202
201
|
<!-- generated:begin page=/contact -->
|
|
203
202
|
|
|
204
|
-
| # | Section
|
|
205
|
-
| --- |
|
|
206
|
-
| 1 | `
|
|
207
|
-
| 2 | `items` (tiles · columns=2 · items ×4) | `Items` | {Add appointment scheduling to your site} |
|
|
203
|
+
| # | Section | Component | Copy (first line) |
|
|
204
|
+
| --- | ----------------------------------- | ------------- | ----------------- |
|
|
205
|
+
| 1 | `contact-form` (column · fields ×0) | `ContactForm` | |
|
|
208
206
|
|
|
209
207
|
<!-- generated:end -->
|
|
210
208
|
|
|
@@ -227,13 +225,21 @@ A base-layer seed every starter carries (#6658 D5). The form posts to lead captu
|
|
|
227
225
|
|
|
228
226
|
<!-- generated:begin page=/newsletter -->
|
|
229
227
|
|
|
230
|
-
| # | Section
|
|
231
|
-
| --- |
|
|
232
|
-
| 1 | `
|
|
233
|
-
| 2 | `faq` (expanded · items ×3) | `FAQ` | FAQs |
|
|
228
|
+
| # | Section | Component | Copy (first line) |
|
|
229
|
+
| --- | ----------------------------------- | ------------- | ----------------- |
|
|
230
|
+
| 1 | `contact-form` (column · fields ×0) | `ContactForm` | |
|
|
234
231
|
|
|
235
232
|
<!-- generated:end -->
|
|
236
233
|
|
|
234
|
+
### `/unsubscribe` — code route (the unsubscribe landing) · chrome on
|
|
235
|
+
|
|
236
|
+
The landing every signed unsubscribe link calls (#8438 D17) — a code route like `/sign-in`, copied into every scaffold and never gated, listed so the manifest is a complete install record (#8850 D1). No reference page.
|
|
237
|
+
|
|
238
|
+
<!-- generated:begin page=/unsubscribe -->
|
|
239
|
+
|
|
240
|
+
_Code route — no content, no sections._
|
|
241
|
+
<!-- generated:end -->
|
|
242
|
+
|
|
237
243
|
### `/meet` — LandingPage · schema `WebPage` · chrome on
|
|
238
244
|
|
|
239
245
|
An always-copied overlay seed (#6897 D3): a meeting-types hub, served by the generic `[slug]` route, listing the four `/meet/<slug>` tiles below through the same `items` `tiles` variant Contact uses. A template carrying the scheduling module serves its own `meet/` route directory instead, by Next.js static-segment precedence.
|
|
@@ -253,12 +259,10 @@ Four always-copied overlay seeds (#6897 D4/D5), served by the new `[slug]/[detai
|
|
|
253
259
|
|
|
254
260
|
<!-- generated:begin page=/meet/[slug] -->
|
|
255
261
|
|
|
256
|
-
| # | Section | Component | Copy (first line)
|
|
257
|
-
| --- | -------------------------------------- | -------------- |
|
|
258
|
-
| 1 | `hero` (eyebrow "Book a Call" · 1 CTA) | `Hero` | Book a Call
|
|
259
|
-
| 2 | `
|
|
260
|
-
| 3 | `items` (columns=3 · items ×3) | `Items` | What happens on the call? |
|
|
261
|
-
| 4 | `content-block` (1 CTA) | `ContentBlock` | |
|
|
262
|
+
| # | Section | Component | Copy (first line) |
|
|
263
|
+
| --- | -------------------------------------- | -------------- | ----------------- |
|
|
264
|
+
| 1 | `hero` (eyebrow "Book a Call" · 1 CTA) | `Hero` | Book a Call |
|
|
265
|
+
| 2 | `content-block` (1 CTA) | `ContentBlock` | |
|
|
262
266
|
|
|
263
267
|
<!-- generated:end -->
|
|
264
268
|
|
|
@@ -268,12 +272,11 @@ Reference: `screenshots/blog.png`, `copy/blog.txt` for the opener and the newsle
|
|
|
268
272
|
|
|
269
273
|
<!-- generated:begin page=/blog -->
|
|
270
274
|
|
|
271
|
-
| # | Section
|
|
272
|
-
| --- |
|
|
273
|
-
| 1 | `hero` (centered · gapBelow=tight · eyebrow "Blog"
|
|
274
|
-
| 2 | `
|
|
275
|
-
| 3 | `
|
|
276
|
-
| 4 | `testimonials` (quote · items ×1) | `Testimonials` | {A customer quote, in their own words, about the result they got} |
|
|
275
|
+
| # | Section | Component | Copy (first line) |
|
|
276
|
+
| --- | --------------------------------------------------- | -------------- | ----------------------------------------------------------------- |
|
|
277
|
+
| 1 | `hero` (centered · gapBelow=tight · eyebrow "Blog") | `Hero` | {Blog} |
|
|
278
|
+
| 2 | `logoCloud` (layout=inline · logos ×6) | `LogoCloud` | Don’t just take our word for it |
|
|
279
|
+
| 3 | `testimonials` (quote · items ×1) | `Testimonials` | {A customer quote, in their own words, about the result they got} |
|
|
277
280
|
|
|
278
281
|
<!-- generated:end -->
|
|
279
282
|
|
|
@@ -442,6 +445,7 @@ marketing-site-free:
|
|
|
442
445
|
- { route: "/contact", kind: page, content: ["content/en/ContactPage/contact.mdx"] }
|
|
443
446
|
- { route: "/glossary", kind: page, content: ["content/en/GlossaryList/glossary.mdx"] }
|
|
444
447
|
- { route: "/newsletter", kind: page, content: ["content/en/NewsletterSignup/newsletter.mdx"] }
|
|
448
|
+
- { route: "/unsubscribe", kind: route }
|
|
445
449
|
- { route: "/sign-in", kind: route }
|
|
446
450
|
- { route: "/sign-up", kind: route }
|
|
447
451
|
- { route: "/privacy", kind: page, content: ["content/en/PrivacyPage/privacy.mdx"] }
|
|
@@ -505,11 +509,11 @@ reversed (`docs/decisions/starter-roster-page-set.md` D4, D7).
|
|
|
505
509
|
|
|
506
510
|
<!-- generated:begin inventory -->
|
|
507
511
|
|
|
508
|
-
| Tier | Used by this template
|
|
509
|
-
| -------- |
|
|
510
|
-
| Shell | `MarketingShell`
|
|
511
|
-
| Chrome | `Nav`, `Footer`, `Banner` (+ `BannerConsentIsland`, `BannerDismissIsland`)
|
|
512
|
-
| Sections | `
|
|
512
|
+
| Tier | Used by this template |
|
|
513
|
+
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
514
|
+
| Shell | `MarketingShell` |
|
|
515
|
+
| Chrome | `Nav`, `Footer`, `Banner` (+ `BannerConsentIsland`, `BannerDismissIsland`) |
|
|
516
|
+
| Sections | `ContactForm`, `ContentBlock`, `CTA`, `DecisionSplit`, `DocumentChassis`, `FAQ`, `Feature`, `GlossaryIndex`, `Hero`, `Items`, `LogoCloud`, `MediaBand`, `Pricing`, `Team`, `Testimonials` |
|
|
513
517
|
|
|
514
518
|
<!-- generated:end -->
|
|
515
519
|
|