@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.
Files changed (164) hide show
  1. package/README.md +4 -4
  2. package/bin/aci-darwin-arm64 +0 -0
  3. package/bin/aci.js +33 -32
  4. package/dist/astro/assets.d.ts +46 -0
  5. package/dist/astro/assets.js +51 -0
  6. package/dist/astro/index.d.ts +2 -0
  7. package/dist/astro/index.js +8 -0
  8. package/dist/astro/page.d.ts +88 -0
  9. package/dist/astro/page.js +117 -0
  10. package/dist/content/provider.d.ts +7 -0
  11. package/dist/dev/content-watch.d.ts +1 -0
  12. package/dist/dev/content-watch.js +1 -1
  13. package/dist/next/config.d.ts +6 -0
  14. package/dist/next/config.js +20 -13
  15. package/dist/next/content-watch.d.ts +1 -0
  16. package/dist/next/content-watch.js +2 -2
  17. package/dist/next/index.d.ts +1 -0
  18. package/dist/next/index.js +1 -0
  19. package/dist/next/middleware.d.ts +3 -2
  20. package/dist/next/middleware.js +40 -7
  21. package/dist/next/page.d.ts +13 -5
  22. package/dist/next/page.js +42 -17
  23. package/dist/next/server.d.ts +1 -1
  24. package/dist/next/server.js +33 -9
  25. package/dist/providers/s3.d.ts +7 -0
  26. package/dist/providers/s3.js +20 -0
  27. package/dist/testing/conformance/checks.d.ts +12 -0
  28. package/dist/testing/conformance/checks.js +483 -0
  29. package/dist/testing/conformance/index.d.ts +3 -0
  30. package/dist/testing/conformance/index.js +2 -0
  31. package/dist/testing/conformance/preset.d.ts +14 -0
  32. package/dist/testing/conformance/preset.js +98 -0
  33. package/dist/testing/conformance/types.d.ts +45 -0
  34. package/dist/testing/conformance/types.js +7 -0
  35. package/package.json +17 -9
  36. package/src/cli/materialize-template.mjs +133 -0
  37. package/src/cli/validate-content.mjs +0 -0
  38. package/src/cli/verify-next-cdn-routes.mjs +10 -19
  39. package/templates/astro/starter-content/src/cms/contracts/components/button.contract.ts +19 -0
  40. package/templates/astro/starter-content/src/cms/contracts/components/container.contract.ts +19 -0
  41. package/templates/astro/starter-content/src/cms/contracts/components/featureCard.contract.ts +15 -0
  42. package/templates/astro/starter-content/src/cms/contracts/components/featureGrid.contract.ts +16 -0
  43. package/templates/astro/starter-content/src/cms/contracts/components/homeHero.contract.ts +36 -0
  44. package/templates/astro/starter-content/src/cms/contracts/components/index.ts +21 -0
  45. package/templates/astro/starter-content/src/cms/contracts/components/statsBar.contract.ts +19 -0
  46. package/templates/astro/starter-content/src/cms/registry.ts +28 -0
  47. package/templates/astro/template/{.aci.yaml → .aci.yaml.tmpl} +1 -1
  48. package/templates/astro/template/README.md.tmpl +53 -0
  49. package/templates/astro/template/gitignore +12 -0
  50. package/templates/astro/template/package.json.tmpl +5 -3
  51. package/templates/astro/template/src/cms/contracts/components/index.ts +3 -0
  52. package/templates/astro/template/src/cms/registry.ts +3 -26
  53. package/templates/astro/template/src/pages/[...slug].astro +13 -35
  54. package/templates/astro/template/tests/conformance.test.ts.tmpl +12 -0
  55. package/templates/common/.agents/AGENTS.md +3 -5
  56. package/templates/common/.agents/skills/aci/SKILL.md +72 -23
  57. package/templates/common/.agents/skills/authoring/SKILL.md +53 -14
  58. package/templates/common/.agents/skills/authoring/references/block-registry.md +109 -15
  59. package/templates/common/.agents/skills/authoring/references/contracts.md +23 -7
  60. package/templates/common/.agents/skills/authoring/references/repo-structure.md +35 -19
  61. package/templates/common/.agents/skills/authoring/references/sdk-server-functions.md +75 -17
  62. package/templates/common/.agents/skills/migration/SKILL.md +7 -1
  63. package/templates/common/.agents/skills/migration/references/canon-migration.md +471 -0
  64. package/templates/common/.content/config/site.json.tmpl +15 -0
  65. package/templates/common/.content/pages/home/_index.json +4 -103
  66. package/templates/common/.nvmrc +1 -0
  67. package/templates/common/README.md.tmpl +32 -11
  68. package/templates/common/contracts/components/index.ts +1 -19
  69. package/templates/common/design-system/tokens/colors.css +34 -10
  70. package/templates/common/starter-content/.content/config/robots.txt +2 -0
  71. package/templates/common/starter-content/.content/pages/home/_index.json +112 -0
  72. package/templates/common/starter-content/.content/schemas/site.schema.json +138 -0
  73. package/templates/nextjs/starter-content/src/cms/contracts/components/container.contract.ts +19 -0
  74. package/templates/nextjs/starter-content/src/cms/contracts/components/featureCard.contract.ts +15 -0
  75. package/templates/nextjs/starter-content/src/cms/contracts/components/featureGrid.contract.ts +16 -0
  76. package/templates/nextjs/starter-content/src/cms/contracts/components/index.ts +21 -0
  77. package/templates/nextjs/starter-content/src/cms/contracts/components/siteFooter.contract.ts +45 -0
  78. package/templates/nextjs/starter-content/src/cms/contracts/components/siteNavigation.contract.ts +30 -0
  79. package/templates/nextjs/starter-content/src/cms/contracts/components/statsBar.contract.ts +19 -0
  80. package/templates/nextjs/starter-content/src/cms/registry.ts +28 -0
  81. package/templates/nextjs/template/{.aci.yaml → .aci.yaml.tmpl} +1 -1
  82. package/templates/nextjs/template/README.md.tmpl +52 -0
  83. package/templates/nextjs/template/gitignore +15 -0
  84. package/templates/nextjs/template/next.config.mjs +1 -6
  85. package/templates/nextjs/template/package.json.tmpl +5 -5
  86. package/templates/nextjs/template/src/app/gradial/assets/[...path]/route.ts +1 -4
  87. package/templates/nextjs/template/src/app/layout.tsx +1 -3
  88. package/templates/nextjs/template/src/cms/contracts/components/index.ts +1 -13
  89. package/templates/nextjs/template/src/cms/registry.ts +3 -26
  90. package/templates/nextjs/template/src/design-system/styles.css +346 -0
  91. package/templates/nextjs/template/src/design-system/tokens/colors.css +110 -0
  92. package/templates/nextjs/template/src/design-system/tokens/components.css +86 -0
  93. package/templates/nextjs/template/src/design-system/tokens/index.css +6 -0
  94. package/templates/nextjs/template/src/design-system/tokens/radii.css +5 -0
  95. package/templates/nextjs/template/src/design-system/tokens/shadows.css +9 -0
  96. package/templates/nextjs/template/src/design-system/tokens/spacing.css +26 -0
  97. package/templates/nextjs/template/src/design-system/tokens/typography.css +32 -0
  98. package/templates/nextjs/template/src/middleware.ts.tmpl +12 -0
  99. package/templates/nextjs/template/tests/conformance.test.ts.tmpl +12 -0
  100. package/templates/nextjs/template/src/app/_components/ConsentManager.tsx +0 -132
  101. package/templates/nextjs/template/src/cms/contracts/components/container.contract.ts +0 -20
  102. package/templates/nextjs/template/src/middleware.ts +0 -7
  103. /package/templates/{nextjs/template → astro/starter-content}/src/cms/contracts/components/siteFooter.contract.ts +0 -0
  104. /package/templates/{nextjs/template → astro/starter-content}/src/cms/contracts/components/siteNavigation.contract.ts +0 -0
  105. /package/templates/astro/{template → starter-content}/src/components/chrome/Footer.astro +0 -0
  106. /package/templates/astro/{template → starter-content}/src/components/chrome/Header.astro +0 -0
  107. /package/templates/astro/{template → starter-content}/src/components/elements/AtomicBlock.astro +0 -0
  108. /package/templates/astro/{template → starter-content}/src/components/elements/AtomicBlocks.astro +0 -0
  109. /package/templates/astro/{template → starter-content}/src/components/elements/Button.astro +0 -0
  110. /package/templates/astro/{template → starter-content}/src/components/elements/ButtonBlock.astro +0 -0
  111. /package/templates/astro/{template → starter-content}/src/components/elements/Container.astro +0 -0
  112. /package/templates/astro/{template → starter-content}/src/components/elements/Icon.astro +0 -0
  113. /package/templates/astro/{template → starter-content}/src/components/elements/Logo.astro +0 -0
  114. /package/templates/astro/{template → starter-content}/src/components/elements/RemoteImage.astro +0 -0
  115. /package/templates/astro/{template → starter-content}/src/components/sections/ContainerSection.astro +0 -0
  116. /package/templates/astro/{template → starter-content}/src/components/sections/FeatureCard.astro +0 -0
  117. /package/templates/astro/{template → starter-content}/src/components/sections/FeatureGrid.astro +0 -0
  118. /package/templates/astro/{template → starter-content}/src/components/sections/HomeHero.astro +0 -0
  119. /package/templates/astro/{template → starter-content}/src/components/sections/StatsBar.astro +0 -0
  120. /package/templates/astro/{template → starter-content}/src/fixtures/atomicBlocks.ts +0 -0
  121. /package/templates/astro/{template → starter-content}/src/fixtures/composition.ts +0 -0
  122. /package/templates/astro/{template → starter-content}/src/fixtures/index.ts +0 -0
  123. /package/templates/astro/{template → starter-content}/src/fixtures/sections.ts +0 -0
  124. /package/templates/astro/{template → starter-content}/src/render/RenderPage.astro +0 -0
  125. /package/templates/astro/{template → starter-content}/src/stories/CompositionStoryFrame.astro +0 -0
  126. /package/templates/astro/{template → starter-content}/src/stories/HomeHero.stories.ts +0 -0
  127. /package/templates/astro/{template → starter-content}/src/stories/SectionStoryFrame.astro +0 -0
  128. /package/templates/astro/{template → starter-content}/src/stories/StoryDocFrame.astro +0 -0
  129. /package/templates/common/{.content → starter-content/.content}/.gradial-dam/blobs/sha256/7f/bf/7fbfc7fe230ff12688c496f660119e41d9725c4504d82e310c15665c73c09292 +0 -0
  130. /package/templates/common/{.content → starter-content/.content}/.gradial-dam/blobs/sha256/a0/f5/a0f506689de9b15a7055f70103a3f02cd3ba105771ae2de6754df2ede1210d3a +0 -0
  131. /package/templates/common/{.content → starter-content/.content}/.gradial-dam/blobs/sha256/dd/b7/ddb7e9642be08317bcd4b2bd26b58ba8d0d34dd7239e03e684a4f3634fa3845b +0 -0
  132. /package/templates/common/{.content → starter-content/.content}/.gradial-dam/blobs/sha256/fb/32/fb3260e8286ea8231ea1c77b9c0be92d6edd9026565731eb14cfdcfd6b1b75b3 +0 -0
  133. /package/templates/common/{.content → starter-content/.content}/config/site.json +0 -0
  134. /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_about_hero/asset.json +0 -0
  135. /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_about_hero/editorial.json +0 -0
  136. /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_about_hero/governance.json +0 -0
  137. /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_about_hero/versions/v0001.json +0 -0
  138. /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_home_hero/asset.json +0 -0
  139. /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_home_hero/editorial.json +0 -0
  140. /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_home_hero/governance.json +0 -0
  141. /package/templates/common/{.content → starter-content/.content}/dam/folders/seed/ast_site_home_hero/versions/v0001.json +0 -0
  142. /package/templates/common/{.content → starter-content/.content}/fragments/navbar/_index.json +0 -0
  143. /package/templates/common/{.content → starter-content/.content}/fragments/site-footer/_index.json +0 -0
  144. /package/templates/common/{.content → starter-content/.content}/pages/about/_index.json +0 -0
  145. /package/templates/common/{public → starter-content/public}/assets/Dwire-model.png +0 -0
  146. /package/templates/common/{public → starter-content/public}/assets/seattle.avif +0 -0
  147. /package/templates/nextjs/{template → starter-content}/src/cms/contracts/components/button.contract.ts +0 -0
  148. /package/templates/nextjs/{template → starter-content}/src/cms/contracts/components/homeHero.contract.ts +0 -0
  149. /package/templates/nextjs/{template → starter-content}/src/components/chrome/Footer.tsx +0 -0
  150. /package/templates/nextjs/{template → starter-content}/src/components/chrome/Header.tsx +0 -0
  151. /package/templates/nextjs/{template → starter-content}/src/components/elements/AtomicBlock.tsx +0 -0
  152. /package/templates/nextjs/{template → starter-content}/src/components/elements/Button.tsx +0 -0
  153. /package/templates/nextjs/{template → starter-content}/src/components/elements/ButtonBlock.tsx +0 -0
  154. /package/templates/nextjs/{template → starter-content}/src/components/elements/Container.tsx +0 -0
  155. /package/templates/nextjs/{template → starter-content}/src/components/elements/Icon.tsx +0 -0
  156. /package/templates/nextjs/{template → starter-content}/src/components/elements/Logo.tsx +0 -0
  157. /package/templates/nextjs/{template → starter-content}/src/components/sections/ContainerSection.tsx +0 -0
  158. /package/templates/nextjs/{template → starter-content}/src/components/sections/FeatureCard.tsx +0 -0
  159. /package/templates/nextjs/{template → starter-content}/src/components/sections/FeatureGrid.tsx +0 -0
  160. /package/templates/nextjs/{template → starter-content}/src/components/sections/HomeHero.tsx +0 -0
  161. /package/templates/nextjs/{template → starter-content}/src/components/sections/StatsBar.tsx +0 -0
  162. /package/templates/nextjs/{template → starter-content}/src/stories/Button.stories.tsx +0 -0
  163. /package/templates/nextjs/{template → starter-content}/src/stories/Header.stories.tsx +0 -0
  164. /package/templates/nextjs/{template → starter-content}/src/stories/HomeHero.stories.tsx +0 -0
@@ -0,0 +1,110 @@
1
+ @theme {
2
+ --color-white: #ffffff;
3
+ --color-black: #000000;
4
+
5
+ /* Light palette — airy, modern */
6
+ --color-surface-50: #f8fafc;
7
+ --color-surface-100: #f1f5f9;
8
+ --color-surface-200: #e2e8f0;
9
+ --color-surface-300: #cbd5e1;
10
+ --color-surface-400: #94a3b8;
11
+ --color-surface-900: #0f172a;
12
+ --color-surface-950: #020617;
13
+
14
+ /* Brand accents — electric blue + warm orange */
15
+ --color-brand-500: #0ea5e9;
16
+ --color-brand-400: #38bdf8;
17
+ --color-brand-600: #0284c7;
18
+ --color-brand-300: #7dd3fc;
19
+ --color-brand-glow: rgba(14, 165, 233, 0.25);
20
+
21
+ --color-warm-500: #f97316;
22
+ --color-warm-400: #fb923c;
23
+ --color-warm-600: #ea580c;
24
+ --color-warm-300: #fdba74;
25
+
26
+ /* Text */
27
+ --color-text-primary: #0f172a;
28
+ --color-text-secondary: #475569;
29
+ --color-text-tertiary: #64748b;
30
+ --color-text-muted: #94a3b8;
31
+ --color-text-inverse: #ffffff;
32
+
33
+ /* Borders */
34
+ --color-border-subtle: rgba(15, 23, 42, 0.06);
35
+ --color-border-default: rgba(15, 23, 42, 0.1);
36
+ --color-border-strong: rgba(15, 23, 42, 0.16);
37
+ --color-border-inverse: rgba(255, 255, 255, 0.2);
38
+
39
+ /* Focus */
40
+ --color-focus: var(--color-brand-600);
41
+
42
+ /* Semantic aliases — light theme default */
43
+ --color-page: var(--color-white);
44
+ --color-page-inverse: var(--color-surface-900);
45
+ --color-page-light: var(--color-white);
46
+ --color-chrome-surface: var(--color-white);
47
+ --color-chrome-surface-default: var(--color-white);
48
+
49
+ --color-surface: var(--color-white);
50
+ --color-surface-muted: var(--color-surface-100);
51
+ --color-surface-raised: var(--color-surface-200);
52
+ --color-surface-dark: var(--color-surface-900);
53
+ --color-surface-raised-dark: var(--color-surface-800);
54
+
55
+ --color-fg: var(--color-text-primary);
56
+ --color-fg-muted: var(--color-text-secondary);
57
+ --color-fg-base-muted: var(--color-text-secondary);
58
+ --color-fg-inverse: var(--color-text-inverse);
59
+ --color-fg-inverse-soft: var(--color-surface-200);
60
+ --color-fg-inverse-muted: var(--color-surface-400);
61
+
62
+ --color-border: var(--color-border-default);
63
+ --color-edge: var(--color-border-default);
64
+ --color-edge-dark: var(--color-border-strong);
65
+ --color-edge-inverse: var(--color-border-inverse);
66
+
67
+ --color-accent-primary: var(--color-brand-600);
68
+ --color-accent-secondary: var(--color-brand-500);
69
+ --color-accent-tertiary: var(--color-warm-500);
70
+ --color-accent-pink: var(--color-brand-500);
71
+ --color-accent-blue: var(--color-brand-500);
72
+ --color-accent-warm: var(--color-warm-500);
73
+
74
+ --color-icon-default: var(--color-text-tertiary);
75
+ --color-link-hover: var(--color-brand-600);
76
+
77
+ /* Gradients */
78
+ --gradient-hero-base: radial-gradient(
79
+ ellipse 80% 60% at 50% 0%,
80
+ rgba(14, 165, 233, 0.12) 0%,
81
+ rgba(14, 165, 233, 0.04) 40%,
82
+ transparent 70%
83
+ );
84
+ --gradient-hero-overlay: linear-gradient(
85
+ 180deg,
86
+ rgba(255, 255, 255, 0.2) 0%,
87
+ rgba(255, 255, 255, 0.7) 60%,
88
+ rgba(255, 255, 255, 0.95) 100%
89
+ );
90
+ --gradient-hero-overlay-rtl: linear-gradient(
91
+ 180deg,
92
+ rgba(255, 255, 255, 0.95) 0%,
93
+ rgba(255, 255, 255, 0.7) 60%,
94
+ rgba(255, 255, 255, 0.2) 100%
95
+ );
96
+ --gradient-hero-radial: radial-gradient(
97
+ ellipse 60% 40% at 80% 20%,
98
+ rgba(249, 115, 22, 0.06) 0%,
99
+ transparent 60%
100
+ );
101
+ --gradient-card: linear-gradient(
102
+ 180deg,
103
+ rgba(255, 255, 255, 0.95) 0%,
104
+ rgba(241, 245, 249, 0.6) 100%
105
+ );
106
+ --gradient-cta: linear-gradient(135deg, var(--color-brand-500) 0%, var(--color-brand-400) 100%);
107
+ --gradient-cta-dark: linear-gradient(135deg, var(--color-surface-100) 0%, var(--color-surface-200) 100%);
108
+ --gradient-cta-default: var(--gradient-cta);
109
+ --gradient-top-rail: linear-gradient(90deg, var(--color-brand-500) 0%, var(--color-warm-500) 100%);
110
+ }
@@ -0,0 +1,86 @@
1
+ @theme {
2
+ --width-logo-mobile: 8rem;
3
+ --width-logo: 12rem;
4
+ --width-logo-footer-mobile: 9rem;
5
+ --width-logo-footer: 14rem;
6
+ --logo-filter: none;
7
+
8
+ --text-button: var(--text-size-base);
9
+ --leading-button: 1;
10
+ --button-hover-opacity: 0.92;
11
+ --transition-duration-fast: 200ms;
12
+
13
+ --button-primary-bg: var(--color-accent-primary);
14
+ --button-primary-text: var(--color-white);
15
+ --button-primary-border: var(--color-accent-primary);
16
+ --button-primary-hover-bg: var(--color-brand-500);
17
+ --button-primary-hover-border: var(--color-brand-500);
18
+
19
+ --button-secondary-bg: var(--color-surface-100);
20
+ --button-secondary-text: var(--color-text-primary);
21
+ --button-secondary-border: var(--color-surface-200);
22
+ --button-secondary-hover-bg: var(--color-surface-200);
23
+ --button-secondary-hover-border: var(--color-surface-300);
24
+
25
+ --button-outline-bg: transparent;
26
+ --button-outline-text: var(--color-text-primary);
27
+ --button-outline-border: var(--color-border-strong);
28
+ --button-outline-hover-bg: var(--color-surface-100);
29
+ --button-outline-hover-border: var(--color-text-primary);
30
+
31
+ --button-tertiary-bg: transparent;
32
+ --button-tertiary-text: var(--color-accent-primary);
33
+ --button-tertiary-border: transparent;
34
+ --button-tertiary-hover-bg: rgba(14, 165, 233, 0.08);
35
+ --button-tertiary-hover-text: var(--color-brand-600);
36
+
37
+ --button-ghost-bg: transparent;
38
+ --button-ghost-text: var(--color-text-primary);
39
+ --button-ghost-border: transparent;
40
+ --button-ghost-hover-bg: var(--color-surface-100);
41
+ --button-ghost-hover-text: var(--color-text-primary);
42
+
43
+ --header-bg: rgba(255, 255, 255, 0.85);
44
+ --header-text: var(--color-text-primary);
45
+ --header-muted: var(--color-text-secondary);
46
+ --header-border: var(--color-border-default);
47
+ --header-link-hover: var(--color-accent-primary);
48
+ --header-icon: var(--color-text-tertiary);
49
+ --header-scrolled-bg: var(--color-white);
50
+
51
+ --mobile-nav-bg: var(--color-white);
52
+ --mobile-nav-text: var(--color-text-primary);
53
+ --mobile-nav-muted: var(--color-text-secondary);
54
+ --mobile-nav-border: var(--color-border-default);
55
+ --mobile-nav-link-hover: var(--color-accent-primary);
56
+ --mobile-nav-link-size: 1.75rem;
57
+ --mobile-nav-link-line-height: 1.1;
58
+
59
+ --footer-bg: var(--color-surface-100);
60
+ --footer-text: var(--color-text-primary);
61
+ --footer-muted: var(--color-text-secondary);
62
+ --footer-border: var(--color-border-default);
63
+ --footer-link-hover: var(--color-accent-primary);
64
+ --footer-grid-columns: 1fr 2fr;
65
+
66
+ --color-callout-icon-bg-light: rgba(14, 165, 233, 0.08);
67
+ --color-callout-icon-bg-dark: rgba(14, 165, 233, 0.12);
68
+ --color-callout-icon-bg: var(--color-callout-icon-bg-light);
69
+ --callout-icon-color: var(--color-accent-primary);
70
+
71
+ --rich-text-flow-space: 1.5rem;
72
+ --rich-text-heading-space: 2rem;
73
+ --rich-text-link-decoration-thickness: 0.09em;
74
+ --rich-text-link-underline-offset: 0.18em;
75
+ --rich-text-list-indent: 1.4em;
76
+ --rich-text-blockquote-border-width: 0.25rem;
77
+ --rich-text-inline-code-padding: 0.08em 0.32em;
78
+ --rich-text-quote-border: var(--color-brand-500);
79
+ --rich-text-quote-bg: rgba(14, 165, 233, 0.06);
80
+ --rich-text-quote-bg-dark: rgba(14, 165, 233, 0.1);
81
+ --rich-text-quote-bg-default: var(--rich-text-quote-bg-light);
82
+ --rich-text-inline-code-bg: rgba(15, 23, 42, 0.06);
83
+ --rich-text-inline-code-bg-dark: rgba(255, 255, 255, 0.08);
84
+ --rich-text-inline-code-bg-default: var(--rich-text-inline-code-bg);
85
+ --rich-text-inline-code-text: var(--color-fg);
86
+ }
@@ -0,0 +1,6 @@
1
+ @import "./colors.css";
2
+ @import "./typography.css";
3
+ @import "./spacing.css";
4
+ @import "./shadows.css";
5
+ @import "./radii.css";
6
+ @import "./components.css";
@@ -0,0 +1,5 @@
1
+ @theme {
2
+ --radius-button: 0.5rem;
3
+ --radius-card: 0.875rem;
4
+ --radius-cta: 1rem;
5
+ }
@@ -0,0 +1,9 @@
1
+ @theme {
2
+ --shadow-card: 0 1px 3px rgba(15, 23, 42, 0.04), 0 12px 32px rgba(15, 23, 42, 0.08);
3
+ --shadow-card-dark: 0 1px 3px rgba(0, 0, 0, 0.1), 0 16px 40px rgba(0, 0, 0, 0.15);
4
+ --shadow-card-default: var(--shadow-card);
5
+ --shadow-elevated: 0 1px 3px rgba(15, 23, 42, 0.05), 0 20px 48px rgba(15, 23, 42, 0.12);
6
+ --shadow-glow: 0 0 30px rgba(14, 165, 233, 0.25);
7
+ --shadow-glow-sm: 0 0 15px rgba(14, 165, 233, 0.18);
8
+ --shadow-glow-lg: 0 0 40px rgba(14, 165, 233, 0.3);
9
+ }
@@ -0,0 +1,26 @@
1
+ @theme {
2
+ --max-width-container: 80rem;
3
+ --max-width-container-narrow: 48rem;
4
+ --max-width-rich-text: var(--max-width-container-narrow);
5
+ --max-width-rich-text-wide: 54rem;
6
+ --max-width-cta: 76rem;
7
+
8
+ --spacing-container: clamp(1rem, 5vw, 3rem);
9
+ --spacing-section-y: clamp(4rem, 8vw, 7rem);
10
+ --spacing-footer-y: clamp(4rem, 8vw, 6rem);
11
+ --spacing-cta-y: clamp(4rem, 8vw, 6rem);
12
+ --spacing-cta-x: clamp(1.5rem, 5vw, 5rem);
13
+ --spacing-card: 1.5rem;
14
+ --spacing-hero-py: clamp(8rem, 20vh, 14rem);
15
+
16
+ --height-header: 4.5rem;
17
+ --height-hero-min: 100svh;
18
+ --width-hero-content: 48rem;
19
+ --height-button-min: 3rem;
20
+
21
+ --spacing-button-x: 1.5rem;
22
+ --spacing-button-y: 0.875rem;
23
+
24
+ --z-header: 50;
25
+ --z-overlay: 60;
26
+ }
@@ -0,0 +1,32 @@
1
+ @theme {
2
+ --font-family-display: var(--font-inter), "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
3
+ --font-family-heading: var(--font-family-display);
4
+ --font-family-base: var(--font-inter), "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
5
+
6
+ --font-weight-regular: 400;
7
+ --font-weight-medium: 500;
8
+ --font-weight-semibold: 600;
9
+ --font-weight-bold: 700;
10
+
11
+ --text-size-brand: 1.5rem;
12
+ --text-size-eyebrow: 0.75rem;
13
+ --text-size-caption: 0.75rem;
14
+ --text-size-body-small: 0.875rem;
15
+ --text-size-body: 1rem;
16
+ --text-size-body-large: 1.125rem;
17
+ --text-size-h1-mobile: 3rem;
18
+ --text-size-h1: 4.5rem;
19
+ --text-size-h2-mobile: 2rem;
20
+ --text-size-h2: 3rem;
21
+ --text-size-h3: 1.25rem;
22
+ --text-size-h4: 1.125rem;
23
+
24
+ --leading-none: 1;
25
+ --leading-tight: 1.05;
26
+ --leading-heading: 1.1;
27
+ --leading-snug: 1.25;
28
+ --leading-body: 1.6;
29
+ --leading-relaxed: 1.7;
30
+ --letter-spacing-label: 0.08em;
31
+ --letter-spacing-tight: -0.02em;
32
+ }
@@ -0,0 +1,12 @@
1
+ import { createGradialMiddleware } from '@gradial/aci/next/middleware';
2
+
3
+ export default createGradialMiddleware({
4
+ siteId: '{{siteName}}',
5
+ });
6
+
7
+ // The matcher value below is inlined for Next.js static analysis compatibility.
8
+ // Source of truth: aciMiddlewareMatcher from '@gradial/aci/next/middleware'.
9
+ // The conformance check verifies this stays in sync with the SDK export.
10
+ export const config = {
11
+ matcher: ['/((?!_next(?:/|$)|api(?:/|$)|favicon\\.ico$|\\.gradial-dam(?:/|$)).*)'],
12
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * ACI Conformance Tests
3
+ *
4
+ * Validates that the site conforms to canonical ACI integration patterns.
5
+ * See https://docs.gradial.com/aci/testing for details.
6
+ */
7
+ import { conformancePreset } from '@gradial/aci/testing';
8
+
9
+ conformancePreset({
10
+ framework: 'next',
11
+ siteId: '{{siteName}}',
12
+ });
@@ -1,132 +0,0 @@
1
- 'use client';
2
-
3
- import {
4
- ConsentBanner,
5
- ConsentDialog,
6
- ConsentManagerProvider,
7
- useConsentManager,
8
- type ConsentManagerProviderProps,
9
- } from '@c15t/nextjs';
10
- import { useEffect, useMemo, type ReactNode } from 'react';
11
-
12
- // Hosted c15t backend (consent.io or self-hosted). Unset = offline mode:
13
- // consent is stored client-side and no network calls are made.
14
- const C15T_BACKEND_URL = process.env.NEXT_PUBLIC_C15T_BACKEND_URL;
15
-
16
- // The CMP's own categories. The mapping from categories to the Gradial
17
- // personalization purpose lives in .content/config/site.json
18
- // (personalization.consentCategories), not here.
19
- const CONSENT_CATEGORIES = ['necessary', 'measurement', 'marketing'] as const;
20
-
21
- // ---------------------------------------------------------------------------
22
- // Gradial collect bridge
23
- //
24
- // The Gradial collect SDK's c15t preset (the site config's
25
- // `personalization.consentPreset: "c15t"`, emitted as
26
- // `data-aci-consent="c15t"` on the collect tag) reads
27
- // `window.c15t = { consents, onConsentChange }`. c15t itself does not
28
- // publish that shape, so this bridge mirrors the store onto it — only after
29
- // a real visitor decision (`consentInfo` set), never for pre-decision
30
- // defaults, so the SDK cannot mistake an untouched banner for a withdrawal.
31
- // ---------------------------------------------------------------------------
32
-
33
- type Consents = Record<string, boolean>;
34
- type ConsentListener = (payload: { consents: Consents }) => void;
35
-
36
- declare global {
37
- interface Window {
38
- c15t?: {
39
- consents?: Consents;
40
- onConsentChange?: (cb: ConsentListener) => void;
41
- };
42
- }
43
- }
44
-
45
- const consentListeners: ConsentListener[] = [];
46
-
47
- function publishAciConsents(consents: Consents): void {
48
- const bridge = (window.c15t ??= {});
49
- bridge.consents = consents;
50
- bridge.onConsentChange ??= (cb: ConsentListener) => {
51
- consentListeners.push(cb);
52
- };
53
- for (const listener of [...consentListeners]) {
54
- listener({ consents });
55
- }
56
- }
57
-
58
- function AciConsentBridge() {
59
- const { consents, consentInfo } = useConsentManager();
60
- useEffect(() => {
61
- if (!consentInfo || !consents) return;
62
- publishAciConsents(consents as Consents);
63
- }, [consents, consentInfo]);
64
- return null;
65
- }
66
-
67
- // ---------------------------------------------------------------------------
68
- // Consent manager
69
- // ---------------------------------------------------------------------------
70
-
71
- function getConsentOptions(): ConsentManagerProviderProps['options'] {
72
- const baseOptions = {
73
- consentCategories: [...CONSENT_CATEGORIES],
74
- legalLinks: {
75
- privacyPolicy: {
76
- href: '/privacy/',
77
- target: '_self' as const,
78
- label: 'Privacy policy',
79
- },
80
- },
81
- };
82
-
83
- if (C15T_BACKEND_URL) {
84
- return {
85
- ...baseOptions,
86
- mode: 'hosted',
87
- backendURL: C15T_BACKEND_URL,
88
- };
89
- }
90
-
91
- return {
92
- ...baseOptions,
93
- mode: 'offline',
94
- offlinePolicy: {
95
- policyPacks: [
96
- {
97
- id: 'default-opt-in',
98
- match: { isDefault: true },
99
- consent: {
100
- model: 'opt-in',
101
- categories: [...CONSENT_CATEGORIES],
102
- },
103
- ui: { mode: 'banner' },
104
- },
105
- ],
106
- },
107
- };
108
- }
109
-
110
- export function ConsentManager({ children }: { children: ReactNode }) {
111
- const options = useMemo(() => getConsentOptions(), []);
112
-
113
- return (
114
- <ConsentManagerProvider options={options}>
115
- {children}
116
- <AciConsentBridge />
117
- <ConsentBanner
118
- title="Cookie preferences"
119
- description="We use cookies to keep the site working, measure performance, and support marketing."
120
- acceptButtonText="Accept all"
121
- rejectButtonText="Reject all"
122
- customizeButtonText="Customize"
123
- legalLinks={['privacyPolicy']}
124
- layout={[['reject', 'accept'], 'customize']}
125
- primaryButton="accept"
126
- scrollLock={false}
127
- hideBranding
128
- />
129
- <ConsentDialog legalLinks={['privacyPolicy']} scrollLock trapFocus hideBranding />
130
- </ConsentManagerProvider>
131
- );
132
- }
@@ -1,20 +0,0 @@
1
- import { defineComponentContract } from '@gradial/aci';
2
- import { z } from 'zod';
3
-
4
- export const schema = z.object({
5
- theme: z.enum(['auto', 'light', 'dark']).optional(),
6
- className: z.string().optional(),
7
- });
8
-
9
- export type ContentProps = z.infer<typeof schema>;
10
-
11
- export const containerContract = defineComponentContract({
12
- id: 'container',
13
- props: schema,
14
- slots: {
15
- content: {
16
- allowed: ['button'],
17
- multiple: true,
18
- },
19
- },
20
- });
@@ -1,7 +0,0 @@
1
- import { createGradialMiddleware } from '@gradial/aci/next/middleware';
2
-
3
- export default createGradialMiddleware();
4
-
5
- export const config = {
6
- matcher: ['/((?!_next(?:/|$)|api(?:/|$)|gradial/assets(?:/|$)|favicon\\.ico$).*)'],
7
- };