create-agntcms-app 0.2.1
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 +39 -0
- package/dist/index.mjs +297 -0
- package/dist/template/.claude/settings.json +6 -0
- package/dist/template/.claude/skills/.gitkeep +0 -0
- package/dist/template/.claude-plugin/channel/server.mjs +254 -0
- package/dist/template/.claude-plugin/channel/server.ts +369 -0
- package/dist/template/.claude-plugin/plugin.json +17 -0
- package/dist/template/.mcp.json +8 -0
- package/dist/template/BRAND.md +49 -0
- package/dist/template/CLAUDE.md +157 -0
- package/dist/template/agntcms/config.ts +49 -0
- package/dist/template/agntcms/sections/ArticleBody/component.tsx +32 -0
- package/dist/template/agntcms/sections/ArticleBody/index.ts +10 -0
- package/dist/template/agntcms/sections/ArticleBody/schema.ts +5 -0
- package/dist/template/agntcms/sections/ArticleHero/component.tsx +87 -0
- package/dist/template/agntcms/sections/ArticleHero/index.ts +10 -0
- package/dist/template/agntcms/sections/ArticleHero/schema.ts +12 -0
- package/dist/template/agntcms/sections/Banner/component.tsx +83 -0
- package/dist/template/agntcms/sections/Banner/index.ts +10 -0
- package/dist/template/agntcms/sections/Banner/schema.ts +9 -0
- package/dist/template/agntcms/sections/BlogIndex/component.tsx +173 -0
- package/dist/template/agntcms/sections/BlogIndex/index.ts +10 -0
- package/dist/template/agntcms/sections/BlogIndex/schema.ts +33 -0
- package/dist/template/agntcms/sections/BlogIndexHeader/component.tsx +44 -0
- package/dist/template/agntcms/sections/BlogIndexHeader/index.ts +10 -0
- package/dist/template/agntcms/sections/BlogIndexHeader/schema.ts +8 -0
- package/dist/template/agntcms/sections/BlogPostBody/component.tsx +50 -0
- package/dist/template/agntcms/sections/BlogPostBody/index.ts +10 -0
- package/dist/template/agntcms/sections/BlogPostBody/schema.ts +10 -0
- package/dist/template/agntcms/sections/BlogPostHero/component.tsx +88 -0
- package/dist/template/agntcms/sections/BlogPostHero/index.ts +10 -0
- package/dist/template/agntcms/sections/BlogPostHero/schema.ts +35 -0
- package/dist/template/agntcms/sections/CaseStudies/component.tsx +92 -0
- package/dist/template/agntcms/sections/CaseStudies/index.ts +10 -0
- package/dist/template/agntcms/sections/CaseStudies/schema.ts +17 -0
- package/dist/template/agntcms/sections/ContactForm/component.tsx +119 -0
- package/dist/template/agntcms/sections/ContactForm/index.ts +10 -0
- package/dist/template/agntcms/sections/ContactForm/schema.ts +15 -0
- package/dist/template/agntcms/sections/DocsArticle/component.tsx +266 -0
- package/dist/template/agntcms/sections/DocsArticle/index.ts +10 -0
- package/dist/template/agntcms/sections/DocsArticle/schema.ts +33 -0
- package/dist/template/agntcms/sections/FAQ/component.tsx +57 -0
- package/dist/template/agntcms/sections/FAQ/index.ts +10 -0
- package/dist/template/agntcms/sections/FAQ/schema.ts +11 -0
- package/dist/template/agntcms/sections/FeatureGrid/component.tsx +117 -0
- package/dist/template/agntcms/sections/FeatureGrid/index.ts +10 -0
- package/dist/template/agntcms/sections/FeatureGrid/schema.ts +21 -0
- package/dist/template/agntcms/sections/FeaturedArticles/component.tsx +99 -0
- package/dist/template/agntcms/sections/FeaturedArticles/index.ts +10 -0
- package/dist/template/agntcms/sections/FeaturedArticles/schema.ts +17 -0
- package/dist/template/agntcms/sections/GettingStarted/component.tsx +116 -0
- package/dist/template/agntcms/sections/GettingStarted/index.ts +10 -0
- package/dist/template/agntcms/sections/GettingStarted/schema.ts +11 -0
- package/dist/template/agntcms/sections/Hero/component.tsx +148 -0
- package/dist/template/agntcms/sections/Hero/index.ts +10 -0
- package/dist/template/agntcms/sections/Hero/schema.ts +16 -0
- package/dist/template/agntcms/sections/HowItWorks/component.tsx +57 -0
- package/dist/template/agntcms/sections/HowItWorks/index.ts +10 -0
- package/dist/template/agntcms/sections/HowItWorks/schema.ts +11 -0
- package/dist/template/agntcms/sections/ImageText/component.tsx +110 -0
- package/dist/template/agntcms/sections/ImageText/index.ts +10 -0
- package/dist/template/agntcms/sections/ImageText/schema.ts +14 -0
- package/dist/template/agntcms/sections/LogoStrip/component.tsx +37 -0
- package/dist/template/agntcms/sections/LogoStrip/index.ts +10 -0
- package/dist/template/agntcms/sections/LogoStrip/schema.ts +6 -0
- package/dist/template/agntcms/sections/Newsletter/component.tsx +48 -0
- package/dist/template/agntcms/sections/Newsletter/index.ts +10 -0
- package/dist/template/agntcms/sections/Newsletter/schema.ts +8 -0
- package/dist/template/agntcms/sections/OpenSource/component.tsx +99 -0
- package/dist/template/agntcms/sections/OpenSource/index.ts +10 -0
- package/dist/template/agntcms/sections/OpenSource/schema.ts +13 -0
- package/dist/template/agntcms/sections/PainAnswer/component.tsx +81 -0
- package/dist/template/agntcms/sections/PainAnswer/index.ts +10 -0
- package/dist/template/agntcms/sections/PainAnswer/schema.ts +15 -0
- package/dist/template/agntcms/sections/PricingPlans/component.tsx +100 -0
- package/dist/template/agntcms/sections/PricingPlans/index.ts +10 -0
- package/dist/template/agntcms/sections/PricingPlans/schema.ts +13 -0
- package/dist/template/agntcms/sections/Problem/component.tsx +49 -0
- package/dist/template/agntcms/sections/Problem/index.ts +10 -0
- package/dist/template/agntcms/sections/Problem/schema.ts +12 -0
- package/dist/template/agntcms/sections/SiteFooter/component.tsx +88 -0
- package/dist/template/agntcms/sections/SiteFooter/index.ts +10 -0
- package/dist/template/agntcms/sections/SiteFooter/schema.ts +13 -0
- package/dist/template/agntcms/sections/SiteHeader/component.tsx +99 -0
- package/dist/template/agntcms/sections/SiteHeader/index.ts +10 -0
- package/dist/template/agntcms/sections/SiteHeader/schema.ts +14 -0
- package/dist/template/agntcms/sections/SiteMeta/component.tsx +26 -0
- package/dist/template/agntcms/sections/SiteMeta/index.ts +13 -0
- package/dist/template/agntcms/sections/SiteMeta/schema.ts +18 -0
- package/dist/template/agntcms/sections/TabbedFeatures/component.tsx +120 -0
- package/dist/template/agntcms/sections/TabbedFeatures/index.ts +10 -0
- package/dist/template/agntcms/sections/TabbedFeatures/schema.ts +13 -0
- package/dist/template/agntcms/sections/TeamGrid/component.tsx +77 -0
- package/dist/template/agntcms/sections/TeamGrid/index.ts +10 -0
- package/dist/template/agntcms/sections/TeamGrid/schema.ts +14 -0
- package/dist/template/agntcms/sections/Testimonials/component.tsx +76 -0
- package/dist/template/agntcms/sections/Testimonials/index.ts +10 -0
- package/dist/template/agntcms/sections/Testimonials/schema.ts +12 -0
- package/dist/template/agntcms/sections/WhatIsBuilt/component.tsx +86 -0
- package/dist/template/agntcms/sections/WhatIsBuilt/index.ts +10 -0
- package/dist/template/agntcms/sections/WhatIsBuilt/schema.ts +20 -0
- package/dist/template/agntcms/site-meta.ts +81 -0
- package/dist/template/app/[[...slug]]/page.tsx +123 -0
- package/dist/template/app/admin/AdminPageClient.tsx +77 -0
- package/dist/template/app/admin/AdminPageDynamic.tsx +24 -0
- package/dist/template/app/admin/page.tsx +14 -0
- package/dist/template/app/api/agntcms/_shared.ts +80 -0
- package/dist/template/app/api/agntcms/assets/route.ts +11 -0
- package/dist/template/app/api/agntcms/assets/upload/route.ts +11 -0
- package/dist/template/app/api/agntcms/draft/discard/route.ts +12 -0
- package/dist/template/app/api/agntcms/draft/list/route.ts +11 -0
- package/dist/template/app/api/agntcms/draft/publish/route.ts +11 -0
- package/dist/template/app/api/agntcms/draft/reorder/route.ts +10 -0
- package/dist/template/app/api/agntcms/draft/save/route.ts +11 -0
- package/dist/template/app/api/agntcms/events/route.ts +12 -0
- package/dist/template/app/api/agntcms/forms/delete/route.ts +17 -0
- package/dist/template/app/api/agntcms/forms/list/route.ts +24 -0
- package/dist/template/app/api/agntcms/forms/read/route.ts +23 -0
- package/dist/template/app/api/agntcms/forms/submit/route.ts +17 -0
- package/dist/template/app/api/agntcms/global/delete/route.ts +13 -0
- package/dist/template/app/api/agntcms/global/history/route.ts +10 -0
- package/dist/template/app/api/agntcms/global/list/route.ts +14 -0
- package/dist/template/app/api/agntcms/global/read/route.ts +11 -0
- package/dist/template/app/api/agntcms/global/rollback/route.ts +10 -0
- package/dist/template/app/api/agntcms/global/save/route.ts +14 -0
- package/dist/template/app/api/agntcms/mcp/route.ts +12 -0
- package/dist/template/app/api/agntcms/page/delete/route.ts +10 -0
- package/dist/template/app/api/agntcms/page/duplicate/route.ts +11 -0
- package/dist/template/app/api/agntcms/page/history/route.ts +10 -0
- package/dist/template/app/api/agntcms/page/list/route.ts +10 -0
- package/dist/template/app/api/agntcms/page/read/route.ts +11 -0
- package/dist/template/app/api/agntcms/page/rename/route.ts +10 -0
- package/dist/template/app/api/agntcms/page/rollback/route.ts +10 -0
- package/dist/template/app/api/agntcms/page/unpublish/route.ts +11 -0
- package/dist/template/app/api/agntcms/preview/enter/route.ts +13 -0
- package/dist/template/app/api/agntcms/preview/exit/route.ts +10 -0
- package/dist/template/app/api/agntcms/preview/issue/route.ts +12 -0
- package/dist/template/app/api/agntcms/template/list/route.ts +15 -0
- package/dist/template/app/apple-icon.svg +9 -0
- package/dist/template/app/icon.svg +9 -0
- package/dist/template/app/layout.tsx +107 -0
- package/dist/template/app/not-found.tsx +75 -0
- package/dist/template/app/robots.ts +33 -0
- package/dist/template/app/sitemap.ts +49 -0
- package/dist/template/content/globals/site-footer.json +53 -0
- package/dist/template/content/globals/site-header.json +18 -0
- package/dist/template/content/globals/site-meta.json +13 -0
- package/dist/template/content/pages/404.json +34 -0
- package/dist/template/content/pages/about.json +307 -0
- package/dist/template/content/pages/article-editor.json +61 -0
- package/dist/template/content/pages/article-schemas.json +61 -0
- package/dist/template/content/pages/blog.json +162 -0
- package/dist/template/content/pages/contact.json +29 -0
- package/dist/template/content/pages/home.json +243 -0
- package/dist/template/content/pages/pricing.json +219 -0
- package/dist/template/content/pages/services.json +177 -0
- package/dist/template/fonts/Satoshi-Medium.woff2 +0 -0
- package/dist/template/fonts/Satoshi-Regular.woff2 +0 -0
- package/dist/template/next.config.ts +6 -0
- package/dist/template/package.json +36 -0
- package/dist/template/postcss.config.mjs +5 -0
- package/dist/template/public/assets/.gitkeep +0 -0
- package/dist/template/public/assets/0418d7ed21f57e7b9e0546725c92b8419daeaa355675d9070fab0c2013cf1524.jpg +0 -0
- package/dist/template/public/assets/0d0475f21aa96435a8ed3cdb2fddcc6278492e76ae842f569432454f4d33631a.jpg +0 -0
- package/dist/template/public/assets/27457a1adee2372030d9876b0d52c44d46be98843999935eaef2526b9b961f12.jpg +0 -0
- package/dist/template/public/assets/3855d91192f0c6120b01427b78ef84e52baa9f4b5a17d4271e41c1bfd95a5b0c.jpg +0 -0
- package/dist/template/public/assets/3b3b90c5084635b746be673ede92a328f002f5621a42c9a5cb89c5e2435652cb.jpg +0 -0
- package/dist/template/public/assets/3e76165a78fd3e7b8ed1e93dee50803ae11110c756c8c1c89229a2dec2bc0abf.jpg +0 -0
- package/dist/template/public/assets/4a3e28f85dc850c347ea0fd931696aa936a6bd45f193e7f1c9328b5896fb272c.jpg +0 -0
- package/dist/template/public/assets/579f67d5fd4c9106c6cdf2ef29f50df934ad0fc2b7849bac1e1cfb1e3f92303b.jpg +0 -0
- package/dist/template/public/assets/5b95209269661bb60fb250f1da682e05b9efa64dd42f350608b299e6bf1f2f35.jpg +0 -0
- package/dist/template/public/assets/5e04b46f8317ef95a7ddf85aedfe5c098a755f05056325d0251eccf95ce51172.jpg +0 -0
- package/dist/template/public/assets/6167a9164be2cf1183bdfdd4946bf9b908570e79e92a2380c25f0bb702422bbd.jpg +0 -0
- package/dist/template/public/assets/75e723ec316de28247924e5dfb73a4b266e10de605e749f150883d280ed8ed16.jpg +0 -0
- package/dist/template/public/assets/816a11e6a7245feaf51bbebf09d1bda3f125b334bc24fc3b8f47b5380a7b4294.jpg +0 -0
- package/dist/template/public/assets/81eba6f5654b8746a9b0cba1a9521a67f2b4afaaefc7c88d66dfab1461270d8f.jpg +0 -0
- package/dist/template/public/assets/82a2ce9e49361098f77a28755779dc5a7c026831cbd135175749c1304e21dacc.jpg +0 -0
- package/dist/template/public/assets/8d7b02ba277ba56bdafdbd47b01f7df6d993c714b4dc2305eb65a1307c09647d.jpg +0 -0
- package/dist/template/public/assets/b303185b471678e4d62f678a1549ee26022f4745407d08cae44ecb1c25352293.jpg +0 -0
- package/dist/template/public/assets/b69b49169c11546100d6dd5280073bc0d84cbbcc6d33fa01ecf6a5866fa42237.jpg +0 -0
- package/dist/template/public/assets/c4d2f0d1a310e457ac722a399693652e3c86c55b294243d5ffc679394e12f9d1.jpg +0 -0
- package/dist/template/public/assets/cae09f4729f8a348b67267c2f2a550be0f3bfa420689afe1a5cf8b7e2b146238.png +0 -0
- package/dist/template/public/assets/cb3acf58b57417a4b26474ba04c096af7103c4320ed2f4f3683f79d7670a055c.jpg +0 -0
- package/dist/template/public/assets/d5a0701b2d156284e0ce851cd2534ec632db34f91fbcbee3b8a7784d45ce78d2.jpg +0 -0
- package/dist/template/public/assets/d6ef1c3f48b0e488521794fb60701da1fd2c3a1621d6ac5f17ccfd4909d3be60.jpg +0 -0
- package/dist/template/public/assets/de249ff9be2539cf0d1ce092de3c57001839b6c3e14fcee3fc31a7b7673ae007.jpg +0 -0
- package/dist/template/public/assets/eac45438956be187b010e24b3289757aa00f227c190d49ee99fea510552dd2ba.jpg +0 -0
- package/dist/template/public/assets/f8b9200065b5436c6a88361839edc2b89be88d3037c84a80d3ee95c32891510b.jpg +0 -0
- package/dist/template/public/assets/placeholder.png +0 -0
- package/dist/template/public/brand/mark.svg +6 -0
- package/dist/template/public/brand/wordmark-light.svg +6 -0
- package/dist/template/public/brand/wordmark.svg +6 -0
- package/dist/template/styles/globals.css +69 -0
- package/dist/template/styles/theme.css +492 -0
- package/dist/template/styles/typography.css +469 -0
- package/dist/template/tsconfig.json +30 -0
- package/package.json +30 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineSection } from '@agntcms/next'
|
|
2
|
+
import { schema } from './schema'
|
|
3
|
+
import { DocsArticleComponent } from './component'
|
|
4
|
+
|
|
5
|
+
export const DocsArticle = defineSection({
|
|
6
|
+
name: 'DocsArticle',
|
|
7
|
+
category: 'Docs',
|
|
8
|
+
schema,
|
|
9
|
+
component: DocsArticleComponent,
|
|
10
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { LinkField, ListField } from '@agntcms/next'
|
|
2
|
+
|
|
3
|
+
export const schema = {
|
|
4
|
+
// Sidebar nav: groups of links shared across all docs pages.
|
|
5
|
+
sidebar: ListField({
|
|
6
|
+
title: { kind: 'richText' as const, default: 'Getting started' },
|
|
7
|
+
items: ListField({
|
|
8
|
+
label: { kind: 'richText' as const, default: 'Quick start' },
|
|
9
|
+
href: { kind: 'text' as const, default: '/docs/quick-start' },
|
|
10
|
+
active: { kind: 'boolean' as const, default: false },
|
|
11
|
+
}),
|
|
12
|
+
}),
|
|
13
|
+
|
|
14
|
+
// Page header.
|
|
15
|
+
eyebrow: { kind: 'richText' as const, default: 'Getting started' },
|
|
16
|
+
title: { kind: 'richText' as const, default: '# Quick start' },
|
|
17
|
+
lead: {
|
|
18
|
+
kind: 'richText' as const,
|
|
19
|
+
default: 'Spin up an agntcms project and ship your first page in under five minutes.',
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
// Main article — markdown. Headings (##, ###) become anchored sections;
|
|
23
|
+
// the right-hand TOC is built from them at runtime.
|
|
24
|
+
body: {
|
|
25
|
+
kind: 'richText' as const,
|
|
26
|
+
default:
|
|
27
|
+
'## Install\n\nRun the create command in an empty directory:\n\n```bash\nnpx create-agntcms@latest\n```\n',
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
// Bottom prev/next links.
|
|
31
|
+
prev: LinkField,
|
|
32
|
+
next: LinkField,
|
|
33
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { EditableRichText, EditableList } from '@agntcms/next/client'
|
|
4
|
+
import type { EditableSlot, SlotItem } from '@agntcms/next/client'
|
|
5
|
+
import { schema } from './schema'
|
|
6
|
+
|
|
7
|
+
type FaqItem = SlotItem<typeof schema.entries.itemSchema>
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
readonly eyebrow: EditableSlot<'richText', string>
|
|
11
|
+
readonly headline: EditableSlot<'richText', string>
|
|
12
|
+
readonly lead: EditableSlot<'richText', string>
|
|
13
|
+
readonly entries: EditableSlot<'list', ReadonlyArray<FaqItem>>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function FAQComponent({ eyebrow, headline, lead, entries }: Props) {
|
|
17
|
+
return (
|
|
18
|
+
<section className="bg-paper">
|
|
19
|
+
<div className="mx-auto w-full max-w-[720px] px-8 py-[88px]">
|
|
20
|
+
<EditableRichText
|
|
21
|
+
field={eyebrow}
|
|
22
|
+
className="[&_p]:font-mono [&_p]:font-medium [&_p]:text-[12px] [&_p]:tracking-[0.07em] [&_p]:uppercase [&_p]:text-ink-3 [&_p]:m-0"
|
|
23
|
+
/>
|
|
24
|
+
<div className="mt-3 [&_h2]:m-0 [&_h2]:font-display [&_h2]:font-semibold [&_h2]:text-ink [&_h2]:text-[44px] [&_h2]:leading-[1.05] [&_h2]:tracking-[-0.03em] [&_p]:m-0 [&_p]:font-display [&_p]:font-semibold [&_p]:text-ink [&_p]:text-[44px] [&_p]:leading-[1.05] [&_p]:tracking-[-0.03em] [&_em]:not-italic [&_em]:text-ink-3 [&_em]:font-semibold">
|
|
25
|
+
<EditableRichText field={headline} />
|
|
26
|
+
</div>
|
|
27
|
+
<EditableRichText
|
|
28
|
+
field={lead}
|
|
29
|
+
className="mt-4 [&_p]:text-[18px] [&_p]:leading-[1.55] [&_p]:text-ink-2 [&_p]:m-0"
|
|
30
|
+
/>
|
|
31
|
+
<EditableList
|
|
32
|
+
field={entries}
|
|
33
|
+
itemSchema={schema.entries.itemSchema}
|
|
34
|
+
className="mt-8 border-t border-hairline"
|
|
35
|
+
renderItem={(q) => (
|
|
36
|
+
<details className="group border-b border-hairline py-5">
|
|
37
|
+
<summary className="flex cursor-pointer list-none items-center justify-between gap-4">
|
|
38
|
+
<EditableRichText
|
|
39
|
+
field={q.question}
|
|
40
|
+
as="span"
|
|
41
|
+
className="[&_p]:m-0 [&_p]:text-[17px] [&_p]:font-medium [&_p]:tracking-[-0.01em] [&_p]:text-ink"
|
|
42
|
+
/>
|
|
43
|
+
<span className="font-mono text-ink-3 group-open:rotate-45 transition-transform">
|
|
44
|
+
+
|
|
45
|
+
</span>
|
|
46
|
+
</summary>
|
|
47
|
+
<EditableRichText
|
|
48
|
+
field={q.answer}
|
|
49
|
+
className="mt-3 max-w-[620px] [&_p]:m-0 [&_p]:text-[15.5px] [&_p]:leading-[1.6] [&_p]:text-ink-3 [&_p+p]:mt-3"
|
|
50
|
+
/>
|
|
51
|
+
</details>
|
|
52
|
+
)}
|
|
53
|
+
/>
|
|
54
|
+
</div>
|
|
55
|
+
</section>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
EditableRichText,
|
|
5
|
+
EditableText,
|
|
6
|
+
EditableLink,
|
|
7
|
+
EditableList,
|
|
8
|
+
read,
|
|
9
|
+
isSlotInPreview,
|
|
10
|
+
} from '@agntcms/next/client'
|
|
11
|
+
import type { EditableSlot, SlotItem } from '@agntcms/next/client'
|
|
12
|
+
import { hrefOf, isExternalLink } from '@agntcms/next'
|
|
13
|
+
import type { LinkValue } from '@agntcms/next'
|
|
14
|
+
import { schema } from './schema'
|
|
15
|
+
|
|
16
|
+
type Card = SlotItem<typeof schema.cards.itemSchema>
|
|
17
|
+
|
|
18
|
+
interface Props {
|
|
19
|
+
readonly eyebrow: EditableSlot<'richText', string>
|
|
20
|
+
readonly headline: EditableSlot<'richText', string>
|
|
21
|
+
readonly lead: EditableSlot<'richText', string>
|
|
22
|
+
readonly columns: EditableSlot<'text', string>
|
|
23
|
+
readonly variant: EditableSlot<'text', string>
|
|
24
|
+
readonly cards: EditableSlot<'list', ReadonlyArray<Card>>
|
|
25
|
+
readonly footerCta: EditableSlot<'link', LinkValue>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function FeatureGridComponent({
|
|
29
|
+
eyebrow,
|
|
30
|
+
headline,
|
|
31
|
+
lead,
|
|
32
|
+
columns,
|
|
33
|
+
variant,
|
|
34
|
+
cards,
|
|
35
|
+
footerCta,
|
|
36
|
+
}: Props) {
|
|
37
|
+
const cols = read(columns) === '4' ? 4 : 3
|
|
38
|
+
const kind = read(variant) || 'icon'
|
|
39
|
+
const colClass = cols === 4 ? 'lg:grid-cols-4' : 'lg:grid-cols-3'
|
|
40
|
+
const cta = read(footerCta)
|
|
41
|
+
const ctaHref = hrefOf(cta)
|
|
42
|
+
const showCta = Boolean(ctaHref) || isSlotInPreview(footerCta)
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<section className="bg-paper">
|
|
46
|
+
<div className="mx-auto w-full max-w-[1280px] px-8 py-24">
|
|
47
|
+
<div className="max-w-[720px]">
|
|
48
|
+
<EditableRichText
|
|
49
|
+
field={eyebrow}
|
|
50
|
+
className="[&_p]:font-mono [&_p]:font-medium [&_p]:text-[12px] [&_p]:tracking-[0.07em] [&_p]:uppercase [&_p]:text-ink-3 [&_p]:m-0"
|
|
51
|
+
/>
|
|
52
|
+
<div className="mt-3 [&_h2]:m-0 [&_h2]:font-display [&_h2]:font-semibold [&_h2]:text-ink [&_h2]:text-[44px] [&_h2]:leading-[1.05] [&_h2]:tracking-[-0.03em] [&_p]:m-0 [&_p]:font-display [&_p]:font-semibold [&_p]:text-ink [&_p]:text-[44px] [&_p]:leading-[1.05] [&_p]:tracking-[-0.03em] [&_em]:not-italic [&_em]:text-ink-3 [&_em]:font-semibold">
|
|
53
|
+
<EditableRichText field={headline} />
|
|
54
|
+
</div>
|
|
55
|
+
<EditableRichText
|
|
56
|
+
field={lead}
|
|
57
|
+
className="mt-4 max-w-[580px] [&_p]:text-[18px] [&_p]:leading-[1.55] [&_p]:text-ink-2 [&_p]:m-0"
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<EditableList
|
|
62
|
+
field={cards}
|
|
63
|
+
itemSchema={schema.cards.itemSchema}
|
|
64
|
+
className={`mt-14 grid grid-cols-1 ${colClass}`}
|
|
65
|
+
renderItem={(card) => (
|
|
66
|
+
<div className="flex h-full flex-col gap-3 border border-hairline -ml-px -mt-px p-7">
|
|
67
|
+
{kind === 'icon' ? (
|
|
68
|
+
<div
|
|
69
|
+
className="h-9 w-9 text-ink-2 [&_svg]:h-[22px] [&_svg]:w-[22px]"
|
|
70
|
+
dangerouslySetInnerHTML={{ __html: read(card.iconSvg) || '' }}
|
|
71
|
+
/>
|
|
72
|
+
) : null}
|
|
73
|
+
{kind === 'stat' ? (
|
|
74
|
+
<EditableText
|
|
75
|
+
field={card.stat}
|
|
76
|
+
as="div"
|
|
77
|
+
className="font-display text-[48px] font-semibold leading-none tracking-[-0.03em] text-ink"
|
|
78
|
+
/>
|
|
79
|
+
) : null}
|
|
80
|
+
{kind === 'step' ? (
|
|
81
|
+
<EditableText
|
|
82
|
+
field={card.stat}
|
|
83
|
+
as="div"
|
|
84
|
+
className="font-mono text-[12px] font-medium tracking-[0.07em] uppercase text-ink-3"
|
|
85
|
+
/>
|
|
86
|
+
) : null}
|
|
87
|
+
<EditableText
|
|
88
|
+
field={card.label}
|
|
89
|
+
as="h4"
|
|
90
|
+
className="m-0 text-[19px] font-semibold tracking-[-0.015em] text-ink"
|
|
91
|
+
/>
|
|
92
|
+
<EditableRichText
|
|
93
|
+
field={card.body}
|
|
94
|
+
className="[&_p]:m-0 [&_p]:text-[14.5px] [&_p]:leading-[1.6] [&_p]:text-ink-3 [&_p+p]:mt-2"
|
|
95
|
+
/>
|
|
96
|
+
</div>
|
|
97
|
+
)}
|
|
98
|
+
/>
|
|
99
|
+
|
|
100
|
+
{showCta && (
|
|
101
|
+
<div className="mt-10 text-center">
|
|
102
|
+
<a
|
|
103
|
+
href={ctaHref || '#'}
|
|
104
|
+
target={isExternalLink(cta) ? '_blank' : undefined}
|
|
105
|
+
rel={isExternalLink(cta) ? 'noreferrer' : undefined}
|
|
106
|
+
>
|
|
107
|
+
<EditableLink
|
|
108
|
+
field={footerCta}
|
|
109
|
+
className="inline-flex items-center gap-2 rounded-sm border border-hairline-2 bg-transparent px-[22px] py-[13px] text-[15px] font-medium text-ink no-underline hover:border-ink"
|
|
110
|
+
/>
|
|
111
|
+
</a>
|
|
112
|
+
</div>
|
|
113
|
+
)}
|
|
114
|
+
</div>
|
|
115
|
+
</section>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineSection } from '@agntcms/next'
|
|
2
|
+
import { schema } from './schema'
|
|
3
|
+
import { FeatureGridComponent } from './component'
|
|
4
|
+
|
|
5
|
+
export const FeatureGrid = defineSection({
|
|
6
|
+
name: 'FeatureGrid',
|
|
7
|
+
category: 'Features',
|
|
8
|
+
schema,
|
|
9
|
+
component: FeatureGridComponent,
|
|
10
|
+
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { RichTextField, TextField, LinkField, ListField } from '@agntcms/next'
|
|
2
|
+
|
|
3
|
+
export const schema = {
|
|
4
|
+
eyebrow: RichTextField,
|
|
5
|
+
headline: RichTextField,
|
|
6
|
+
lead: RichTextField,
|
|
7
|
+
// "3" | "4"
|
|
8
|
+
columns: TextField,
|
|
9
|
+
// "icon" | "stat" | "step" — controls visual emphasis of each card
|
|
10
|
+
variant: TextField,
|
|
11
|
+
cards: ListField({
|
|
12
|
+
// Inline SVG markup as a raw string. Not inline-editable; intended to be
|
|
13
|
+
// populated from a curated icon set. Rendered via dangerouslySetInnerHTML
|
|
14
|
+
// so currentColor and stroke utilities work.
|
|
15
|
+
iconSvg: TextField,
|
|
16
|
+
stat: TextField,
|
|
17
|
+
label: TextField,
|
|
18
|
+
body: RichTextField,
|
|
19
|
+
}),
|
|
20
|
+
footerCta: LinkField,
|
|
21
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
EditableRichText,
|
|
5
|
+
EditableText,
|
|
6
|
+
EditableImage,
|
|
7
|
+
EditableList,
|
|
8
|
+
read,
|
|
9
|
+
} from '@agntcms/next/client'
|
|
10
|
+
import type { EditableSlot, SlotItem } from '@agntcms/next/client'
|
|
11
|
+
import { hrefOf, isExternalLink } from '@agntcms/next'
|
|
12
|
+
import { schema } from './schema'
|
|
13
|
+
|
|
14
|
+
type Article = SlotItem<typeof schema.articles.itemSchema>
|
|
15
|
+
|
|
16
|
+
interface Props {
|
|
17
|
+
readonly eyebrow: EditableSlot<'richText', string>
|
|
18
|
+
readonly headline: EditableSlot<'richText', string>
|
|
19
|
+
readonly lead: EditableSlot<'richText', string>
|
|
20
|
+
readonly columns: EditableSlot<'text', string>
|
|
21
|
+
readonly articles: EditableSlot<'list', ReadonlyArray<Article>>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function FeaturedArticlesComponent({
|
|
25
|
+
eyebrow,
|
|
26
|
+
headline,
|
|
27
|
+
lead,
|
|
28
|
+
columns,
|
|
29
|
+
articles,
|
|
30
|
+
}: Props) {
|
|
31
|
+
const cols = read(columns) === '4' ? 4 : 3
|
|
32
|
+
const colClass = cols === 4 ? 'lg:grid-cols-4' : 'lg:grid-cols-3'
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<section className="bg-paper">
|
|
36
|
+
<div className="mx-auto w-full max-w-[1280px] px-8 py-[88px]">
|
|
37
|
+
<div className="max-w-[720px]">
|
|
38
|
+
<EditableRichText
|
|
39
|
+
field={eyebrow}
|
|
40
|
+
className="[&_p]:font-mono [&_p]:font-medium [&_p]:text-[12px] [&_p]:tracking-[0.07em] [&_p]:uppercase [&_p]:text-ink-3 [&_p]:m-0"
|
|
41
|
+
/>
|
|
42
|
+
<div className="mt-3 [&_h2]:m-0 [&_h2]:font-display [&_h2]:font-semibold [&_h2]:text-ink [&_h2]:text-[44px] [&_h2]:leading-[1.05] [&_h2]:tracking-[-0.03em] [&_p]:m-0 [&_p]:font-display [&_p]:font-semibold [&_p]:text-ink [&_p]:text-[44px] [&_p]:leading-[1.05] [&_p]:tracking-[-0.03em] [&_em]:not-italic [&_em]:text-ink-3 [&_em]:font-semibold">
|
|
43
|
+
<EditableRichText field={headline} />
|
|
44
|
+
</div>
|
|
45
|
+
<EditableRichText
|
|
46
|
+
field={lead}
|
|
47
|
+
className="mt-4 max-w-[580px] [&_p]:text-[18px] [&_p]:leading-[1.55] [&_p]:text-ink-2 [&_p]:m-0"
|
|
48
|
+
/>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<EditableList
|
|
52
|
+
field={articles}
|
|
53
|
+
itemSchema={schema.articles.itemSchema}
|
|
54
|
+
className={`mt-12 grid grid-cols-1 border-t border-hairline ${colClass}`}
|
|
55
|
+
renderItem={(a) => {
|
|
56
|
+
const link = read(a.link)
|
|
57
|
+
const href = hrefOf(link) || '#'
|
|
58
|
+
return (
|
|
59
|
+
<a
|
|
60
|
+
href={href}
|
|
61
|
+
target={isExternalLink(link) ? '_blank' : undefined}
|
|
62
|
+
rel={isExternalLink(link) ? 'noreferrer' : undefined}
|
|
63
|
+
className="block border-b border-r border-hairline -mr-px last:mr-0"
|
|
64
|
+
>
|
|
65
|
+
<div className="aspect-[3/2] overflow-hidden border-b border-hairline bg-paper-2">
|
|
66
|
+
<EditableImage
|
|
67
|
+
field={a.image}
|
|
68
|
+
className="!block h-full w-full object-cover [&_img]:h-full [&_img]:w-full [&_img]:object-cover"
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
<div className="p-6">
|
|
72
|
+
<EditableText
|
|
73
|
+
field={a.category}
|
|
74
|
+
as="span"
|
|
75
|
+
className="font-mono text-[11px] font-medium tracking-[0.07em] uppercase text-ink-3"
|
|
76
|
+
/>
|
|
77
|
+
<EditableText
|
|
78
|
+
field={a.title}
|
|
79
|
+
as="h4"
|
|
80
|
+
className="mt-2.5 mb-2 text-[19px] font-semibold leading-[1.3] tracking-[-0.015em] text-ink"
|
|
81
|
+
/>
|
|
82
|
+
<EditableRichText
|
|
83
|
+
field={a.excerpt}
|
|
84
|
+
className="[&_p]:m-0 [&_p]:text-[14px] [&_p]:leading-[1.55] [&_p]:text-ink-3"
|
|
85
|
+
/>
|
|
86
|
+
<EditableText
|
|
87
|
+
field={a.meta}
|
|
88
|
+
as="div"
|
|
89
|
+
className="mt-3.5 font-mono text-[11px] tracking-[0.07em] uppercase text-ink-3"
|
|
90
|
+
/>
|
|
91
|
+
</div>
|
|
92
|
+
</a>
|
|
93
|
+
)
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
</div>
|
|
97
|
+
</section>
|
|
98
|
+
)
|
|
99
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineSection } from '@agntcms/next'
|
|
2
|
+
import { schema } from './schema'
|
|
3
|
+
import { FeaturedArticlesComponent } from './component'
|
|
4
|
+
|
|
5
|
+
export const FeaturedArticles = defineSection({
|
|
6
|
+
name: 'FeaturedArticles',
|
|
7
|
+
category: 'Blog',
|
|
8
|
+
schema,
|
|
9
|
+
component: FeaturedArticlesComponent,
|
|
10
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RichTextField, TextField, LinkField, ImageField, ListField } from '@agntcms/next'
|
|
2
|
+
|
|
3
|
+
export const schema = {
|
|
4
|
+
eyebrow: RichTextField,
|
|
5
|
+
headline: RichTextField,
|
|
6
|
+
lead: RichTextField,
|
|
7
|
+
// "3" | "4"
|
|
8
|
+
columns: TextField,
|
|
9
|
+
articles: ListField({
|
|
10
|
+
image: ImageField,
|
|
11
|
+
category: TextField,
|
|
12
|
+
title: TextField,
|
|
13
|
+
excerpt: RichTextField,
|
|
14
|
+
meta: TextField,
|
|
15
|
+
link: LinkField,
|
|
16
|
+
}),
|
|
17
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useState } from 'react'
|
|
4
|
+
import { EditableLink, EditableRichText, read } from '@agntcms/next/client'
|
|
5
|
+
import type { EditableSlot } from '@agntcms/next/client'
|
|
6
|
+
import { hrefOf, isExternalLink } from '@agntcms/next'
|
|
7
|
+
import type { LinkValue } from '@agntcms/next'
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
readonly eyebrow: EditableSlot<'richText', string>
|
|
11
|
+
readonly headline: EditableSlot<'richText', string>
|
|
12
|
+
readonly intro: EditableSlot<'richText', string>
|
|
13
|
+
readonly command: EditableSlot<'richText', string>
|
|
14
|
+
readonly meta: EditableSlot<'richText', string>
|
|
15
|
+
readonly primaryCta: EditableSlot<'link', LinkValue>
|
|
16
|
+
readonly secondaryCta: EditableSlot<'link', LinkValue>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function GettingStartedComponent({ eyebrow, headline, intro, command, meta, primaryCta: rawPrimary, secondaryCta: rawSecondary }: Props) {
|
|
20
|
+
const primaryCta = read(rawPrimary)
|
|
21
|
+
const secondaryCta = read(rawSecondary)
|
|
22
|
+
const [copied, setCopied] = useState(false)
|
|
23
|
+
const handleCopy = async () => {
|
|
24
|
+
try {
|
|
25
|
+
await navigator.clipboard.writeText(read(command))
|
|
26
|
+
setCopied(true)
|
|
27
|
+
setTimeout(() => setCopied(false), 1500)
|
|
28
|
+
} catch {
|
|
29
|
+
/* clipboard unavailable — silently ignore */
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return (
|
|
33
|
+
<section id="start" className="bg-bg-primary">
|
|
34
|
+
<div className="mx-auto max-w-[1080px] px-8 py-16 border-t-[0.5px] border-border-secondary">
|
|
35
|
+
<EditableRichText
|
|
36
|
+
field={eyebrow}
|
|
37
|
+
className="prose mb-3.5 [&_p]:text-[11px] [&_p]:font-medium [&_p]:tracking-[0.10em] [&_p]:uppercase [&_p]:text-text-brand-primary [&_p]:m-0"
|
|
38
|
+
/>
|
|
39
|
+
<EditableRichText
|
|
40
|
+
field={headline}
|
|
41
|
+
className="mb-6
|
|
42
|
+
[&_h2]:font-display [&_h2]:font-medium [&_h2]:text-text-primary [&_h2]:m-0
|
|
43
|
+
[&_h2]:max-w-[22ch]
|
|
44
|
+
[&_h2]:!text-[clamp(28px,3.6vw,40px)] [&_h2]:!leading-[1.1] [&_h2]:!tracking-[-0.02em]"
|
|
45
|
+
/>
|
|
46
|
+
<EditableRichText
|
|
47
|
+
field={intro}
|
|
48
|
+
className="prose max-w-[60ch] mb-7 [&_p]:text-text-primary [&_p]:m-0"
|
|
49
|
+
/>
|
|
50
|
+
|
|
51
|
+
<div className="relative bg-bg-brand-primary border-[0.5px] border-border-primary rounded-xl px-7 py-6 mb-5">
|
|
52
|
+
<button
|
|
53
|
+
type="button"
|
|
54
|
+
onClick={handleCopy}
|
|
55
|
+
aria-label="Copy command"
|
|
56
|
+
className="absolute top-3 right-3 inline-flex items-center gap-1.5 font-mono text-[11px] tracking-[0.06em] uppercase text-text-secondary hover:text-text-primary bg-transparent border-[0.5px] border-border-primary rounded-sm px-2 py-1 cursor-pointer transition-colors"
|
|
57
|
+
>
|
|
58
|
+
{copied ? (
|
|
59
|
+
<>
|
|
60
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
61
|
+
<polyline points="20 6 9 17 4 12" />
|
|
62
|
+
</svg>
|
|
63
|
+
<span>copied</span>
|
|
64
|
+
</>
|
|
65
|
+
) : (
|
|
66
|
+
<>
|
|
67
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
68
|
+
<rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
|
|
69
|
+
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
|
|
70
|
+
</svg>
|
|
71
|
+
<span>copy</span>
|
|
72
|
+
</>
|
|
73
|
+
)}
|
|
74
|
+
</button>
|
|
75
|
+
<div className="flex items-center gap-3 flex-wrap pr-20">
|
|
76
|
+
<span className="font-mono text-text-brand-primary text-[16px] opacity-60">$</span>
|
|
77
|
+
<EditableRichText
|
|
78
|
+
field={command}
|
|
79
|
+
as="code"
|
|
80
|
+
className="font-mono text-[16px] text-text-brand-primary bg-transparent p-0 flex-1 min-w-0 break-all"
|
|
81
|
+
/>
|
|
82
|
+
</div>
|
|
83
|
+
<EditableRichText
|
|
84
|
+
field={meta}
|
|
85
|
+
className="prose mt-4 [&_p]:text-[13px] [&_p]:text-text-secondary [&_p]:font-mono [&_p]:m-0"
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div className="flex gap-2.5 flex-wrap">
|
|
90
|
+
{hrefOf(primaryCta) && (
|
|
91
|
+
<a
|
|
92
|
+
href={hrefOf(primaryCta)}
|
|
93
|
+
target={isExternalLink(primaryCta) ? '_blank' : undefined}
|
|
94
|
+
rel={isExternalLink(primaryCta) ? 'noreferrer' : undefined}
|
|
95
|
+
className="inline-flex items-center gap-2 bg-transparent text-text-primary border-[0.5px] border-border-primary rounded-sm text-[13px] font-medium px-4 py-2 no-underline hover:bg-bg-secondary transition-colors"
|
|
96
|
+
>
|
|
97
|
+
<EditableLink field={rawPrimary} className="no-underline" />
|
|
98
|
+
<span aria-hidden="true">→</span>
|
|
99
|
+
</a>
|
|
100
|
+
)}
|
|
101
|
+
{hrefOf(secondaryCta) && (
|
|
102
|
+
<a
|
|
103
|
+
href={hrefOf(secondaryCta)}
|
|
104
|
+
target={isExternalLink(secondaryCta) ? '_blank' : undefined}
|
|
105
|
+
rel={isExternalLink(secondaryCta) ? 'noreferrer' : undefined}
|
|
106
|
+
className="inline-flex items-center gap-2 bg-transparent text-text-primary border-[0.5px] border-border-primary rounded-sm text-[13px] font-medium px-4 py-2 no-underline hover:bg-bg-secondary transition-colors"
|
|
107
|
+
>
|
|
108
|
+
<EditableLink field={rawSecondary} className="no-underline" />
|
|
109
|
+
<span aria-hidden="true">↗</span>
|
|
110
|
+
</a>
|
|
111
|
+
)}
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
</section>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineSection } from '@agntcms/next'
|
|
2
|
+
import { schema } from './schema'
|
|
3
|
+
import { GettingStartedComponent } from './component'
|
|
4
|
+
|
|
5
|
+
export const GettingStarted = defineSection({
|
|
6
|
+
name: 'GettingStarted',
|
|
7
|
+
category: 'CTA',
|
|
8
|
+
schema,
|
|
9
|
+
component: GettingStartedComponent,
|
|
10
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RichTextField, LinkField } from '@agntcms/next'
|
|
2
|
+
|
|
3
|
+
export const schema = {
|
|
4
|
+
eyebrow: RichTextField,
|
|
5
|
+
headline: RichTextField,
|
|
6
|
+
intro: RichTextField,
|
|
7
|
+
command: RichTextField,
|
|
8
|
+
meta: RichTextField,
|
|
9
|
+
primaryCta: LinkField,
|
|
10
|
+
secondaryCta: LinkField,
|
|
11
|
+
}
|