@tangle-network/starter-foundry 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/compose.js +2 -0
- package/dist/lib/compose.js.map +1 -1
- package/dist/lib/index.d.ts +3 -1
- package/dist/lib/index.js +2 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/industries.d.ts +33 -0
- package/dist/lib/industries.js +52 -0
- package/dist/lib/industries.js.map +1 -0
- package/dist/lib/keywords.d.ts +6 -0
- package/dist/lib/keywords.js +21 -0
- package/dist/lib/keywords.js.map +1 -1
- package/dist/lib/prompt-planner.js +5 -1
- package/dist/lib/prompt-planner.js.map +1 -1
- package/dist/lib/telemetry.d.ts +1 -0
- package/dist/lib/telemetry.js.map +1 -1
- package/package.json +1 -1
- package/registry/layers/capability/layout-landing/files/features-section.tsx +54 -77
- package/registry/layers/capability/layout-landing/files/hero-section.tsx +18 -23
- package/registry/layers/capability/layout-landing/files/landing-page.tsx +25 -63
- package/registry/layers/capability/layout-landing/files/personalize.json +146 -0
- package/registry/layers/capability/layout-landing/files/pricing-section.tsx +45 -94
- package/registry/layers/capability/layout-landing/manifest.json +4 -0
- package/registry/layers/capability/layout-landing/variants/dark-product/features-section.tsx +55 -59
- package/registry/layers/capability/layout-landing/variants/dark-product/hero-section.tsx +83 -55
- package/registry/layers/capability/layout-landing/variants/dark-product/landing-page.tsx +25 -63
- package/registry/layers/capability/layout-landing/variants/dark-product/personalize.json +53 -0
- package/registry/layers/capability/layout-landing/variants/dark-product/pricing-section.tsx +51 -91
- package/registry/layers/capability/layout-landing/variants/default/features-section.tsx +54 -77
- package/registry/layers/capability/layout-landing/variants/default/hero-section.tsx +18 -23
- package/registry/layers/capability/layout-landing/variants/default/landing-page.tsx +25 -63
- package/registry/layers/capability/layout-landing/variants/default/personalize.json +146 -0
- package/registry/layers/capability/layout-landing/variants/default/pricing-section.tsx +45 -94
- package/registry/layers/capability/layout-landing/variants/gradient-hero/features-section.tsx +53 -57
- package/registry/layers/capability/layout-landing/variants/gradient-hero/hero-section.tsx +86 -53
- package/registry/layers/capability/layout-landing/variants/gradient-hero/landing-page.tsx +25 -63
- package/registry/layers/capability/layout-landing/variants/gradient-hero/personalize.json +53 -0
- package/registry/layers/capability/layout-landing/variants/gradient-hero/pricing-section.tsx +49 -88
- package/registry/layers/capability/layout-landing/variants/minimal-clean/features-section.tsx +53 -51
- package/registry/layers/capability/layout-landing/variants/minimal-clean/hero-section.tsx +88 -47
- package/registry/layers/capability/layout-landing/variants/minimal-clean/landing-page.tsx +25 -63
- package/registry/layers/capability/layout-landing/variants/minimal-clean/personalize.json +53 -0
- package/registry/layers/capability/layout-landing/variants/minimal-clean/pricing-section.tsx +51 -87
- package/registry/layers/framework/nextjs-app-router/files/layout.tsx +1 -0
- package/registry/layers/framework/nextjs-app-router/files/personalize.css +1 -0
- package/registry/layers/framework/nextjs-app-router/manifest.json +4 -0
- package/registry/layers/framework/react-vite-ts/files/main.ts +1 -0
- package/registry/layers/framework/react-vite-ts/files/personalize.css +1 -0
- package/registry/layers/framework/react-vite-ts/manifest.json +4 -0
- package/registry/layers/industry/creative/files/personalize.css +11 -0
- package/registry/layers/industry/creative/manifest.json +39 -0
- package/registry/layers/industry/crypto/files/personalize.css +11 -0
- package/registry/layers/industry/crypto/manifest.json +41 -0
- package/registry/layers/industry/ecommerce/files/personalize.css +11 -0
- package/registry/layers/industry/ecommerce/manifest.json +39 -0
- package/registry/layers/industry/education/files/personalize.css +11 -0
- package/registry/layers/industry/education/manifest.json +39 -0
- package/registry/layers/industry/finance/files/personalize.css +11 -0
- package/registry/layers/industry/finance/manifest.json +39 -0
- package/registry/layers/industry/fitness/files/personalize.css +11 -0
- package/registry/layers/industry/fitness/manifest.json +43 -0
- package/registry/layers/industry/gaming/files/personalize.css +11 -0
- package/registry/layers/industry/gaming/manifest.json +39 -0
- package/registry/layers/industry/health/files/personalize.css +11 -0
- package/registry/layers/industry/health/manifest.json +39 -0
- package/registry/layers/industry/restaurant/files/personalize.css +11 -0
- package/registry/layers/industry/restaurant/manifest.json +41 -0
- package/registry/layers/industry/saas/files/personalize.css +11 -0
- package/registry/layers/industry/saas/manifest.json +39 -0
|
@@ -1,98 +1,75 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Icons from 'lucide-react'
|
|
2
|
+
import type { LucideIcon } from 'lucide-react'
|
|
3
|
+
import personalize from '@/personalize.json'
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
description:
|
|
8
|
-
'Optimized for speed with edge-first architecture. Sub-second response times out of the box with automatic CDN distribution.',
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
icon: Shield,
|
|
12
|
-
title: 'Secure by Default',
|
|
13
|
-
description:
|
|
14
|
-
'Enterprise-grade security with end-to-end encryption, SOC 2 compliance, and role-based access controls baked into every layer.',
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
icon: BarChart3,
|
|
18
|
-
title: 'Built-in Analytics',
|
|
19
|
-
description:
|
|
20
|
-
'Real-time dashboards and custom reports so you always know what is working. Track every metric that matters to your business.',
|
|
21
|
-
},
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
const secondaryFeatures = [
|
|
25
|
-
{ icon: Layers, label: 'Composable modules — pick only the pieces you need' },
|
|
26
|
-
{ icon: Globe, label: 'Deploy to 30+ regions with a single command' },
|
|
27
|
-
{ icon: Lock, label: 'SSO, SAML, and audit logs for compliance' },
|
|
28
|
-
]
|
|
5
|
+
function getIcon(name: string): LucideIcon {
|
|
6
|
+
const Icon = (Icons as unknown as Record<string, LucideIcon>)[name]
|
|
7
|
+
return Icon ?? Icons.Sparkles
|
|
8
|
+
}
|
|
29
9
|
|
|
30
10
|
export function FeaturesSection() {
|
|
11
|
+
const { features } = personalize
|
|
31
12
|
return (
|
|
32
|
-
<section className="relative bg-
|
|
33
|
-
<style>{`
|
|
34
|
-
@keyframes fadeInUp {
|
|
35
|
-
from {
|
|
36
|
-
opacity: 0;
|
|
37
|
-
transform: translateY(20px);
|
|
38
|
-
}
|
|
39
|
-
to {
|
|
40
|
-
opacity: 1;
|
|
41
|
-
transform: translateY(0);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
`}</style>
|
|
45
|
-
|
|
13
|
+
<section id="features" className="relative bg-background py-24 sm:py-32">
|
|
46
14
|
<div className="mx-auto max-w-6xl px-6 lg:px-8">
|
|
47
15
|
<div className="mx-auto max-w-2xl text-center">
|
|
48
|
-
<
|
|
49
|
-
|
|
16
|
+
<p className="text-sm font-semibold uppercase tracking-wider text-primary">
|
|
17
|
+
{features.eyebrow}
|
|
18
|
+
</p>
|
|
19
|
+
<h2 className="mt-3 text-4xl font-bold tracking-tight text-foreground sm:text-5xl">
|
|
20
|
+
{features.headline}
|
|
50
21
|
</h2>
|
|
51
|
-
<p className="mt-
|
|
52
|
-
|
|
22
|
+
<p className="mt-6 text-lg leading-relaxed text-muted-foreground">
|
|
23
|
+
{features.subheadline}
|
|
53
24
|
</p>
|
|
54
25
|
</div>
|
|
55
26
|
|
|
56
|
-
<div className="
|
|
57
|
-
{
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
className="relative rounded-xl border border-border/50 bg-card p-8 opacity-0 transition-all duration-200 hover:border-border hover:shadow-md [animation:fadeInUp_0.5s_ease_forwards]"
|
|
61
|
-
style={{ animationDelay: `${0.1 + i * 0.15}s` }}
|
|
62
|
-
>
|
|
63
|
-
{/* Gradient top border */}
|
|
27
|
+
<div className="mt-20 grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
28
|
+
{features.primary.map((feature, i) => {
|
|
29
|
+
const Icon = getIcon(feature.icon)
|
|
30
|
+
return (
|
|
64
31
|
<div
|
|
65
|
-
|
|
66
|
-
className="
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<
|
|
32
|
+
key={feature.title}
|
|
33
|
+
className="group relative overflow-hidden rounded-xl border border-border/50 bg-card p-8 shadow-sm transition-all duration-200 hover:border-border hover:shadow-md"
|
|
34
|
+
style={{ animation: `fadeInUp 0.6s ease ${i * 0.15}s both` }}
|
|
35
|
+
>
|
|
36
|
+
<div className="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-primary/50 to-transparent" />
|
|
37
|
+
<div className="flex h-11 w-11 items-center justify-center rounded-lg bg-gradient-to-br from-primary/20 to-primary/5 text-primary">
|
|
38
|
+
<Icon className="h-5 w-5" />
|
|
39
|
+
</div>
|
|
40
|
+
<h3 className="mt-6 text-lg font-semibold text-foreground">{feature.title}</h3>
|
|
41
|
+
<p className="mt-3 text-sm leading-relaxed text-muted-foreground">
|
|
42
|
+
{feature.description}
|
|
43
|
+
</p>
|
|
70
44
|
</div>
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
</h3>
|
|
74
|
-
<p className="mt-2 text-sm leading-relaxed text-muted-foreground">
|
|
75
|
-
{feature.description}
|
|
76
|
-
</p>
|
|
77
|
-
</div>
|
|
78
|
-
))}
|
|
45
|
+
)
|
|
46
|
+
})}
|
|
79
47
|
</div>
|
|
80
48
|
|
|
81
|
-
<div className="
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
49
|
+
<div className="mt-16 grid gap-8 border-t border-border/50 pt-16 sm:grid-cols-3">
|
|
50
|
+
{features.secondary.map((feature) => {
|
|
51
|
+
const Icon = getIcon(feature.icon)
|
|
52
|
+
return (
|
|
53
|
+
<div key={feature.title} className="flex gap-4">
|
|
54
|
+
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground">
|
|
55
|
+
<Icon className="h-4 w-4" />
|
|
56
|
+
</div>
|
|
57
|
+
<div>
|
|
58
|
+
<h4 className="text-sm font-semibold text-foreground">{feature.title}</h4>
|
|
59
|
+
<p className="mt-1 text-sm text-muted-foreground">{feature.description}</p>
|
|
87
60
|
</div>
|
|
88
|
-
<p className="text-sm leading-snug text-muted-foreground">
|
|
89
|
-
{feature.label}
|
|
90
|
-
</p>
|
|
91
61
|
</div>
|
|
92
|
-
)
|
|
93
|
-
|
|
62
|
+
)
|
|
63
|
+
})}
|
|
94
64
|
</div>
|
|
95
65
|
</div>
|
|
66
|
+
|
|
67
|
+
<style>{`
|
|
68
|
+
@keyframes fadeInUp {
|
|
69
|
+
from { opacity: 0; transform: translateY(20px); }
|
|
70
|
+
to { opacity: 1; transform: translateY(0); }
|
|
71
|
+
}
|
|
72
|
+
`}</style>
|
|
96
73
|
</section>
|
|
97
74
|
)
|
|
98
75
|
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { Button } from '@/components/ui/button'
|
|
2
2
|
import { ArrowRight, Play } from 'lucide-react'
|
|
3
|
+
import personalize from '@/personalize.json'
|
|
3
4
|
|
|
4
5
|
export function HeroSection() {
|
|
6
|
+
const { hero, trust } = personalize
|
|
5
7
|
return (
|
|
6
8
|
<section className="relative overflow-hidden bg-background">
|
|
7
|
-
{/* Radial gradient backdrop */}
|
|
8
9
|
<div
|
|
9
10
|
aria-hidden="true"
|
|
10
11
|
className="pointer-events-none absolute inset-0 bg-[radial-gradient(ellipse_80%_50%_at_50%_-20%,hsl(var(--primary)/0.08),transparent)]"
|
|
11
12
|
/>
|
|
12
|
-
|
|
13
|
-
{/* Decorative blur orbs */}
|
|
14
13
|
<div
|
|
15
14
|
aria-hidden="true"
|
|
16
15
|
className="pointer-events-none absolute -right-40 -top-40 h-[500px] w-[500px] rounded-full bg-primary/15 blur-3xl"
|
|
@@ -22,27 +21,25 @@ export function HeroSection() {
|
|
|
22
21
|
|
|
23
22
|
<div className="relative mx-auto max-w-6xl px-6 py-28 sm:py-36 lg:px-8 lg:py-44">
|
|
24
23
|
<div className="grid items-center gap-12 lg:grid-cols-2 lg:gap-16">
|
|
25
|
-
{/* Left column — text content */}
|
|
26
24
|
<div className="flex flex-col items-center text-center lg:items-start lg:text-left">
|
|
27
|
-
<div className="rounded-full border border-
|
|
28
|
-
|
|
25
|
+
<div className="rounded-full border border-border/40 bg-muted/50 px-4 py-1.5 text-xs font-medium tracking-wider text-muted-foreground backdrop-blur-sm">
|
|
26
|
+
{hero.badge}
|
|
29
27
|
</div>
|
|
30
28
|
|
|
31
29
|
<h1 className="mt-8 text-5xl font-bold tracking-tighter text-foreground sm:text-6xl lg:text-7xl">
|
|
32
|
-
{
|
|
30
|
+
{hero.headline}
|
|
33
31
|
</h1>
|
|
34
32
|
|
|
35
33
|
<p className="mt-6 max-w-xl text-lg leading-relaxed text-muted-foreground">
|
|
36
|
-
|
|
37
|
-
that gives your team everything it needs to go from idea to production.
|
|
34
|
+
{hero.subheadline}
|
|
38
35
|
</p>
|
|
39
36
|
|
|
40
|
-
<div className="mt-10 flex items-center gap-4">
|
|
37
|
+
<div className="mt-10 flex flex-wrap items-center justify-center gap-4 lg:justify-start">
|
|
41
38
|
<Button
|
|
42
39
|
size="lg"
|
|
43
40
|
className="h-12 gap-2 rounded-lg px-8 font-medium shadow-lg shadow-primary/25 transition-transform hover:scale-105 active:scale-95 focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2"
|
|
44
41
|
>
|
|
45
|
-
|
|
42
|
+
{hero.ctaPrimary}
|
|
46
43
|
<ArrowRight className="h-4 w-4" />
|
|
47
44
|
</Button>
|
|
48
45
|
<Button
|
|
@@ -51,11 +48,11 @@ export function HeroSection() {
|
|
|
51
48
|
className="h-12 gap-2 rounded-lg border-2 px-8 font-medium transition-transform hover:scale-105 active:scale-95 focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2"
|
|
52
49
|
>
|
|
53
50
|
<Play className="h-4 w-4" />
|
|
54
|
-
|
|
51
|
+
{hero.ctaSecondary}
|
|
55
52
|
</Button>
|
|
56
53
|
</div>
|
|
57
54
|
|
|
58
|
-
<div className="mt-
|
|
55
|
+
<div className="mt-12 flex items-center gap-3">
|
|
59
56
|
<div className="flex -space-x-2">
|
|
60
57
|
{['bg-primary', 'bg-chart-1', 'bg-chart-2', 'bg-chart-3', 'bg-chart-4'].map((color, i) => (
|
|
61
58
|
<div
|
|
@@ -65,20 +62,17 @@ export function HeroSection() {
|
|
|
65
62
|
))}
|
|
66
63
|
</div>
|
|
67
64
|
<p className="text-sm font-medium text-muted-foreground">
|
|
68
|
-
|
|
65
|
+
{trust.label}
|
|
69
66
|
</p>
|
|
70
67
|
</div>
|
|
71
68
|
</div>
|
|
72
69
|
|
|
73
|
-
{/* Right column — product mockup */}
|
|
74
70
|
<div className="relative mx-auto w-full max-w-lg lg:mx-0">
|
|
75
|
-
{/* Glow behind mockup */}
|
|
76
71
|
<div
|
|
77
72
|
aria-hidden="true"
|
|
78
73
|
className="pointer-events-none absolute -inset-4 rounded-2xl bg-primary/10 blur-2xl"
|
|
79
74
|
/>
|
|
80
|
-
<div className="relative rounded-xl border border-border/50 bg-card shadow-2xl shadow-primary/5
|
|
81
|
-
{/* Browser toolbar */}
|
|
75
|
+
<div className="relative overflow-hidden rounded-xl border border-border/50 bg-card shadow-2xl shadow-primary/5">
|
|
82
76
|
<div className="flex items-center gap-2 border-b border-border/50 bg-muted/50 px-4 py-3">
|
|
83
77
|
<div className="flex items-center gap-1.5">
|
|
84
78
|
<div className="h-3 w-3 rounded-full bg-red-400/80" />
|
|
@@ -86,20 +80,21 @@ export function HeroSection() {
|
|
|
86
80
|
<div className="h-3 w-3 rounded-full bg-green-400/80" />
|
|
87
81
|
</div>
|
|
88
82
|
<div className="ml-3 flex-1 rounded-md bg-background/80 px-3 py-1 text-xs text-muted-foreground">
|
|
89
|
-
|
|
83
|
+
{personalize.brand.name.toLowerCase()}.com
|
|
90
84
|
</div>
|
|
91
85
|
</div>
|
|
92
|
-
{/* Content area */}
|
|
93
86
|
<div className="relative aspect-[4/3]">
|
|
94
87
|
<img
|
|
95
88
|
src="/images/hero-product.png"
|
|
96
|
-
alt=
|
|
89
|
+
alt={`${personalize.brand.name} product screenshot`}
|
|
97
90
|
className="h-full w-full object-cover"
|
|
98
91
|
onError={(e) => { e.currentTarget.style.display = 'none' }}
|
|
99
92
|
/>
|
|
100
|
-
{/* Gradient fallback shown when image hasn't been generated yet */}
|
|
101
93
|
<div className="absolute inset-0 flex items-center justify-center bg-gradient-to-br from-primary/10 to-accent/10">
|
|
102
|
-
<
|
|
94
|
+
<div className="text-center">
|
|
95
|
+
<p className="text-sm font-medium text-foreground">{personalize.brand.name}</p>
|
|
96
|
+
<p className="mt-1 text-xs text-muted-foreground">{personalize.brand.tagline}</p>
|
|
97
|
+
</div>
|
|
103
98
|
</div>
|
|
104
99
|
</div>
|
|
105
100
|
</div>
|
|
@@ -2,43 +2,10 @@ import { Button } from '@/components/ui/button'
|
|
|
2
2
|
import { HeroSection } from '@/components/landing/hero-section'
|
|
3
3
|
import { FeaturesSection } from '@/components/landing/features-section'
|
|
4
4
|
import { PricingSection } from '@/components/landing/pricing-section'
|
|
5
|
-
|
|
6
|
-
const footerLinks = {
|
|
7
|
-
Product: [
|
|
8
|
-
{ label: 'Features', href: '#features' },
|
|
9
|
-
{ label: 'Pricing', href: '#pricing' },
|
|
10
|
-
{ label: 'Changelog', href: '/changelog' },
|
|
11
|
-
{ label: 'Docs', href: '/docs' },
|
|
12
|
-
],
|
|
13
|
-
Company: [
|
|
14
|
-
{ label: 'About', href: '/about' },
|
|
15
|
-
{ label: 'Blog', href: '/blog' },
|
|
16
|
-
{ label: 'Careers', href: '/careers' },
|
|
17
|
-
{ label: 'Contact', href: '/contact' },
|
|
18
|
-
],
|
|
19
|
-
Resources: [
|
|
20
|
-
{ label: 'Documentation', href: '/docs' },
|
|
21
|
-
{ label: 'API Reference', href: '/docs/api' },
|
|
22
|
-
{ label: 'Status', href: '/status' },
|
|
23
|
-
{ label: 'Support', href: '/support' },
|
|
24
|
-
],
|
|
25
|
-
Legal: [
|
|
26
|
-
{ label: 'Privacy', href: '/privacy' },
|
|
27
|
-
{ label: 'Terms', href: '/terms' },
|
|
28
|
-
{ label: 'Security', href: '/security' },
|
|
29
|
-
],
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const trustLogos = [
|
|
33
|
-
'Acme Corp',
|
|
34
|
-
'TechFlow',
|
|
35
|
-
'Quantum',
|
|
36
|
-
'NovaSoft',
|
|
37
|
-
'BuildStack',
|
|
38
|
-
'DataPipe',
|
|
39
|
-
]
|
|
5
|
+
import personalize from '@/personalize.json'
|
|
40
6
|
|
|
41
7
|
export default function LandingPage() {
|
|
8
|
+
const { brand, trust, footer } = personalize
|
|
42
9
|
return (
|
|
43
10
|
<div className="min-h-screen scroll-smooth bg-background text-foreground">
|
|
44
11
|
<a
|
|
@@ -53,28 +20,28 @@ export default function LandingPage() {
|
|
|
53
20
|
<span className="flex items-center gap-2 text-lg font-semibold tracking-tight">
|
|
54
21
|
<img
|
|
55
22
|
src="/images/logo.svg"
|
|
56
|
-
alt=
|
|
23
|
+
alt={brand.name}
|
|
57
24
|
className="h-8 w-auto"
|
|
58
25
|
onError={(e) => { e.currentTarget.style.display = 'none' }}
|
|
59
26
|
/>
|
|
60
|
-
<span>{
|
|
27
|
+
<span>{brand.name}</span>
|
|
61
28
|
</span>
|
|
62
29
|
<nav className="hidden items-center gap-8 text-sm md:flex">
|
|
63
30
|
<a
|
|
64
31
|
href="#features"
|
|
65
|
-
className="font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2
|
|
32
|
+
className="font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2"
|
|
66
33
|
>
|
|
67
34
|
Features
|
|
68
35
|
</a>
|
|
69
36
|
<a
|
|
70
37
|
href="#pricing"
|
|
71
|
-
className="font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2
|
|
38
|
+
className="font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2"
|
|
72
39
|
>
|
|
73
40
|
Pricing
|
|
74
41
|
</a>
|
|
75
42
|
<a
|
|
76
43
|
href="/sign-in"
|
|
77
|
-
className="font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2
|
|
44
|
+
className="font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2"
|
|
78
45
|
>
|
|
79
46
|
Sign in
|
|
80
47
|
</a>
|
|
@@ -95,17 +62,16 @@ export default function LandingPage() {
|
|
|
95
62
|
<main id="main">
|
|
96
63
|
<HeroSection />
|
|
97
64
|
|
|
98
|
-
{/* Trust section */}
|
|
99
65
|
<section className="border-y border-border/50 bg-muted/20 py-12 dark:bg-muted/5">
|
|
100
66
|
<div className="mx-auto max-w-6xl px-6 lg:px-8">
|
|
101
67
|
<p className="mb-8 text-center text-xs font-medium uppercase tracking-widest text-muted-foreground">
|
|
102
68
|
Trusted by teams at
|
|
103
69
|
</p>
|
|
104
70
|
<div className="flex flex-wrap items-center justify-center gap-x-10 gap-y-4 lg:gap-x-16">
|
|
105
|
-
{
|
|
71
|
+
{trust.logoNames.map((name) => (
|
|
106
72
|
<span
|
|
107
73
|
key={name}
|
|
108
|
-
className="text-lg font-semibold tracking-tight text-muted-foreground/30
|
|
74
|
+
className="select-none text-lg font-semibold tracking-tight text-muted-foreground/30"
|
|
109
75
|
>
|
|
110
76
|
{name}
|
|
111
77
|
</span>
|
|
@@ -114,35 +80,33 @@ export default function LandingPage() {
|
|
|
114
80
|
</div>
|
|
115
81
|
</section>
|
|
116
82
|
|
|
117
|
-
{/* Gradient divider */}
|
|
118
83
|
<div aria-hidden="true" className="h-px bg-gradient-to-r from-transparent via-border to-transparent" />
|
|
119
84
|
|
|
120
|
-
<
|
|
121
|
-
<FeaturesSection />
|
|
122
|
-
</section>
|
|
85
|
+
<FeaturesSection />
|
|
123
86
|
|
|
124
|
-
{/* Gradient divider */}
|
|
125
87
|
<div aria-hidden="true" className="h-px bg-gradient-to-r from-transparent via-border to-transparent" />
|
|
126
88
|
|
|
127
|
-
<
|
|
128
|
-
<PricingSection />
|
|
129
|
-
</section>
|
|
89
|
+
<PricingSection />
|
|
130
90
|
</main>
|
|
131
91
|
|
|
132
|
-
<footer className="border-t
|
|
92
|
+
<footer className="border-t border-border/50 bg-muted/10">
|
|
133
93
|
<div className="mx-auto max-w-6xl px-6 py-16 lg:px-8">
|
|
134
|
-
<div className="grid gap-8
|
|
135
|
-
|
|
136
|
-
<
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
94
|
+
<div className="grid gap-8 lg:grid-cols-5 lg:gap-12">
|
|
95
|
+
<div className="lg:col-span-1">
|
|
96
|
+
<span className="text-lg font-semibold tracking-tight">{brand.name}</span>
|
|
97
|
+
<p className="mt-3 text-sm leading-relaxed text-muted-foreground">
|
|
98
|
+
{footer.tagline}
|
|
99
|
+
</p>
|
|
100
|
+
</div>
|
|
101
|
+
{Object.entries(footer.sections).map(([title, links]) => (
|
|
102
|
+
<div key={title}>
|
|
103
|
+
<h4 className="text-sm font-semibold text-foreground">{title}</h4>
|
|
140
104
|
<ul className="mt-4 space-y-3">
|
|
141
105
|
{links.map((link) => (
|
|
142
106
|
<li key={link.label}>
|
|
143
107
|
<a
|
|
144
108
|
href={link.href}
|
|
145
|
-
className="text-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:
|
|
109
|
+
className="text-sm text-muted-foreground transition-colors hover:text-foreground focus-visible:rounded focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2"
|
|
146
110
|
>
|
|
147
111
|
{link.label}
|
|
148
112
|
</a>
|
|
@@ -152,10 +116,8 @@ export default function LandingPage() {
|
|
|
152
116
|
</div>
|
|
153
117
|
))}
|
|
154
118
|
</div>
|
|
155
|
-
<div className="mt-12 border-t pt-8">
|
|
156
|
-
<p className="text-sm text-muted-foreground">
|
|
157
|
-
© {new Date().getFullYear()} {'{{headline}}'}. All rights reserved.
|
|
158
|
-
</p>
|
|
119
|
+
<div className="mt-12 border-t border-border/50 pt-8">
|
|
120
|
+
<p className="text-sm text-muted-foreground">{footer.copyright}</p>
|
|
159
121
|
</div>
|
|
160
122
|
</div>
|
|
161
123
|
</footer>
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_meta": {
|
|
3
|
+
"doc": "Edit this file to customize ALL copy, branding, and content on the landing page. Components read from this at build time. Agents personalizing scaffolds should rewrite this file based on the user's actual product.",
|
|
4
|
+
"version": 1
|
|
5
|
+
},
|
|
6
|
+
"brand": {
|
|
7
|
+
"name": "Acme",
|
|
8
|
+
"tagline": "The platform for shipping fast"
|
|
9
|
+
},
|
|
10
|
+
"hero": {
|
|
11
|
+
"badge": "NOW IN BETA — GET EARLY ACCESS",
|
|
12
|
+
"headline": "Build something people want.",
|
|
13
|
+
"subheadline": "The modern platform that gives your team everything it needs to go from idea to production.",
|
|
14
|
+
"ctaPrimary": "Get Started",
|
|
15
|
+
"ctaSecondary": "See a Demo"
|
|
16
|
+
},
|
|
17
|
+
"trust": {
|
|
18
|
+
"label": "Trusted by 1,000+ teams worldwide",
|
|
19
|
+
"logoNames": ["Acme Corp", "TechFlow", "Quantum", "NovaSoft", "BuildStack", "DataPipe"]
|
|
20
|
+
},
|
|
21
|
+
"features": {
|
|
22
|
+
"eyebrow": "Features",
|
|
23
|
+
"headline": "Everything you need, nothing you don't",
|
|
24
|
+
"subheadline": "Built for teams who care about craft and ship fast.",
|
|
25
|
+
"primary": [
|
|
26
|
+
{
|
|
27
|
+
"icon": "Zap",
|
|
28
|
+
"title": "Lightning fast",
|
|
29
|
+
"description": "Optimized for speed at every layer. Sub-second cold starts, instant hot reload."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"icon": "Shield",
|
|
33
|
+
"title": "Secure by default",
|
|
34
|
+
"description": "Authentication, authorization, and encryption built in. SOC 2 ready out of the box."
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"icon": "BarChart3",
|
|
38
|
+
"title": "Built-in analytics",
|
|
39
|
+
"description": "Real-time metrics, custom dashboards, and automatic alerting on what matters."
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"secondary": [
|
|
43
|
+
{
|
|
44
|
+
"icon": "Layers",
|
|
45
|
+
"title": "Composable architecture",
|
|
46
|
+
"description": "Mix and match the pieces you need."
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"icon": "Globe",
|
|
50
|
+
"title": "Global by default",
|
|
51
|
+
"description": "Edge-deployed across 200+ regions."
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"icon": "Lock",
|
|
55
|
+
"title": "Privacy-first",
|
|
56
|
+
"description": "Your data stays yours. No tracking, no telemetry."
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"pricing": {
|
|
61
|
+
"eyebrow": "Pricing",
|
|
62
|
+
"headline": "Simple, transparent pricing",
|
|
63
|
+
"subheadline": "Start free. Upgrade when you're ready. Cancel anytime.",
|
|
64
|
+
"toggleMonthly": "Monthly",
|
|
65
|
+
"toggleYearly": "Yearly",
|
|
66
|
+
"yearlyDiscount": "Save 20%",
|
|
67
|
+
"tiers": [
|
|
68
|
+
{
|
|
69
|
+
"name": "Free",
|
|
70
|
+
"price": "$0",
|
|
71
|
+
"period": "/mo",
|
|
72
|
+
"description": "For side projects and exploration",
|
|
73
|
+
"features": [
|
|
74
|
+
"Up to 3 projects",
|
|
75
|
+
"Community support",
|
|
76
|
+
"Basic analytics",
|
|
77
|
+
"1 team member"
|
|
78
|
+
],
|
|
79
|
+
"cta": "Start for free",
|
|
80
|
+
"highlighted": false,
|
|
81
|
+
"note": "No credit card required"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "Pro",
|
|
85
|
+
"price": "$29",
|
|
86
|
+
"period": "/mo",
|
|
87
|
+
"description": "For growing teams shipping in production",
|
|
88
|
+
"features": [
|
|
89
|
+
"Unlimited projects",
|
|
90
|
+
"Priority support",
|
|
91
|
+
"Advanced analytics",
|
|
92
|
+
"Up to 10 team members",
|
|
93
|
+
"Custom integrations",
|
|
94
|
+
"API access"
|
|
95
|
+
],
|
|
96
|
+
"cta": "Start free trial",
|
|
97
|
+
"highlighted": true
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "Enterprise",
|
|
101
|
+
"price": "Custom",
|
|
102
|
+
"period": "",
|
|
103
|
+
"description": "For organizations with custom needs",
|
|
104
|
+
"features": [
|
|
105
|
+
"Everything in Pro",
|
|
106
|
+
"Unlimited team members",
|
|
107
|
+
"Dedicated support",
|
|
108
|
+
"Custom SLAs",
|
|
109
|
+
"SSO and SAML",
|
|
110
|
+
"On-premise deployment"
|
|
111
|
+
],
|
|
112
|
+
"cta": "Contact sales",
|
|
113
|
+
"highlighted": false
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
"footer": {
|
|
118
|
+
"tagline": "Built with care by people who give a damn.",
|
|
119
|
+
"sections": {
|
|
120
|
+
"Product": [
|
|
121
|
+
{ "label": "Features", "href": "#features" },
|
|
122
|
+
{ "label": "Pricing", "href": "#pricing" },
|
|
123
|
+
{ "label": "Changelog", "href": "/changelog" },
|
|
124
|
+
{ "label": "Docs", "href": "/docs" }
|
|
125
|
+
],
|
|
126
|
+
"Company": [
|
|
127
|
+
{ "label": "About", "href": "/about" },
|
|
128
|
+
{ "label": "Blog", "href": "/blog" },
|
|
129
|
+
{ "label": "Careers", "href": "/careers" },
|
|
130
|
+
{ "label": "Contact", "href": "/contact" }
|
|
131
|
+
],
|
|
132
|
+
"Resources": [
|
|
133
|
+
{ "label": "Documentation", "href": "/docs" },
|
|
134
|
+
{ "label": "API Reference", "href": "/docs/api" },
|
|
135
|
+
{ "label": "Status", "href": "/status" },
|
|
136
|
+
{ "label": "Support", "href": "/support" }
|
|
137
|
+
],
|
|
138
|
+
"Legal": [
|
|
139
|
+
{ "label": "Privacy", "href": "/privacy" },
|
|
140
|
+
{ "label": "Terms", "href": "/terms" },
|
|
141
|
+
{ "label": "Security", "href": "/security" }
|
|
142
|
+
]
|
|
143
|
+
},
|
|
144
|
+
"copyright": "© 2026 Acme. All rights reserved."
|
|
145
|
+
}
|
|
146
|
+
}
|