kaddidlehopper 0.5.0 → 0.6.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/cli.js +104 -208
- package/dist/index.js +1 -31
- package/dist/types/cli.d.ts +1 -8
- package/dist/types/types.d.ts +7 -12
- package/package.json +1 -2
- package/src/cli.ts +129 -271
- package/src/index.ts +1 -47
- package/src/types.ts +7 -13
- package/CONTEXT.md +0 -139
- package/add-ons/ai/README.md +0 -34
- package/add-ons/ai/assets/AGENTS.md.append +0 -24
- package/add-ons/ai/assets/_dot_env.local.append +0 -13
- package/add-ons/ai/assets/src/components/AIAssistant.tsx +0 -149
- package/add-ons/ai/assets/src/lib/ai-hook.ts +0 -21
- package/add-ons/ai/assets/src/lib/weather-tools.ts +0 -30
- package/add-ons/ai/assets/src/routes/api.chat.ts +0 -94
- package/add-ons/ai/assets/src/routes/chat.css +0 -175
- package/add-ons/ai/assets/src/routes/chat.tsx +0 -141
- package/add-ons/ai/info.json +0 -22
- package/add-ons/ai/package.json +0 -17
- package/add-ons/ai/small-logo.svg +0 -8
- package/add-ons/db/assets/AGENTS.md.append +0 -22
- package/add-ons/db/assets/DB-SETUP.md +0 -65
- package/add-ons/db/assets/_dot_env.local.append +0 -2
- package/add-ons/db/assets/drizzle.config.ts +0 -10
- package/add-ons/db/assets/src/db/index.ts +0 -8
- package/add-ons/db/assets/src/db/schema.ts +0 -8
- package/add-ons/db/assets/src/routes/db-example.tsx +0 -118
- package/add-ons/db/assets/src/server/guestbook.functions.ts +0 -23
- package/add-ons/db/info.json +0 -22
- package/add-ons/db/package.json +0 -10
- package/add-ons/forms/assets/AGENTS.md.append +0 -13
- package/add-ons/forms/assets/public/form-example.html +0 -14
- package/add-ons/forms/assets/src/routes/form-example.tsx +0 -76
- package/add-ons/forms/info.json +0 -18
- package/add-ons/forms/package.json +0 -3
- package/examples/ai-chat/README.md +0 -36
- package/examples/ai-chat/assets/AGENTS.md.append +0 -24
- package/examples/ai-chat/assets/src/lib/ai-hook.ts +0 -21
- package/examples/ai-chat/assets/src/lib/weather-tools.ts +0 -30
- package/examples/ai-chat/assets/src/routes/__root.tsx +0 -57
- package/examples/ai-chat/assets/src/routes/api.chat.ts +0 -94
- package/examples/ai-chat/assets/src/routes/index.tsx +0 -141
- package/examples/ai-chat/assets/src/styles.css +0 -165
- package/examples/ai-chat/info.json +0 -25
- package/examples/ai-chat/package.json +0 -14
- package/examples/blog/README.md +0 -60
- package/examples/blog/assets/AGENTS.md.append +0 -18
- package/examples/blog/assets/content/posts/beach.md +0 -12
- package/examples/blog/assets/content/posts/jungle.md.ejs +0 -12
- package/examples/blog/assets/content/posts/mountains.md.ejs +0 -12
- package/examples/blog/assets/content/posts/snorkeling.md.ejs +0 -12
- package/examples/blog/assets/content/posts/waterfall.md.ejs +0 -12
- package/examples/blog/assets/content-collections.ts +0 -30
- package/examples/blog/assets/public/beach.jpg +0 -0
- package/examples/blog/assets/public/jungle.jpg +0 -0
- package/examples/blog/assets/public/mountains.jpg +0 -0
- package/examples/blog/assets/public/snorkeling.jpg +0 -0
- package/examples/blog/assets/public/waterfall.jpg +0 -0
- package/examples/blog/assets/src/components/Header.tsx +0 -52
- package/examples/blog/assets/src/components/VacayAssistant.tsx +0 -205
- package/examples/blog/assets/src/components/blog-posts.tsx +0 -78
- package/examples/blog/assets/src/components/ui/card.tsx +0 -92
- package/examples/blog/assets/src/lib/blog-ai-hook.ts +0 -25
- package/examples/blog/assets/src/lib/blog-tools.ts +0 -111
- package/examples/blog/assets/src/lib/utils.ts +0 -6
- package/examples/blog/assets/src/routes/__root.tsx +0 -57
- package/examples/blog/assets/src/routes/api.blog-chat.ts +0 -117
- package/examples/blog/assets/src/routes/category.$category.tsx +0 -19
- package/examples/blog/assets/src/routes/index.tsx +0 -19
- package/examples/blog/assets/src/routes/posts.$slug.tsx +0 -63
- package/examples/blog/assets/src/styles.css +0 -138
- package/examples/blog/info.json +0 -40
- package/examples/blog/package.json +0 -23
- package/examples/calculator/README.md +0 -16
- package/examples/calculator/assets/AGENTS.md.append +0 -9
- package/examples/calculator/assets/src/components/Calculator.tsx +0 -238
- package/examples/calculator/assets/src/components/Header.tsx +0 -17
- package/examples/calculator/assets/src/routes/__root.tsx +0 -57
- package/examples/calculator/assets/src/routes/index.tsx +0 -14
- package/examples/calculator/info.json +0 -20
- package/examples/calculator/package.json +0 -1
- package/examples/dashboard/README.md +0 -17
- package/examples/dashboard/assets/AGENTS.md.append +0 -12
- package/examples/dashboard/assets/src/components/Header.tsx +0 -17
- package/examples/dashboard/assets/src/routes/__root.tsx +0 -57
- package/examples/dashboard/assets/src/routes/index.tsx +0 -158
- package/examples/dashboard/info.json +0 -19
- package/examples/dashboard/package.json +0 -6
- package/examples/ecommerce/README.md +0 -48
- package/examples/ecommerce/assets/AGENTS.md.append +0 -22
- package/examples/ecommerce/assets/public/logo.png +0 -0
- package/examples/ecommerce/assets/public/motorcycle-scooter.jpg +0 -0
- package/examples/ecommerce/assets/src/components/BuyButton.tsx +0 -35
- package/examples/ecommerce/assets/src/components/Header.tsx +0 -36
- package/examples/ecommerce/assets/src/components/MotorcycleAIAssistant.tsx +0 -162
- package/examples/ecommerce/assets/src/components/MotorcycleRecommendation.tsx +0 -53
- package/examples/ecommerce/assets/src/data/motorcycles.ts +0 -27
- package/examples/ecommerce/assets/src/lib/motorcycle-ai-hook.ts +0 -24
- package/examples/ecommerce/assets/src/lib/motorcycle-tools.ts +0 -42
- package/examples/ecommerce/assets/src/lib/stripe.server.ts +0 -39
- package/examples/ecommerce/assets/src/routes/__root.tsx +0 -57
- package/examples/ecommerce/assets/src/routes/api.motorcycle-chat.ts +0 -78
- package/examples/ecommerce/assets/src/routes/checkout/cancel.tsx +0 -25
- package/examples/ecommerce/assets/src/routes/checkout/success.tsx +0 -25
- package/examples/ecommerce/assets/src/routes/index.tsx +0 -76
- package/examples/ecommerce/assets/src/routes/motorcycles/$motorcycleId.tsx +0 -55
- package/examples/ecommerce/assets/src/store/motorcycle-assistant.ts +0 -3
- package/examples/ecommerce/assets/src/styles.css +0 -212
- package/examples/ecommerce/info.json +0 -38
- package/examples/ecommerce/package.json +0 -13
- package/examples/events/README.md +0 -110
- package/examples/events/assets/AGENTS.md.append +0 -21
- package/examples/events/assets/content/speakers/andre-costa.md +0 -22
- package/examples/events/assets/content/speakers/hans-mueller.md.ejs +0 -22
- package/examples/events/assets/content/speakers/isabella-martinez.md.ejs +0 -22
- package/examples/events/assets/content/speakers/kenji-nakamura.md.ejs +0 -22
- package/examples/events/assets/content/speakers/marie-dubois.md.ejs +0 -20
- package/examples/events/assets/content/speakers/priya-sharma.md.ejs +0 -22
- package/examples/events/assets/content/talks/croissant-lamination-secrets.md +0 -39
- package/examples/events/assets/content/talks/french-macaron-mastery.md.ejs +0 -39
- package/examples/events/assets/content/talks/neapolitan-pizza-tradition-meets-innovation.md.ejs +0 -39
- package/examples/events/assets/content/talks/savory-breads-of-the-mediterranean.md.ejs +0 -39
- package/examples/events/assets/content/talks/sourdough-from-starter-to-masterpiece.md.ejs +0 -36
- package/examples/events/assets/content/talks/the-art-of-the-perfect-tart.md.ejs +0 -32
- package/examples/events/assets/content/talks/the-science-of-sugar.md.ejs +0 -39
- package/examples/events/assets/content/talks/umami-in-pastry-east-meets-west.md.ejs +0 -39
- package/examples/events/assets/content-collections.ts +0 -56
- package/examples/events/assets/public/background-1.jpg +0 -0
- package/examples/events/assets/public/background-2.jpg +0 -0
- package/examples/events/assets/public/background-3.jpg +0 -0
- package/examples/events/assets/public/background-4.jpg +0 -0
- package/examples/events/assets/public/conference-logo.png +0 -0
- package/examples/events/assets/public/favicon.ico +0 -0
- package/examples/events/assets/public/speakers/andre-costa.jpg +0 -0
- package/examples/events/assets/public/speakers/hans-mueller.jpg +0 -0
- package/examples/events/assets/public/speakers/isabella-martinez.jpg +0 -0
- package/examples/events/assets/public/speakers/kenji-nakamura.jpg +0 -0
- package/examples/events/assets/public/speakers/marie-dubois.jpg +0 -0
- package/examples/events/assets/public/speakers/priya-sharma.jpg +0 -0
- package/examples/events/assets/public/talks/croissant-lamination-secrets.jpg +0 -0
- package/examples/events/assets/public/talks/french-macaron-mastery.jpg +0 -0
- package/examples/events/assets/public/talks/neapolitan-pizza-tradition-meets-innovation.jpg +0 -0
- package/examples/events/assets/public/talks/savory-breads-of-the-mediterranean.jpg +0 -0
- package/examples/events/assets/public/talks/sourdough-from-starter-to-masterpiece.jpg +0 -0
- package/examples/events/assets/public/talks/the-art-of-the-perfect-tart.jpg +0 -0
- package/examples/events/assets/public/talks/the-science-of-sugar.jpg +0 -0
- package/examples/events/assets/public/talks/umami-in-pastry-east-meets-west.jpg +0 -0
- package/examples/events/assets/public/tanstack-circle-logo.png +0 -0
- package/examples/events/assets/public/tanstack-word-logo-white.svg +0 -1
- package/examples/events/assets/src/components/Header.tsx +0 -59
- package/examples/events/assets/src/components/HeaderNav.tsx +0 -67
- package/examples/events/assets/src/components/HeroCarousel.tsx +0 -61
- package/examples/events/assets/src/components/RemyAssistant.tsx +0 -207
- package/examples/events/assets/src/components/SpeakerCard.tsx +0 -67
- package/examples/events/assets/src/components/TalkCard.tsx +0 -77
- package/examples/events/assets/src/components/ui/card.tsx +0 -92
- package/examples/events/assets/src/lib/conference-ai-hook.ts +0 -26
- package/examples/events/assets/src/lib/conference-tools.ts +0 -210
- package/examples/events/assets/src/lib/model-selection.ts +0 -1
- package/examples/events/assets/src/lib/utils.ts +0 -6
- package/examples/events/assets/src/routes/__root.tsx +0 -70
- package/examples/events/assets/src/routes/api.remy-chat.ts +0 -119
- package/examples/events/assets/src/routes/index.tsx +0 -192
- package/examples/events/assets/src/routes/schedule.index.tsx +0 -274
- package/examples/events/assets/src/routes/speakers.$slug.tsx +0 -122
- package/examples/events/assets/src/routes/speakers.index.tsx +0 -40
- package/examples/events/assets/src/routes/talks.$slug.tsx +0 -116
- package/examples/events/assets/src/routes/talks.index.tsx +0 -40
- package/examples/events/assets/src/styles.css +0 -182
- package/examples/events/info.json +0 -61
- package/examples/events/package.json +0 -23
- package/examples/marketing/README.md +0 -60
- package/examples/marketing/assets/AGENTS.md.append +0 -15
- package/examples/marketing/assets/public/logo.png +0 -0
- package/examples/marketing/assets/public/motorcycle-adventure.jpg +0 -0
- package/examples/marketing/assets/public/motorcycle-cruiser.jpg +0 -0
- package/examples/marketing/assets/public/motorcycle-scooter.jpg +0 -0
- package/examples/marketing/assets/public/motorcycle-sport.jpg +0 -0
- package/examples/marketing/assets/public/motorcycle-supersport.jpg +0 -0
- package/examples/marketing/assets/src/components/Header.tsx +0 -36
- package/examples/marketing/assets/src/components/MotorcycleAIAssistant.tsx +0 -162
- package/examples/marketing/assets/src/components/MotorcycleRecommendation.tsx +0 -53
- package/examples/marketing/assets/src/data/motorcycles.ts.ejs +0 -77
- package/examples/marketing/assets/src/lib/motorcycle-ai-hook.ts +0 -24
- package/examples/marketing/assets/src/lib/motorcycle-tools.ts +0 -42
- package/examples/marketing/assets/src/routes/__root.tsx +0 -57
- package/examples/marketing/assets/src/routes/api.motorcycle-chat.ts +0 -78
- package/examples/marketing/assets/src/routes/index.tsx +0 -72
- package/examples/marketing/assets/src/routes/motorcycles/$motorcycleId.tsx +0 -56
- package/examples/marketing/assets/src/store/motorcycle-assistant.ts +0 -3
- package/examples/marketing/assets/src/styles.css +0 -212
- package/examples/marketing/info.json +0 -33
- package/examples/marketing/package.json +0 -14
- package/examples/portfolio/README.md +0 -49
- package/examples/portfolio/assets/AGENTS.md.append +0 -21
- package/examples/portfolio/assets/content/blog/getting-started-with-tanstack.md +0 -53
- package/examples/portfolio/assets/content/blog/react-19-features.md +0 -78
- package/examples/portfolio/assets/content/blog/tailwind-css-v4-guide.md +0 -60
- package/examples/portfolio/assets/content/education/code-school.md +0 -17
- package/examples/portfolio/assets/content/jobs/initech-junior.md +0 -20
- package/examples/portfolio/assets/content/projects/portfolio-site.md +0 -15
- package/examples/portfolio/assets/content/projects/task-manager.md +0 -15
- package/examples/portfolio/assets/content-collections.ts +0 -65
- package/examples/portfolio/assets/public/contact.html +0 -6
- package/examples/portfolio/assets/public/headshot-on-white.jpg +0 -0
- package/examples/portfolio/assets/src/components/Header.tsx +0 -33
- package/examples/portfolio/assets/src/components/ResumeAssistant.tsx +0 -193
- package/examples/portfolio/assets/src/components/ui/badge.tsx +0 -46
- package/examples/portfolio/assets/src/components/ui/card.tsx +0 -92
- package/examples/portfolio/assets/src/components/ui/checkbox.tsx +0 -30
- package/examples/portfolio/assets/src/components/ui/hover-card.tsx +0 -44
- package/examples/portfolio/assets/src/components/ui/separator.tsx +0 -26
- package/examples/portfolio/assets/src/lib/resume-ai-hook.ts +0 -21
- package/examples/portfolio/assets/src/lib/resume-tools.ts +0 -165
- package/examples/portfolio/assets/src/lib/utils.ts +0 -6
- package/examples/portfolio/assets/src/routes/__root.tsx +0 -57
- package/examples/portfolio/assets/src/routes/api.resume-chat.ts +0 -116
- package/examples/portfolio/assets/src/routes/blog/$slug.tsx +0 -73
- package/examples/portfolio/assets/src/routes/contact.tsx +0 -121
- package/examples/portfolio/assets/src/routes/index.tsx +0 -55
- package/examples/portfolio/assets/src/routes/projects.tsx +0 -62
- package/examples/portfolio/assets/src/routes/resume.tsx +0 -220
- package/examples/portfolio/assets/src/styles.css +0 -138
- package/examples/portfolio/info.json +0 -50
- package/examples/portfolio/package.json +0 -26
- package/examples/resume/README.md +0 -82
- package/examples/resume/assets/AGENTS.md.append +0 -19
- package/examples/resume/assets/content/education/code-school.md +0 -17
- package/examples/resume/assets/content/jobs/freelance.md.ejs +0 -13
- package/examples/resume/assets/content/jobs/initech-junior.md +0 -20
- package/examples/resume/assets/content/jobs/initech-lead.md.ejs +0 -29
- package/examples/resume/assets/content/jobs/initrode-senior.md.ejs +0 -28
- package/examples/resume/assets/content-collections.ts +0 -36
- package/examples/resume/assets/public/headshot-on-white.jpg +0 -0
- package/examples/resume/assets/src/components/Header.tsx +0 -33
- package/examples/resume/assets/src/components/ResumeAssistant.tsx +0 -193
- package/examples/resume/assets/src/components/ui/badge.tsx +0 -46
- package/examples/resume/assets/src/components/ui/card.tsx +0 -92
- package/examples/resume/assets/src/components/ui/checkbox.tsx +0 -30
- package/examples/resume/assets/src/components/ui/hover-card.tsx +0 -44
- package/examples/resume/assets/src/components/ui/separator.tsx +0 -26
- package/examples/resume/assets/src/lib/resume-ai-hook.ts +0 -21
- package/examples/resume/assets/src/lib/resume-tools.ts +0 -165
- package/examples/resume/assets/src/lib/utils.ts +0 -6
- package/examples/resume/assets/src/routes/api.resume-chat.ts +0 -110
- package/examples/resume/assets/src/routes/index.tsx +0 -220
- package/examples/resume/assets/src/styles.css +0 -138
- package/examples/resume/info.json +0 -35
- package/examples/resume/package.json +0 -26
- package/examples/saas/README.md +0 -16
- package/examples/saas/assets/AGENTS.md.append +0 -9
- package/examples/saas/assets/src/components/Header.tsx +0 -17
- package/examples/saas/assets/src/routes/__root.tsx +0 -57
- package/examples/saas/assets/src/routes/faq.tsx +0 -94
- package/examples/saas/assets/src/routes/index.tsx +0 -197
- package/examples/saas/info.json +0 -23
- package/examples/saas/package.json +0 -1
- package/examples/survey/README.md +0 -20
- package/examples/survey/assets/AGENTS.md.append +0 -9
- package/examples/survey/assets/public/form-survey.html +0 -15
- package/examples/survey/assets/src/components/SurveyForm.tsx +0 -128
- package/examples/survey/assets/src/routes/index.tsx +0 -14
- package/examples/survey/info.json +0 -19
- package/examples/survey/package.json +0 -1
- package/project/base/AGENTS.md +0 -86
- package/project/base/_dot_claude/skills/content-collections/SKILL.md +0 -505
- package/project/base/_dot_claude/skills/netlify-blobs/SKILL.md +0 -410
- package/project/base/_dot_claude/skills/netlify-db/SKILL.md +0 -424
- package/project/base/_dot_claude/skills/netlify-debugging/SKILL.md +0 -419
- package/project/base/_dot_claude/skills/netlify-forms/SKILL.md +0 -243
- package/project/base/_dot_claude/skills/netlify-functions/SKILL.md +0 -372
- package/project/base/_dot_claude/skills/tanstack-start-api-routes/SKILL.md +0 -421
- package/project/base/_dot_claude/skills/tanstack-start-loaders/SKILL.md +0 -426
- package/project/base/_dot_claude/skills/tanstack-start-project-setup/SKILL.md +0 -493
- package/project/base/_dot_claude/skills/tanstack-start-routes/SKILL.md +0 -430
- package/project/base/_dot_claude/skills/tanstack-start-server-functions/SKILL.md +0 -445
- package/project/base/_dot_claude/skills/tanstack-start-typesafe-routing/SKILL.md +0 -494
- package/project/base/_dot_gitignore +0 -8
- package/project/base/netlify.toml +0 -7
- package/project/base/package.json +0 -33
- package/project/base/public/favicon.ico +0 -0
- package/project/base/public/tanstack-circle-logo.png +0 -0
- package/project/base/public/tanstack-word-logo-white.svg +0 -1
- package/project/base/src/components/Header.tsx +0 -17
- package/project/base/src/components/HeaderNav.tsx.ejs +0 -179
- package/project/base/src/router.tsx +0 -15
- package/project/base/src/routes/__root.tsx +0 -57
- package/project/base/src/routes/index.tsx +0 -48
- package/project/base/src/styles.css +0 -15
- package/project/base/tsconfig.json +0 -28
- package/project/base/vite.config.ts.ejs +0 -25
- package/project/info.json +0 -17
- package/project/packages.json +0 -22
- package/scripts/check-outdated-packages.js +0 -421
- package/src/agents-md.ts +0 -139
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
@import 'tailwindcss';
|
|
2
|
-
|
|
3
|
-
@plugin "tailwindcss-animate";
|
|
4
|
-
|
|
5
|
-
@custom-variant dark (&:is(.dark *));
|
|
6
|
-
|
|
7
|
-
body {
|
|
8
|
-
@apply m-0;
|
|
9
|
-
font-family:
|
|
10
|
-
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
|
|
11
|
-
'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
|
12
|
-
-webkit-font-smoothing: antialiased;
|
|
13
|
-
-moz-osx-font-smoothing: grayscale;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
code {
|
|
17
|
-
font-family:
|
|
18
|
-
source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
:root {
|
|
22
|
-
--background: oklch(1 0 0);
|
|
23
|
-
--foreground: oklch(0.141 0.005 285.823);
|
|
24
|
-
--card: oklch(1 0 0);
|
|
25
|
-
--card-foreground: oklch(0.141 0.005 285.823);
|
|
26
|
-
--popover: oklch(1 0 0);
|
|
27
|
-
--popover-foreground: oklch(0.141 0.005 285.823);
|
|
28
|
-
--primary: oklch(0.21 0.006 285.885);
|
|
29
|
-
--primary-foreground: oklch(0.985 0 0);
|
|
30
|
-
--secondary: oklch(0.967 0.001 286.375);
|
|
31
|
-
--secondary-foreground: oklch(0.21 0.006 285.885);
|
|
32
|
-
--muted: oklch(0.967 0.001 286.375);
|
|
33
|
-
--muted-foreground: oklch(0.552 0.016 285.938);
|
|
34
|
-
--accent: oklch(0.967 0.001 286.375);
|
|
35
|
-
--accent-foreground: oklch(0.21 0.006 285.885);
|
|
36
|
-
--destructive: oklch(0.577 0.245 27.325);
|
|
37
|
-
--destructive-foreground: oklch(0.577 0.245 27.325);
|
|
38
|
-
--border: oklch(0.92 0.004 286.32);
|
|
39
|
-
--input: oklch(0.92 0.004 286.32);
|
|
40
|
-
--ring: oklch(0.871 0.006 286.286);
|
|
41
|
-
--chart-1: oklch(0.646 0.222 41.116);
|
|
42
|
-
--chart-2: oklch(0.6 0.118 184.704);
|
|
43
|
-
--chart-3: oklch(0.398 0.07 227.392);
|
|
44
|
-
--chart-4: oklch(0.828 0.189 84.429);
|
|
45
|
-
--chart-5: oklch(0.769 0.188 70.08);
|
|
46
|
-
--radius: 0.625rem;
|
|
47
|
-
--sidebar: oklch(0.985 0 0);
|
|
48
|
-
--sidebar-foreground: oklch(0.141 0.005 285.823);
|
|
49
|
-
--sidebar-primary: oklch(0.21 0.006 285.885);
|
|
50
|
-
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
51
|
-
--sidebar-accent: oklch(0.967 0.001 286.375);
|
|
52
|
-
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
|
|
53
|
-
--sidebar-border: oklch(0.92 0.004 286.32);
|
|
54
|
-
--sidebar-ring: oklch(0.871 0.006 286.286);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.dark {
|
|
58
|
-
--background: oklch(0.141 0.005 285.823);
|
|
59
|
-
--foreground: oklch(0.985 0 0);
|
|
60
|
-
--card: oklch(0.141 0.005 285.823);
|
|
61
|
-
--card-foreground: oklch(0.985 0 0);
|
|
62
|
-
--popover: oklch(0.141 0.005 285.823);
|
|
63
|
-
--popover-foreground: oklch(0.985 0 0);
|
|
64
|
-
--primary: oklch(0.985 0 0);
|
|
65
|
-
--primary-foreground: oklch(0.21 0.006 285.885);
|
|
66
|
-
--secondary: oklch(0.274 0.006 286.033);
|
|
67
|
-
--secondary-foreground: oklch(0.985 0 0);
|
|
68
|
-
--muted: oklch(0.274 0.006 286.033);
|
|
69
|
-
--muted-foreground: oklch(0.705 0.015 286.067);
|
|
70
|
-
--accent: oklch(0.274 0.006 286.033);
|
|
71
|
-
--accent-foreground: oklch(0.985 0 0);
|
|
72
|
-
--destructive: oklch(0.396 0.141 25.723);
|
|
73
|
-
--destructive-foreground: oklch(0.637 0.237 25.331);
|
|
74
|
-
--border: oklch(0.274 0.006 286.033);
|
|
75
|
-
--input: oklch(0.274 0.006 286.033);
|
|
76
|
-
--ring: oklch(0.442 0.017 285.786);
|
|
77
|
-
--chart-1: oklch(0.488 0.243 264.376);
|
|
78
|
-
--chart-2: oklch(0.696 0.17 162.48);
|
|
79
|
-
--chart-3: oklch(0.769 0.188 70.08);
|
|
80
|
-
--chart-4: oklch(0.627 0.265 303.9);
|
|
81
|
-
--chart-5: oklch(0.645 0.246 16.439);
|
|
82
|
-
--sidebar: oklch(0.21 0.006 285.885);
|
|
83
|
-
--sidebar-foreground: oklch(0.985 0 0);
|
|
84
|
-
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
85
|
-
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
86
|
-
--sidebar-accent: oklch(0.274 0.006 286.033);
|
|
87
|
-
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
88
|
-
--sidebar-border: oklch(0.274 0.006 286.033);
|
|
89
|
-
--sidebar-ring: oklch(0.442 0.017 285.786);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
@theme inline {
|
|
93
|
-
--color-background: var(--background);
|
|
94
|
-
--color-foreground: var(--foreground);
|
|
95
|
-
--color-card: var(--card);
|
|
96
|
-
--color-card-foreground: var(--card-foreground);
|
|
97
|
-
--color-popover: var(--popover);
|
|
98
|
-
--color-popover-foreground: var(--popover-foreground);
|
|
99
|
-
--color-primary: var(--primary);
|
|
100
|
-
--color-primary-foreground: var(--primary-foreground);
|
|
101
|
-
--color-secondary: var(--secondary);
|
|
102
|
-
--color-secondary-foreground: var(--secondary-foreground);
|
|
103
|
-
--color-muted: var(--muted);
|
|
104
|
-
--color-muted-foreground: var(--muted-foreground);
|
|
105
|
-
--color-accent: var(--accent);
|
|
106
|
-
--color-accent-foreground: var(--accent-foreground);
|
|
107
|
-
--color-destructive: var(--destructive);
|
|
108
|
-
--color-destructive-foreground: var(--destructive-foreground);
|
|
109
|
-
--color-border: var(--border);
|
|
110
|
-
--color-input: var(--input);
|
|
111
|
-
--color-ring: var(--ring);
|
|
112
|
-
--color-chart-1: var(--chart-1);
|
|
113
|
-
--color-chart-2: var(--chart-2);
|
|
114
|
-
--color-chart-3: var(--chart-3);
|
|
115
|
-
--color-chart-4: var(--chart-4);
|
|
116
|
-
--color-chart-5: var(--chart-5);
|
|
117
|
-
--radius-sm: calc(var(--radius) - 4px);
|
|
118
|
-
--radius-md: calc(var(--radius) - 2px);
|
|
119
|
-
--radius-lg: var(--radius);
|
|
120
|
-
--radius-xl: calc(var(--radius) + 4px);
|
|
121
|
-
--color-sidebar: var(--sidebar);
|
|
122
|
-
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
123
|
-
--color-sidebar-primary: var(--sidebar-primary);
|
|
124
|
-
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
125
|
-
--color-sidebar-accent: var(--sidebar-accent);
|
|
126
|
-
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
127
|
-
--color-sidebar-border: var(--sidebar-border);
|
|
128
|
-
--color-sidebar-ring: var(--sidebar-ring);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
@layer base {
|
|
132
|
-
* {
|
|
133
|
-
@apply border-border outline-ring/50;
|
|
134
|
-
}
|
|
135
|
-
body {
|
|
136
|
-
@apply bg-background text-foreground;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Resume",
|
|
3
|
-
"description": "Professional resume template with content-collections and shadcn UI components for Netlify.",
|
|
4
|
-
"phase": "example",
|
|
5
|
-
"modes": ["file-router"],
|
|
6
|
-
"type": "example",
|
|
7
|
-
"priority": 10,
|
|
8
|
-
"link": "",
|
|
9
|
-
"routes": [{"url": "/", "path": "src/routes/index.tsx", "jsName": "ResumeHome"}],
|
|
10
|
-
"features": ["tanstack-start", "content-collections", "tanstack-ai"],
|
|
11
|
-
"integrations": [{"type": "vite-plugin", "import": "import contentCollections from '@content-collections/vite'", "code": "contentCollections()"}],
|
|
12
|
-
"dependsOn": [],
|
|
13
|
-
"variables": [],
|
|
14
|
-
"packageFileDescriptions": {
|
|
15
|
-
"content-collections.ts": "Content Collections: jobs, education schemas.",
|
|
16
|
-
"content/jobs/initech-junior.md": "Job content: Initech Junior.",
|
|
17
|
-
"content/jobs/freelance.md.ejs": "Job template: Freelance.",
|
|
18
|
-
"content/jobs/initech-lead.md.ejs": "Job template: Initech Lead.",
|
|
19
|
-
"content/jobs/initrode-senior.md.ejs": "Job template: Initrode Senior.",
|
|
20
|
-
"content/education/code-school.md": "Education content: Code School.",
|
|
21
|
-
"src/styles.css": "Global styles.",
|
|
22
|
-
"src/routes/index.tsx": "Resume home: full resume with ResumeAssistant.",
|
|
23
|
-
"src/routes/api.resume-chat.ts": "POST handler for resume AI chat.",
|
|
24
|
-
"src/lib/utils.ts": "cn() helper.",
|
|
25
|
-
"src/lib/resume-tools.ts": "AI tools: getJobsBySkill, getAllJobs, getAllEducation, searchExperience.",
|
|
26
|
-
"src/lib/resume-ai-hook.ts": "useResumeChat hook.",
|
|
27
|
-
"src/components/Header.tsx": "Header.",
|
|
28
|
-
"src/components/ResumeAssistant.tsx": "Resume AI assistant.",
|
|
29
|
-
"src/components/ui/badge.tsx": "Badge component.",
|
|
30
|
-
"src/components/ui/card.tsx": "Card component.",
|
|
31
|
-
"src/components/ui/checkbox.tsx": "Checkbox component.",
|
|
32
|
-
"src/components/ui/hover-card.tsx": "HoverCard component.",
|
|
33
|
-
"src/components/ui/separator.tsx": "Separator component."
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"dependencies": {
|
|
3
|
-
"@radix-ui/react-checkbox": "^1.2.2",
|
|
4
|
-
"@radix-ui/react-hover-card": "^1.1.10",
|
|
5
|
-
"@radix-ui/react-separator": "^1.1.4",
|
|
6
|
-
"@radix-ui/react-slot": "^1.2.0",
|
|
7
|
-
"@tanstack/ai": "0.2.2",
|
|
8
|
-
"@tanstack/ai-anthropic": "0.2.0",
|
|
9
|
-
"@tanstack/ai-client": "0.2.2",
|
|
10
|
-
"@tanstack/ai-gemini": "0.3.2",
|
|
11
|
-
"@tanstack/ai-ollama": "0.3.0",
|
|
12
|
-
"@tanstack/ai-openai": "0.3.0",
|
|
13
|
-
"@tanstack/ai-react": "0.2.2",
|
|
14
|
-
"class-variance-authority": "^0.7.1",
|
|
15
|
-
"clsx": "^2.1.1",
|
|
16
|
-
"marked": "^17.0.1",
|
|
17
|
-
"streamdown": "^2.1.0",
|
|
18
|
-
"tailwind-merge": "^3.0.2",
|
|
19
|
-
"tailwindcss-animate": "^1.0.7",
|
|
20
|
-
"zod": "^4.3.5"
|
|
21
|
-
},
|
|
22
|
-
"devDependencies": {
|
|
23
|
-
"@content-collections/core": "^0.13.1",
|
|
24
|
-
"@content-collections/vite": "^0.2.8"
|
|
25
|
-
}
|
|
26
|
-
}
|
package/examples/saas/README.md
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# SaaS Example
|
|
2
|
-
|
|
3
|
-
A SaaS landing page built with TanStack Start and Tailwind CSS for Netlify deployment.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Hero Section**: Bold headline with call-to-action buttons
|
|
8
|
-
- **Feature Grid**: Four feature cards showcasing product capabilities
|
|
9
|
-
- **Pricing Tiers**: Three-tier pricing (Starter, Pro, Enterprise)
|
|
10
|
-
- **FAQ Page**: Accordion-style frequently asked questions
|
|
11
|
-
|
|
12
|
-
## Development
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
npm run dev
|
|
16
|
-
```
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
### SaaS Landing Page
|
|
2
|
-
|
|
3
|
-
Landing page with pricing tiers, features section, and FAQ accordion.
|
|
4
|
-
|
|
5
|
-
**Routes:** / (hero, pricing, features), /faq (accordion Q&A)
|
|
6
|
-
|
|
7
|
-
**FAQ:** ChevronDown accordion with expand/collapse; pricing tiers: Starter (free), Pro, Enterprise
|
|
8
|
-
|
|
9
|
-
No special dependencies or environment variables beyond base TanStack Start.
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Link } from '@tanstack/react-router'
|
|
2
|
-
import HeaderNav from './HeaderNav'
|
|
3
|
-
|
|
4
|
-
interface HeaderProps {
|
|
5
|
-
children?: React.ReactNode
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export default function Header({ children }: HeaderProps) {
|
|
9
|
-
return (
|
|
10
|
-
<header className="p-4 flex items-center justify-between bg-gray-800 text-white shadow-lg">
|
|
11
|
-
<nav className="flex items-center gap-4">{children ?? <HeaderNav />}</nav>
|
|
12
|
-
<Link to="/" className="text-xl font-semibold">
|
|
13
|
-
Acme SaaS
|
|
14
|
-
</Link>
|
|
15
|
-
</header>
|
|
16
|
-
)
|
|
17
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router'
|
|
2
|
-
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
|
|
3
|
-
import { TanStackDevtools } from '@tanstack/react-devtools'
|
|
4
|
-
|
|
5
|
-
import Header from '../components/Header'
|
|
6
|
-
|
|
7
|
-
import appCss from '../styles.css?url'
|
|
8
|
-
|
|
9
|
-
export const Route = createRootRoute({
|
|
10
|
-
head: () => ({
|
|
11
|
-
meta: [
|
|
12
|
-
{
|
|
13
|
-
charSet: 'utf-8',
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
name: 'viewport',
|
|
17
|
-
content: 'width=device-width, initial-scale=1',
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
title: 'Acme SaaS',
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
links: [
|
|
24
|
-
{
|
|
25
|
-
rel: 'stylesheet',
|
|
26
|
-
href: appCss,
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
}),
|
|
30
|
-
shellComponent: RootDocument,
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
function RootDocument({ children }: { children: React.ReactNode }) {
|
|
34
|
-
return (
|
|
35
|
-
<html lang="en">
|
|
36
|
-
<head>
|
|
37
|
-
<HeadContent />
|
|
38
|
-
</head>
|
|
39
|
-
<body>
|
|
40
|
-
<Header />
|
|
41
|
-
{children}
|
|
42
|
-
<TanStackDevtools
|
|
43
|
-
config={{
|
|
44
|
-
position: 'bottom-right',
|
|
45
|
-
}}
|
|
46
|
-
plugins={[
|
|
47
|
-
{
|
|
48
|
-
name: 'Tanstack Router',
|
|
49
|
-
render: <TanStackRouterDevtoolsPanel />,
|
|
50
|
-
},
|
|
51
|
-
]}
|
|
52
|
-
/>
|
|
53
|
-
<Scripts />
|
|
54
|
-
</body>
|
|
55
|
-
</html>
|
|
56
|
-
)
|
|
57
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
2
|
-
import { useState } from 'react'
|
|
3
|
-
import { ChevronDown } from 'lucide-react'
|
|
4
|
-
|
|
5
|
-
export const Route = createFileRoute('/faq')({
|
|
6
|
-
component: FAQ,
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
const faqs = [
|
|
10
|
-
{
|
|
11
|
-
question: 'What is Acme SaaS?',
|
|
12
|
-
answer:
|
|
13
|
-
'Acme SaaS is an all-in-one platform that provides real-time analytics, automated workflows, and team collaboration tools. It helps teams ship products faster by consolidating the tools they need into a single, easy-to-use interface.',
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
question: 'How does the free plan work?',
|
|
17
|
-
answer:
|
|
18
|
-
'The Starter plan is completely free and includes up to 3 projects and 1,000 events per month. No credit card is required to sign up. You can upgrade to a paid plan at any time as your needs grow.',
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
question: 'Can I cancel my subscription at any time?',
|
|
22
|
-
answer:
|
|
23
|
-
"Yes. You can cancel your subscription at any time from your account settings. When you cancel, you'll retain access to your paid features until the end of your current billing cycle.",
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
question: 'Is my data secure?',
|
|
27
|
-
answer:
|
|
28
|
-
'Absolutely. Acme SaaS is SOC 2 Type II compliant and uses end-to-end encryption for all data in transit and at rest. We also support SSO, role-based access controls, and provide detailed audit logs for Enterprise customers.',
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
question: 'What integrations do you support?',
|
|
32
|
-
answer:
|
|
33
|
-
'We integrate with popular tools like Slack, GitHub, Jira, Linear, Notion, and many more. Our API and webhook system also allows you to build custom integrations with any service.',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
question: 'Do you offer support for teams?',
|
|
37
|
-
answer:
|
|
38
|
-
'All plans include community support via our forum. Pro plans get priority email support with a 24-hour response time. Enterprise customers receive a dedicated account manager and phone support with guaranteed SLAs.',
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
question: 'Can I import data from other tools?',
|
|
42
|
-
answer:
|
|
43
|
-
'Yes. We provide migration guides and import tools for common platforms. Our support team can also assist with custom migrations for Enterprise customers.',
|
|
44
|
-
},
|
|
45
|
-
]
|
|
46
|
-
|
|
47
|
-
function FAQ() {
|
|
48
|
-
return (
|
|
49
|
-
<div className="min-h-screen bg-gray-950 text-white py-20 px-4">
|
|
50
|
-
<div className="max-w-3xl mx-auto">
|
|
51
|
-
<h1 className="text-4xl md:text-5xl font-bold text-center mb-4">
|
|
52
|
-
Frequently Asked Questions
|
|
53
|
-
</h1>
|
|
54
|
-
<p className="text-gray-400 text-center mb-14 max-w-xl mx-auto">
|
|
55
|
-
Got questions? We've got answers. If you can't find what you're
|
|
56
|
-
looking for, reach out to our support team.
|
|
57
|
-
</p>
|
|
58
|
-
<div className="space-y-3">
|
|
59
|
-
{faqs.map((faq, i) => (
|
|
60
|
-
<Accordion key={i} question={faq.question} answer={faq.answer} />
|
|
61
|
-
))}
|
|
62
|
-
</div>
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function Accordion({
|
|
69
|
-
question,
|
|
70
|
-
answer,
|
|
71
|
-
}: {
|
|
72
|
-
question: string
|
|
73
|
-
answer: string
|
|
74
|
-
}) {
|
|
75
|
-
const [open, setOpen] = useState(false)
|
|
76
|
-
|
|
77
|
-
return (
|
|
78
|
-
<div className="border border-white/10 rounded-lg overflow-hidden">
|
|
79
|
-
<button
|
|
80
|
-
onClick={() => setOpen(!open)}
|
|
81
|
-
className="w-full flex items-center justify-between p-5 text-left hover:bg-white/5 transition-colors"
|
|
82
|
-
>
|
|
83
|
-
<span className="font-medium text-lg">{question}</span>
|
|
84
|
-
<ChevronDown
|
|
85
|
-
size={20}
|
|
86
|
-
className={`text-gray-400 transition-transform ${open ? 'rotate-180' : ''}`}
|
|
87
|
-
/>
|
|
88
|
-
</button>
|
|
89
|
-
{open && (
|
|
90
|
-
<div className="px-5 pb-5 text-gray-400 leading-relaxed">{answer}</div>
|
|
91
|
-
)}
|
|
92
|
-
</div>
|
|
93
|
-
)
|
|
94
|
-
}
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
2
|
-
import { Link } from '@tanstack/react-router'
|
|
3
|
-
import { Zap, Shield, BarChart3, Users, ArrowRight } from 'lucide-react'
|
|
4
|
-
|
|
5
|
-
export const Route = createFileRoute('/')({
|
|
6
|
-
component: Home,
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
function Home() {
|
|
10
|
-
return (
|
|
11
|
-
<div className="min-h-screen bg-gray-950 text-white">
|
|
12
|
-
{/* Hero */}
|
|
13
|
-
<section className="relative overflow-hidden py-24 px-4">
|
|
14
|
-
<div className="absolute inset-0 bg-linear-to-br from-indigo-900/30 via-transparent to-cyan-900/20" />
|
|
15
|
-
<div className="relative max-w-4xl mx-auto text-center">
|
|
16
|
-
<p className="text-indigo-400 font-semibold mb-4 tracking-wide uppercase text-sm">
|
|
17
|
-
The modern platform for teams
|
|
18
|
-
</p>
|
|
19
|
-
<h1 className="text-5xl md:text-7xl font-black tracking-tight mb-6">
|
|
20
|
-
Ship faster with{' '}
|
|
21
|
-
<span className="bg-linear-to-r from-indigo-400 to-cyan-400 bg-clip-text text-transparent">
|
|
22
|
-
Acme SaaS
|
|
23
|
-
</span>
|
|
24
|
-
</h1>
|
|
25
|
-
<p className="text-lg md:text-xl text-gray-400 max-w-2xl mx-auto mb-10">
|
|
26
|
-
Acme SaaS gives your team real-time analytics, automated workflows,
|
|
27
|
-
and seamless collaboration — all in one place. Stop juggling tools
|
|
28
|
-
and start shipping.
|
|
29
|
-
</p>
|
|
30
|
-
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
|
31
|
-
<a
|
|
32
|
-
href="#pricing"
|
|
33
|
-
className="inline-flex items-center gap-2 px-8 py-3 bg-indigo-600 hover:bg-indigo-500 text-white font-semibold rounded-lg transition-colors shadow-lg shadow-indigo-600/30"
|
|
34
|
-
>
|
|
35
|
-
Get Started Free <ArrowRight size={18} />
|
|
36
|
-
</a>
|
|
37
|
-
<Link
|
|
38
|
-
to="/faq"
|
|
39
|
-
className="px-8 py-3 bg-white/10 hover:bg-white/15 text-white font-semibold rounded-lg transition-colors border border-white/10"
|
|
40
|
-
>
|
|
41
|
-
Learn More
|
|
42
|
-
</Link>
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
</section>
|
|
46
|
-
|
|
47
|
-
{/* Features */}
|
|
48
|
-
<section className="py-20 px-4 border-t border-white/5">
|
|
49
|
-
<div className="max-w-5xl mx-auto">
|
|
50
|
-
<h2 className="text-3xl md:text-4xl font-bold text-center mb-4">
|
|
51
|
-
Everything you need to scale
|
|
52
|
-
</h2>
|
|
53
|
-
<p className="text-gray-400 text-center mb-14 max-w-xl mx-auto">
|
|
54
|
-
Built for startups and growing teams that need reliable
|
|
55
|
-
infrastructure without the overhead.
|
|
56
|
-
</p>
|
|
57
|
-
<div className="grid md:grid-cols-2 gap-8">
|
|
58
|
-
<FeatureCard
|
|
59
|
-
icon={<BarChart3 size={28} />}
|
|
60
|
-
title="Real-Time Analytics"
|
|
61
|
-
description="Track key metrics, user behavior, and revenue in real time with customizable dashboards and automated reports."
|
|
62
|
-
/>
|
|
63
|
-
<FeatureCard
|
|
64
|
-
icon={<Zap size={28} />}
|
|
65
|
-
title="Automated Workflows"
|
|
66
|
-
description="Set up triggers, automate repetitive tasks, and integrate with the tools you already use — no code required."
|
|
67
|
-
/>
|
|
68
|
-
<FeatureCard
|
|
69
|
-
icon={<Users size={28} />}
|
|
70
|
-
title="Team Collaboration"
|
|
71
|
-
description="Shared workspaces, role-based access, and live editing so your entire team stays in sync."
|
|
72
|
-
/>
|
|
73
|
-
<FeatureCard
|
|
74
|
-
icon={<Shield size={28} />}
|
|
75
|
-
title="Enterprise Security"
|
|
76
|
-
description="SOC 2 compliant, end-to-end encryption, SSO support, and audit logs to keep your data safe."
|
|
77
|
-
/>
|
|
78
|
-
</div>
|
|
79
|
-
</div>
|
|
80
|
-
</section>
|
|
81
|
-
|
|
82
|
-
{/* Pricing */}
|
|
83
|
-
<section id="pricing" className="py-20 px-4 border-t border-white/5">
|
|
84
|
-
<div className="max-w-5xl mx-auto">
|
|
85
|
-
<h2 className="text-3xl md:text-4xl font-bold text-center mb-4">
|
|
86
|
-
Simple, transparent pricing
|
|
87
|
-
</h2>
|
|
88
|
-
<p className="text-gray-400 text-center mb-14 max-w-xl mx-auto">
|
|
89
|
-
Start free, upgrade when you're ready. No hidden fees.
|
|
90
|
-
</p>
|
|
91
|
-
<div className="grid md:grid-cols-3 gap-8 max-w-4xl mx-auto">
|
|
92
|
-
<PricingCard
|
|
93
|
-
name="Starter"
|
|
94
|
-
price="Free"
|
|
95
|
-
description="For individuals and small experiments."
|
|
96
|
-
features={[
|
|
97
|
-
'Up to 3 projects',
|
|
98
|
-
'1,000 events/mo',
|
|
99
|
-
'Community support',
|
|
100
|
-
]}
|
|
101
|
-
/>
|
|
102
|
-
<PricingCard
|
|
103
|
-
name="Pro"
|
|
104
|
-
price="$29/mo"
|
|
105
|
-
description="For growing teams that need more."
|
|
106
|
-
features={[
|
|
107
|
-
'Unlimited projects',
|
|
108
|
-
'100,000 events/mo',
|
|
109
|
-
'Priority support',
|
|
110
|
-
'Custom dashboards',
|
|
111
|
-
]}
|
|
112
|
-
highlighted
|
|
113
|
-
/>
|
|
114
|
-
<PricingCard
|
|
115
|
-
name="Enterprise"
|
|
116
|
-
price="Custom"
|
|
117
|
-
description="For organizations with advanced needs."
|
|
118
|
-
features={[
|
|
119
|
-
'Unlimited everything',
|
|
120
|
-
'Dedicated account manager',
|
|
121
|
-
'SSO & audit logs',
|
|
122
|
-
'SLA guarantee',
|
|
123
|
-
]}
|
|
124
|
-
/>
|
|
125
|
-
</div>
|
|
126
|
-
</div>
|
|
127
|
-
</section>
|
|
128
|
-
|
|
129
|
-
{/* Footer */}
|
|
130
|
-
<footer className="border-t border-white/5 py-10 px-4 text-center text-gray-500 text-sm">
|
|
131
|
-
© 2026 Acme SaaS. All rights reserved.
|
|
132
|
-
</footer>
|
|
133
|
-
</div>
|
|
134
|
-
)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function FeatureCard({
|
|
138
|
-
icon,
|
|
139
|
-
title,
|
|
140
|
-
description,
|
|
141
|
-
}: {
|
|
142
|
-
icon: React.ReactNode
|
|
143
|
-
title: string
|
|
144
|
-
description: string
|
|
145
|
-
}) {
|
|
146
|
-
return (
|
|
147
|
-
<div className="p-6 rounded-xl bg-white/5 border border-white/5 hover:border-indigo-500/30 transition-colors">
|
|
148
|
-
<div className="text-indigo-400 mb-4">{icon}</div>
|
|
149
|
-
<h3 className="text-xl font-semibold mb-2">{title}</h3>
|
|
150
|
-
<p className="text-gray-400 leading-relaxed">{description}</p>
|
|
151
|
-
</div>
|
|
152
|
-
)
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function PricingCard({
|
|
156
|
-
name,
|
|
157
|
-
price,
|
|
158
|
-
description,
|
|
159
|
-
features,
|
|
160
|
-
highlighted,
|
|
161
|
-
}: {
|
|
162
|
-
name: string
|
|
163
|
-
price: string
|
|
164
|
-
description: string
|
|
165
|
-
features: string[]
|
|
166
|
-
highlighted?: boolean
|
|
167
|
-
}) {
|
|
168
|
-
return (
|
|
169
|
-
<div
|
|
170
|
-
className={`p-6 rounded-xl border flex flex-col ${
|
|
171
|
-
highlighted
|
|
172
|
-
? 'bg-indigo-600/10 border-indigo-500/40'
|
|
173
|
-
: 'bg-white/5 border-white/5'
|
|
174
|
-
}`}
|
|
175
|
-
>
|
|
176
|
-
<h3 className="text-lg font-semibold mb-1">{name}</h3>
|
|
177
|
-
<p className="text-3xl font-bold mb-2">{price}</p>
|
|
178
|
-
<p className="text-gray-400 text-sm mb-6">{description}</p>
|
|
179
|
-
<ul className="space-y-2 text-sm text-gray-300 flex-1">
|
|
180
|
-
{features.map((f) => (
|
|
181
|
-
<li key={f} className="flex items-center gap-2">
|
|
182
|
-
<span className="text-indigo-400">✓</span> {f}
|
|
183
|
-
</li>
|
|
184
|
-
))}
|
|
185
|
-
</ul>
|
|
186
|
-
<button
|
|
187
|
-
className={`mt-6 w-full py-2 rounded-lg font-semibold transition-colors ${
|
|
188
|
-
highlighted
|
|
189
|
-
? 'bg-indigo-600 hover:bg-indigo-500 text-white'
|
|
190
|
-
: 'bg-white/10 hover:bg-white/15 text-white'
|
|
191
|
-
}`}
|
|
192
|
-
>
|
|
193
|
-
{price === 'Custom' ? 'Contact Sales' : 'Get Started'}
|
|
194
|
-
</button>
|
|
195
|
-
</div>
|
|
196
|
-
)
|
|
197
|
-
}
|
package/examples/saas/info.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "SaaS",
|
|
3
|
-
"description": "A SaaS landing page with pricing, features, and FAQ built with TanStack Start and Tailwind CSS for Netlify.",
|
|
4
|
-
"phase": "example",
|
|
5
|
-
"modes": ["file-router"],
|
|
6
|
-
"type": "example",
|
|
7
|
-
"priority": 10,
|
|
8
|
-
"link": "",
|
|
9
|
-
"routes": [
|
|
10
|
-
{"url": "/", "path": "src/routes/index.tsx", "jsName": "Home"},
|
|
11
|
-
{"url": "/faq", "name": "FAQ", "icon": "HelpCircle", "path": "src/routes/faq.tsx", "jsName": "FAQ"}
|
|
12
|
-
],
|
|
13
|
-
"features": ["tanstack-start"],
|
|
14
|
-
"integrations": [],
|
|
15
|
-
"dependsOn": [],
|
|
16
|
-
"variables": [],
|
|
17
|
-
"packageFileDescriptions": {
|
|
18
|
-
"src/routes/index.tsx": "Landing page: hero, pricing, features.",
|
|
19
|
-
"src/routes/faq.tsx": "FAQ page: accordion with Acme SaaS Q&A.",
|
|
20
|
-
"src/routes/__root.tsx": "Root layout: Header, styles.",
|
|
21
|
-
"src/components/Header.tsx": "Header with nav links."
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# Survey Example
|
|
2
|
-
|
|
3
|
-
A movie survey form built with TanStack Start and Netlify Forms for Netlify deployment.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Netlify Forms**: Server-side form handling without a backend
|
|
8
|
-
- **Movie Selection**: Dropdown with popular movie choices
|
|
9
|
-
- **Honeypot Protection**: Spam prevention via hidden field
|
|
10
|
-
- **Success Feedback**: Thank-you message after submission
|
|
11
|
-
|
|
12
|
-
## How It Works
|
|
13
|
-
|
|
14
|
-
The form uses Netlify's built-in form handling. A hidden HTML file (`public/form-survey.html`) registers the form with Netlify at build time. Submissions are viewable in the Netlify dashboard.
|
|
15
|
-
|
|
16
|
-
## Development
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
npm run dev
|
|
20
|
-
```
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
### Netlify Forms Survey
|
|
2
|
-
|
|
3
|
-
Movie survey form using Netlify Forms.
|
|
4
|
-
|
|
5
|
-
**Form:** `best-movie-survey` - name, movie select, reason textarea
|
|
6
|
-
**Spam protection:** `netlify-honeypot="bot-field"` + hidden bot-field input
|
|
7
|
-
**Detection:** `public/form-survey.html` declares the form (hidden) for Netlify build detection
|
|
8
|
-
|
|
9
|
-
No environment variables. Works after deploy to Netlify.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<title>Form</title>
|
|
6
|
-
</head>
|
|
7
|
-
<body>
|
|
8
|
-
<form name="best-movie-survey" method="POST" data-netlify="true" netlify-honeypot="bot-field" hidden>
|
|
9
|
-
<input type="text" name="name" />
|
|
10
|
-
<select name="movie"></select>
|
|
11
|
-
<textarea name="reason"></textarea>
|
|
12
|
-
<input name="bot-field" />
|
|
13
|
-
</form>
|
|
14
|
-
</body>
|
|
15
|
-
</html>
|