@gradial/aci 0.1.30 → 0.1.33
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 +4 -4
- package/bin/aci-darwin-arm64 +0 -0
- package/bin/aci.js +33 -32
- package/dist/astro/assets.d.ts +46 -0
- package/dist/astro/assets.js +51 -0
- package/dist/astro/index.d.ts +2 -0
- package/dist/astro/index.js +8 -0
- package/dist/astro/page.d.ts +88 -0
- package/dist/astro/page.js +117 -0
- package/dist/content/provider.d.ts +7 -0
- package/dist/dev/content-watch.d.ts +1 -0
- package/dist/dev/content-watch.js +1 -1
- package/dist/next/config.d.ts +6 -0
- package/dist/next/config.js +20 -13
- package/dist/next/content-watch.d.ts +1 -0
- package/dist/next/content-watch.js +2 -2
- package/dist/next/index.d.ts +1 -0
- package/dist/next/index.js +1 -0
- package/dist/next/middleware.d.ts +3 -2
- package/dist/next/middleware.js +40 -7
- package/dist/next/page.d.ts +13 -5
- package/dist/next/page.js +42 -17
- package/dist/next/server.d.ts +1 -1
- package/dist/next/server.js +33 -9
- package/dist/providers/s3.d.ts +7 -0
- package/dist/providers/s3.js +20 -0
- package/dist/testing/conformance/checks.d.ts +12 -0
- package/dist/testing/conformance/checks.js +483 -0
- package/dist/testing/conformance/index.d.ts +3 -0
- package/dist/testing/conformance/index.js +2 -0
- package/dist/testing/conformance/preset.d.ts +14 -0
- package/dist/testing/conformance/preset.js +98 -0
- package/dist/testing/conformance/types.d.ts +45 -0
- package/dist/testing/conformance/types.js +7 -0
- package/package.json +17 -9
- package/src/cli/materialize-template.mjs +133 -0
- package/src/cli/validate-content.mjs +0 -0
- package/src/cli/verify-next-cdn-routes.mjs +10 -19
- package/templates/astro/starter-content/src/cms/contracts/components/button.contract.ts +19 -0
- package/templates/astro/starter-content/src/cms/contracts/components/container.contract.ts +19 -0
- package/templates/astro/starter-content/src/cms/contracts/components/featureCard.contract.ts +15 -0
- package/templates/astro/starter-content/src/cms/contracts/components/featureGrid.contract.ts +16 -0
- package/templates/astro/starter-content/src/cms/contracts/components/homeHero.contract.ts +36 -0
- package/templates/astro/starter-content/src/cms/contracts/components/index.ts +21 -0
- package/templates/astro/starter-content/src/cms/contracts/components/statsBar.contract.ts +19 -0
- package/templates/astro/starter-content/src/cms/registry.ts +28 -0
- package/templates/astro/template/{.aci.yaml → .aci.yaml.tmpl} +1 -1
- package/templates/astro/template/README.md.tmpl +53 -0
- package/templates/astro/template/gitignore +12 -0
- package/templates/astro/template/package.json.tmpl +5 -3
- package/templates/astro/template/src/cms/contracts/components/index.ts +3 -0
- package/templates/astro/template/src/cms/registry.ts +3 -26
- package/templates/astro/template/src/pages/[...slug].astro +13 -35
- package/templates/astro/template/tests/conformance.test.ts.tmpl +12 -0
- package/templates/common/.agents/AGENTS.md +3 -5
- package/templates/common/.agents/skills/aci/SKILL.md +72 -23
- package/templates/common/.agents/skills/authoring/SKILL.md +53 -14
- package/templates/common/.agents/skills/authoring/references/block-registry.md +109 -15
- package/templates/common/.agents/skills/authoring/references/contracts.md +23 -7
- package/templates/common/.agents/skills/authoring/references/repo-structure.md +35 -19
- package/templates/common/.agents/skills/authoring/references/sdk-server-functions.md +75 -17
- package/templates/common/.agents/skills/migration/SKILL.md +7 -1
- package/templates/common/.agents/skills/migration/references/canon-migration.md +471 -0
- package/templates/common/.content/config/site.json.tmpl +15 -0
- package/templates/common/.content/pages/home/_index.json +4 -103
- package/templates/common/.nvmrc +1 -0
- package/templates/common/README.md.tmpl +32 -11
- package/templates/common/contracts/components/index.ts +1 -19
- package/templates/common/design-system/tokens/colors.css +34 -10
- package/templates/common/starter-content/.content/config/robots.txt +2 -0
- package/templates/common/starter-content/.content/pages/home/_index.json +112 -0
- package/templates/common/starter-content/.content/schemas/site.schema.json +138 -0
- package/templates/nextjs/starter-content/src/cms/contracts/components/container.contract.ts +19 -0
- package/templates/nextjs/starter-content/src/cms/contracts/components/featureCard.contract.ts +15 -0
- package/templates/nextjs/starter-content/src/cms/contracts/components/featureGrid.contract.ts +16 -0
- package/templates/nextjs/starter-content/src/cms/contracts/components/index.ts +21 -0
- package/templates/nextjs/starter-content/src/cms/contracts/components/siteFooter.contract.ts +45 -0
- package/templates/nextjs/starter-content/src/cms/contracts/components/siteNavigation.contract.ts +30 -0
- package/templates/nextjs/starter-content/src/cms/contracts/components/statsBar.contract.ts +19 -0
- package/templates/nextjs/starter-content/src/cms/registry.ts +28 -0
- package/templates/nextjs/template/{.aci.yaml → .aci.yaml.tmpl} +1 -1
- package/templates/nextjs/template/README.md.tmpl +52 -0
- package/templates/nextjs/template/gitignore +15 -0
- package/templates/nextjs/template/next.config.mjs +1 -6
- package/templates/nextjs/template/package.json.tmpl +5 -5
- package/templates/nextjs/template/src/app/gradial/assets/[...path]/route.ts +1 -4
- package/templates/nextjs/template/src/app/layout.tsx +1 -3
- package/templates/nextjs/template/src/cms/contracts/components/index.ts +1 -13
- package/templates/nextjs/template/src/cms/registry.ts +3 -26
- package/templates/nextjs/template/src/design-system/styles.css +346 -0
- package/templates/nextjs/template/src/design-system/tokens/colors.css +110 -0
- package/templates/nextjs/template/src/design-system/tokens/components.css +86 -0
- package/templates/nextjs/template/src/design-system/tokens/index.css +6 -0
- package/templates/nextjs/template/src/design-system/tokens/radii.css +5 -0
- package/templates/nextjs/template/src/design-system/tokens/shadows.css +9 -0
- package/templates/nextjs/template/src/design-system/tokens/spacing.css +26 -0
- package/templates/nextjs/template/src/design-system/tokens/typography.css +32 -0
- package/templates/nextjs/template/src/middleware.ts.tmpl +12 -0
- package/templates/nextjs/template/tests/conformance.test.ts.tmpl +12 -0
- package/templates/nextjs/template/src/app/_components/ConsentManager.tsx +0 -132
- package/templates/nextjs/template/src/cms/contracts/components/container.contract.ts +0 -20
- package/templates/nextjs/template/src/middleware.ts +0 -7
- /package/templates/{nextjs/template → astro/starter-content}/src/cms/contracts/components/siteFooter.contract.ts +0 -0
- /package/templates/{nextjs/template → astro/starter-content}/src/cms/contracts/components/siteNavigation.contract.ts +0 -0
- /package/templates/astro/{template → starter-content}/src/components/chrome/Footer.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/chrome/Header.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/elements/AtomicBlock.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/elements/AtomicBlocks.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/elements/Button.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/elements/ButtonBlock.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/elements/Container.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/elements/Icon.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/elements/Logo.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/elements/RemoteImage.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/sections/ContainerSection.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/sections/FeatureCard.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/sections/FeatureGrid.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/sections/HomeHero.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/components/sections/StatsBar.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/fixtures/atomicBlocks.ts +0 -0
- /package/templates/astro/{template → starter-content}/src/fixtures/composition.ts +0 -0
- /package/templates/astro/{template → starter-content}/src/fixtures/index.ts +0 -0
- /package/templates/astro/{template → starter-content}/src/fixtures/sections.ts +0 -0
- /package/templates/astro/{template → starter-content}/src/render/RenderPage.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/stories/CompositionStoryFrame.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/stories/HomeHero.stories.ts +0 -0
- /package/templates/astro/{template → starter-content}/src/stories/SectionStoryFrame.astro +0 -0
- /package/templates/astro/{template → starter-content}/src/stories/StoryDocFrame.astro +0 -0
- /package/templates/common/{.content → starter-content/.content}/.gradial-dam/blobs/sha256/7f/bf/7fbfc7fe230ff12688c496f660119e41d9725c4504d82e310c15665c73c09292 +0 -0
- /package/templates/common/{.content → starter-content/.content}/.gradial-dam/blobs/sha256/a0/f5/a0f506689de9b15a7055f70103a3f02cd3ba105771ae2de6754df2ede1210d3a +0 -0
- /package/templates/common/{.content → starter-content/.content}/.gradial-dam/blobs/sha256/dd/b7/ddb7e9642be08317bcd4b2bd26b58ba8d0d34dd7239e03e684a4f3634fa3845b +0 -0
- /package/templates/common/{.content → starter-content/.content}/.gradial-dam/blobs/sha256/fb/32/fb3260e8286ea8231ea1c77b9c0be92d6edd9026565731eb14cfdcfd6b1b75b3 +0 -0
- /package/templates/common/{.content → starter-content/.content}/config/site.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_about_hero/asset.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_about_hero/editorial.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_about_hero/governance.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_about_hero/versions/v0001.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_home_hero/asset.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_home_hero/editorial.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_home_hero/governance.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_home_hero/versions/v0001.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/fragments/navbar/_index.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/fragments/site-footer/_index.json +0 -0
- /package/templates/common/{.content → starter-content/.content}/pages/about/_index.json +0 -0
- /package/templates/common/{public → starter-content/public}/assets/Dwire-model.png +0 -0
- /package/templates/common/{public → starter-content/public}/assets/seattle.avif +0 -0
- /package/templates/nextjs/{template → starter-content}/src/cms/contracts/components/button.contract.ts +0 -0
- /package/templates/nextjs/{template → starter-content}/src/cms/contracts/components/homeHero.contract.ts +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/chrome/Footer.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/chrome/Header.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/elements/AtomicBlock.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/elements/Button.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/elements/ButtonBlock.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/elements/Container.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/elements/Icon.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/elements/Logo.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/sections/ContainerSection.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/sections/FeatureCard.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/sections/FeatureGrid.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/sections/HomeHero.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/components/sections/StatsBar.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/stories/Button.stories.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/stories/Header.stories.tsx +0 -0
- /package/templates/nextjs/{template → starter-content}/src/stories/HomeHero.stories.tsx +0 -0
|
@@ -1,112 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "page",
|
|
3
|
-
"id": "
|
|
3
|
+
"id": "home",
|
|
4
4
|
"status": "published",
|
|
5
5
|
"layout": "default",
|
|
6
6
|
"metadata": {
|
|
7
|
-
"title": "
|
|
8
|
-
"description": "
|
|
9
|
-
"canonical": "https://www.meridian.local/"
|
|
7
|
+
"title": "Home",
|
|
8
|
+
"description": "Welcome to your new ACI site."
|
|
10
9
|
},
|
|
11
10
|
"regions": {
|
|
12
|
-
"main": [
|
|
13
|
-
{
|
|
14
|
-
"id": "hero",
|
|
15
|
-
"component": "home_hero",
|
|
16
|
-
"props": {
|
|
17
|
-
"eyebrow": "Global satellite internet",
|
|
18
|
-
"headline": "Connect from anywhere on Earth.",
|
|
19
|
-
"description": "Meridian delivers low-latency broadband to homes, businesses, and remote operations in over 40 countries. No ground infrastructure required.",
|
|
20
|
-
"ctaLabel": "Explore plans",
|
|
21
|
-
"ctaHref": "/plans/",
|
|
22
|
-
"image": {
|
|
23
|
-
"$type": "dam.assetRef",
|
|
24
|
-
"assetId": "ast_site_home_hero",
|
|
25
|
-
"alt": "Light abstract hero background with satellite constellation"
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"id": "why-meridian",
|
|
31
|
-
"component": "feature_grid",
|
|
32
|
-
"props": {
|
|
33
|
-
"title": "Why Meridian",
|
|
34
|
-
"subtitle": "Engineered for the edges of the world.",
|
|
35
|
-
"features": [
|
|
36
|
-
{
|
|
37
|
-
"id": "global-coverage",
|
|
38
|
-
"component": "feature_card",
|
|
39
|
-
"props": {
|
|
40
|
-
"icon": "globe",
|
|
41
|
-
"title": "Global coverage",
|
|
42
|
-
"description": "A constellation of low-orbit satellites keeps you connected across continents, oceans, and remote terrain."
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"id": "low-latency",
|
|
47
|
-
"component": "feature_card",
|
|
48
|
-
"props": {
|
|
49
|
-
"icon": "speed",
|
|
50
|
-
"title": "Low latency",
|
|
51
|
-
"description": "Sub-50ms latency means video calls, gaming, and real-time control feel local, even in the middle of nowhere."
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"id": "easy-setup",
|
|
56
|
-
"component": "feature_card",
|
|
57
|
-
"props": {
|
|
58
|
-
"icon": "setup",
|
|
59
|
-
"title": "Easy setup",
|
|
60
|
-
"description": "A compact terminal and a phone app. Point at the sky, power on, and get online in minutes."
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
]
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"id": "stats",
|
|
68
|
-
"component": "stats_bar",
|
|
69
|
-
"props": {
|
|
70
|
-
"stats": [
|
|
71
|
-
{ "label": "Network uptime", "value": "99.9", "suffix": "%" },
|
|
72
|
-
{ "label": "Average latency", "value": "<50", "suffix": "ms" },
|
|
73
|
-
{ "label": "Countries covered", "value": "40", "suffix": "+" },
|
|
74
|
-
{ "label": "Orbital satellites", "value": "2,400", "suffix": "" }
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"id": "cta",
|
|
80
|
-
"component": "container",
|
|
81
|
-
"props": {
|
|
82
|
-
"theme": "light",
|
|
83
|
-
"className": "items-center justify-center text-center",
|
|
84
|
-
"content": [
|
|
85
|
-
{
|
|
86
|
-
"id": "cta-primary",
|
|
87
|
-
"component": "button",
|
|
88
|
-
"props": {
|
|
89
|
-
"label": "Explore plans",
|
|
90
|
-
"href": "/plans/",
|
|
91
|
-
"variant": "primary",
|
|
92
|
-
"icon": "arrow_forward",
|
|
93
|
-
"iconPosition": "after"
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
"id": "cta-secondary",
|
|
98
|
-
"component": "button",
|
|
99
|
-
"props": {
|
|
100
|
-
"label": "Contact sales",
|
|
101
|
-
"href": "/contact-sales/",
|
|
102
|
-
"variant": "outline",
|
|
103
|
-
"icon": "arrow_forward",
|
|
104
|
-
"iconPosition": "after"
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
]
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
]
|
|
11
|
+
"main": []
|
|
111
12
|
}
|
|
112
13
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
22
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
# {{siteName}}
|
|
2
2
|
|
|
3
|
+
A CMS-driven {{frameworkName}} site built on the **Gradial ACI** content
|
|
4
|
+
platform, seeded with the Meridian sample site.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
- **Node 22** (see `.nvmrc`)
|
|
9
|
+
- **npm 10+** (ships with Node 22)
|
|
10
|
+
|
|
11
|
+
No environment variables, accounts, or API tokens are required for local
|
|
12
|
+
development.
|
|
13
|
+
|
|
3
14
|
## Quick Start
|
|
4
15
|
|
|
5
16
|
```bash
|
|
6
17
|
npm install
|
|
7
|
-
npm run dev
|
|
18
|
+
npm run dev # → {{devUrl}}/
|
|
8
19
|
```
|
|
9
20
|
|
|
21
|
+
The sample site serves the home page at `/` and an about page at `/about/`.
|
|
22
|
+
The dev server compiles `.content/` into `.aci/compiled/` on startup and
|
|
23
|
+
recompiles (with browser refresh) whenever content changes.
|
|
24
|
+
|
|
10
25
|
## Skills
|
|
11
26
|
|
|
12
27
|
This project uses progressive disclosure skills for both humans and agents.
|
|
@@ -23,27 +38,33 @@ Agents: load skills from `.agents/skills/`. See `.agents/AGENTS.md`.
|
|
|
23
38
|
## Commands
|
|
24
39
|
|
|
25
40
|
```bash
|
|
26
|
-
npm run dev # Start dev server
|
|
27
|
-
npm run build #
|
|
28
|
-
npm run
|
|
29
|
-
npm run
|
|
30
|
-
npm run
|
|
31
|
-
npm run
|
|
32
|
-
npm run aci:doctor # Check project health
|
|
33
|
-
npm run aci:build # Full build (contracts + content + framework)
|
|
41
|
+
npm run dev # Start dev server at {{devUrl}}
|
|
42
|
+
npm run build # Production build
|
|
43
|
+
npm run content:compile # Compile content from .content/ into .aci/
|
|
44
|
+
npm run typecheck # TypeScript validation
|
|
45
|
+
npm run storybook # Component development (http://localhost:6006)
|
|
46
|
+
npm run build:storybook # Build Storybook for deployment
|
|
34
47
|
```
|
|
35
48
|
|
|
36
49
|
## Project Structure
|
|
37
50
|
|
|
38
51
|
```
|
|
39
|
-
.content/ Content source (JSON)
|
|
52
|
+
.content/ Content source (JSON pages, fragments, site config)
|
|
40
53
|
src/cms/ Contracts and component registry
|
|
41
54
|
src/components/ Runtime components (elements, sections, chrome)
|
|
42
55
|
src/design-system/ Design tokens and global styles
|
|
43
56
|
.agents/skills/ Skills for humans and agents
|
|
44
|
-
.aci/ Generated artifacts (compiled, schemas)
|
|
57
|
+
.aci/ Generated artifacts (compiled content, schemas) — git-ignored
|
|
45
58
|
```
|
|
46
59
|
|
|
60
|
+
## How It Works
|
|
61
|
+
|
|
62
|
+
Pages are JSON files in `.content/pages/{slug}/_index.json`. Each page lists
|
|
63
|
+
content blocks in `regions.main`; a block names a component and passes props.
|
|
64
|
+
Components are defined by **contracts** (Zod schemas in
|
|
65
|
+
`src/cms/contracts/components/`) and mapped to rendered components in
|
|
66
|
+
`src/cms/registry.ts`.
|
|
67
|
+
|
|
47
68
|
## Personalization
|
|
48
69
|
|
|
49
70
|
The `personalization` block in `.content/config/site.json` controls the
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import { containerContract } from './container.contract';
|
|
3
|
-
import { featureCardContract } from './featureCard.contract';
|
|
4
|
-
import { featureGridContract } from './featureGrid.contract';
|
|
5
|
-
import { homeHeroContract } from './homeHero.contract';
|
|
6
|
-
import { siteNavigationContract } from './siteNavigation.contract';
|
|
7
|
-
import { siteFooterContract } from './siteFooter.contract';
|
|
8
|
-
import { statsBarContract } from './statsBar.contract';
|
|
9
|
-
|
|
10
|
-
const componentContracts = [
|
|
11
|
-
homeHeroContract,
|
|
12
|
-
containerContract,
|
|
13
|
-
buttonContract,
|
|
14
|
-
siteNavigationContract,
|
|
15
|
-
siteFooterContract,
|
|
16
|
-
featureGridContract,
|
|
17
|
-
featureCardContract,
|
|
18
|
-
statsBarContract,
|
|
19
|
-
];
|
|
1
|
+
const componentContracts: readonly unknown[] = [];
|
|
20
2
|
|
|
21
3
|
export default componentContracts;
|
|
@@ -39,6 +39,24 @@
|
|
|
39
39
|
/* Focus */
|
|
40
40
|
--color-focus: var(--color-brand-600);
|
|
41
41
|
|
|
42
|
+
/* Extended surface palette */
|
|
43
|
+
--color-surface-500: #64748b;
|
|
44
|
+
--color-surface-600: #475569;
|
|
45
|
+
--color-surface-700: #334155;
|
|
46
|
+
--color-surface-800: #1e293b;
|
|
47
|
+
|
|
48
|
+
/* "Space" dark section palette — used by FeatureGrid, StatsBar, FeatureCard */
|
|
49
|
+
--color-space-deep: #080e1e;
|
|
50
|
+
--color-space-surface: #0f1829;
|
|
51
|
+
--color-space-raised: #162036;
|
|
52
|
+
--color-edge-space: rgba(255, 255, 255, 0.06);
|
|
53
|
+
--color-edge-space-strong: rgba(255, 255, 255, 0.12);
|
|
54
|
+
--color-fg-space-muted: #94a3b8;
|
|
55
|
+
--color-fg-secondary: #64748b;
|
|
56
|
+
--color-brand-blue: #0ea5e9;
|
|
57
|
+
--color-brand-blue-light: #38bdf8;
|
|
58
|
+
--color-launch-orange: #f97316;
|
|
59
|
+
|
|
42
60
|
/* Semantic aliases — light theme default */
|
|
43
61
|
--color-page: var(--color-white);
|
|
44
62
|
--color-page-inverse: var(--color-surface-900);
|
|
@@ -76,27 +94,33 @@
|
|
|
76
94
|
|
|
77
95
|
/* Gradients */
|
|
78
96
|
--gradient-hero-base: radial-gradient(
|
|
79
|
-
ellipse
|
|
80
|
-
rgba(14, 165, 233, 0.
|
|
81
|
-
rgba(14, 165, 233, 0.
|
|
97
|
+
ellipse 120% 80% at 60% 10%,
|
|
98
|
+
rgba(14, 165, 233, 0.22) 0%,
|
|
99
|
+
rgba(14, 165, 233, 0.08) 40%,
|
|
82
100
|
transparent 70%
|
|
83
101
|
);
|
|
84
102
|
--gradient-hero-overlay: linear-gradient(
|
|
85
103
|
180deg,
|
|
86
|
-
rgba(
|
|
87
|
-
rgba(
|
|
104
|
+
rgba(6, 10, 26, 0.70) 0%,
|
|
105
|
+
rgba(6, 10, 26, 0.65) 30%,
|
|
106
|
+
rgba(6, 10, 26, 0.55) 55%,
|
|
107
|
+
rgba(6, 10, 26, 0.40) 75%,
|
|
108
|
+
rgba(30, 40, 60, 0.25) 90%,
|
|
88
109
|
rgba(255, 255, 255, 0.95) 100%
|
|
89
110
|
);
|
|
90
111
|
--gradient-hero-overlay-rtl: linear-gradient(
|
|
91
112
|
180deg,
|
|
92
113
|
rgba(255, 255, 255, 0.95) 0%,
|
|
93
|
-
rgba(
|
|
94
|
-
rgba(
|
|
114
|
+
rgba(30, 40, 60, 0.25) 10%,
|
|
115
|
+
rgba(6, 10, 26, 0.40) 25%,
|
|
116
|
+
rgba(6, 10, 26, 0.55) 45%,
|
|
117
|
+
rgba(6, 10, 26, 0.65) 70%,
|
|
118
|
+
rgba(6, 10, 26, 0.70) 100%
|
|
95
119
|
);
|
|
96
120
|
--gradient-hero-radial: radial-gradient(
|
|
97
|
-
ellipse
|
|
98
|
-
rgba(
|
|
99
|
-
transparent
|
|
121
|
+
ellipse 80% 60% at 70% 20%,
|
|
122
|
+
rgba(14, 165, 233, 0.10) 0%,
|
|
123
|
+
transparent 55%
|
|
100
124
|
);
|
|
101
125
|
--gradient-card: linear-gradient(
|
|
102
126
|
180deg,
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$type": "page",
|
|
3
|
+
"id": "meridian-home",
|
|
4
|
+
"status": "published",
|
|
5
|
+
"layout": "default",
|
|
6
|
+
"metadata": {
|
|
7
|
+
"title": "Meridian — Global Satellite Internet",
|
|
8
|
+
"description": "Connect from anywhere on Earth. Low-latency satellite internet for homes, businesses, and beyond.",
|
|
9
|
+
"canonical": "https://www.meridian.local/"
|
|
10
|
+
},
|
|
11
|
+
"regions": {
|
|
12
|
+
"main": [
|
|
13
|
+
{
|
|
14
|
+
"id": "hero",
|
|
15
|
+
"component": "home_hero",
|
|
16
|
+
"props": {
|
|
17
|
+
"eyebrow": "Global satellite internet",
|
|
18
|
+
"headline": "Connect from anywhere on Earth.",
|
|
19
|
+
"description": "Meridian delivers low-latency broadband to homes, businesses, and remote operations in over 40 countries. No ground infrastructure required.",
|
|
20
|
+
"ctaLabel": "Explore plans",
|
|
21
|
+
"ctaHref": "/plans/",
|
|
22
|
+
"image": {
|
|
23
|
+
"$type": "dam.assetRef",
|
|
24
|
+
"assetId": "ast_site_home_hero",
|
|
25
|
+
"alt": "Light abstract hero background with satellite constellation"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "why-meridian",
|
|
31
|
+
"component": "feature_grid",
|
|
32
|
+
"props": {
|
|
33
|
+
"title": "Why Meridian",
|
|
34
|
+
"subtitle": "Engineered for the edges of the world.",
|
|
35
|
+
"features": [
|
|
36
|
+
{
|
|
37
|
+
"id": "global-coverage",
|
|
38
|
+
"component": "feature_card",
|
|
39
|
+
"props": {
|
|
40
|
+
"icon": "globe",
|
|
41
|
+
"title": "Global coverage",
|
|
42
|
+
"description": "A constellation of low-orbit satellites keeps you connected across continents, oceans, and remote terrain."
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": "low-latency",
|
|
47
|
+
"component": "feature_card",
|
|
48
|
+
"props": {
|
|
49
|
+
"icon": "speed",
|
|
50
|
+
"title": "Low latency",
|
|
51
|
+
"description": "Sub-50ms latency means video calls, gaming, and real-time control feel local, even in the middle of nowhere."
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"id": "easy-setup",
|
|
56
|
+
"component": "feature_card",
|
|
57
|
+
"props": {
|
|
58
|
+
"icon": "setup",
|
|
59
|
+
"title": "Easy setup",
|
|
60
|
+
"description": "A compact terminal and a phone app. Point at the sky, power on, and get online in minutes."
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"id": "stats",
|
|
68
|
+
"component": "stats_bar",
|
|
69
|
+
"props": {
|
|
70
|
+
"stats": [
|
|
71
|
+
{ "label": "Network uptime", "value": "99.9", "suffix": "%" },
|
|
72
|
+
{ "label": "Average latency", "value": "<50", "suffix": "ms" },
|
|
73
|
+
{ "label": "Countries covered", "value": "40", "suffix": "+" },
|
|
74
|
+
{ "label": "Orbital satellites", "value": "2,400", "suffix": "" }
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": "cta",
|
|
80
|
+
"component": "container",
|
|
81
|
+
"props": {
|
|
82
|
+
"theme": "light",
|
|
83
|
+
"className": "items-center justify-center text-center",
|
|
84
|
+
"content": [
|
|
85
|
+
{
|
|
86
|
+
"id": "cta-primary",
|
|
87
|
+
"component": "button",
|
|
88
|
+
"props": {
|
|
89
|
+
"label": "Explore plans",
|
|
90
|
+
"href": "/plans/",
|
|
91
|
+
"variant": "primary",
|
|
92
|
+
"icon": "arrow_forward",
|
|
93
|
+
"iconPosition": "after"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "cta-secondary",
|
|
98
|
+
"component": "button",
|
|
99
|
+
"props": {
|
|
100
|
+
"label": "Contact sales",
|
|
101
|
+
"href": "/contact-sales/",
|
|
102
|
+
"variant": "outline",
|
|
103
|
+
"icon": "arrow_forward",
|
|
104
|
+
"iconPosition": "after"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://baremetal.local/schemas/site.schema.json",
|
|
4
|
+
"title": "bare-metal Site Config",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["$type", "id", "status", "title", "domain", "defaultLocale", "overlayResolution"],
|
|
7
|
+
"additionalProperties": true,
|
|
8
|
+
"properties": {
|
|
9
|
+
"$type": { "const": "site" },
|
|
10
|
+
"id": { "type": "string", "minLength": 1 },
|
|
11
|
+
"status": { "type": "string", "minLength": 1 },
|
|
12
|
+
"title": { "type": "string", "minLength": 1 },
|
|
13
|
+
"domain": { "type": "string", "minLength": 1 },
|
|
14
|
+
"defaultLocale": { "type": "string", "minLength": 1 },
|
|
15
|
+
"locales": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"items": { "type": "string", "minLength": 1 }
|
|
18
|
+
},
|
|
19
|
+
"overlayResolution": {
|
|
20
|
+
"type": "array",
|
|
21
|
+
"items": { "enum": ["locale", "audience"] }
|
|
22
|
+
},
|
|
23
|
+
"brandHref": { "type": "string" },
|
|
24
|
+
"brandLogo": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"additionalProperties": true,
|
|
27
|
+
"properties": {
|
|
28
|
+
"src": { "type": "string", "minLength": 1 },
|
|
29
|
+
"alt": { "type": "string" }
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"navigation": {
|
|
33
|
+
"type": "array",
|
|
34
|
+
"items": { "$ref": "#/$defs/link" }
|
|
35
|
+
},
|
|
36
|
+
"utilities": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"items": {
|
|
39
|
+
"allOf": [
|
|
40
|
+
{ "$ref": "#/$defs/link" },
|
|
41
|
+
{
|
|
42
|
+
"type": "object",
|
|
43
|
+
"properties": {
|
|
44
|
+
"variant": {
|
|
45
|
+
"enum": ["primary", "secondary", "outline", "ghost"]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"footer": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"additionalProperties": true,
|
|
55
|
+
"properties": {
|
|
56
|
+
"columns": {
|
|
57
|
+
"type": "array",
|
|
58
|
+
"items": { "$ref": "#/$defs/footerColumn" }
|
|
59
|
+
},
|
|
60
|
+
"social": {
|
|
61
|
+
"type": "array",
|
|
62
|
+
"items": { "$ref": "#/$defs/link" }
|
|
63
|
+
},
|
|
64
|
+
"legalLinks": {
|
|
65
|
+
"type": "array",
|
|
66
|
+
"items": { "$ref": "#/$defs/link" }
|
|
67
|
+
},
|
|
68
|
+
"copyright": { "type": "string" }
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"seo": {
|
|
72
|
+
"type": "object",
|
|
73
|
+
"additionalProperties": true,
|
|
74
|
+
"properties": {
|
|
75
|
+
"title": { "type": "string" },
|
|
76
|
+
"description": { "type": "string" },
|
|
77
|
+
"siteName": { "type": "string" }
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"personalization": {
|
|
81
|
+
"type": "object",
|
|
82
|
+
"additionalProperties": true,
|
|
83
|
+
"properties": {
|
|
84
|
+
"collect": { "type": "boolean" },
|
|
85
|
+
"consentPreset": {
|
|
86
|
+
"enum": ["c15t", "onetrust", "cookiebot", "trustarc", "manual"]
|
|
87
|
+
},
|
|
88
|
+
"consentCategories": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"pattern": "^\\s*[A-Za-z0-9._-]+(\\s*,\\s*[A-Za-z0-9._-]+)*\\s*$"
|
|
91
|
+
},
|
|
92
|
+
"debug": { "type": "boolean" }
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"$defs": {
|
|
97
|
+
"link": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"required": ["id", "label", "href"],
|
|
100
|
+
"additionalProperties": true,
|
|
101
|
+
"properties": {
|
|
102
|
+
"id": { "type": "string", "minLength": 1 },
|
|
103
|
+
"label": { "type": "string", "minLength": 1 },
|
|
104
|
+
"href": { "type": "string", "minLength": 1 }
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"footerGroup": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"required": ["id", "title", "links"],
|
|
110
|
+
"additionalProperties": true,
|
|
111
|
+
"properties": {
|
|
112
|
+
"id": { "type": "string", "minLength": 1 },
|
|
113
|
+
"title": { "type": "string" },
|
|
114
|
+
"links": {
|
|
115
|
+
"type": "array",
|
|
116
|
+
"items": { "$ref": "#/$defs/link" }
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"footerColumn": {
|
|
121
|
+
"type": "object",
|
|
122
|
+
"required": ["id"],
|
|
123
|
+
"additionalProperties": true,
|
|
124
|
+
"properties": {
|
|
125
|
+
"id": { "type": "string", "minLength": 1 },
|
|
126
|
+
"title": { "type": "string" },
|
|
127
|
+
"groups": {
|
|
128
|
+
"type": "array",
|
|
129
|
+
"items": { "$ref": "#/$defs/footerGroup" }
|
|
130
|
+
},
|
|
131
|
+
"links": {
|
|
132
|
+
"type": "array",
|
|
133
|
+
"items": { "$ref": "#/$defs/link" }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineComponentContract, blockRefArray } from '@gradial/aci';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { buttonContract } from './button.contract';
|
|
4
|
+
import { featureGridContract } from './featureGrid.contract';
|
|
5
|
+
import { featureCardContract } from './featureCard.contract';
|
|
6
|
+
import { statsBarContract } from './statsBar.contract';
|
|
7
|
+
|
|
8
|
+
export const schema = z.object({
|
|
9
|
+
theme: z.enum(['auto', 'light', 'dark']).optional(),
|
|
10
|
+
className: z.string().optional(),
|
|
11
|
+
content: blockRefArray([buttonContract, featureGridContract, featureCardContract, statsBarContract]).optional(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export type ContentProps = z.infer<typeof schema>;
|
|
15
|
+
|
|
16
|
+
export const containerContract = defineComponentContract({
|
|
17
|
+
id: 'container',
|
|
18
|
+
props: schema,
|
|
19
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineComponentContract } from '@gradial/aci';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
export const schema = z.object({
|
|
5
|
+
icon: z.string().optional(),
|
|
6
|
+
title: z.string().min(1),
|
|
7
|
+
description: z.string().optional(),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
export type ContentProps = z.infer<typeof schema>;
|
|
11
|
+
|
|
12
|
+
export const featureCardContract = defineComponentContract({
|
|
13
|
+
id: 'feature_card',
|
|
14
|
+
props: schema,
|
|
15
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineComponentContract, blockRefArray } from '@gradial/aci';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { featureCardContract } from './featureCard.contract';
|
|
4
|
+
|
|
5
|
+
export const schema = z.object({
|
|
6
|
+
title: z.string().optional(),
|
|
7
|
+
subtitle: z.string().optional(),
|
|
8
|
+
features: blockRefArray([featureCardContract]).optional(),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export type ContentProps = z.infer<typeof schema>;
|
|
12
|
+
|
|
13
|
+
export const featureGridContract = defineComponentContract({
|
|
14
|
+
id: 'feature_grid',
|
|
15
|
+
props: schema,
|
|
16
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { buttonContract } from './button.contract';
|
|
2
|
+
import { containerContract } from './container.contract';
|
|
3
|
+
import { featureCardContract } from './featureCard.contract';
|
|
4
|
+
import { featureGridContract } from './featureGrid.contract';
|
|
5
|
+
import { homeHeroContract } from './homeHero.contract';
|
|
6
|
+
import { siteFooterContract } from './siteFooter.contract';
|
|
7
|
+
import { siteNavigationContract } from './siteNavigation.contract';
|
|
8
|
+
import { statsBarContract } from './statsBar.contract';
|
|
9
|
+
|
|
10
|
+
const componentContracts = [
|
|
11
|
+
homeHeroContract,
|
|
12
|
+
containerContract,
|
|
13
|
+
buttonContract,
|
|
14
|
+
siteNavigationContract,
|
|
15
|
+
siteFooterContract,
|
|
16
|
+
featureGridContract,
|
|
17
|
+
featureCardContract,
|
|
18
|
+
statsBarContract,
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export default componentContracts;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { defineComponentContract } from '@gradial/aci';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
const linkSchema = z.object({
|
|
5
|
+
id: z.string().min(1),
|
|
6
|
+
label: z.string().min(1),
|
|
7
|
+
href: z.string().min(1),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const groupSchema = z.object({
|
|
11
|
+
id: z.string().min(1),
|
|
12
|
+
title: z.string(),
|
|
13
|
+
links: z.array(linkSchema),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const columnSchema = z.object({
|
|
17
|
+
id: z.string().min(1),
|
|
18
|
+
title: z.string().optional(),
|
|
19
|
+
links: z.array(linkSchema).optional(),
|
|
20
|
+
groups: z.array(groupSchema).optional(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const socialSchema = linkSchema.extend({
|
|
24
|
+
icon: z.string().optional(),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export const schema = z.object({
|
|
28
|
+
brandHref: z.string().min(1),
|
|
29
|
+
brandLabel: z.string().min(1),
|
|
30
|
+
brandLogo: z.object({
|
|
31
|
+
src: z.string(),
|
|
32
|
+
alt: z.string(),
|
|
33
|
+
}).nullable().optional(),
|
|
34
|
+
columns: z.array(columnSchema),
|
|
35
|
+
social: z.array(socialSchema).optional(),
|
|
36
|
+
legalLinks: z.array(linkSchema).optional(),
|
|
37
|
+
copyright: z.string().optional(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export type ContentProps = z.infer<typeof schema>;
|
|
41
|
+
|
|
42
|
+
export const siteFooterContract = defineComponentContract({
|
|
43
|
+
id: 'site-footer',
|
|
44
|
+
props: schema,
|
|
45
|
+
});
|