create-landing-app 0.1.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 (91) hide show
  1. package/dist/index.js +21 -0
  2. package/dist/install.js +18 -0
  3. package/dist/prompts.js +62 -0
  4. package/dist/scaffold.js +159 -0
  5. package/dist/utils/__tests__/merge-json.test.js +144 -0
  6. package/dist/utils/__tests__/replace-tokens.test.js +212 -0
  7. package/dist/utils/copy-dir.js +22 -0
  8. package/dist/utils/merge-json.js +19 -0
  9. package/dist/utils/replace-tokens.js +8 -0
  10. package/package.json +48 -0
  11. package/templates/nextjs/base/.env.example +8 -0
  12. package/templates/nextjs/base/.github/workflows/ci.yml +40 -0
  13. package/templates/nextjs/base/.husky/commit-msg +7 -0
  14. package/templates/nextjs/base/.husky/pre-commit +3 -0
  15. package/templates/nextjs/base/.husky/pre-push +46 -0
  16. package/templates/nextjs/base/.lighthouserc.json +28 -0
  17. package/templates/nextjs/base/.prettierignore +11 -0
  18. package/templates/nextjs/base/.prettierrc.json +10 -0
  19. package/templates/nextjs/base/Dockerfile +42 -0
  20. package/templates/nextjs/base/app/globals.css +82 -0
  21. package/templates/nextjs/base/app/layout.tsx +32 -0
  22. package/templates/nextjs/base/app/not-found.tsx +13 -0
  23. package/templates/nextjs/base/app/page.tsx +15 -0
  24. package/templates/nextjs/base/app/robots.ts +9 -0
  25. package/templates/nextjs/base/commitlint.config.mjs +32 -0
  26. package/templates/nextjs/base/components/navs/navbar-mobile.tsx +39 -0
  27. package/templates/nextjs/base/components/navs/navbar.tsx +39 -0
  28. package/templates/nextjs/base/components/providers.tsx +12 -0
  29. package/templates/nextjs/base/components/sections/features-section.tsx +78 -0
  30. package/templates/nextjs/base/components/sections/footer-section.tsx +98 -0
  31. package/templates/nextjs/base/components/sections/hero-section.tsx +74 -0
  32. package/templates/nextjs/base/components/ui/accordion.tsx +47 -0
  33. package/templates/nextjs/base/components/ui/button.tsx +44 -0
  34. package/templates/nextjs/base/components/ui/dialog.tsx +61 -0
  35. package/templates/nextjs/base/components/ui/dropdown-menu.tsx +55 -0
  36. package/templates/nextjs/base/components/ui/sonner.tsx +6 -0
  37. package/templates/nextjs/base/components.json +19 -0
  38. package/templates/nextjs/base/constants/common.ts +15 -0
  39. package/templates/nextjs/base/eslint.config.mjs +25 -0
  40. package/templates/nextjs/base/lib/metadata.ts +36 -0
  41. package/templates/nextjs/base/lib/utils.ts +7 -0
  42. package/templates/nextjs/base/next.config.ts +33 -0
  43. package/templates/nextjs/base/package.json +61 -0
  44. package/templates/nextjs/base/postcss.config.mjs +7 -0
  45. package/templates/nextjs/base/scripts/build-and-scan.sh +127 -0
  46. package/templates/nextjs/base/scripts/lighthouse-check.sh +86 -0
  47. package/templates/nextjs/base/styles/theme.css +63 -0
  48. package/templates/nextjs/base/tsconfig.json +21 -0
  49. package/templates/nextjs/base/types/index.ts +16 -0
  50. package/templates/nextjs/optional/docker/files/.dockerignore +6 -0
  51. package/templates/nextjs/optional/docker/files/Dockerfile +36 -0
  52. package/templates/nextjs/optional/docker/files/docker-compose.yml +9 -0
  53. package/templates/nextjs/optional/i18n-dict/files/app/[lang]/layout.tsx +19 -0
  54. package/templates/nextjs/optional/i18n-dict/files/app/[lang]/page.tsx +15 -0
  55. package/templates/nextjs/optional/i18n-dict/files/components/navs/language-switcher.tsx +39 -0
  56. package/templates/nextjs/optional/i18n-dict/files/components/navs/navbar-mobile.tsx +41 -0
  57. package/templates/nextjs/optional/i18n-dict/files/components/navs/navbar.tsx +41 -0
  58. package/templates/nextjs/optional/i18n-dict/files/components/providers.tsx +16 -0
  59. package/templates/nextjs/optional/i18n-dict/files/components/sections/features-section.tsx +80 -0
  60. package/templates/nextjs/optional/i18n-dict/files/components/sections/footer-section.tsx +98 -0
  61. package/templates/nextjs/optional/i18n-dict/files/dictionaries/en.json +21 -0
  62. package/templates/nextjs/optional/i18n-dict/files/dictionaries/vi.json +21 -0
  63. package/templates/nextjs/optional/i18n-dict/files/get-dictionary.ts +10 -0
  64. package/templates/nextjs/optional/i18n-dict/files/i18n-config.ts +6 -0
  65. package/templates/nextjs/optional/i18n-dict/files/lib/dict-context.tsx +23 -0
  66. package/templates/nextjs/optional/i18n-dict/files/middleware.ts +31 -0
  67. package/templates/nextjs/optional/i18n-dict/pkg.json +9 -0
  68. package/templates/nextjs/optional/sections/about/files/components/sections/about-section.tsx +36 -0
  69. package/templates/nextjs/optional/sections/about/inject/app__[lang]__page.tsx +5 -0
  70. package/templates/nextjs/optional/sections/about/inject/app__page.tsx +5 -0
  71. package/templates/nextjs/optional/sections/about/inject/constants__common.ts +2 -0
  72. package/templates/nextjs/optional/sections/blog/files/components/sections/blog-section.tsx +191 -0
  73. package/templates/nextjs/optional/sections/blog/inject/app__[lang]__page.tsx +5 -0
  74. package/templates/nextjs/optional/sections/blog/inject/app__page.tsx +5 -0
  75. package/templates/nextjs/optional/sections/blog/inject/constants__common.ts +2 -0
  76. package/templates/nextjs/optional/sections/contact/files/components/sections/contact-section.tsx +79 -0
  77. package/templates/nextjs/optional/sections/contact/inject/app__[lang]__page.tsx +5 -0
  78. package/templates/nextjs/optional/sections/contact/inject/app__page.tsx +5 -0
  79. package/templates/nextjs/optional/sections/contact/inject/constants__common.ts +2 -0
  80. package/templates/nextjs/optional/tanstack-query/files/lib/custom-fetch.ts +9 -0
  81. package/templates/nextjs/optional/tanstack-query/files/lib/query-client.ts +21 -0
  82. package/templates/nextjs/optional/tanstack-query/inject/components__providers.tsx +9 -0
  83. package/templates/nextjs/optional/tanstack-query/pkg.json +5 -0
  84. package/templates/nextjs/optional/zustand/files/store/ui-store.ts +16 -0
  85. package/templates/nextjs/optional/zustand/inject/components__providers.tsx +3 -0
  86. package/templates/nextjs/optional/zustand/pkg.json +5 -0
  87. package/templates/nextjs/themes/dark.css +36 -0
  88. package/templates/nextjs/themes/forest.css +58 -0
  89. package/templates/nextjs/themes/ocean.css +58 -0
  90. package/templates/nextjs/themes/pila.css +75 -0
  91. package/templates/nextjs/themes/purple.css +58 -0
@@ -0,0 +1,3 @@
1
+ MARKER:__PROVIDERS_IMPORT__
2
+ // Zustand store is imported per-component — no provider needed (it's global)
3
+ // import { useUIStore } from "@/store/ui-store";
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "zustand": "^5.0.0"
4
+ }
5
+ }
@@ -0,0 +1,36 @@
1
+ /* Dark Theme — dark-first, neutral monochrome */
2
+ :root {
3
+ --radius: 0.5rem;
4
+ --background: oklch(0.12 0.005 250);
5
+ --foreground: oklch(0.95 0.005 250);
6
+ --card: oklch(0.18 0.007 250);
7
+ --card-foreground: oklch(0.95 0.005 250);
8
+ --popover: oklch(0.18 0.007 250);
9
+ --popover-foreground: oklch(0.95 0.005 250);
10
+ --primary: oklch(0.92 0.005 250);
11
+ --primary-foreground: oklch(0.12 0.005 250);
12
+ --secondary: oklch(0.22 0.008 250);
13
+ --secondary-foreground: oklch(0.92 0.005 250);
14
+ --muted: oklch(0.22 0.008 250);
15
+ --muted-foreground: oklch(0.6 0.008 250);
16
+ --accent: oklch(0.28 0.01 250);
17
+ --accent-foreground: oklch(0.92 0.005 250);
18
+ --destructive: oklch(0.704 0.191 22.216);
19
+ --border: oklch(1 0 0 / 12%);
20
+ --input: oklch(1 0 0 / 12%);
21
+ --ring: oklch(0.6 0.01 250);
22
+ --brand-primary: #e2e8f0;
23
+ --brand-action: #cbd5e1;
24
+ --brand-footer-from: #1e293b;
25
+ --brand-footer-to: #0f172a;
26
+ --brand-surface: #1e293b;
27
+ --brand-border: #334155;
28
+ --brand-gradient-from: #94a3b8;
29
+ --brand-gradient-to: #e2e8f0;
30
+ }
31
+
32
+ .dark {
33
+ /* Dark theme is already dark by default — .dark class mirrors :root */
34
+ --background: oklch(0.12 0.005 250);
35
+ --foreground: oklch(0.95 0.005 250);
36
+ }
@@ -0,0 +1,58 @@
1
+ /* Forest Theme — green + emerald */
2
+ :root {
3
+ --radius: 0.75rem;
4
+ --background: oklch(1 0 0);
5
+ --foreground: oklch(0.15 0.02 150);
6
+ --card: oklch(1 0 0);
7
+ --card-foreground: oklch(0.15 0.02 150);
8
+ --popover: oklch(1 0 0);
9
+ --popover-foreground: oklch(0.15 0.02 150);
10
+ --primary: oklch(0.45 0.18 155); /* forest green */
11
+ --primary-foreground: oklch(1 0 0);
12
+ --secondary: oklch(0.95 0.04 140);
13
+ --secondary-foreground: oklch(0.15 0.02 150);
14
+ --muted: oklch(0.95 0.04 140);
15
+ --muted-foreground: oklch(0.5 0.05 150);
16
+ --accent: oklch(0.88 0.08 145);
17
+ --accent-foreground: oklch(0.15 0.02 150);
18
+ --destructive: oklch(0.577 0.245 27.325);
19
+ --border: oklch(0.88 0.06 145);
20
+ --input: oklch(0.88 0.06 145);
21
+ --ring: oklch(0.6 0.15 155);
22
+ --brand-primary: #16a34a;
23
+ --brand-action: #15803d;
24
+ --brand-footer-from: #166534;
25
+ --brand-footer-to: #052e16;
26
+ --brand-surface: #dcfce7;
27
+ --brand-border: #bbf7d0;
28
+ --brand-gradient-from: #4ade80;
29
+ --brand-gradient-to: #059669;
30
+ }
31
+
32
+ .dark {
33
+ --background: oklch(0.1 0.02 150);
34
+ --foreground: oklch(0.98 0 0);
35
+ --card: oklch(0.14 0.02 150);
36
+ --card-foreground: oklch(0.98 0 0);
37
+ --popover: oklch(0.14 0.02 150);
38
+ --popover-foreground: oklch(0.98 0 0);
39
+ --primary: oklch(0.65 0.18 155);
40
+ --primary-foreground: oklch(0.1 0.02 150);
41
+ --secondary: oklch(0.2 0.03 150);
42
+ --muted: oklch(0.2 0.03 150);
43
+ --muted-foreground: oklch(0.6 0.05 150);
44
+ --accent: oklch(0.2 0.03 150);
45
+ --accent-foreground: oklch(0.98 0 0);
46
+ --destructive: oklch(0.704 0.191 22.216);
47
+ --border: oklch(1 0 0 / 10%);
48
+ --input: oklch(1 0 0 / 15%);
49
+ --ring: oklch(0.55 0.12 155);
50
+ --brand-primary: #4ade80;
51
+ --brand-action: #22c55e;
52
+ --brand-footer-from: #14532d;
53
+ --brand-footer-to: #052e16;
54
+ --brand-surface: #0d2818;
55
+ --brand-border: #166534;
56
+ --brand-gradient-from: #4ade80;
57
+ --brand-gradient-to: #86efac;
58
+ }
@@ -0,0 +1,58 @@
1
+ /* Ocean Theme — sky blue + cyan */
2
+ :root {
3
+ --radius: 0.5rem;
4
+ --background: oklch(1 0 0);
5
+ --foreground: oklch(0.15 0.01 220);
6
+ --card: oklch(1 0 0);
7
+ --card-foreground: oklch(0.15 0.01 220);
8
+ --popover: oklch(1 0 0);
9
+ --popover-foreground: oklch(0.15 0.01 220);
10
+ --primary: oklch(0.55 0.2 225); /* sky blue */
11
+ --primary-foreground: oklch(1 0 0);
12
+ --secondary: oklch(0.95 0.04 200);
13
+ --secondary-foreground: oklch(0.15 0.01 220);
14
+ --muted: oklch(0.95 0.04 200);
15
+ --muted-foreground: oklch(0.5 0.05 220);
16
+ --accent: oklch(0.85 0.1 195); /* cyan tint */
17
+ --accent-foreground: oklch(0.15 0.01 220);
18
+ --destructive: oklch(0.577 0.245 27.325);
19
+ --border: oklch(0.88 0.06 210);
20
+ --input: oklch(0.88 0.06 210);
21
+ --ring: oklch(0.65 0.15 225);
22
+ --brand-primary: #0ea5e9;
23
+ --brand-action: #0284c7;
24
+ --brand-footer-from: #0369a1;
25
+ --brand-footer-to: #0c4a6e;
26
+ --brand-surface: #e0f2fe;
27
+ --brand-border: #bae6fd;
28
+ --brand-gradient-from: #38bdf8;
29
+ --brand-gradient-to: #06b6d4;
30
+ }
31
+
32
+ .dark {
33
+ --background: oklch(0.1 0.02 220);
34
+ --foreground: oklch(0.98 0 0);
35
+ --card: oklch(0.15 0.02 220);
36
+ --card-foreground: oklch(0.98 0 0);
37
+ --popover: oklch(0.15 0.02 220);
38
+ --popover-foreground: oklch(0.98 0 0);
39
+ --primary: oklch(0.7 0.18 225);
40
+ --primary-foreground: oklch(0.1 0.02 220);
41
+ --secondary: oklch(0.2 0.03 220);
42
+ --muted: oklch(0.2 0.03 220);
43
+ --muted-foreground: oklch(0.6 0.05 220);
44
+ --accent: oklch(0.2 0.03 220);
45
+ --accent-foreground: oklch(0.98 0 0);
46
+ --destructive: oklch(0.704 0.191 22.216);
47
+ --border: oklch(1 0 0 / 10%);
48
+ --input: oklch(1 0 0 / 15%);
49
+ --ring: oklch(0.6 0.1 225);
50
+ --brand-primary: #38bdf8;
51
+ --brand-action: #0ea5e9;
52
+ --brand-footer-from: #075985;
53
+ --brand-footer-to: #0c4a6e;
54
+ --brand-surface: #0c2d3f;
55
+ --brand-border: #164e63;
56
+ --brand-gradient-from: #38bdf8;
57
+ --brand-gradient-to: #67e8f9;
58
+ }
@@ -0,0 +1,75 @@
1
+ /* Pila Theme — white + deep blue brand */
2
+ /* Edit this file to rebrand your site */
3
+
4
+ :root {
5
+ --radius: 0.625rem;
6
+
7
+ /* Surfaces */
8
+ --background: oklch(1 0 0);
9
+ --foreground: oklch(0.147 0.004 49.25);
10
+ --card: oklch(1 0 0);
11
+ --card-foreground: oklch(0.147 0.004 49.25);
12
+ --popover: oklch(1 0 0);
13
+ --popover-foreground: oklch(0.147 0.004 49.25);
14
+
15
+ /* Brand primary — deep blue #1849a9 */
16
+ --primary: oklch(0.45 0.18 250);
17
+ --primary-foreground: oklch(0.98 0 0);
18
+
19
+ /* Secondary — very light blue tint #f2fffe */
20
+ --secondary: oklch(0.97 0.015 210);
21
+ --secondary-foreground: oklch(0.216 0.006 56.043);
22
+
23
+ /* Muted */
24
+ --muted: oklch(0.97 0.015 210);
25
+ --muted-foreground: oklch(0.553 0.013 58.071);
26
+
27
+ /* Accent — light blue #e0f2ff */
28
+ --accent: oklch(0.95 0.03 220);
29
+ --accent-foreground: oklch(0.45 0.18 250);
30
+
31
+ /* System */
32
+ --destructive: oklch(0.577 0.245 27.325);
33
+ --border: oklch(0.88 0.04 220); /* ~#d1e9ff */
34
+ --input: oklch(0.88 0.04 220);
35
+ --ring: oklch(0.65 0.12 230); /* ~#84caff */
36
+
37
+ /* Brand-specific tokens */
38
+ --brand-primary: #1849a9;
39
+ --brand-action: #1570ef;
40
+ --brand-footer-from: #1764eb;
41
+ --brand-footer-to: #002d7b;
42
+ --brand-surface: #daf8ff;
43
+ --brand-border: #d1e9ff;
44
+ --brand-gradient-from: #327eff;
45
+ --brand-gradient-to: #ffffff;
46
+ }
47
+
48
+ .dark {
49
+ --background: oklch(0.1 0.02 250);
50
+ --foreground: oklch(0.985 0.001 106.423);
51
+ --card: oklch(0.15 0.03 250);
52
+ --card-foreground: oklch(0.985 0.001 106.423);
53
+ --popover: oklch(0.15 0.03 250);
54
+ --popover-foreground: oklch(0.985 0.001 106.423);
55
+ --primary: oklch(0.65 0.16 250);
56
+ --primary-foreground: oklch(0.1 0.02 250);
57
+ --secondary: oklch(0.2 0.03 250);
58
+ --secondary-foreground: oklch(0.985 0.001 106.423);
59
+ --muted: oklch(0.2 0.03 250);
60
+ --muted-foreground: oklch(0.6 0.06 250);
61
+ --accent: oklch(0.2 0.03 250);
62
+ --accent-foreground: oklch(0.985 0.001 106.423);
63
+ --destructive: oklch(0.704 0.191 22.216);
64
+ --border: oklch(1 0 0 / 10%);
65
+ --input: oklch(1 0 0 / 15%);
66
+ --ring: oklch(0.553 0.013 58.071);
67
+ --brand-primary: #6aaeff;
68
+ --brand-action: #3b82f6;
69
+ --brand-footer-from: #1e3a8a;
70
+ --brand-footer-to: #0f172a;
71
+ --brand-surface: #1e293b;
72
+ --brand-border: #334155;
73
+ --brand-gradient-from: #6aaeff;
74
+ --brand-gradient-to: #dbeafe;
75
+ }
@@ -0,0 +1,58 @@
1
+ /* Purple Theme — violet + indigo */
2
+ :root {
3
+ --radius: 0.625rem;
4
+ --background: oklch(1 0 0);
5
+ --foreground: oklch(0.13 0.02 280);
6
+ --card: oklch(1 0 0);
7
+ --card-foreground: oklch(0.13 0.02 280);
8
+ --popover: oklch(1 0 0);
9
+ --popover-foreground: oklch(0.13 0.02 280);
10
+ --primary: oklch(0.5 0.24 280); /* violet */
11
+ --primary-foreground: oklch(1 0 0);
12
+ --secondary: oklch(0.95 0.04 280);
13
+ --secondary-foreground: oklch(0.13 0.02 280);
14
+ --muted: oklch(0.95 0.04 280);
15
+ --muted-foreground: oklch(0.5 0.05 280);
16
+ --accent: oklch(0.9 0.07 285);
17
+ --accent-foreground: oklch(0.13 0.02 280);
18
+ --destructive: oklch(0.577 0.245 27.325);
19
+ --border: oklch(0.88 0.06 280);
20
+ --input: oklch(0.88 0.06 280);
21
+ --ring: oklch(0.65 0.18 280);
22
+ --brand-primary: #7c3aed;
23
+ --brand-action: #6d28d9;
24
+ --brand-footer-from: #5b21b6;
25
+ --brand-footer-to: #2e1065;
26
+ --brand-surface: #ede9fe;
27
+ --brand-border: #ddd6fe;
28
+ --brand-gradient-from: #a78bfa;
29
+ --brand-gradient-to: #818cf8;
30
+ }
31
+
32
+ .dark {
33
+ --background: oklch(0.1 0.03 280);
34
+ --foreground: oklch(0.98 0 0);
35
+ --card: oklch(0.14 0.03 280);
36
+ --card-foreground: oklch(0.98 0 0);
37
+ --popover: oklch(0.14 0.03 280);
38
+ --popover-foreground: oklch(0.98 0 0);
39
+ --primary: oklch(0.68 0.22 280);
40
+ --primary-foreground: oklch(0.1 0.03 280);
41
+ --secondary: oklch(0.2 0.04 280);
42
+ --muted: oklch(0.2 0.04 280);
43
+ --muted-foreground: oklch(0.6 0.06 280);
44
+ --accent: oklch(0.2 0.04 280);
45
+ --accent-foreground: oklch(0.98 0 0);
46
+ --destructive: oklch(0.704 0.191 22.216);
47
+ --border: oklch(1 0 0 / 10%);
48
+ --input: oklch(1 0 0 / 15%);
49
+ --ring: oklch(0.6 0.15 280);
50
+ --brand-primary: #a78bfa;
51
+ --brand-action: #8b5cf6;
52
+ --brand-footer-from: #4c1d95;
53
+ --brand-footer-to: #2e1065;
54
+ --brand-surface: #1e1040;
55
+ --brand-border: #4c1d95;
56
+ --brand-gradient-from: #a78bfa;
57
+ --brand-gradient-to: #c4b5fd;
58
+ }