ship-create 1.0.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.
Files changed (56) hide show
  1. package/README.md +39 -0
  2. package/create.mjs +301 -0
  3. package/package.json +25 -0
  4. package/templates/.cursorrules +51 -0
  5. package/templates/.windsurfrules +51 -0
  6. package/templates/AGENTS.md +51 -0
  7. package/templates/CLAUDE.md +51 -0
  8. package/templates/docs/HUMAN_FLOW.md +205 -0
  9. package/templates/docs/PROJECT.md +154 -0
  10. package/templates/docs/PROMPTS.md +246 -0
  11. package/templates/docs/product-types/CRM_TEMPLATE.md +78 -0
  12. package/templates/docs/product-types/DASHBOARD_TEMPLATE.md +78 -0
  13. package/templates/docs/product-types/DIRECTORY_TEMPLATE.md +75 -0
  14. package/templates/docs/product-types/INTERNAL_TOOL_TEMPLATE.md +77 -0
  15. package/templates/docs/product-types/LEADGEN_TEMPLATE.md +78 -0
  16. package/templates/docs/product-types/MARKETPLACE_TEMPLATE.md +81 -0
  17. package/templates/docs/product-types/MEMBERSHIP_TEMPLATE.md +80 -0
  18. package/templates/docs/product-types/SAAS_TEMPLATE.md +79 -0
  19. package/templates/starter-kit/README.md +64 -0
  20. package/templates/starter-kit/app/backoffice/content/page.tsx +93 -0
  21. package/templates/starter-kit/app/backoffice/layout.tsx +105 -0
  22. package/templates/starter-kit/app/backoffice/page.tsx +165 -0
  23. package/templates/starter-kit/app/backoffice/settings/page.tsx +145 -0
  24. package/templates/starter-kit/app/backoffice/users/page.tsx +134 -0
  25. package/templates/starter-kit/app/globals.css +141 -0
  26. package/templates/starter-kit/app/layout.tsx +43 -0
  27. package/templates/starter-kit/app/member/(app)/billing/page.tsx +137 -0
  28. package/templates/starter-kit/app/member/(app)/content/page.tsx +111 -0
  29. package/templates/starter-kit/app/member/(app)/dashboard/page.tsx +129 -0
  30. package/templates/starter-kit/app/member/(app)/layout.tsx +130 -0
  31. package/templates/starter-kit/app/member/(app)/settings/page.tsx +96 -0
  32. package/templates/starter-kit/app/member/login/page.tsx +106 -0
  33. package/templates/starter-kit/app/member/signup/page.tsx +120 -0
  34. package/templates/starter-kit/app/page.tsx +82 -0
  35. package/templates/starter-kit/app/sale/_components/cta-footer.tsx +66 -0
  36. package/templates/starter-kit/app/sale/_components/faq.tsx +107 -0
  37. package/templates/starter-kit/app/sale/_components/features.tsx +95 -0
  38. package/templates/starter-kit/app/sale/_components/hero.tsx +106 -0
  39. package/templates/starter-kit/app/sale/_components/pricing.tsx +133 -0
  40. package/templates/starter-kit/app/sale/_components/problem.tsx +59 -0
  41. package/templates/starter-kit/app/sale/_components/testimonials.tsx +100 -0
  42. package/templates/starter-kit/app/sale/page.tsx +21 -0
  43. package/templates/starter-kit/components/ui/avatar.tsx +50 -0
  44. package/templates/starter-kit/components/ui/badge.tsx +36 -0
  45. package/templates/starter-kit/components/ui/button.tsx +56 -0
  46. package/templates/starter-kit/components/ui/card.tsx +78 -0
  47. package/templates/starter-kit/components/ui/input.tsx +24 -0
  48. package/templates/starter-kit/components/ui/table.tsx +88 -0
  49. package/templates/starter-kit/components/ui/tabs.tsx +55 -0
  50. package/templates/starter-kit/lib/mock-data.ts +118 -0
  51. package/templates/starter-kit/lib/utils.ts +6 -0
  52. package/templates/starter-kit/next.config.mjs +6 -0
  53. package/templates/starter-kit/package.json +36 -0
  54. package/templates/starter-kit/postcss.config.mjs +9 -0
  55. package/templates/starter-kit/tailwind.config.ts +83 -0
  56. package/templates/starter-kit/tsconfig.json +41 -0
@@ -0,0 +1,130 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import Link from "next/link";
5
+ import { usePathname, useRouter } from "next/navigation";
6
+ import {
7
+ LayoutDashboard,
8
+ BookOpen,
9
+ CreditCard,
10
+ Settings,
11
+ LogOut,
12
+ } from "lucide-react";
13
+
14
+ import { cn } from "@/lib/utils";
15
+ import { users } from "@/lib/mock-data";
16
+ import { Avatar, AvatarFallback } from "@/components/ui/avatar";
17
+
18
+ const mockUser = users[0];
19
+
20
+ const navItems = [
21
+ { label: "Dashboard", href: "/member/dashboard", icon: LayoutDashboard },
22
+ { label: "Courses", href: "/member/content", icon: BookOpen },
23
+ { label: "Billing", href: "/member/billing", icon: CreditCard },
24
+ { label: "Settings", href: "/member/settings", icon: Settings },
25
+ ];
26
+
27
+ function initials(name: string) {
28
+ return name
29
+ .split(" ")
30
+ .map((part) => part[0])
31
+ .join("")
32
+ .slice(0, 2)
33
+ .toUpperCase();
34
+ }
35
+
36
+ const pageTitles: Record<string, string> = {
37
+ "/member/dashboard": "Dashboard",
38
+ "/member/content": "Courses",
39
+ "/member/billing": "Billing",
40
+ "/member/settings": "Settings",
41
+ };
42
+
43
+ export default function MemberAppLayout({
44
+ children,
45
+ }: {
46
+ children: React.ReactNode;
47
+ }) {
48
+ const pathname = usePathname();
49
+ const router = useRouter();
50
+
51
+ const title = pageTitles[pathname] ?? "Member Area";
52
+
53
+ return (
54
+ <div className="flex min-h-screen bg-background">
55
+ <aside className="flex w-64 flex-col border-r border-border/70 bg-card shadow-soft">
56
+ <div className="flex items-center gap-3 border-b border-border/70 px-6 py-6">
57
+ <span className="font-display text-xl font-medium tracking-tight text-foreground">
58
+ SHIP<span className="text-primary">.</span>
59
+ </span>
60
+ </div>
61
+
62
+ <div className="flex items-center gap-3 border-b border-border/70 px-6 py-5">
63
+ <Avatar>
64
+ <AvatarFallback>{initials(mockUser.name)}</AvatarFallback>
65
+ </Avatar>
66
+ <div className="min-w-0">
67
+ <p className="truncate text-sm font-semibold leading-tight">
68
+ {mockUser.name}
69
+ </p>
70
+ <p className="label-mono truncate text-muted-foreground">
71
+ {mockUser.plan} plan
72
+ </p>
73
+ </div>
74
+ </div>
75
+
76
+ <nav className="flex-1 space-y-1 px-3 py-5">
77
+ <p className="label-mono px-3 pb-2 text-muted-foreground/70">Menu</p>
78
+ {navItems.map((item) => {
79
+ const Icon = item.icon;
80
+ const active = pathname === item.href;
81
+ return (
82
+ <Link
83
+ key={item.href}
84
+ href={item.href}
85
+ className={cn(
86
+ "group relative flex items-center gap-3 rounded-full px-3 py-2.5 text-sm font-medium transition-all duration-200",
87
+ active
88
+ ? "bg-primary text-primary-foreground shadow-soft"
89
+ : "text-foreground/70 hover:bg-muted hover:text-foreground"
90
+ )}
91
+ >
92
+ {active && (
93
+ <span className="absolute -left-3 top-1/2 h-5 w-1 -translate-y-1/2 rounded-full bg-primary" />
94
+ )}
95
+ <Icon className="h-4 w-4" />
96
+ {item.label}
97
+ </Link>
98
+ );
99
+ })}
100
+ </nav>
101
+
102
+ <div className="border-t border-border/70 px-3 py-4">
103
+ <button
104
+ type="button"
105
+ onClick={() => router.push("/member/login")}
106
+ className="flex w-full items-center gap-3 rounded-full px-3 py-2.5 text-sm font-medium text-foreground/70 transition-all duration-200 hover:bg-muted hover:text-foreground"
107
+ >
108
+ <LogOut className="h-4 w-4" />
109
+ Logout
110
+ </button>
111
+ </div>
112
+ </aside>
113
+
114
+ <div className="flex flex-1 flex-col">
115
+ <header className="flex items-center justify-between border-b border-border/70 bg-card/60 px-8 py-4">
116
+ <h1 className="font-display text-lg font-medium tracking-tight">{title}</h1>
117
+ <div className="flex items-center gap-3">
118
+ <Avatar className="h-8 w-8">
119
+ <AvatarFallback className="text-xs">
120
+ {initials(mockUser.name)}
121
+ </AvatarFallback>
122
+ </Avatar>
123
+ </div>
124
+ </header>
125
+
126
+ <main className="flex-1 p-8">{children}</main>
127
+ </div>
128
+ </div>
129
+ );
130
+ }
@@ -0,0 +1,96 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+
5
+ import { users } from "@/lib/mock-data";
6
+ import {
7
+ Card,
8
+ CardHeader,
9
+ CardTitle,
10
+ CardDescription,
11
+ CardContent,
12
+ CardFooter,
13
+ } from "@/components/ui/card";
14
+ import { Input } from "@/components/ui/input";
15
+ import { Button } from "@/components/ui/button";
16
+
17
+ const mockUser = users[0];
18
+
19
+ export default function MemberSettingsPage() {
20
+ const [name, setName] = React.useState(mockUser.name);
21
+ const [email, setEmail] = React.useState(mockUser.email);
22
+
23
+ function handleSave(e: React.FormEvent) {
24
+ e.preventDefault();
25
+ // Mock save only — no backend wired up.
26
+ }
27
+
28
+ return (
29
+ <div className="space-y-6">
30
+ <div>
31
+ <h2 className="font-display text-3xl font-medium tracking-tight">
32
+ Settings
33
+ </h2>
34
+ <p className="mt-1 text-muted-foreground">
35
+ Manage your account details and preferences.
36
+ </p>
37
+ </div>
38
+
39
+ <Card className="animate-fade-up">
40
+ <CardHeader>
41
+ <CardTitle className="text-base">Account Information</CardTitle>
42
+ <CardDescription>
43
+ Update your name and email address.
44
+ </CardDescription>
45
+ </CardHeader>
46
+ <form onSubmit={handleSave}>
47
+ <CardContent className="space-y-4">
48
+ <div className="space-y-2">
49
+ <label htmlFor="settings-name" className="text-sm font-medium">
50
+ Name
51
+ </label>
52
+ <Input
53
+ id="settings-name"
54
+ value={name}
55
+ onChange={(e) => setName(e.target.value)}
56
+ />
57
+ </div>
58
+ <div className="space-y-2">
59
+ <label htmlFor="settings-email" className="text-sm font-medium">
60
+ Email
61
+ </label>
62
+ <Input
63
+ id="settings-email"
64
+ type="email"
65
+ value={email}
66
+ onChange={(e) => setEmail(e.target.value)}
67
+ />
68
+ </div>
69
+ </CardContent>
70
+ <CardFooter>
71
+ <Button type="submit">Save Changes</Button>
72
+ </CardFooter>
73
+ </form>
74
+ </Card>
75
+
76
+ <Card
77
+ className="animate-fade-up border-destructive/40 bg-destructive/[0.06]"
78
+ style={{ animationDelay: "80ms" }}
79
+ >
80
+ <CardHeader>
81
+ <span className="label-mono text-destructive">Danger Zone</span>
82
+ <CardTitle className="text-base text-destructive">
83
+ Delete account
84
+ </CardTitle>
85
+ <CardDescription>
86
+ Permanently delete your account and all associated data. This
87
+ action cannot be undone.
88
+ </CardDescription>
89
+ </CardHeader>
90
+ <CardFooter>
91
+ <Button variant="destructive">Delete Account</Button>
92
+ </CardFooter>
93
+ </Card>
94
+ </div>
95
+ );
96
+ }
@@ -0,0 +1,106 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import Link from "next/link";
5
+ import { useRouter } from "next/navigation";
6
+
7
+ import { Button } from "@/components/ui/button";
8
+ import { Input } from "@/components/ui/input";
9
+ import {
10
+ Card,
11
+ CardHeader,
12
+ CardTitle,
13
+ CardDescription,
14
+ CardContent,
15
+ CardFooter,
16
+ } from "@/components/ui/card";
17
+
18
+ export default function MemberLoginPage() {
19
+ const router = useRouter();
20
+ const [email, setEmail] = React.useState("");
21
+ const [password, setPassword] = React.useState("");
22
+
23
+ function handleLogin(e: React.FormEvent) {
24
+ e.preventDefault();
25
+ router.push("/member/dashboard");
26
+ }
27
+
28
+ return (
29
+ <div className="flex min-h-screen bg-background">
30
+ {/* Decorative panel — desktop only */}
31
+ <div className="relative hidden w-1/2 flex-col justify-between overflow-hidden bg-card px-12 py-12 lg:flex">
32
+ <div className="bg-grid absolute inset-0" />
33
+ <div className="relative z-10">
34
+ <span className="label-mono text-muted-foreground">SHIP Method OS</span>
35
+ </div>
36
+ <div className="relative z-10 max-w-md">
37
+ <p className="font-display text-4xl leading-tight tracking-tight text-foreground">
38
+ “Build the thing, ship the thing,
39
+ <span className="text-primary"> repeat</span> the thing.”
40
+ </p>
41
+ <p className="label-mono mt-6 text-muted-foreground">
42
+ Member Area — 2026
43
+ </p>
44
+ </div>
45
+ <div className="relative z-10 h-px w-24 bg-primary/40" />
46
+ </div>
47
+
48
+ {/* Form panel */}
49
+ <div className="flex w-full flex-1 items-center justify-center px-4 py-12 lg:w-1/2">
50
+ <Card className="animate-fade-up w-full max-w-sm">
51
+ <CardHeader className="space-y-1">
52
+ <span className="label-mono text-primary">Welcome back</span>
53
+ <CardTitle className="text-3xl">Log in</CardTitle>
54
+ <CardDescription>
55
+ Access your member dashboard and pick up where you left off.
56
+ </CardDescription>
57
+ </CardHeader>
58
+ <form onSubmit={handleLogin}>
59
+ <CardContent className="space-y-4">
60
+ <div className="space-y-2">
61
+ <label htmlFor="email" className="label-mono text-muted-foreground">
62
+ Email
63
+ </label>
64
+ <Input
65
+ id="email"
66
+ type="email"
67
+ placeholder="you@example.com"
68
+ value={email}
69
+ onChange={(e) => setEmail(e.target.value)}
70
+ required
71
+ />
72
+ </div>
73
+ <div className="space-y-2">
74
+ <label htmlFor="password" className="label-mono text-muted-foreground">
75
+ Password
76
+ </label>
77
+ <Input
78
+ id="password"
79
+ type="password"
80
+ placeholder="••••••••"
81
+ value={password}
82
+ onChange={(e) => setPassword(e.target.value)}
83
+ required
84
+ />
85
+ </div>
86
+ </CardContent>
87
+ <CardFooter className="flex flex-col gap-4">
88
+ <Button type="submit" className="w-full">
89
+ Log In
90
+ </Button>
91
+ <p className="text-center text-sm text-muted-foreground">
92
+ Don&apos;t have an account?{" "}
93
+ <Link
94
+ href="/member/signup"
95
+ className="font-medium text-primary hover:underline"
96
+ >
97
+ Sign up
98
+ </Link>
99
+ </p>
100
+ </CardFooter>
101
+ </form>
102
+ </Card>
103
+ </div>
104
+ </div>
105
+ );
106
+ }
@@ -0,0 +1,120 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import Link from "next/link";
5
+ import { useRouter } from "next/navigation";
6
+
7
+ import { Button } from "@/components/ui/button";
8
+ import { Input } from "@/components/ui/input";
9
+ import {
10
+ Card,
11
+ CardHeader,
12
+ CardTitle,
13
+ CardDescription,
14
+ CardContent,
15
+ CardFooter,
16
+ } from "@/components/ui/card";
17
+
18
+ export default function MemberSignupPage() {
19
+ const router = useRouter();
20
+ const [name, setName] = React.useState("");
21
+ const [email, setEmail] = React.useState("");
22
+ const [password, setPassword] = React.useState("");
23
+
24
+ function handleSignup(e: React.FormEvent) {
25
+ e.preventDefault();
26
+ router.push("/member/dashboard");
27
+ }
28
+
29
+ return (
30
+ <div className="flex min-h-screen bg-background">
31
+ {/* Decorative panel — desktop only */}
32
+ <div className="relative hidden w-1/2 flex-col justify-between overflow-hidden bg-card px-12 py-12 lg:flex">
33
+ <div className="bg-grid absolute inset-0" />
34
+ <div className="relative z-10">
35
+ <span className="label-mono text-muted-foreground">SHIP Method OS</span>
36
+ </div>
37
+ <div className="relative z-10 max-w-md">
38
+ <p className="font-display text-4xl leading-tight tracking-tight text-foreground">
39
+ “Every course you finish is a
40
+ <span className="text-primary"> compounding</span> decision.”
41
+ </p>
42
+ <p className="label-mono mt-6 text-muted-foreground">
43
+ Member Area — 2026
44
+ </p>
45
+ </div>
46
+ <div className="relative z-10 h-px w-24 bg-primary/40" />
47
+ </div>
48
+
49
+ {/* Form panel */}
50
+ <div className="flex w-full flex-1 items-center justify-center px-4 py-12 lg:w-1/2">
51
+ <Card className="animate-fade-up w-full max-w-sm">
52
+ <CardHeader className="space-y-1">
53
+ <span className="label-mono text-primary">Get started</span>
54
+ <CardTitle className="text-3xl">Create your account</CardTitle>
55
+ <CardDescription>
56
+ Join the member area to start your courses.
57
+ </CardDescription>
58
+ </CardHeader>
59
+ <form onSubmit={handleSignup}>
60
+ <CardContent className="space-y-4">
61
+ <div className="space-y-2">
62
+ <label htmlFor="name" className="label-mono text-muted-foreground">
63
+ Name
64
+ </label>
65
+ <Input
66
+ id="name"
67
+ type="text"
68
+ placeholder="Jane Doe"
69
+ value={name}
70
+ onChange={(e) => setName(e.target.value)}
71
+ required
72
+ />
73
+ </div>
74
+ <div className="space-y-2">
75
+ <label htmlFor="email" className="label-mono text-muted-foreground">
76
+ Email
77
+ </label>
78
+ <Input
79
+ id="email"
80
+ type="email"
81
+ placeholder="you@example.com"
82
+ value={email}
83
+ onChange={(e) => setEmail(e.target.value)}
84
+ required
85
+ />
86
+ </div>
87
+ <div className="space-y-2">
88
+ <label htmlFor="password" className="label-mono text-muted-foreground">
89
+ Password
90
+ </label>
91
+ <Input
92
+ id="password"
93
+ type="password"
94
+ placeholder="••••••••"
95
+ value={password}
96
+ onChange={(e) => setPassword(e.target.value)}
97
+ required
98
+ />
99
+ </div>
100
+ </CardContent>
101
+ <CardFooter className="flex flex-col gap-4">
102
+ <Button type="submit" className="w-full">
103
+ Create Account
104
+ </Button>
105
+ <p className="text-center text-sm text-muted-foreground">
106
+ Already have an account?{" "}
107
+ <Link
108
+ href="/member/login"
109
+ className="font-medium text-primary hover:underline"
110
+ >
111
+ Log in
112
+ </Link>
113
+ </p>
114
+ </CardFooter>
115
+ </form>
116
+ </Card>
117
+ </div>
118
+ </div>
119
+ );
120
+ }
@@ -0,0 +1,82 @@
1
+ import Link from "next/link";
2
+ import { Rocket, GraduationCap, Settings2, ArrowRight } from "lucide-react";
3
+
4
+ import {
5
+ Card,
6
+ CardContent,
7
+ CardDescription,
8
+ CardFooter,
9
+ CardHeader,
10
+ CardTitle,
11
+ } from "@/components/ui/card";
12
+ import { Button } from "@/components/ui/button";
13
+
14
+ const areas = [
15
+ {
16
+ href: "/sale",
17
+ icon: Rocket,
18
+ title: "Sale Page",
19
+ description:
20
+ "Public-facing offer page. Headline, pitch, pricing, and the CTA that turns visitors into members.",
21
+ },
22
+ {
23
+ href: "/member/login",
24
+ icon: GraduationCap,
25
+ title: "Member Area",
26
+ description:
27
+ "Logged-in member dashboard. Course access, progress tracking, and account settings.",
28
+ },
29
+ {
30
+ href: "/backoffice",
31
+ icon: Settings2,
32
+ title: "Backoffice",
33
+ description:
34
+ "Internal admin console. Member management, metrics, and operational tools.",
35
+ },
36
+ ];
37
+
38
+ export default function Home() {
39
+ return (
40
+ <main className="flex min-h-screen flex-col items-center justify-center bg-background px-6 py-24">
41
+ <div className="mx-auto max-w-3xl text-center">
42
+ <p className="text-sm font-medium uppercase tracking-wide text-muted-foreground">
43
+ The SHIP Method OS
44
+ </p>
45
+ <h1 className="mt-2 text-4xl font-bold tracking-tight text-foreground sm:text-5xl">
46
+ Pick your area
47
+ </h1>
48
+ <p className="mt-4 text-base text-muted-foreground">
49
+ This starter kit ships with three route groups. Each one is being
50
+ built independently on top of the shared UI and mock data layer
51
+ defined here.
52
+ </p>
53
+ </div>
54
+
55
+ <div className="mt-12 grid w-full max-w-5xl gap-6 sm:grid-cols-3">
56
+ {areas.map((area) => {
57
+ const Icon = area.icon;
58
+ return (
59
+ <Card key={area.href} className="flex flex-col">
60
+ <CardHeader>
61
+ <div className="mb-2 flex h-10 w-10 items-center justify-center rounded-md bg-primary/10 text-primary">
62
+ <Icon className="h-5 w-5" />
63
+ </div>
64
+ <CardTitle>{area.title}</CardTitle>
65
+ <CardDescription>{area.description}</CardDescription>
66
+ </CardHeader>
67
+ <CardContent className="flex-1" />
68
+ <CardFooter>
69
+ <Button asChild className="w-full">
70
+ <Link href={area.href}>
71
+ Enter
72
+ <ArrowRight className="h-4 w-4" />
73
+ </Link>
74
+ </Button>
75
+ </CardFooter>
76
+ </Card>
77
+ );
78
+ })}
79
+ </div>
80
+ </main>
81
+ );
82
+ }
@@ -0,0 +1,66 @@
1
+ import { ArrowRight } from "lucide-react";
2
+
3
+ import { Button } from "@/components/ui/button";
4
+
5
+ const footerLinks = [
6
+ { label: "Product", href: "#" },
7
+ { label: "Pricing", href: "#" },
8
+ { label: "About", href: "#" },
9
+ { label: "Contact", href: "#" },
10
+ ];
11
+
12
+ export function CtaFooter() {
13
+ return (
14
+ <>
15
+ <section className="container mx-auto px-4 py-28">
16
+ <div className="relative overflow-hidden rounded-3xl border border-primary/30 bg-card px-6 py-20 sm:px-16">
17
+ <div className="bg-grid pointer-events-none absolute inset-0 opacity-40" />
18
+ <div className="pointer-events-none absolute -right-24 -top-24 h-72 w-72 rounded-full bg-primary/30 blur-[100px]" />
19
+ <span
20
+ aria-hidden
21
+ className="pointer-events-none absolute -bottom-10 -left-6 select-none font-display text-[10rem] font-medium leading-none text-foreground/[0.05]"
22
+ >
23
+ &rarr;
24
+ </span>
25
+
26
+ <div className="relative flex flex-col items-start gap-6 text-left">
27
+ <p className="label-mono text-primary">Ready when you are</p>
28
+ <h2 className="max-w-2xl font-display text-4xl font-medium leading-tight tracking-tight sm:text-5xl">
29
+ Ready to <span className="italic text-primary">ship</span>{" "}
30
+ faster?
31
+ </h2>
32
+ <p className="max-w-xl text-muted-foreground">
33
+ Join hundreds of teams who&apos;ve already ditched the
34
+ spreadsheet chaos. Start your free trial today — no credit card
35
+ required.
36
+ </p>
37
+ <Button size="lg" className="glow-primary gap-2">
38
+ Get Started
39
+ <ArrowRight className="h-4 w-4" />
40
+ </Button>
41
+ </div>
42
+ </div>
43
+ </section>
44
+
45
+ <footer className="border-t border-border">
46
+ <div className="container mx-auto flex flex-col items-center justify-between gap-6 px-4 py-10 sm:flex-row">
47
+ <p className="font-display text-sm font-medium">SHIP Method OS</p>
48
+ <nav className="flex flex-wrap items-center justify-center gap-6 text-sm text-muted-foreground">
49
+ {footerLinks.map((link) => (
50
+ <a
51
+ key={link.label}
52
+ href={link.href}
53
+ className="transition-colors hover:text-foreground"
54
+ >
55
+ {link.label}
56
+ </a>
57
+ ))}
58
+ </nav>
59
+ <p className="label-mono text-muted-foreground">
60
+ Built with The SHIP Method OS
61
+ </p>
62
+ </div>
63
+ </footer>
64
+ </>
65
+ );
66
+ }