kofi-stack-template-generator 2.1.60 → 2.1.61

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.
@@ -1,9 +1,9 @@
1
1
 
2
- > kofi-stack-template-generator@2.1.60 build /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
2
+ > kofi-stack-template-generator@2.1.61 build /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
3
3
  > pnpm run prebuild && tsup src/index.ts --format esm --dts
4
4
 
5
5
 
6
- > kofi-stack-template-generator@2.1.60 prebuild /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
6
+ > kofi-stack-template-generator@2.1.61 prebuild /Users/theodenanyoh/Documents/Krumalabs/create-kofi-stack-v2/packages/template-generator
7
7
  > node scripts/generate-templates.js
8
8
 
9
9
  Generating templates.generated.ts...
@@ -14,7 +14,7 @@ CLI tsup v8.5.1
14
14
  CLI Target: es2022
15
15
  ESM Build start
16
16
  ESM dist/index.js 2.61 MB
17
- ESM ⚡️ Build success in 58ms
17
+ ESM ⚡️ Build success in 60ms
18
18
  DTS Build start
19
- DTS ⚡️ Build success in 509ms
19
+ DTS ⚡️ Build success in 476ms
20
20
  DTS dist/index.d.ts 2.96 KB
package/dist/index.js CHANGED
@@ -2669,7 +2669,7 @@ import FinalCTA from "../components/blocks/FinalCTA.astro"
2669
2669
  "marketing/astro/tsconfig.json.hbs": '{\n "extends": "astro/tsconfigs/strict",\n "compilerOptions": {\n "baseUrl": ".",\n "paths": {\n "@/*": ["./src/*"]\n }\n },\n "include": ["src/**/*", ".astro/types.d.ts"],\n "exclude": ["node_modules", "dist"]\n}\n',
2670
2670
  "marketing/nextjs/components.json.hbs": '{\n "$schema": "https://ui.shadcn.com/schema.json",\n{{#if (eq shadcn.style "nova")}}\n "style": "new-york",\n{{else if (eq shadcn.style "vega")}}\n "style": "default",\n{{else if (eq shadcn.style "maia")}}\n "style": "new-york",\n{{else if (eq shadcn.style "lyra")}}\n "style": "new-york",\n{{else if (eq shadcn.style "mira")}}\n "style": "default",\n{{else}}\n "style": "new-york",\n{{/if}}\n "rsc": true,\n "tsx": true,\n "tailwind": {\n "config": "",\n "css": "src/app/globals.css",\n "baseColor": "{{shadcn.baseColor}}",\n "cssVariables": true,\n "prefix": ""\n },\n{{#if (eq shadcn.iconLibrary "lucide")}}\n "iconLibrary": "lucide",\n{{else if (eq shadcn.iconLibrary "hugeicons")}}\n "iconLibrary": "lucide",\n{{else if (eq shadcn.iconLibrary "tabler")}}\n "iconLibrary": "lucide",\n{{else if (eq shadcn.iconLibrary "phosphor")}}\n "iconLibrary": "lucide",\n{{else}}\n "iconLibrary": "lucide",\n{{/if}}\n "aliases": {\n "components": "@/components",\n "utils": "@/lib/utils",\n "ui": "@/components/ui",\n "lib": "@/lib",\n "hooks": "@/hooks"\n },\n "registries": {}\n}\n',
2671
2671
  "marketing/nextjs/next.config.ts.hbs": "import type { NextConfig } from 'next'\n\nconst nextConfig: NextConfig = {\n transpilePackages: ['@repo/ui'],\n}\n\nexport default nextConfig\n",
2672
- "marketing/nextjs/package.json.hbs": '{\n "name": "@repo/marketing",\n "version": "0.1.0",\n "private": true,\n "scripts": {\n "dev": "next dev --turbopack --port 3000",\n "build": "next build",\n "start": "next start",\n "lint": "biome check .",\n "lint:fix": "biome check --write .",\n "typecheck": "tsc --noEmit"\n },\n "dependencies": {\n "next": "^16.0.0",\n "react": "^19.0.0",\n "react-dom": "^19.0.0",\n "@repo/ui": "workspace:*",\n "lucide-react": "^0.468.0",\n "next-themes": "^0.4.4",\n "clsx": "^2.1.1",\n "tailwind-merge": "^2.6.0",\n "class-variance-authority": "^0.7.1"\n },\n "devDependencies": {\n "@repo/config-typescript": "workspace:*",\n "@types/node": "^20.0.0",\n "@types/react": "^19.0.0",\n "@types/react-dom": "^19.0.0",\n "tailwindcss": "^4.0.0",\n "@tailwindcss/postcss": "^4.0.0",\n "postcss": "^8.4.0",\n "typescript": "^5.0.0"\n }\n}\n',
2672
+ "marketing/nextjs/package.json.hbs": '{\n "name": "@repo/marketing",\n "version": "0.1.0",\n "private": true,\n "scripts": {\n "dev": "next dev --turbopack --port 3000",\n "build": "next build",\n "start": "next start",\n "lint": "biome check .",\n "lint:fix": "biome check --write .",\n "typecheck": "tsc --noEmit"\n },\n "dependencies": {\n "next": "^16.0.0",\n "react": "^19.0.0",\n "react-dom": "^19.0.0",\n "@repo/ui": "workspace:*",\n "lucide-react": "^0.468.0",\n "next-themes": "^0.4.4",\n "clsx": "^2.1.1",\n "tailwind-merge": "^2.6.0",\n "class-variance-authority": "^0.7.1",\n "tw-animate-css": "^1.3.0"\n },\n "devDependencies": {\n "@repo/config-typescript": "workspace:*",\n "@types/node": "^20.0.0",\n "@types/react": "^19.0.0",\n "@types/react-dom": "^19.0.0",\n "tailwindcss": "^4.0.0",\n "@tailwindcss/postcss": "^4.0.0",\n "postcss": "^8.4.0",\n "typescript": "^5.0.0"\n }\n}\n',
2673
2673
  "marketing/nextjs/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
2674
2674
  "marketing/nextjs/src/app/about/page.tsx": `import { Header } from "@/components/Header"
2675
2675
  import { Footer } from "@/components/Footer"
@@ -12706,7 +12706,7 @@ export default function Index() {
12706
12706
  "packages/ui/src/styles.css.hbs": '@import "tailwindcss";\n\n@custom-variant dark (&:is(.dark *));\n\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --font-sans: var(--font-geist-sans);\n --font-mono: var(--font-geist-mono);\n --color-sidebar-ring: var(--sidebar-ring);\n --color-sidebar-border: var(--sidebar-border);\n --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);\n --color-sidebar-accent: var(--sidebar-accent);\n --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);\n --color-sidebar-primary: var(--sidebar-primary);\n --color-sidebar-foreground: var(--sidebar-foreground);\n --color-sidebar: var(--sidebar);\n --color-chart-5: var(--chart-5);\n --color-chart-4: var(--chart-4);\n --color-chart-3: var(--chart-3);\n --color-chart-2: var(--chart-2);\n --color-chart-1: var(--chart-1);\n --color-ring: var(--ring);\n --color-input: var(--input);\n --color-border: var(--border);\n --color-destructive: var(--destructive);\n --color-accent-foreground: var(--accent-foreground);\n --color-accent: var(--accent);\n --color-muted-foreground: var(--muted-foreground);\n --color-muted: var(--muted);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-secondary: var(--secondary);\n --color-primary-foreground: var(--primary-foreground);\n --color-primary: var(--primary);\n --color-popover-foreground: var(--popover-foreground);\n --color-popover: var(--popover);\n --color-card-foreground: var(--card-foreground);\n --color-card: var(--card);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n}\n\n:root {\n --radius: 0.625rem;\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0 0);\n --primary: oklch(0.205 0 0);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.97 0 0);\n --secondary-foreground: oklch(0.205 0 0);\n --muted: oklch(0.97 0 0);\n --muted-foreground: oklch(0.556 0 0);\n --accent: oklch(0.97 0 0);\n --accent-foreground: oklch(0.205 0 0);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.922 0 0);\n --input: oklch(0.922 0 0);\n --ring: oklch(0.708 0 0);\n --chart-1: oklch(0.646 0.222 41.116);\n --chart-2: oklch(0.6 0.118 184.704);\n --chart-3: oklch(0.398 0.07 227.392);\n --chart-4: oklch(0.828 0.189 84.429);\n --chart-5: oklch(0.769 0.188 70.08);\n --sidebar: oklch(0.985 0 0);\n --sidebar-foreground: oklch(0.145 0 0);\n --sidebar-primary: oklch(0.205 0 0);\n --sidebar-primary-foreground: oklch(0.985 0 0);\n --sidebar-accent: oklch(0.97 0 0);\n --sidebar-accent-foreground: oklch(0.205 0 0);\n --sidebar-border: oklch(0.922 0 0);\n --sidebar-ring: oklch(0.708 0 0);\n}\n\n.dark {\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.205 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.922 0 0);\n --primary-foreground: oklch(0.205 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.269 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.556 0 0);\n --chart-1: oklch(0.488 0.243 264.376);\n --chart-2: oklch(0.696 0.17 162.48);\n --chart-3: oklch(0.769 0.188 70.08);\n --chart-4: oklch(0.627 0.265 303.9);\n --chart-5: oklch(0.645 0.246 16.439);\n --sidebar: oklch(0.205 0 0);\n --sidebar-foreground: oklch(0.985 0 0);\n --sidebar-primary: oklch(0.488 0.243 264.376);\n --sidebar-primary-foreground: oklch(0.985 0 0);\n --sidebar-accent: oklch(0.269 0 0);\n --sidebar-accent-foreground: oklch(0.985 0 0);\n --sidebar-border: oklch(1 0 0 / 10%);\n --sidebar-ring: oklch(0.556 0 0);\n}\n\n@layer base {\n * {\n @apply border-border outline-ring/50;\n }\n body {\n @apply bg-background text-foreground;\n }\n}\n',
12707
12707
  "packages/ui/tsconfig.json.hbs": '{\n "compilerOptions": {\n "target": "ES2020",\n "lib": ["dom", "dom.iterable", "esnext"],\n "allowJs": true,\n "skipLibCheck": true,\n "strict": true,\n "noEmit": true,\n "esModuleInterop": true,\n "module": "esnext",\n "moduleResolution": "bundler",\n "resolveJsonModule": true,\n "isolatedModules": true,\n "jsx": "react-jsx",\n "incremental": true,\n "paths": {\n "@/*": ["./src/*"]\n }\n },\n "include": ["src/**/*"],\n "exclude": ["node_modules"]\n}\n',
12708
12708
  "web/_env.local.hbs": "# Convex - These values are synced from packages/backend/.env.local after running convex dev\n# NEXT_PUBLIC_CONVEX_URL and NEXT_PUBLIC_CONVEX_SITE_URL are auto-synced by dev script\nNEXT_PUBLIC_CONVEX_URL=\nNEXT_PUBLIC_CONVEX_SITE_URL=\n\n# Site URL for auth (your frontend URL)\nNEXT_PUBLIC_SITE_URL=http://localhost:3000\n{{#if (eq integrations.analytics 'posthog')}}\n\n# PostHog\nNEXT_PUBLIC_POSTHOG_KEY=\nNEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com\n{{/if}}\n{{#if (eq integrations.payments 'stripe')}}\n\n# Stripe\nNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=\n{{/if}}\n",
12709
- "web/components.json.hbs": '{\n "$schema": "https://ui.shadcn.com/schema.json",\n "style": "new-york",\n "rsc": true,\n "tsx": true,\n "tailwind": {\n "config": "",\n "css": "src/app/globals.css",\n "baseColor": "{{shadcn.baseColor}}",\n "cssVariables": true,\n "prefix": ""\n },\n "aliases": {\n "components": "@/components",\n "utils": "@/lib/utils",\n "ui": "@/components/ui",\n "lib": "@/lib",\n "hooks": "@/hooks"\n },\n "iconLibrary": "{{shadcn.iconLibrary}}"\n}\n',
12709
+ "web/components.json.hbs": '{\n "$schema": "https://ui.shadcn.com/schema.json",\n{{#if (eq shadcn.style "nova")}}\n "style": "new-york",\n{{else if (eq shadcn.style "vega")}}\n "style": "default",\n{{else}}\n "style": "new-york",\n{{/if}}\n "rsc": true,\n "tsx": true,\n "tailwind": {\n "config": "",\n "css": "src/app/globals.css",\n "baseColor": "{{shadcn.baseColor}}",\n "cssVariables": true,\n "prefix": ""\n },\n "aliases": {\n "components": "@/components",\n "utils": "@/lib/utils",\n "ui": "@/components/ui",\n "lib": "@/lib",\n "hooks": "@/hooks"\n },\n "iconLibrary": "{{shadcn.iconLibrary}}"\n}\n',
12710
12710
  "web/next.config.ts.hbs": "import type { NextConfig } from 'next'\n\nconst nextConfig: NextConfig = {\n{{#if (eq structure 'monorepo')}}\n transpilePackages: ['@repo/ui', '@repo/backend'],\n{{/if}}\n}\n\nexport default nextConfig\n",
12711
12711
  "web/package.json.hbs": `{
12712
12712
  "name": "{{#if (eq structure 'monorepo')}}@repo/web{{else}}{{projectName}}{{/if}}",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kofi-stack-template-generator",
3
- "version": "2.1.60",
3
+ "version": "2.1.61",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "typecheck": "tsc --noEmit"
18
18
  },
19
19
  "dependencies": {
20
- "kofi-stack-types": "^2.1.60",
20
+ "kofi-stack-types": "^2.1.61",
21
21
  "handlebars": "^4.7.8",
22
22
  "memfs": "^4.9.0"
23
23
  },
@@ -1,6 +1,6 @@
1
1
  // Auto-generated file. Do not edit manually.
2
2
  // Run 'pnpm prebuild' to regenerate.
3
- // Generated: 2026-01-19T19:28:47.282Z
3
+ // Generated: 2026-01-19T19:40:59.995Z
4
4
  // Template count: 415
5
5
 
6
6
  export const EMBEDDED_TEMPLATES: Record<string, string> = {
@@ -73,7 +73,7 @@ export const EMBEDDED_TEMPLATES: Record<string, string> = {
73
73
  "marketing/astro/tsconfig.json.hbs": "{\n \"extends\": \"astro/tsconfigs/strict\",\n \"compilerOptions\": {\n \"baseUrl\": \".\",\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n },\n \"include\": [\"src/**/*\", \".astro/types.d.ts\"],\n \"exclude\": [\"node_modules\", \"dist\"]\n}\n",
74
74
  "marketing/nextjs/components.json.hbs": "{\n \"$schema\": \"https://ui.shadcn.com/schema.json\",\n{{#if (eq shadcn.style \"nova\")}}\n \"style\": \"new-york\",\n{{else if (eq shadcn.style \"vega\")}}\n \"style\": \"default\",\n{{else if (eq shadcn.style \"maia\")}}\n \"style\": \"new-york\",\n{{else if (eq shadcn.style \"lyra\")}}\n \"style\": \"new-york\",\n{{else if (eq shadcn.style \"mira\")}}\n \"style\": \"default\",\n{{else}}\n \"style\": \"new-york\",\n{{/if}}\n \"rsc\": true,\n \"tsx\": true,\n \"tailwind\": {\n \"config\": \"\",\n \"css\": \"src/app/globals.css\",\n \"baseColor\": \"{{shadcn.baseColor}}\",\n \"cssVariables\": true,\n \"prefix\": \"\"\n },\n{{#if (eq shadcn.iconLibrary \"lucide\")}}\n \"iconLibrary\": \"lucide\",\n{{else if (eq shadcn.iconLibrary \"hugeicons\")}}\n \"iconLibrary\": \"lucide\",\n{{else if (eq shadcn.iconLibrary \"tabler\")}}\n \"iconLibrary\": \"lucide\",\n{{else if (eq shadcn.iconLibrary \"phosphor\")}}\n \"iconLibrary\": \"lucide\",\n{{else}}\n \"iconLibrary\": \"lucide\",\n{{/if}}\n \"aliases\": {\n \"components\": \"@/components\",\n \"utils\": \"@/lib/utils\",\n \"ui\": \"@/components/ui\",\n \"lib\": \"@/lib\",\n \"hooks\": \"@/hooks\"\n },\n \"registries\": {}\n}\n",
75
75
  "marketing/nextjs/next.config.ts.hbs": "import type { NextConfig } from 'next'\n\nconst nextConfig: NextConfig = {\n transpilePackages: ['@repo/ui'],\n}\n\nexport default nextConfig\n",
76
- "marketing/nextjs/package.json.hbs": "{\n \"name\": \"@repo/marketing\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"next dev --turbopack --port 3000\",\n \"build\": \"next build\",\n \"start\": \"next start\",\n \"lint\": \"biome check .\",\n \"lint:fix\": \"biome check --write .\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"next\": \"^16.0.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"@repo/ui\": \"workspace:*\",\n \"lucide-react\": \"^0.468.0\",\n \"next-themes\": \"^0.4.4\",\n \"clsx\": \"^2.1.1\",\n \"tailwind-merge\": \"^2.6.0\",\n \"class-variance-authority\": \"^0.7.1\"\n },\n \"devDependencies\": {\n \"@repo/config-typescript\": \"workspace:*\",\n \"@types/node\": \"^20.0.0\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n \"tailwindcss\": \"^4.0.0\",\n \"@tailwindcss/postcss\": \"^4.0.0\",\n \"postcss\": \"^8.4.0\",\n \"typescript\": \"^5.0.0\"\n }\n}\n",
76
+ "marketing/nextjs/package.json.hbs": "{\n \"name\": \"@repo/marketing\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"next dev --turbopack --port 3000\",\n \"build\": \"next build\",\n \"start\": \"next start\",\n \"lint\": \"biome check .\",\n \"lint:fix\": \"biome check --write .\",\n \"typecheck\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"next\": \"^16.0.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"@repo/ui\": \"workspace:*\",\n \"lucide-react\": \"^0.468.0\",\n \"next-themes\": \"^0.4.4\",\n \"clsx\": \"^2.1.1\",\n \"tailwind-merge\": \"^2.6.0\",\n \"class-variance-authority\": \"^0.7.1\",\n \"tw-animate-css\": \"^1.3.0\"\n },\n \"devDependencies\": {\n \"@repo/config-typescript\": \"workspace:*\",\n \"@types/node\": \"^20.0.0\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n \"tailwindcss\": \"^4.0.0\",\n \"@tailwindcss/postcss\": \"^4.0.0\",\n \"postcss\": \"^8.4.0\",\n \"typescript\": \"^5.0.0\"\n }\n}\n",
77
77
  "marketing/nextjs/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
78
78
  "marketing/nextjs/src/app/about/page.tsx": "import { Header } from \"@/components/Header\"\nimport { Footer } from \"@/components/Footer\"\nimport { LogoBanner, FinalCTA } from \"@/components/blocks\"\nimport { Users, Target, Heart, Zap } from \"lucide-react\"\n\nconst values = [\n {\n icon: <Users className=\"h-6 w-6\" />,\n title: \"Customer First\",\n description:\n \"Every decision we make starts with our customers. Their success is our success.\",\n },\n {\n icon: <Target className=\"h-6 w-6\" />,\n title: \"Simplicity Wins\",\n description:\n \"We believe powerful software doesn't have to be complicated. We obsess over making things simple.\",\n },\n {\n icon: <Heart className=\"h-6 w-6\" />,\n title: \"Built with Care\",\n description:\n \"We sweat the details because we know they matter. Quality is never an accident.\",\n },\n {\n icon: <Zap className=\"h-6 w-6\" />,\n title: \"Move Fast\",\n description:\n \"We ship early and often. Progress beats perfection when you're learning from real users.\",\n },\n]\n\nconst stats = [\n { value: \"50K+\", label: \"Teams worldwide\" },\n { value: \"180+\", label: \"Countries\" },\n { value: \"99.9%\", label: \"Uptime\" },\n { value: \"4.8/5\", label: \"Customer rating\" },\n]\n\nexport default function AboutPage() {\n return (\n <div className=\"min-h-screen flex flex-col\">\n <Header />\n\n <main className=\"flex-1\">\n {/* Hero */}\n <section className=\"py-16 md:py-24\">\n <div className=\"container mx-auto px-4\">\n <div className=\"max-w-3xl mx-auto text-center\">\n <h1 className=\"text-4xl md:text-5xl font-bold tracking-tight mb-6\">\n We're on a mission to help teams work better together\n </h1>\n <p className=\"text-xl text-muted-foreground\">\n SaaSify was founded in 2020 with a simple belief: work doesn't have to be\n complicated. We're building the tools that help teams focus on what matters.\n </p>\n </div>\n </div>\n </section>\n\n {/* Stats */}\n <section className=\"py-12 bg-muted/30\">\n <div className=\"container mx-auto px-4\">\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-8\">\n {stats.map((stat) => (\n <div key={stat.label} className=\"text-center\">\n <div className=\"text-4xl md:text-5xl font-bold text-primary mb-2\">\n {stat.value}\n </div>\n <div className=\"text-muted-foreground\">{stat.label}</div>\n </div>\n ))}\n </div>\n </div>\n </section>\n\n {/* Story */}\n <section className=\"py-16 md:py-24\">\n <div className=\"container mx-auto px-4\">\n <div className=\"max-w-3xl mx-auto\">\n <h2 className=\"text-3xl md:text-4xl font-bold tracking-tight mb-8 text-center\">\n Our story\n </h2>\n <div className=\"prose prose-lg max-w-none text-muted-foreground\">\n <p className=\"mb-6\">\n It all started with a frustration we've all felt: too many tools, too many\n tabs, too much time wasted switching between them. We knew there had to be\n a better way.\n </p>\n <p className=\"mb-6\">\n So we set out to build a platform that brings everything together—tasks,\n documents, communication, and automation—in one seamless experience. No more\n context switching. No more lost information. Just focused, productive work.\n </p>\n <p>\n Today, SaaSify is used by over 50,000 teams worldwide, from two-person\n startups to Fortune 500 companies. And we're just getting started.\n </p>\n </div>\n </div>\n </div>\n </section>\n\n {/* Values */}\n <section className=\"py-16 md:py-24 bg-muted/30\">\n <div className=\"container mx-auto px-4\">\n <div className=\"text-center mb-12 md:mb-16\">\n <h2 className=\"text-3xl md:text-4xl font-bold tracking-tight mb-4\">\n Our values\n </h2>\n <p className=\"text-lg text-muted-foreground max-w-2xl mx-auto\">\n These principles guide everything we do, from product decisions to how we\n treat each other.\n </p>\n </div>\n\n <div className=\"grid md:grid-cols-2 lg:grid-cols-4 gap-8 max-w-5xl mx-auto\">\n {values.map((value) => (\n <div\n key={value.title}\n className=\"bg-card rounded-lg border border-border p-6\"\n >\n <div className=\"w-12 h-12 rounded-lg bg-primary/10 text-primary flex items-center justify-center mb-4\">\n {value.icon}\n </div>\n <h3 className=\"text-lg font-semibold mb-2\">{value.title}</h3>\n <p className=\"text-muted-foreground text-sm\">{value.description}</p>\n </div>\n ))}\n </div>\n </div>\n </section>\n\n {/* Trusted By */}\n <LogoBanner\n heading=\"Trusted by teams at companies of all sizes\"\n style=\"scroll\"\n />\n\n {/* Final CTA */}\n <FinalCTA\n headline=\"Join us on our mission\"\n subheading=\"Start your free trial today and see why thousands of teams trust SaaSify.\"\n style=\"dark\"\n links={[\n { label: \"Start free trial\", href: \"/sign-up\", variant: \"outline\" },\n { label: \"Contact us\", href: \"/contact\", variant: \"default\" },\n ]}\n />\n </main>\n\n <Footer />\n </div>\n )\n}\n",
79
79
  "marketing/nextjs/src/app/blog/[slug]/page.tsx": "import { Header } from \"@/components/Header\"\nimport { Footer } from \"@/components/Footer\"\nimport { FinalCTA } from \"@/components/blocks\"\nimport Link from \"next/link\"\nimport { ArrowLeft, Calendar, Clock, User } from \"lucide-react\"\n\n// This is sample data - in a real app, you would fetch this from a CMS or MDX files\nconst blogPosts: Record<string, {\n title: string\n description: string\n content: string\n date: string\n author: string\n readTime: string\n category: string\n}> = {\n \"boost-team-productivity\": {\n title: \"10 Ways to Boost Your Team's Productivity\",\n description: \"Discover proven strategies to help your team work smarter, not harder.\",\n date: \"January 15, 2025\",\n author: \"Sarah Johnson\",\n readTime: \"8 min read\",\n category: \"Productivity\",\n content: `\n <p>In today's fast-paced business environment, productivity isn't just about working harder—it's about working smarter. Here are 10 proven strategies to help your team achieve more while maintaining a healthy work-life balance.</p>\n\n <h2>1. Set Clear Goals and Priorities</h2>\n <p>Without clear direction, teams can easily get lost in busywork. Start each week by defining the top 3-5 priorities that will move the needle for your organization.</p>\n\n <h2>2. Embrace Asynchronous Communication</h2>\n <p>Not every message needs an immediate response. By embracing async communication, you give your team members uninterrupted blocks of time to focus on deep work.</p>\n\n <h2>3. Automate Repetitive Tasks</h2>\n <p>If your team is doing the same task more than twice, it's time to automate it. Modern tools make it easy to create workflows that handle routine work automatically.</p>\n\n <h2>4. Hold Fewer, Better Meetings</h2>\n <p>Before scheduling a meeting, ask yourself: \"Could this be an email?\" When meetings are necessary, have a clear agenda and stick to the allotted time.</p>\n\n <h2>5. Invest in the Right Tools</h2>\n <p>The right tools can multiply your team's effectiveness. Look for platforms that integrate well with each other to reduce context switching.</p>\n\n <h2>6. Create a Culture of Documentation</h2>\n <p>When knowledge lives only in people's heads, it creates bottlenecks. Document processes, decisions, and learnings so everyone can move faster independently.</p>\n\n <h2>7. Encourage Regular Breaks</h2>\n <p>Counterintuitive as it may seem, taking breaks actually improves productivity. The human brain needs rest to perform at its best.</p>\n\n <h2>8. Provide Feedback Continuously</h2>\n <p>Don't wait for annual reviews to give feedback. Regular, constructive feedback helps team members course-correct and grow continuously.</p>\n\n <h2>9. Eliminate Unnecessary Approvals</h2>\n <p>Too many approval steps slow teams down. Trust your people to make good decisions and only require sign-off when truly necessary.</p>\n\n <h2>10. Celebrate Wins (Big and Small)</h2>\n <p>Recognition fuels motivation. Take time to acknowledge achievements, whether it's closing a big deal or simply shipping a feature on time.</p>\n\n <h2>Conclusion</h2>\n <p>Improving productivity is an ongoing journey, not a destination. Start with one or two of these strategies, measure the impact, and keep iterating. Your team will thank you for it.</p>\n `,\n },\n}\n\n// Generate static params for static generation\nexport function generateStaticParams() {\n return Object.keys(blogPosts).map((slug) => ({\n slug,\n }))\n}\n\nexport default async function BlogPostPage({\n params,\n}: {\n params: Promise<{ slug: string }>\n}) {\n const { slug } = await params\n const post = blogPosts[slug]\n\n // If post doesn't exist, show a placeholder\n if (!post) {\n return (\n <div className=\"min-h-screen flex flex-col\">\n <Header />\n <main className=\"flex-1\">\n <section className=\"py-16 md:py-24\">\n <div className=\"container mx-auto px-4 text-center\">\n <h1 className=\"text-4xl font-bold mb-4\">Post Not Found</h1>\n <p className=\"text-muted-foreground mb-8\">\n This blog post doesn&apos;t exist or has been removed.\n </p>\n <Link\n href=\"/blog\"\n className=\"inline-flex items-center text-primary hover:underline\"\n >\n <ArrowLeft className=\"h-4 w-4 mr-2\" />\n Back to blog\n </Link>\n </div>\n </section>\n </main>\n <Footer />\n </div>\n )\n }\n\n return (\n <div className=\"min-h-screen flex flex-col\">\n <Header />\n\n <main className=\"flex-1\">\n {/* Back Link */}\n <section className=\"pt-8\">\n <div className=\"container mx-auto px-4\">\n <Link\n href=\"/blog\"\n className=\"inline-flex items-center text-muted-foreground hover:text-foreground transition-colors\"\n >\n <ArrowLeft className=\"h-4 w-4 mr-2\" />\n Back to blog\n </Link>\n </div>\n </section>\n\n {/* Header */}\n <section className=\"py-12 md:py-16\">\n <div className=\"container mx-auto px-4\">\n <div className=\"max-w-3xl mx-auto\">\n <div className=\"mb-6\">\n <span className=\"inline-block px-3 py-1 text-xs font-medium rounded-full bg-primary/10 text-primary\">\n {post.category}\n </span>\n </div>\n <h1 className=\"text-4xl md:text-5xl font-bold tracking-tight mb-6\">\n {post.title}\n </h1>\n <p className=\"text-xl text-muted-foreground mb-8\">\n {post.description}\n </p>\n <div className=\"flex flex-wrap items-center gap-6 text-sm text-muted-foreground\">\n <div className=\"flex items-center gap-2\">\n <User className=\"h-4 w-4\" />\n {post.author}\n </div>\n <div className=\"flex items-center gap-2\">\n <Calendar className=\"h-4 w-4\" />\n {post.date}\n </div>\n <div className=\"flex items-center gap-2\">\n <Clock className=\"h-4 w-4\" />\n {post.readTime}\n </div>\n </div>\n </div>\n </div>\n </section>\n\n {/* Content */}\n <section className=\"pb-16 md:pb-24\">\n <div className=\"container mx-auto px-4\">\n <div\n className=\"max-w-3xl mx-auto prose prose-lg prose-gray dark:prose-invert\"\n dangerouslySetInnerHTML={{ __html: post.content }}\n />\n </div>\n </section>\n\n {/* Final CTA */}\n <FinalCTA\n headline=\"Ready to transform how your team works?\"\n subheading=\"Start your free trial and see the difference SaaSify can make.\"\n style=\"dark\"\n links={[\n { label: \"Start free trial\", href: \"/sign-up\", variant: \"outline\" },\n { label: \"View pricing\", href: \"/pricing\", variant: \"default\" },\n ]}\n />\n </main>\n\n <Footer />\n </div>\n )\n}\n",
@@ -398,7 +398,7 @@ export const EMBEDDED_TEMPLATES: Record<string, string> = {
398
398
  "packages/ui/src/styles.css.hbs": "@import \"tailwindcss\";\n\n@custom-variant dark (&:is(.dark *));\n\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --font-sans: var(--font-geist-sans);\n --font-mono: var(--font-geist-mono);\n --color-sidebar-ring: var(--sidebar-ring);\n --color-sidebar-border: var(--sidebar-border);\n --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);\n --color-sidebar-accent: var(--sidebar-accent);\n --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);\n --color-sidebar-primary: var(--sidebar-primary);\n --color-sidebar-foreground: var(--sidebar-foreground);\n --color-sidebar: var(--sidebar);\n --color-chart-5: var(--chart-5);\n --color-chart-4: var(--chart-4);\n --color-chart-3: var(--chart-3);\n --color-chart-2: var(--chart-2);\n --color-chart-1: var(--chart-1);\n --color-ring: var(--ring);\n --color-input: var(--input);\n --color-border: var(--border);\n --color-destructive: var(--destructive);\n --color-accent-foreground: var(--accent-foreground);\n --color-accent: var(--accent);\n --color-muted-foreground: var(--muted-foreground);\n --color-muted: var(--muted);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-secondary: var(--secondary);\n --color-primary-foreground: var(--primary-foreground);\n --color-primary: var(--primary);\n --color-popover-foreground: var(--popover-foreground);\n --color-popover: var(--popover);\n --color-card-foreground: var(--card-foreground);\n --color-card: var(--card);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n}\n\n:root {\n --radius: 0.625rem;\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0 0);\n --primary: oklch(0.205 0 0);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.97 0 0);\n --secondary-foreground: oklch(0.205 0 0);\n --muted: oklch(0.97 0 0);\n --muted-foreground: oklch(0.556 0 0);\n --accent: oklch(0.97 0 0);\n --accent-foreground: oklch(0.205 0 0);\n --destructive: oklch(0.577 0.245 27.325);\n --border: oklch(0.922 0 0);\n --input: oklch(0.922 0 0);\n --ring: oklch(0.708 0 0);\n --chart-1: oklch(0.646 0.222 41.116);\n --chart-2: oklch(0.6 0.118 184.704);\n --chart-3: oklch(0.398 0.07 227.392);\n --chart-4: oklch(0.828 0.189 84.429);\n --chart-5: oklch(0.769 0.188 70.08);\n --sidebar: oklch(0.985 0 0);\n --sidebar-foreground: oklch(0.145 0 0);\n --sidebar-primary: oklch(0.205 0 0);\n --sidebar-primary-foreground: oklch(0.985 0 0);\n --sidebar-accent: oklch(0.97 0 0);\n --sidebar-accent-foreground: oklch(0.205 0 0);\n --sidebar-border: oklch(0.922 0 0);\n --sidebar-ring: oklch(0.708 0 0);\n}\n\n.dark {\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.205 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.922 0 0);\n --primary-foreground: oklch(0.205 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.269 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.556 0 0);\n --chart-1: oklch(0.488 0.243 264.376);\n --chart-2: oklch(0.696 0.17 162.48);\n --chart-3: oklch(0.769 0.188 70.08);\n --chart-4: oklch(0.627 0.265 303.9);\n --chart-5: oklch(0.645 0.246 16.439);\n --sidebar: oklch(0.205 0 0);\n --sidebar-foreground: oklch(0.985 0 0);\n --sidebar-primary: oklch(0.488 0.243 264.376);\n --sidebar-primary-foreground: oklch(0.985 0 0);\n --sidebar-accent: oklch(0.269 0 0);\n --sidebar-accent-foreground: oklch(0.985 0 0);\n --sidebar-border: oklch(1 0 0 / 10%);\n --sidebar-ring: oklch(0.556 0 0);\n}\n\n@layer base {\n * {\n @apply border-border outline-ring/50;\n }\n body {\n @apply bg-background text-foreground;\n }\n}\n",
399
399
  "packages/ui/tsconfig.json.hbs": "{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n \"allowJs\": true,\n \"skipLibCheck\": true,\n \"strict\": true,\n \"noEmit\": true,\n \"esModuleInterop\": true,\n \"module\": \"esnext\",\n \"moduleResolution\": \"bundler\",\n \"resolveJsonModule\": true,\n \"isolatedModules\": true,\n \"jsx\": \"react-jsx\",\n \"incremental\": true,\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n },\n \"include\": [\"src/**/*\"],\n \"exclude\": [\"node_modules\"]\n}\n",
400
400
  "web/_env.local.hbs": "# Convex - These values are synced from packages/backend/.env.local after running convex dev\n# NEXT_PUBLIC_CONVEX_URL and NEXT_PUBLIC_CONVEX_SITE_URL are auto-synced by dev script\nNEXT_PUBLIC_CONVEX_URL=\nNEXT_PUBLIC_CONVEX_SITE_URL=\n\n# Site URL for auth (your frontend URL)\nNEXT_PUBLIC_SITE_URL=http://localhost:3000\n{{#if (eq integrations.analytics 'posthog')}}\n\n# PostHog\nNEXT_PUBLIC_POSTHOG_KEY=\nNEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com\n{{/if}}\n{{#if (eq integrations.payments 'stripe')}}\n\n# Stripe\nNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=\n{{/if}}\n",
401
- "web/components.json.hbs": "{\n \"$schema\": \"https://ui.shadcn.com/schema.json\",\n \"style\": \"new-york\",\n \"rsc\": true,\n \"tsx\": true,\n \"tailwind\": {\n \"config\": \"\",\n \"css\": \"src/app/globals.css\",\n \"baseColor\": \"{{shadcn.baseColor}}\",\n \"cssVariables\": true,\n \"prefix\": \"\"\n },\n \"aliases\": {\n \"components\": \"@/components\",\n \"utils\": \"@/lib/utils\",\n \"ui\": \"@/components/ui\",\n \"lib\": \"@/lib\",\n \"hooks\": \"@/hooks\"\n },\n \"iconLibrary\": \"{{shadcn.iconLibrary}}\"\n}\n",
401
+ "web/components.json.hbs": "{\n \"$schema\": \"https://ui.shadcn.com/schema.json\",\n{{#if (eq shadcn.style \"nova\")}}\n \"style\": \"new-york\",\n{{else if (eq shadcn.style \"vega\")}}\n \"style\": \"default\",\n{{else}}\n \"style\": \"new-york\",\n{{/if}}\n \"rsc\": true,\n \"tsx\": true,\n \"tailwind\": {\n \"config\": \"\",\n \"css\": \"src/app/globals.css\",\n \"baseColor\": \"{{shadcn.baseColor}}\",\n \"cssVariables\": true,\n \"prefix\": \"\"\n },\n \"aliases\": {\n \"components\": \"@/components\",\n \"utils\": \"@/lib/utils\",\n \"ui\": \"@/components/ui\",\n \"lib\": \"@/lib\",\n \"hooks\": \"@/hooks\"\n },\n \"iconLibrary\": \"{{shadcn.iconLibrary}}\"\n}\n",
402
402
  "web/next.config.ts.hbs": "import type { NextConfig } from 'next'\n\nconst nextConfig: NextConfig = {\n{{#if (eq structure 'monorepo')}}\n transpilePackages: ['@repo/ui', '@repo/backend'],\n{{/if}}\n}\n\nexport default nextConfig\n",
403
403
  "web/package.json.hbs": "{\n \"name\": \"{{#if (eq structure 'monorepo')}}@repo/web{{else}}{{projectName}}{{/if}}\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"dev\": \"{{#if (eq structure 'monorepo')}}next dev --turbopack --port 3001{{else}}node scripts/dev.mjs{{/if}}\",\n \"dev:next\": \"next dev --turbopack\",\n{{#unless (eq structure 'monorepo')}} \"dev:setup\": \"npx convex dev --configure --until-success\",\n{{/unless}} \"build\": \"next build\",\n \"start\": \"next start\",\n \"lint\": \"biome check .\",\n \"lint:fix\": \"biome check --write .\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:e2e\": \"playwright test\"\n },\n \"dependencies\": {\n{{#if (eq structure 'monorepo')}} \"@repo/backend\": \"workspace:*\",\n \"@repo/ui\": \"workspace:*\",\n{{/if}} \"next\": \"^16.0.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"convex\": \"^1.25.0\",\n \"@convex-dev/better-auth\": \"^0.10.0\",\n \"better-auth\": \"1.4.9\",\n{{#unless (eq structure 'monorepo')}}{{#if (eq shadcn.iconLibrary \"hugeicons\")}} \"@hugeicons/react\": \"^0.3.0\",\n{{/if}}{{#if (eq shadcn.iconLibrary \"lucide\")}} \"lucide-react\": \"^0.469.0\",\n{{/if}}{{#if (eq shadcn.iconLibrary \"tabler\")}} \"@tabler/icons-react\": \"^3.31.0\",\n{{/if}}{{#if (eq shadcn.iconLibrary \"phosphor\")}} \"@phosphor-icons/react\": \"^2.1.7\",\n{{/if}}{{/unless}} \"class-variance-authority\": \"^0.7.0\",\n \"clsx\": \"^2.1.0\",\n \"tailwind-merge\": \"^2.5.0\",\n \"tw-animate-css\": \"^1.3.0\",\n \"resend\": \"^4.0.0\",\n \"react-email\": \"^3.0.0\",\n \"@react-email/components\": \"^0.0.36\"{{#if (eq integrations.analytics 'posthog')}},\n \"posthog-js\": \"^1.200.0\",\n \"posthog-node\": \"^5.0.0\"{{/if}}{{#if (eq integrations.analytics 'vercel')}},\n \"@vercel/analytics\": \"^1.4.0\",\n \"@vercel/speed-insights\": \"^1.1.0\"{{/if}}{{#if (eq integrations.uploads 'uploadthing')}},\n \"uploadthing\": \"^7.0.0\",\n \"@uploadthing/react\": \"^7.0.0\"{{/if}}{{#if (eq integrations.uploads 's3')}},\n \"@aws-sdk/client-s3\": \"^3.700.0\",\n \"@aws-sdk/s3-request-presigner\": \"^3.700.0\"{{/if}}{{#if (eq integrations.uploads 'vercel-blob')}},\n \"@vercel/blob\": \"^2.0.0\"{{/if}}{{#if (includes addons 'rate-limiting')}},\n \"@arcjet/next\": \"^1.0.0-beta.16\"{{/if}}{{#if (includes addons 'monitoring')}},\n \"@sentry/nextjs\": \"^8.0.0\"{{/if}}\n },\n \"devDependencies\": {\n{{#if (eq structure 'monorepo')}} \"@repo/config-typescript\": \"workspace:*\",\n{{/if}} \"@types/node\": \"^20.0.0\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n \"tailwindcss\": \"^4.0.0\",\n \"@tailwindcss/postcss\": \"^4.0.0\",\n \"postcss\": \"^8.4.0\",\n \"typescript\": \"^5.0.0\",\n \"vitest\": \"^3.0.0\",\n \"@vitejs/plugin-react\": \"^4.3.0\",\n \"@testing-library/react\": \"^16.0.0\",\n \"jsdom\": \"^26.0.0\",\n \"playwright\": \"^1.50.0\",\n \"@playwright/test\": \"^1.50.0\"\n }\n}\n",
404
404
  "web/postcss.config.mjs.hbs": "export default {\n plugins: {\n '@tailwindcss/postcss': {},\n },\n}\n",
@@ -19,7 +19,8 @@
19
19
  "next-themes": "^0.4.4",
20
20
  "clsx": "^2.1.1",
21
21
  "tailwind-merge": "^2.6.0",
22
- "class-variance-authority": "^0.7.1"
22
+ "class-variance-authority": "^0.7.1",
23
+ "tw-animate-css": "^1.3.0"
23
24
  },
24
25
  "devDependencies": {
25
26
  "@repo/config-typescript": "workspace:*",
@@ -1,6 +1,12 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema.json",
3
+ {{#if (eq shadcn.style "nova")}}
3
4
  "style": "new-york",
5
+ {{else if (eq shadcn.style "vega")}}
6
+ "style": "default",
7
+ {{else}}
8
+ "style": "new-york",
9
+ {{/if}}
4
10
  "rsc": true,
5
11
  "tsx": true,
6
12
  "tailwind": {