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,36 @@
1
+ import * as React from "react";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+
4
+ import { cn } from "@/lib/utils";
5
+
6
+ const badgeVariants = cva(
7
+ "label-mono inline-flex items-center gap-1 rounded-full border px-2.5 py-1 transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default:
12
+ "border-transparent bg-primary/15 text-primary",
13
+ secondary:
14
+ "border-transparent bg-secondary/20 text-secondary",
15
+ outline: "border-border text-muted-foreground",
16
+ destructive:
17
+ "border-transparent bg-destructive/15 text-destructive",
18
+ },
19
+ },
20
+ defaultVariants: {
21
+ variant: "default",
22
+ },
23
+ }
24
+ );
25
+
26
+ export interface BadgeProps
27
+ extends React.HTMLAttributes<HTMLDivElement>,
28
+ VariantProps<typeof badgeVariants> {}
29
+
30
+ function Badge({ className, variant, ...props }: BadgeProps) {
31
+ return (
32
+ <div className={cn(badgeVariants({ variant }), className)} {...props} />
33
+ );
34
+ }
35
+
36
+ export { Badge, badgeVariants };
@@ -0,0 +1,56 @@
1
+ import * as React from "react";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+
5
+ import { cn } from "@/lib/utils";
6
+
7
+ const buttonVariants = cva(
8
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-40 active:scale-[0.97]",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default:
13
+ "bg-primary text-primary-foreground shadow-soft hover:bg-primary/90 hover:-translate-y-0.5",
14
+ secondary:
15
+ "bg-secondary text-secondary-foreground hover:bg-secondary/90 hover:-translate-y-0.5",
16
+ outline:
17
+ "border border-border bg-transparent text-foreground hover:border-primary/50 hover:bg-primary/10",
18
+ ghost: "text-foreground hover:bg-muted",
19
+ destructive:
20
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
21
+ },
22
+ size: {
23
+ default: "h-10 px-5 py-2",
24
+ sm: "h-8 rounded-full px-3.5 text-xs",
25
+ lg: "h-12 rounded-full px-7 text-[0.95rem]",
26
+ icon: "h-10 w-10 rounded-full",
27
+ },
28
+ },
29
+ defaultVariants: {
30
+ variant: "default",
31
+ size: "default",
32
+ },
33
+ }
34
+ );
35
+
36
+ export interface ButtonProps
37
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
38
+ VariantProps<typeof buttonVariants> {
39
+ asChild?: boolean;
40
+ }
41
+
42
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
43
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
44
+ const Comp = asChild ? Slot : "button";
45
+ return (
46
+ <Comp
47
+ className={cn(buttonVariants({ variant, size, className }))}
48
+ ref={ref}
49
+ {...props}
50
+ />
51
+ );
52
+ }
53
+ );
54
+ Button.displayName = "Button";
55
+
56
+ export { Button, buttonVariants };
@@ -0,0 +1,78 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "@/lib/utils";
4
+
5
+ const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
6
+ ({ className, ...props }, ref) => (
7
+ <div
8
+ ref={ref}
9
+ className={cn(
10
+ "rounded-xl border border-border bg-card text-card-foreground shadow-soft transition-colors duration-200",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ );
17
+ Card.displayName = "Card";
18
+
19
+ const CardHeader = React.forwardRef<
20
+ HTMLDivElement,
21
+ React.HTMLAttributes<HTMLDivElement>
22
+ >(({ className, ...props }, ref) => (
23
+ <div
24
+ ref={ref}
25
+ className={cn("flex flex-col space-y-1.5 p-6", className)}
26
+ {...props}
27
+ />
28
+ ));
29
+ CardHeader.displayName = "CardHeader";
30
+
31
+ const CardTitle = React.forwardRef<
32
+ HTMLParagraphElement,
33
+ React.HTMLAttributes<HTMLHeadingElement>
34
+ >(({ className, ...props }, ref) => (
35
+ <h3
36
+ ref={ref}
37
+ className={cn(
38
+ "font-display text-xl font-medium leading-tight tracking-tight text-foreground",
39
+ className
40
+ )}
41
+ {...props}
42
+ />
43
+ ));
44
+ CardTitle.displayName = "CardTitle";
45
+
46
+ const CardDescription = React.forwardRef<
47
+ HTMLParagraphElement,
48
+ React.HTMLAttributes<HTMLParagraphElement>
49
+ >(({ className, ...props }, ref) => (
50
+ <p
51
+ ref={ref}
52
+ className={cn("text-sm leading-relaxed text-muted-foreground", className)}
53
+ {...props}
54
+ />
55
+ ));
56
+ CardDescription.displayName = "CardDescription";
57
+
58
+ const CardContent = React.forwardRef<
59
+ HTMLDivElement,
60
+ React.HTMLAttributes<HTMLDivElement>
61
+ >(({ className, ...props }, ref) => (
62
+ <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
63
+ ));
64
+ CardContent.displayName = "CardContent";
65
+
66
+ const CardFooter = React.forwardRef<
67
+ HTMLDivElement,
68
+ React.HTMLAttributes<HTMLDivElement>
69
+ >(({ className, ...props }, ref) => (
70
+ <div
71
+ ref={ref}
72
+ className={cn("flex items-center p-6 pt-0", className)}
73
+ {...props}
74
+ />
75
+ ));
76
+ CardFooter.displayName = "CardFooter";
77
+
78
+ export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter };
@@ -0,0 +1,24 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "@/lib/utils";
4
+
5
+ export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
6
+
7
+ const Input = React.forwardRef<HTMLInputElement, InputProps>(
8
+ ({ className, type, ...props }, ref) => {
9
+ return (
10
+ <input
11
+ type={type}
12
+ className={cn(
13
+ "flex h-11 w-full rounded-lg border border-input bg-card/60 px-3.5 py-2 text-sm text-foreground ring-offset-background transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground/70 focus-visible:border-primary/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50",
14
+ className
15
+ )}
16
+ ref={ref}
17
+ {...props}
18
+ />
19
+ );
20
+ }
21
+ );
22
+ Input.displayName = "Input";
23
+
24
+ export { Input };
@@ -0,0 +1,88 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "@/lib/utils";
4
+
5
+ const Table = React.forwardRef<
6
+ HTMLTableElement,
7
+ React.HTMLAttributes<HTMLTableElement>
8
+ >(({ className, ...props }, ref) => (
9
+ <div className="relative w-full overflow-auto">
10
+ <table
11
+ ref={ref}
12
+ className={cn("w-full caption-bottom text-sm", className)}
13
+ {...props}
14
+ />
15
+ </div>
16
+ ));
17
+ Table.displayName = "Table";
18
+
19
+ const TableHeader = React.forwardRef<
20
+ HTMLTableSectionElement,
21
+ React.HTMLAttributes<HTMLTableSectionElement>
22
+ >(({ className, ...props }, ref) => (
23
+ <thead
24
+ ref={ref}
25
+ className={cn("[&_tr]:border-b [&_tr]:border-border", className)}
26
+ {...props}
27
+ />
28
+ ));
29
+ TableHeader.displayName = "TableHeader";
30
+
31
+ const TableBody = React.forwardRef<
32
+ HTMLTableSectionElement,
33
+ React.HTMLAttributes<HTMLTableSectionElement>
34
+ >(({ className, ...props }, ref) => (
35
+ <tbody
36
+ ref={ref}
37
+ className={cn("[&_tr:last-child]:border-0", className)}
38
+ {...props}
39
+ />
40
+ ));
41
+ TableBody.displayName = "TableBody";
42
+
43
+ const TableRow = React.forwardRef<
44
+ HTMLTableRowElement,
45
+ React.HTMLAttributes<HTMLTableRowElement>
46
+ >(({ className, ...props }, ref) => (
47
+ <tr
48
+ ref={ref}
49
+ className={cn(
50
+ "border-b border-border/70 transition-colors hover:bg-primary/[0.04] data-[state=selected]:bg-muted",
51
+ className
52
+ )}
53
+ {...props}
54
+ />
55
+ ));
56
+ TableRow.displayName = "TableRow";
57
+
58
+ const TableHead = React.forwardRef<
59
+ HTMLTableCellElement,
60
+ React.ThHTMLAttributes<HTMLTableCellElement>
61
+ >(({ className, ...props }, ref) => (
62
+ <th
63
+ ref={ref}
64
+ className={cn(
65
+ "label-mono h-10 px-2 text-left align-middle text-muted-foreground [&:has([role=checkbox])]:pr-0",
66
+ className
67
+ )}
68
+ {...props}
69
+ />
70
+ ));
71
+ TableHead.displayName = "TableHead";
72
+
73
+ const TableCell = React.forwardRef<
74
+ HTMLTableCellElement,
75
+ React.TdHTMLAttributes<HTMLTableCellElement>
76
+ >(({ className, ...props }, ref) => (
77
+ <td
78
+ ref={ref}
79
+ className={cn(
80
+ "p-2 align-middle [&:has([role=checkbox])]:pr-0",
81
+ className
82
+ )}
83
+ {...props}
84
+ />
85
+ ));
86
+ TableCell.displayName = "TableCell";
87
+
88
+ export { Table, TableHeader, TableBody, TableRow, TableHead, TableCell };
@@ -0,0 +1,55 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import * as TabsPrimitive from "@radix-ui/react-tabs";
5
+
6
+ import { cn } from "@/lib/utils";
7
+
8
+ const Tabs = TabsPrimitive.Root;
9
+
10
+ const TabsList = React.forwardRef<
11
+ React.ElementRef<typeof TabsPrimitive.List>,
12
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
13
+ >(({ className, ...props }, ref) => (
14
+ <TabsPrimitive.List
15
+ ref={ref}
16
+ className={cn(
17
+ "inline-flex h-11 items-center justify-center gap-1 rounded-full border border-border bg-card/60 p-1 text-muted-foreground",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ ));
23
+ TabsList.displayName = TabsPrimitive.List.displayName;
24
+
25
+ const TabsTrigger = React.forwardRef<
26
+ React.ElementRef<typeof TabsPrimitive.Trigger>,
27
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
28
+ >(({ className, ...props }, ref) => (
29
+ <TabsPrimitive.Trigger
30
+ ref={ref}
31
+ className={cn(
32
+ "inline-flex items-center justify-center whitespace-nowrap rounded-full px-4 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-soft",
33
+ className
34
+ )}
35
+ {...props}
36
+ />
37
+ ));
38
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
39
+
40
+ const TabsContent = React.forwardRef<
41
+ React.ElementRef<typeof TabsPrimitive.Content>,
42
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
43
+ >(({ className, ...props }, ref) => (
44
+ <TabsPrimitive.Content
45
+ ref={ref}
46
+ className={cn(
47
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
48
+ className
49
+ )}
50
+ {...props}
51
+ />
52
+ ));
53
+ TabsContent.displayName = TabsPrimitive.Content.displayName;
54
+
55
+ export { Tabs, TabsList, TabsTrigger, TabsContent };
@@ -0,0 +1,118 @@
1
+ // Shared mock data for The SHIP Method OS starter kit.
2
+ // No backend is wired up yet — every route group (sale / member / backoffice)
3
+ // should import from here until real Supabase queries replace these arrays.
4
+ // See README.md for the migration note.
5
+
6
+ export interface MockUser {
7
+ id: string;
8
+ name: string;
9
+ email: string;
10
+ plan: "Free" | "Starter" | "Pro" | "Lifetime";
11
+ status: "active" | "trialing" | "past_due" | "canceled";
12
+ joinedAt: string; // ISO date string
13
+ }
14
+
15
+ export interface MockMemberContent {
16
+ id: string;
17
+ title: string;
18
+ tier: "Free" | "Starter" | "Pro" | "Lifetime";
19
+ progress: number; // 0-100
20
+ }
21
+
22
+ export interface MockMetric {
23
+ label: string;
24
+ value: string;
25
+ change: number; // signed percentage, e.g. 12.4 or -3.1
26
+ }
27
+
28
+ export const users: MockUser[] = [
29
+ {
30
+ id: "usr_001",
31
+ name: "Anan Suwannarat",
32
+ email: "anan@shipmethod.dev",
33
+ plan: "Pro",
34
+ status: "active",
35
+ joinedAt: "2025-11-02",
36
+ },
37
+ {
38
+ id: "usr_002",
39
+ name: "Becky Tran",
40
+ email: "becky.tran@gmail.com",
41
+ plan: "Starter",
42
+ status: "active",
43
+ joinedAt: "2025-12-14",
44
+ },
45
+ {
46
+ id: "usr_003",
47
+ name: "Chai Wattana",
48
+ email: "chai.w@outlook.com",
49
+ plan: "Lifetime",
50
+ status: "active",
51
+ joinedAt: "2025-09-21",
52
+ },
53
+ {
54
+ id: "usr_004",
55
+ name: "Dana Kim",
56
+ email: "dana.kim@proton.me",
57
+ plan: "Free",
58
+ status: "trialing",
59
+ joinedAt: "2026-01-30",
60
+ },
61
+ {
62
+ id: "usr_005",
63
+ name: "Eric Sombat",
64
+ email: "eric.sombat@yahoo.com",
65
+ plan: "Pro",
66
+ status: "past_due",
67
+ joinedAt: "2025-10-08",
68
+ },
69
+ {
70
+ id: "usr_006",
71
+ name: "Faye Nguyen",
72
+ email: "faye.nguyen@icloud.com",
73
+ plan: "Starter",
74
+ status: "canceled",
75
+ joinedAt: "2025-08-17",
76
+ },
77
+ ];
78
+
79
+ export const members: MockMemberContent[] = [
80
+ {
81
+ id: "crs_001",
82
+ title: "SHIP Method Foundations",
83
+ tier: "Free",
84
+ progress: 100,
85
+ },
86
+ {
87
+ id: "crs_002",
88
+ title: "Offer Design & Pricing Mastery",
89
+ tier: "Starter",
90
+ progress: 62,
91
+ },
92
+ {
93
+ id: "crs_003",
94
+ title: "Building Your First Funnel",
95
+ tier: "Starter",
96
+ progress: 30,
97
+ },
98
+ {
99
+ id: "crs_004",
100
+ title: "Advanced Backoffice Automation",
101
+ tier: "Pro",
102
+ progress: 5,
103
+ },
104
+ {
105
+ id: "crs_005",
106
+ title: "Lifetime Mastermind Vault",
107
+ tier: "Lifetime",
108
+ progress: 0,
109
+ },
110
+ ];
111
+
112
+ export const metrics: MockMetric[] = [
113
+ { label: "Monthly Recurring Revenue", value: "$18,420", change: 12.4 },
114
+ { label: "Active Members", value: "342", change: 6.1 },
115
+ { label: "Trial → Paid Conversion", value: "24.8%", change: -1.7 },
116
+ { label: "Churn Rate", value: "3.2%", change: -0.5 },
117
+ { label: "Avg. Course Completion", value: "58%", change: 4.3 },
118
+ ];
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1,6 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ reactStrictMode: true,
4
+ };
5
+
6
+ export default nextConfig;
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "ship-starter-kit",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint"
10
+ },
11
+ "dependencies": {
12
+ "@radix-ui/react-avatar": "^1.1.0",
13
+ "@radix-ui/react-dialog": "^1.1.1",
14
+ "@radix-ui/react-dropdown-menu": "^2.1.1",
15
+ "@radix-ui/react-slot": "^1.1.0",
16
+ "@radix-ui/react-tabs": "^1.1.0",
17
+ "class-variance-authority": "^0.7.0",
18
+ "clsx": "^2.1.1",
19
+ "lucide-react": "^0.439.0",
20
+ "next": "^16.2.9",
21
+ "react": "18.3.1",
22
+ "react-dom": "18.3.1",
23
+ "tailwind-merge": "^2.5.2"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^20.14.15",
27
+ "@types/react": "^18.3.4",
28
+ "@types/react-dom": "^18.3.0",
29
+ "autoprefixer": "^10.4.20",
30
+ "eslint": "^8.57.0",
31
+ "eslint-config-next": "14.2.5",
32
+ "postcss": "^8.4.41",
33
+ "tailwindcss": "^3.4.10",
34
+ "typescript": "^5.5.4"
35
+ }
36
+ }
@@ -0,0 +1,9 @@
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ tailwindcss: {},
5
+ autoprefixer: {},
6
+ },
7
+ };
8
+
9
+ export default config;
@@ -0,0 +1,83 @@
1
+ import type { Config } from "tailwindcss";
2
+
3
+ const config: Config = {
4
+ darkMode: ["class"],
5
+ content: ["./app/**/*.{ts,tsx}", "./components/**/*.{ts,tsx}", "./lib/**/*.{ts,tsx}"],
6
+ theme: {
7
+ container: {
8
+ center: true,
9
+ padding: "1.5rem",
10
+ screens: {
11
+ "2xl": "1280px",
12
+ },
13
+ },
14
+ extend: {
15
+ fontFamily: {
16
+ sans: ["var(--font-sans)", "ui-sans-serif", "system-ui"],
17
+ display: ["var(--font-display)", "ui-serif", "Georgia", "serif"],
18
+ mono: ["var(--font-mono)", "ui-monospace", "SFMono-Regular"],
19
+ },
20
+ colors: {
21
+ border: "hsl(var(--border))",
22
+ input: "hsl(var(--input))",
23
+ ring: "hsl(var(--ring))",
24
+ background: "hsl(var(--background))",
25
+ foreground: "hsl(var(--foreground))",
26
+ primary: {
27
+ DEFAULT: "hsl(var(--primary))",
28
+ foreground: "hsl(var(--primary-foreground))",
29
+ },
30
+ secondary: {
31
+ DEFAULT: "hsl(var(--secondary))",
32
+ foreground: "hsl(var(--secondary-foreground))",
33
+ },
34
+ muted: {
35
+ DEFAULT: "hsl(var(--muted))",
36
+ foreground: "hsl(var(--muted-foreground))",
37
+ },
38
+ accent: {
39
+ DEFAULT: "hsl(var(--accent))",
40
+ foreground: "hsl(var(--accent-foreground))",
41
+ },
42
+ destructive: {
43
+ DEFAULT: "hsl(var(--destructive))",
44
+ foreground: "hsl(var(--destructive-foreground))",
45
+ },
46
+ success: {
47
+ DEFAULT: "hsl(var(--success))",
48
+ foreground: "hsl(var(--success-foreground))",
49
+ },
50
+ card: {
51
+ DEFAULT: "hsl(var(--card))",
52
+ foreground: "hsl(var(--card-foreground))",
53
+ },
54
+ },
55
+ borderRadius: {
56
+ lg: "var(--radius)",
57
+ md: "calc(var(--radius) - 4px)",
58
+ sm: "calc(var(--radius) - 6px)",
59
+ xl: "calc(var(--radius) + 6px)",
60
+ },
61
+ keyframes: {
62
+ "fade-up": {
63
+ from: { opacity: "0", transform: "translateY(14px)" },
64
+ to: { opacity: "1", transform: "translateY(0)" },
65
+ },
66
+ "fade-in": {
67
+ from: { opacity: "0" },
68
+ to: { opacity: "1" },
69
+ },
70
+ },
71
+ animation: {
72
+ "fade-up": "fade-up 0.7s cubic-bezier(0.16, 1, 0.3, 1) both",
73
+ "fade-in": "fade-in 0.6s ease-out both",
74
+ },
75
+ boxShadow: {
76
+ soft: "0 1px 2px hsl(27 30% 4% / 0.4), 0 16px 40px -20px hsl(27 30% 4% / 0.6)",
77
+ },
78
+ },
79
+ },
80
+ plugins: [],
81
+ };
82
+
83
+ export default config;
@@ -0,0 +1,41 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": [
5
+ "dom",
6
+ "dom.iterable",
7
+ "esnext"
8
+ ],
9
+ "allowJs": true,
10
+ "skipLibCheck": true,
11
+ "strict": true,
12
+ "noEmit": true,
13
+ "esModuleInterop": true,
14
+ "module": "esnext",
15
+ "moduleResolution": "bundler",
16
+ "resolveJsonModule": true,
17
+ "isolatedModules": true,
18
+ "jsx": "react-jsx",
19
+ "incremental": true,
20
+ "plugins": [
21
+ {
22
+ "name": "next"
23
+ }
24
+ ],
25
+ "paths": {
26
+ "@/*": [
27
+ "./*"
28
+ ]
29
+ }
30
+ },
31
+ "include": [
32
+ "next-env.d.ts",
33
+ "**/*.ts",
34
+ "**/*.tsx",
35
+ ".next/types/**/*.ts",
36
+ ".next/dev/types/**/*.ts"
37
+ ],
38
+ "exclude": [
39
+ "node_modules"
40
+ ]
41
+ }