@gradial/aci 0.1.20-preview.3 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/README.md +48 -108
  2. package/bin/{aci → aci-darwin-arm64} +0 -0
  3. package/bin/aci.js +99 -6
  4. package/dist/assets/index.d.ts +3 -3
  5. package/dist/assets/index.js +3 -3
  6. package/dist/astro/index.d.ts +12 -3
  7. package/dist/astro/index.js +20 -5
  8. package/dist/content/assets.d.ts +17 -0
  9. package/dist/content/assets.js +65 -0
  10. package/dist/content/index.d.ts +1 -0
  11. package/dist/content/index.js +1 -0
  12. package/dist/define-component.d.ts +1 -2
  13. package/dist/define-component.js +73 -5
  14. package/dist/dev/content-watch.d.ts +37 -0
  15. package/dist/dev/content-watch.js +154 -0
  16. package/dist/dev/index.d.ts +24 -43
  17. package/dist/dev/index.js +4 -169
  18. package/dist/index.d.ts +14 -6
  19. package/dist/index.js +8 -9
  20. package/dist/next/asset-route.js +2 -2
  21. package/dist/next/config.d.ts +2 -2
  22. package/dist/next/config.js +5 -5
  23. package/dist/next/content-watch.js +6 -1
  24. package/dist/next/index.d.ts +2 -2
  25. package/dist/next/index.js +2 -2
  26. package/dist/next/middleware.d.ts +1 -0
  27. package/dist/next/middleware.js +49 -8
  28. package/dist/next/page.d.ts +1 -1
  29. package/dist/next/page.js +14 -12
  30. package/dist/next/render.d.ts +3 -3
  31. package/dist/next/render.js +11 -9
  32. package/dist/next/server.d.ts +12 -12
  33. package/dist/next/server.js +1 -1
  34. package/dist/preview/core.d.ts +5 -0
  35. package/dist/preview/core.js +1 -1
  36. package/dist/react/Media.d.ts +24 -0
  37. package/dist/react/Media.js +30 -0
  38. package/dist/react/Picture.d.ts +12 -0
  39. package/dist/react/Picture.js +11 -0
  40. package/dist/react/VideoPlayer.d.ts +13 -0
  41. package/dist/react/{GradialVideoPlayer.js → VideoPlayer.js} +6 -5
  42. package/dist/react/index.d.ts +333 -3
  43. package/dist/react/index.js +89 -3
  44. package/dist/registry.d.ts +2 -2
  45. package/dist/registry.js +3 -3
  46. package/dist/types/block-ref.d.ts +26 -0
  47. package/dist/types/block-ref.js +28 -0
  48. package/dist/types/component.d.ts +36 -32
  49. package/dist/types/config.d.ts +1 -1
  50. package/dist/types/image.d.ts +33 -20
  51. package/dist/types/image.js +42 -50
  52. package/dist/types/index.d.ts +1 -0
  53. package/dist/types/index.js +1 -0
  54. package/dist/types/link.d.ts +38 -0
  55. package/dist/types/link.js +58 -0
  56. package/dist/types/media.d.ts +16 -35
  57. package/dist/types/media.js +15 -84
  58. package/dist/types/renderer.d.ts +1 -1
  59. package/dist/types/rich-text.d.ts +40 -0
  60. package/dist/types/rich-text.js +39 -0
  61. package/dist/types/video.d.ts +7 -13
  62. package/dist/types/video.js +3 -3
  63. package/package.json +29 -76
  64. package/src/cli/compile-registry.mjs +120 -63
  65. package/src/cli/validate-content.mjs +38 -75
  66. package/src/types/block-ref.ts +74 -0
  67. package/src/types/image.ts +79 -60
  68. package/templates/astro/template/.aci.yaml +28 -0
  69. package/templates/astro/template/.storybook/main.ts +79 -0
  70. package/templates/astro/template/.storybook/manager.ts +6 -0
  71. package/templates/astro/template/.storybook/preview.ts +33 -0
  72. package/templates/astro/template/astro.config.mjs +37 -0
  73. package/templates/astro/template/package.json.tmpl +41 -0
  74. package/templates/astro/template/src/cms/contracts/layouts/index.ts +18 -0
  75. package/templates/astro/template/src/cms/registry.ts +28 -0
  76. package/templates/astro/template/src/components/chrome/Footer.astro +107 -0
  77. package/templates/astro/template/src/components/chrome/Header.astro +94 -0
  78. package/templates/astro/template/src/components/elements/AtomicBlock.astro +15 -0
  79. package/templates/astro/template/src/components/elements/AtomicBlocks.astro +16 -0
  80. package/templates/astro/template/src/components/elements/Button.astro +51 -0
  81. package/templates/astro/template/src/components/elements/ButtonBlock.astro +25 -0
  82. package/templates/astro/template/src/components/elements/Container.astro +11 -0
  83. package/templates/astro/template/src/components/elements/Icon.astro +31 -0
  84. package/templates/astro/template/src/components/elements/Logo.astro +29 -0
  85. package/templates/astro/template/src/components/elements/RemoteImage.astro +41 -0
  86. package/templates/astro/template/src/components/sections/ContainerSection.astro +32 -0
  87. package/templates/astro/template/src/components/sections/FeatureCard.astro +23 -0
  88. package/templates/astro/template/src/components/sections/FeatureGrid.astro +35 -0
  89. package/templates/astro/template/src/components/sections/HomeHero.astro +51 -0
  90. package/templates/astro/template/src/components/sections/StatsBar.astro +33 -0
  91. package/templates/astro/template/src/design-system/styles.css +399 -0
  92. package/templates/astro/template/src/design-system/tokens/colors.css +60 -0
  93. package/templates/astro/template/src/design-system/tokens/components.css +69 -0
  94. package/templates/astro/template/src/design-system/tokens/index.css +6 -0
  95. package/templates/astro/template/src/design-system/tokens/radii.css +5 -0
  96. package/templates/astro/template/src/design-system/tokens/shadows.css +5 -0
  97. package/templates/astro/template/src/design-system/tokens/spacing.css +13 -0
  98. package/templates/astro/template/src/design-system/tokens/typography.css +24 -0
  99. package/templates/astro/template/src/env.d.ts +1 -0
  100. package/templates/astro/template/src/fixtures/atomicBlocks.ts +33 -0
  101. package/templates/astro/template/src/fixtures/composition.ts +31 -0
  102. package/templates/astro/template/src/fixtures/index.ts +17 -0
  103. package/templates/astro/template/src/fixtures/sections.ts +39 -0
  104. package/templates/astro/template/src/layouts/SiteLayout.astro +30 -0
  105. package/templates/astro/template/src/pages/[...slug].astro +61 -0
  106. package/templates/astro/template/src/render/RenderPage.astro +66 -0
  107. package/templates/astro/template/src/stories/CompositionStoryFrame.astro +15 -0
  108. package/templates/astro/template/src/stories/HomeHero.stories.ts +24 -0
  109. package/templates/astro/template/src/stories/SectionStoryFrame.astro +16 -0
  110. package/templates/astro/template/src/stories/StoryDocFrame.astro +31 -0
  111. package/templates/astro/template/tsconfig.json +11 -0
  112. package/templates/common/.agents/AGENTS.md +37 -0
  113. package/templates/common/.agents/skills/aci/SKILL.md +162 -0
  114. package/templates/common/.agents/skills/authoring/SKILL.md +590 -0
  115. package/templates/common/.agents/skills/authoring/references/block-registry.md +151 -0
  116. package/templates/common/.agents/skills/authoring/references/contracts.md +153 -0
  117. package/templates/common/.agents/skills/authoring/references/design-system.md +171 -0
  118. package/templates/common/.agents/skills/authoring/references/image-assets.md +73 -0
  119. package/templates/common/.agents/skills/authoring/references/repo-structure.md +157 -0
  120. package/templates/common/.agents/skills/migration/SKILL.md +160 -0
  121. package/templates/common/.agents/skills/migration/references/analyzing-source.md +215 -0
  122. package/templates/common/.agents/skills/migration/references/component-migration.md +200 -0
  123. package/templates/common/.agents/skills/migration/references/selector-map.md +31 -0
  124. package/templates/common/.content/.gradial-dam/blobs/sha256/7f/bf/7fbfc7fe230ff12688c496f660119e41d9725c4504d82e310c15665c73c09292 +0 -0
  125. package/templates/common/.content/.gradial-dam/blobs/sha256/a0/f5/a0f506689de9b15a7055f70103a3f02cd3ba105771ae2de6754df2ede1210d3a +0 -0
  126. package/templates/common/.content/.gradial-dam/blobs/sha256/dd/b7/ddb7e9642be08317bcd4b2bd26b58ba8d0d34dd7239e03e684a4f3634fa3845b +0 -0
  127. package/templates/common/.content/.gradial-dam/blobs/sha256/fb/32/fb3260e8286ea8231ea1c77b9c0be92d6edd9026565731eb14cfdcfd6b1b75b3 +0 -0
  128. package/templates/common/.content/config/site.json +192 -0
  129. package/templates/common/.content/dam/folders/seed/ast_site_about_hero/asset.json +9 -0
  130. package/templates/common/.content/dam/folders/seed/ast_site_about_hero/editorial.json +14 -0
  131. package/templates/common/.content/dam/folders/seed/ast_site_about_hero/governance.json +23 -0
  132. package/templates/common/.content/dam/folders/seed/ast_site_about_hero/versions/v0001.json +37 -0
  133. package/templates/common/.content/dam/folders/seed/ast_site_home_hero/asset.json +9 -0
  134. package/templates/common/.content/dam/folders/seed/ast_site_home_hero/editorial.json +14 -0
  135. package/templates/common/.content/dam/folders/seed/ast_site_home_hero/governance.json +23 -0
  136. package/templates/common/.content/dam/folders/seed/ast_site_home_hero/versions/v0001.json +37 -0
  137. package/templates/common/.content/fragments/navbar/_index.json +25 -0
  138. package/templates/common/.content/fragments/site-footer/_index.json +62 -0
  139. package/templates/common/.content/pages/about/_index.json +51 -0
  140. package/templates/common/.content/pages/home/_index.json +112 -0
  141. package/templates/common/.content/schemas/site.schema.json +123 -0
  142. package/templates/common/README.md.tmpl +45 -0
  143. package/templates/common/contracts/components/button.contract.ts +19 -0
  144. package/templates/common/contracts/components/container.contract.ts +19 -0
  145. package/templates/common/contracts/components/featureCard.contract.ts +15 -0
  146. package/templates/common/contracts/components/featureGrid.contract.ts +16 -0
  147. package/templates/common/contracts/components/homeHero.contract.ts +36 -0
  148. package/templates/common/contracts/components/index.ts +21 -0
  149. package/templates/common/contracts/components/siteFooter.contract.ts +45 -0
  150. package/templates/common/contracts/components/siteNavigation.contract.ts +30 -0
  151. package/templates/common/contracts/components/statsBar.contract.ts +19 -0
  152. package/templates/common/design-system/styles.css +346 -0
  153. package/templates/common/design-system/tokens/colors.css +110 -0
  154. package/templates/common/design-system/tokens/components.css +86 -0
  155. package/templates/common/design-system/tokens/index.css +6 -0
  156. package/templates/common/design-system/tokens/radii.css +5 -0
  157. package/templates/common/design-system/tokens/shadows.css +9 -0
  158. package/templates/common/design-system/tokens/spacing.css +26 -0
  159. package/templates/common/design-system/tokens/typography.css +32 -0
  160. package/templates/common/eslint-rules/no-raw-tailwind-values.js +127 -0
  161. package/templates/common/public/assets/Dwire-model.png +0 -0
  162. package/templates/common/public/assets/bare-metal-logo.png +0 -0
  163. package/templates/common/public/assets/meridian-logo.svg +8 -0
  164. package/templates/common/public/assets/seattle.avif +0 -0
  165. package/templates/nextjs/template/.aci.yaml +26 -0
  166. package/templates/nextjs/template/.storybook/main.ts +13 -0
  167. package/templates/nextjs/template/.storybook/preview.ts +34 -0
  168. package/templates/nextjs/template/eslint.config.mjs +36 -0
  169. package/templates/nextjs/template/next-env.d.ts +6 -0
  170. package/templates/nextjs/template/next.config.ts +8 -0
  171. package/templates/nextjs/template/package.json.tmpl +46 -0
  172. package/templates/nextjs/template/postcss.config.mjs +7 -0
  173. package/templates/nextjs/template/src/app/[[...slug]]/page.tsx +8 -0
  174. package/templates/nextjs/template/src/app/gradial/assets/[releaseId]/[...path]/route.ts +31 -0
  175. package/templates/nextjs/template/src/app/layout.tsx +29 -0
  176. package/templates/nextjs/template/src/cms/contracts/components/button.contract.ts +19 -0
  177. package/templates/nextjs/template/src/cms/contracts/components/container.contract.ts +20 -0
  178. package/templates/nextjs/template/src/cms/contracts/components/homeHero.contract.ts +36 -0
  179. package/templates/nextjs/template/src/cms/contracts/components/index.ts +15 -0
  180. package/templates/nextjs/template/src/cms/contracts/components/siteFooter.contract.ts +45 -0
  181. package/templates/nextjs/template/src/cms/contracts/components/siteNavigation.contract.ts +30 -0
  182. package/templates/nextjs/template/src/cms/contracts/layouts/index.ts +16 -0
  183. package/templates/nextjs/template/src/cms/registry.ts +28 -0
  184. package/templates/nextjs/template/src/components/chrome/Footer.tsx +86 -0
  185. package/templates/nextjs/template/src/components/chrome/Header.tsx +74 -0
  186. package/templates/nextjs/template/src/components/elements/AtomicBlock.tsx +13 -0
  187. package/templates/nextjs/template/src/components/elements/Button.tsx +40 -0
  188. package/templates/nextjs/template/src/components/elements/ButtonBlock.tsx +18 -0
  189. package/templates/nextjs/template/src/components/elements/Container.tsx +14 -0
  190. package/templates/nextjs/template/src/components/elements/Icon.tsx +29 -0
  191. package/templates/nextjs/template/src/components/elements/Logo.tsx +38 -0
  192. package/templates/nextjs/template/src/components/sections/ContainerSection.tsx +28 -0
  193. package/templates/nextjs/template/src/components/sections/FeatureCard.tsx +25 -0
  194. package/templates/nextjs/template/src/components/sections/FeatureGrid.tsx +36 -0
  195. package/templates/nextjs/template/src/components/sections/HomeHero.tsx +62 -0
  196. package/templates/nextjs/template/src/components/sections/StatsBar.tsx +30 -0
  197. package/templates/nextjs/template/src/middleware.ts +4 -0
  198. package/templates/nextjs/template/src/stories/Button.stories.tsx +38 -0
  199. package/templates/nextjs/template/src/stories/Header.stories.tsx +30 -0
  200. package/templates/nextjs/template/src/stories/HomeHero.stories.tsx +33 -0
  201. package/templates/nextjs/template/tsconfig.json +23 -0
  202. package/templates/nextjs/template/vercel.json +6 -0
  203. package/dist/content/contract.d.ts +0 -83
  204. package/dist/content/contract.js +0 -104
  205. package/dist/content/tailwind-validator.d.ts +0 -6
  206. package/dist/content/tailwind-validator.js +0 -31
  207. package/dist/content/validation.d.ts +0 -108
  208. package/dist/content/validation.js +0 -183
  209. package/dist/react/GradialMedia.d.ts +0 -24
  210. package/dist/react/GradialMedia.js +0 -31
  211. package/dist/react/GradialPicture.d.ts +0 -14
  212. package/dist/react/GradialPicture.js +0 -30
  213. package/dist/react/GradialVideoPlayer.d.ts +0 -13
  214. package/dist/sveltekit/index.d.ts +0 -25
  215. package/dist/sveltekit/index.js +0 -66
  216. package/dist/sveltekit/preview.d.ts +0 -5
  217. package/dist/sveltekit/preview.js +0 -33
  218. package/src/types/component.ts +0 -49
  219. package/src/types/config.ts +0 -37
  220. package/src/types/data.ts +0 -47
  221. package/src/types/index.ts +0 -10
  222. package/src/types/layout.ts +0 -29
  223. package/src/types/media.ts +0 -125
  224. package/src/types/page.ts +0 -47
  225. package/src/types/render-mode.ts +0 -10
  226. package/src/types/renderer.ts +0 -83
  227. package/src/types/video.ts +0 -66
@@ -0,0 +1,94 @@
1
+ ---
2
+ import Button from '../elements/Button.astro';
3
+ import Container from '../elements/Container.astro';
4
+ import Icon from '../elements/Icon.astro';
5
+ import Logo from '../elements/Logo.astro';
6
+
7
+ interface NavItem {
8
+ id: string;
9
+ label: string;
10
+ href: string;
11
+ }
12
+
13
+ interface UtilityItem extends NavItem {
14
+ variant?: 'primary' | 'secondary' | 'outline' | 'ghost';
15
+ }
16
+
17
+ interface Props {
18
+ brandHref: string;
19
+ brandLabel?: string;
20
+ brandLogo?: { src: string; alt?: string } | null;
21
+ navigation?: NavItem[];
22
+ utilities?: UtilityItem[];
23
+ }
24
+
25
+ const {
26
+ brandHref,
27
+ brandLabel = 'Gradial',
28
+ brandLogo = null,
29
+ navigation = [],
30
+ utilities = []
31
+ } = Astro.props;
32
+ ---
33
+
34
+ <header class="bm-header sticky top-0 z-[var(--z-header)] [font-family:var(--font-family-base)] text-fg">
35
+ <a
36
+ href="#content-main"
37
+ class="sr-only focus:not-sr-only focus:absolute focus:left-4 focus:top-4 focus:z-10 focus:rounded-button focus:bg-white focus:px-4 focus:py-2 focus:text-black"
38
+ >
39
+ Skip to main content
40
+ </a>
41
+ <Container className="flex min-h-[var(--height-header)] items-center justify-between gap-4">
42
+ <a href={brandHref} class="shrink-0">
43
+ <Logo label={brandLabel} src={brandLogo?.src || ''} alt={brandLogo?.alt || brandLabel} />
44
+ </a>
45
+ <nav class="hidden items-center gap-9 text-[length:var(--text-size-body-small)] font-[var(--font-weight-semibold)] text-fg-muted lg:flex" aria-label="Primary">
46
+ {navigation.map((item) => (
47
+ <a class="transition hover:text-link-hover" href={item.href}>{item.label}</a>
48
+ ))}
49
+ </nav>
50
+ <div class="flex shrink-0 items-center gap-3">
51
+ <div class="hidden items-center gap-3 sm:flex">
52
+ {utilities.map((item) => (
53
+ <Button href={item.href} variant={item.variant || 'outline'}>{item.label}</Button>
54
+ ))}
55
+ </div>
56
+ <div class="lg:hidden">
57
+ <input id="site-mobile-nav" class="peer sr-only" type="checkbox" />
58
+ <label
59
+ for="site-mobile-nav"
60
+ class="inline-grid size-11 cursor-pointer place-items-center rounded-button border border-edge text-fg transition hover:text-link-hover"
61
+ aria-label="Open main navigation"
62
+ >
63
+ <Icon name="menu" className="size-6" />
64
+ </label>
65
+ <div class="bm-mobile-nav pointer-events-none fixed inset-0 z-[var(--z-overlay)] flex translate-x-full flex-col px-[var(--spacing-container)] py-5 text-fg opacity-0 transition duration-300 ease-out peer-checked:pointer-events-auto peer-checked:translate-x-0 peer-checked:opacity-100">
66
+ <div class="flex min-h-[var(--height-header)] items-center justify-between gap-4">
67
+ <a href={brandHref} class="shrink-0">
68
+ <Logo label={brandLabel} src={brandLogo?.src || ''} alt={brandLogo?.alt || brandLabel} />
69
+ </a>
70
+ <label
71
+ for="site-mobile-nav"
72
+ class="inline-grid size-11 cursor-pointer place-items-center rounded-button border border-edge text-fg transition hover:text-link-hover"
73
+ aria-label="Close main navigation"
74
+ >
75
+ <Icon name="close" className="size-6" />
76
+ </label>
77
+ </div>
78
+ <nav class="grid flex-1 content-center gap-4 py-10 font-[var(--font-weight-bold)] text-[length:var(--mobile-nav-link-size)] leading-[var(--mobile-nav-link-line-height)] text-fg" aria-label="Mobile main navigation">
79
+ {navigation.map((item) => (
80
+ <a class="transition hover:text-link-hover" href={item.href}>{item.label}</a>
81
+ ))}
82
+ </nav>
83
+ {utilities.length ? (
84
+ <div class="grid gap-3 border-t border-edge pt-5 sm:hidden">
85
+ {utilities.map((item) => (
86
+ <Button href={item.href} variant={item.variant || 'outline'} className="w-full">{item.label}</Button>
87
+ ))}
88
+ </div>
89
+ ) : null}
90
+ </div>
91
+ </div>
92
+ </div>
93
+ </Container>
94
+ </header>
@@ -0,0 +1,15 @@
1
+ ---
2
+ import type { KernelAtomicBlock } from '@gradial/aci/content';
3
+ import ButtonBlock from './ButtonBlock.astro';
4
+
5
+ interface Props {
6
+ block: KernelAtomicBlock;
7
+ }
8
+
9
+ const { block } = Astro.props;
10
+ const props = (block.props || {}) as any;
11
+ ---
12
+
13
+ {block.component === 'button' ? (
14
+ <ButtonBlock {...props} />
15
+ ) : null}
@@ -0,0 +1,16 @@
1
+ ---
2
+ import type { KernelAtomicBlock } from '@gradial/aci/content';
3
+ import AtomicBlock from './AtomicBlock.astro';
4
+
5
+ interface Props {
6
+ blocks?: KernelAtomicBlock[];
7
+ }
8
+
9
+ const { blocks = [] } = Astro.props;
10
+ ---
11
+
12
+ <div class="flex flex-wrap gap-4">
13
+ {blocks.map((block) => (
14
+ <AtomicBlock {block} />
15
+ ))}
16
+ </div>
@@ -0,0 +1,51 @@
1
+ ---
2
+ interface Props {
3
+ href: string;
4
+ variant?: 'primary' | 'secondary' | 'tertiary' | 'outline' | 'ghost';
5
+ className?: string;
6
+ target?: string;
7
+ rel?: string;
8
+ }
9
+
10
+ const { href, variant = 'primary', className = '', target, rel } = Astro.props;
11
+
12
+ const variantTokens = {
13
+ primary: {
14
+ background: 'var(--button-primary-bg)',
15
+ border: 'var(--button-primary-border)',
16
+ color: 'var(--button-primary-text)'
17
+ },
18
+ secondary: {
19
+ background: 'var(--button-secondary-bg)',
20
+ border: 'var(--button-secondary-border)',
21
+ color: 'var(--button-secondary-text)'
22
+ },
23
+ outline: {
24
+ background: 'var(--button-outline-bg)',
25
+ border: 'var(--button-outline-border)',
26
+ color: 'var(--button-outline-text)'
27
+ },
28
+ tertiary: {
29
+ background: 'var(--button-tertiary-bg)',
30
+ border: 'var(--button-tertiary-border)',
31
+ color: 'var(--button-tertiary-text)'
32
+ },
33
+ ghost: {
34
+ background: 'transparent',
35
+ border: 'transparent',
36
+ color: 'var(--color-fg)'
37
+ }
38
+ }[variant];
39
+
40
+ const tokenStyle = `background-color: ${variantTokens.background}; border-color: ${variantTokens.border}; color: ${variantTokens.color};`;
41
+ ---
42
+
43
+ <a
44
+ class={`inline-flex min-h-10 items-center justify-center rounded-button border px-[var(--spacing-button-x)] py-[var(--spacing-button-y)] [font-family:var(--font-family-base)] text-[length:var(--text-button)] font-[var(--font-weight-semibold)] leading-button transition duration-200 hover:opacity-85 ${className}`}
45
+ href={href}
46
+ target={target}
47
+ rel={rel}
48
+ style={tokenStyle}
49
+ >
50
+ <slot />
51
+ </a>
@@ -0,0 +1,25 @@
1
+ ---
2
+ import Button from '../elements/Button.astro';
3
+ import Icon from '../elements/Icon.astro';
4
+ import type { ContentProps } from '../../cms/contracts/components/button.contract';
5
+
6
+ type Props = ContentProps;
7
+
8
+ const {
9
+ label,
10
+ href,
11
+ variant = 'primary',
12
+ newWindow = false,
13
+ icon = '',
14
+ iconPosition = 'before',
15
+ className = ''
16
+ } = Astro.props;
17
+ const target = newWindow ? '_blank' : undefined;
18
+ const rel = newWindow ? 'noreferrer' : undefined;
19
+ ---
20
+
21
+ <Button {href} {variant} {target} {rel} {className}>
22
+ {icon && iconPosition === 'before' ? <Icon name={icon} className="mr-2 size-4" /> : null}
23
+ <span>{label}</span>
24
+ {icon && iconPosition === 'after' ? <Icon name={icon} className="ml-2 size-4" /> : null}
25
+ </Button>
@@ -0,0 +1,11 @@
1
+ ---
2
+ interface Props {
3
+ className?: string;
4
+ }
5
+
6
+ const { className = '' } = Astro.props;
7
+ ---
8
+
9
+ <div class={`mx-auto w-full max-w-container px-[var(--spacing-container)] ${className}`}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,31 @@
1
+ ---
2
+ interface Props {
3
+ name: 'auto_awesome' | 'hub' | 'speed' | string;
4
+ className?: string;
5
+ }
6
+
7
+ const { name, className = '' } = Astro.props;
8
+
9
+ const paths: Record<string, string> = {
10
+ arrow_forward: 'M647-440H160v-80h487L423-744l57-56 320 320-320 320-57-56 224-224Z',
11
+ auto_awesome: 'M480-80 376-376 80-480l296-104 104-296 104 296 296 104-296 104L480-80Zm0-167 64-177 177-64-177-64-64-177-64 177-177 64 177 64 64 177ZM760-560l-40-120-120-40 120-40 40-120 40 120 120 40-120 40-40 120Z',
12
+ close: 'm256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z',
13
+ globe: 'M480-80q-82 0-155-31.5t-127.5-86q-54.5-54.5-86-127.5T80-480q0-82 31.5-155t86-127.5q54.5-54.5 127.5-86T480-880q82 0 155 31.5t127.5 86q54.5 54.5 86 127.5T880-480q0 82-31.5 155t-86 127.5q-54.5 54.5-127.5 86T480-80Zm0-80q139-36 209.5-131.5T760-480H520v-280q-64 8-117 38.5T320-640h-40q-54 77-87 153.5T160-480q0 131.5 69.5 227T480-160Zm0 80q-83 0-156-31.5t-127-86q-54.5-54.5-86-127T80-480q0-83 31.5-156t86-127q54.5-54.5 127-86T480-880q83 0 156 31.5t127 86q54.5 54.5 86 127T880-480q0 83-31.5 156t-86 127q-54.5 54.5-127 86T480-80Z',
14
+ hub: 'M200-120q-50 0-85-35t-35-85q0-39 22.5-70t57.5-43v-254q-35-12-57.5-43T80-720q0-50 35-85t85-35q39 0 70 22.5t43 57.5h334q12-35 43-57.5t70-22.5q50 0 85 35t35 85q0 39-22.5 70T800-607v254q35 12 57.5 43t22.5 70q0 50-35 85t-85 35q-39 0-70-22.5T647-200H313q-12 35-43 57.5T200-120Zm0-80q17 0 28.5-11.5T240-240q0-17-11.5-28.5T200-280q-17 0-28.5 11.5T160-240q0 17 11.5 28.5T200-200Zm0-480q17 0 28.5-11.5T240-720q0-17-11.5-28.5T200-760q-17 0-28.5 11.5T160-720q0 17 11.5 28.5T200-680Zm560 480q17 0 28.5-11.5T800-240q0-17-11.5-28.5T760-280q-17 0-28.5 11.5T720-240q0 17 11.5 28.5T760-200Zm0-480q17 0 28.5-11.5T800-720q0-17-11.5-28.5T760-760q-17 0-28.5 11.5T720-720q0 17 11.5 28.5T760-680ZM313-280h334q9-26 29-46t44-27v-254q-24-7-44-27t-29-46H313q-9 26-29 46t-44 27v254q24 7 44 27t29 46Z',
15
+ menu: 'M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z',
16
+ setup: 'M480-240 640-96l-40-200 160-120-200-80-80-200-80 200-200 80 160 120-40 200 160-144ZM160-280l120-72 72 120-192-48Z',
17
+ speed: 'M418-340q24 24 62 23.5t56-27.5l224-336-336 224q-27 18-28 55t22 61Zm62-460q59 0 113.5 16.5T696-734l-76 48q-32-17-68-25.5T480-720q-133 0-226.5 93.5T160-400q0 42 11.5 83t32.5 77h552q21-36 32.5-77t11.5-83q0-36-8.5-72T766-540l48-76q33 48 49.5 102.5T880-400q0 57-16.5 110T816-192q-11 17-30 24.5t-40 7.5H214q-21 0-40-7.5T144-192q-31-45-47.5-98T80-400q0-83 31.5-155.5t86-127Q252-737 324.5-768.5T480-800Z'
18
+ };
19
+
20
+ const path = paths[name] || paths.arrow_forward;
21
+ ---
22
+
23
+ <svg
24
+ class={className}
25
+ viewBox="0 -960 960 960"
26
+ aria-hidden="true"
27
+ focusable="false"
28
+ fill="currentColor"
29
+ >
30
+ <path d={path} />
31
+ </svg>
@@ -0,0 +1,29 @@
1
+ ---
2
+ interface Props {
3
+ label?: string;
4
+ src?: string;
5
+ alt?: string;
6
+ className?: string;
7
+ }
8
+
9
+ const { label = 'Gradial', src = '', alt = '', className = '' } = Astro.props;
10
+ const imageClass = className || 'w-[var(--width-logo-mobile)] md:w-[var(--width-logo)]';
11
+ ---
12
+
13
+ {src ? (
14
+ <img
15
+ class={`h-auto max-w-none object-contain ${imageClass}`}
16
+ src={src}
17
+ alt={alt || label}
18
+ loading="eager"
19
+ decoding="async"
20
+ style="filter: var(--logo-filter);"
21
+ />
22
+ ) : (
23
+ <span
24
+ class={`inline-flex items-center [font-family:var(--font-family-heading)] text-[length:var(--text-size-brand)] font-[var(--font-weight-bold)] leading-none text-fg ${className}`}
25
+ aria-label={label}
26
+ >
27
+ <span>{label}</span>
28
+ </span>
29
+ )}
@@ -0,0 +1,41 @@
1
+ ---
2
+ import { Image } from 'astro:assets';
3
+
4
+ interface Props {
5
+ src: string;
6
+ alt: string;
7
+ className?: string;
8
+ width?: number;
9
+ height?: number;
10
+ srcset?: string;
11
+ sizes?: string;
12
+ loading?: 'lazy' | 'eager';
13
+ }
14
+
15
+ const { src, alt, className = '', width, height, srcset, sizes, loading = 'lazy' } = Astro.props;
16
+ const isStorybook = !!import.meta.env.STORYBOOK;
17
+ ---
18
+
19
+ {isStorybook ? (
20
+ <img
21
+ class={className}
22
+ src={src}
23
+ alt={alt}
24
+ width={width}
25
+ height={height}
26
+ srcset={srcset}
27
+ sizes={sizes}
28
+ loading={loading}
29
+ decoding="async"
30
+ />
31
+ ) : (
32
+ <Image
33
+ class={className}
34
+ src={src}
35
+ alt={alt}
36
+ width={width || 1200}
37
+ height={height || 630}
38
+ sizes={sizes}
39
+ loading={loading}
40
+ />
41
+ )}
@@ -0,0 +1,32 @@
1
+ ---
2
+ import Container from '../elements/Container.astro';
3
+ import type { RenderChildren, RenderableBlock } from '@gradial/aci/astro';
4
+
5
+ interface Props {
6
+ theme?: 'auto' | 'light' | 'dark';
7
+ className?: string;
8
+ content?: any[];
9
+ renderChildren?: RenderChildren;
10
+ }
11
+
12
+ const { theme = 'auto', className = '', content, renderChildren } = Astro.props;
13
+ const children: RenderableBlock[] = content && renderChildren ? renderChildren(content) : [];
14
+ const buttonCount = content?.filter((b: any) => b.component === 'button').length ?? 0;
15
+ const layout = buttonCount === 1
16
+ ? 'flex-col items-center'
17
+ : 'flex-col items-center sm:flex-row sm:justify-center sm:gap-4';
18
+ ---
19
+
20
+ <section class={`theme-${theme} relative overflow-hidden py-[var(--spacing-section-y)] ${className}`}>
21
+ {theme === 'dark' ? (
22
+ <div class="pointer-events-none absolute inset-0 bg-[image:var(--gradient-hero-base)] opacity-30"></div>
23
+ ) : null}
24
+ <Container className="relative">
25
+ <div class={`flex ${layout} gap-6 text-center`}>
26
+ {children.map((child) => {
27
+ const Comp = child.Component as any;
28
+ return Comp ? <Comp {...child.props} /> : null;
29
+ })}
30
+ </div>
31
+ </Container>
32
+ </section>
@@ -0,0 +1,23 @@
1
+ ---
2
+ import Icon from '../elements/Icon.astro';
3
+
4
+ interface Props {
5
+ icon?: string;
6
+ title: string;
7
+ description?: string;
8
+ }
9
+
10
+ const { icon = '', title = '', description = '' } = Astro.props;
11
+ ---
12
+
13
+ <div class="rounded-card border border-[var(--color-edge-space)] bg-[var(--color-space-surface)] p-[var(--spacing-card)] transition-all duration-[var(--transition-duration-fast)] hover:border-[var(--color-edge-space-strong)] hover:bg-[var(--color-space-raised)] hover:shadow-[var(--shadow-card-default)]">
14
+ {icon ? (
15
+ <div class="mb-6 flex h-12 w-12 items-center justify-center rounded-button bg-[color-mix(in_srgb,var(--color-brand-blue)_12%,transparent)] text-[var(--color-brand-blue-light)]">
16
+ <Icon name={icon} className="h-6 w-6" />
17
+ </div>
18
+ ) : null}
19
+ <h3 class="text-[length:var(--text-size-h3)] font-[var(--font-weight-semibold)]">{title}</h3>
20
+ {description ? (
21
+ <p class="mt-3 text-[length:var(--text-size-body)] leading-relaxed text-[var(--color-fg-space-muted)]">{description}</p>
22
+ ) : null}
23
+ </div>
@@ -0,0 +1,35 @@
1
+ ---
2
+ import Container from '../elements/Container.astro';
3
+ import type { RenderChildren, RenderableBlock } from '@gradial/aci/astro';
4
+
5
+ interface Props {
6
+ title?: string;
7
+ subtitle?: string;
8
+ features?: any[];
9
+ renderChildren?: RenderChildren;
10
+ }
11
+
12
+ const { title = '', subtitle = '', features, renderChildren } = Astro.props;
13
+ const children: RenderableBlock[] = features && renderChildren ? renderChildren(features) : [];
14
+ const count = features?.length ?? 0;
15
+ const cols = count <= 2 ? 'sm:grid-cols-2' : 'sm:grid-cols-2 lg:grid-cols-3';
16
+ ---
17
+
18
+ <section class="theme-dark py-[var(--spacing-section-y)] bg-[var(--color-space-deep)]">
19
+ <Container>
20
+ <div class="mb-12 max-w-[var(--max-width-container-narrow)]">
21
+ {title ? (
22
+ <h2 class="text-[length:var(--text-size-h2-mobile)] font-[var(--font-weight-bold)] leading-tight md:text-[length:var(--text-size-h2)]">{title}</h2>
23
+ ) : null}
24
+ {subtitle ? (
25
+ <p class="mt-4 text-[length:var(--text-size-body-large)] leading-relaxed text-[var(--color-fg-space-muted)]">{subtitle}</p>
26
+ ) : null}
27
+ </div>
28
+ <div class={`grid gap-6 ${cols}`}>
29
+ {children.map((child) => {
30
+ const Comp = child.Component as any;
31
+ return Comp ? <Comp {...child.props} /> : null;
32
+ })}
33
+ </div>
34
+ </Container>
35
+ </section>
@@ -0,0 +1,51 @@
1
+ ---
2
+ import Button from '../elements/Button.astro';
3
+ import Container from '../elements/Container.astro';
4
+ import { imageAttrs, type Image } from '@gradial/aci';
5
+
6
+ interface Props {
7
+ eyebrow?: string;
8
+ headline: string;
9
+ description?: string;
10
+ ctaLabel: string;
11
+ ctaHref: string;
12
+ image?: Image;
13
+ }
14
+
15
+ const {
16
+ eyebrow = '',
17
+ headline,
18
+ description = '',
19
+ ctaLabel,
20
+ ctaHref,
21
+ image
22
+ } = Astro.props;
23
+
24
+ const imgAttrs = image ? imageAttrs(image, {
25
+ class: 'absolute inset-0 h-full w-full object-cover',
26
+ loading: 'eager',
27
+ decoding: 'async',
28
+ }) : null;
29
+ ---
30
+
31
+ <section
32
+ class="theme-dark relative min-h-[var(--height-hero-min)] overflow-hidden bg-black text-fg"
33
+ aria-label={image?.alt || headline}
34
+ >
35
+ {imgAttrs && <img {...imgAttrs} />}
36
+ <div class="absolute inset-0 bg-[image:var(--gradient-hero-overlay)]"></div>
37
+ <Container className="relative flex min-h-[var(--height-hero-min)] items-center py-[var(--spacing-section-y)]">
38
+ <div class="max-w-[var(--width-hero-content)]">
39
+ {eyebrow ? (
40
+ <p class="mb-5 text-[length:var(--text-size-eyebrow)] font-[var(--font-weight-semibold)] uppercase tracking-[var(--letter-spacing-label)] text-accent-secondary">{eyebrow}</p>
41
+ ) : null}
42
+ <h1 class="[font-family:var(--font-family-heading)] text-[length:var(--text-size-h1-mobile)] font-[var(--font-weight-bold)] leading-tight md:text-[length:var(--text-size-h1)]">{headline}</h1>
43
+ {description ? (
44
+ <p class="mt-7 max-w-2xl text-[length:var(--text-size-body-large)] leading-body text-fg">{description}</p>
45
+ ) : null}
46
+ <div class="mt-9">
47
+ <Button href={ctaHref} variant="secondary">{ctaLabel}</Button>
48
+ </div>
49
+ </div>
50
+ </Container>
51
+ </section>
@@ -0,0 +1,33 @@
1
+ ---
2
+ import Container from '../elements/Container.astro';
3
+
4
+ interface Stat {
5
+ label: string;
6
+ value: string;
7
+ suffix?: string;
8
+ }
9
+
10
+ interface Props {
11
+ stats?: Stat[];
12
+ }
13
+
14
+ const { stats = [] } = Astro.props;
15
+ ---
16
+
17
+ <section class="theme-dark border-y border-[var(--color-edge-space)] bg-[var(--color-space-surface)] py-[var(--spacing-section-y)]">
18
+ <Container>
19
+ <div class="grid gap-8 sm:grid-cols-2 lg:grid-cols-4">
20
+ {stats.map((stat) => (
21
+ <div class="text-center">
22
+ <p class="text-[length:var(--text-size-h2-mobile)] font-[var(--font-weight-bold)] leading-tight text-[var(--color-brand-blue-light)] md:text-[length:var(--text-size-h2)]">
23
+ {stat.value}
24
+ {stat.suffix ? <span class="text-[var(--color-launch-orange)]">{stat.suffix}</span> : null}
25
+ </p>
26
+ <p class="mt-2 text-[length:var(--text-size-body-small)] font-[var(--font-weight-medium)] text-[var(--color-fg-space-muted)] uppercase tracking-[var(--letter-spacing-label)]">
27
+ {stat.label}
28
+ </p>
29
+ </div>
30
+ ))}
31
+ </div>
32
+ </Container>
33
+ </section>