create-lumen 1.1.3 → 1.2.0-beta.1

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 (247) hide show
  1. package/README.md +43 -35
  2. package/package.json +8 -2
  3. package/src/configure.js +29 -15
  4. package/src/css.js +73 -14
  5. package/src/dependencies.js +8 -3
  6. package/src/format.js +28 -0
  7. package/src/injector.js +131 -28
  8. package/src/main.js +17 -1
  9. package/src/readme.js +65 -22
  10. package/templates/architectures/component-based/main.tsx +1 -1
  11. package/templates/architectures/component-based/src/App.jsx +6 -4
  12. package/templates/architectures/component-based/src/App.tsx +6 -4
  13. package/templates/architectures/component-based/src/components/common/Button.jsx +5 -4
  14. package/templates/architectures/component-based/src/components/common/Button.tsx +5 -4
  15. package/templates/architectures/component-based/src/hooks/useApp.js +10 -0
  16. package/templates/architectures/component-based/src/hooks/useApp.ts +10 -0
  17. package/templates/architectures/component-based/src/hooks/useLocalStorage.ts +5 -5
  18. package/templates/architectures/component-based/src/layouts/MainLayout.jsx +12 -6
  19. package/templates/architectures/component-based/src/layouts/MainLayout.tsx +12 -6
  20. package/templates/architectures/component-based/src/pages/Home/Home.jsx +6 -2
  21. package/templates/architectures/component-based/src/pages/Home/Home.tsx +6 -2
  22. package/templates/architectures/component-based/src/providers/AppProvider.jsx +20 -0
  23. package/templates/architectures/component-based/src/providers/AppProvider.tsx +24 -0
  24. package/templates/architectures/component-based/src/providers/appcontext.js +3 -0
  25. package/templates/architectures/component-based/src/providers/appcontext.ts +8 -0
  26. package/templates/architectures/{feature-based → component-based}/src/types/index.js +7 -0
  27. package/templates/architectures/{feature-based → component-based}/src/types/index.ts +5 -0
  28. package/templates/architectures/component-based/src/utils/cn.ts +3 -1
  29. package/templates/architectures/feature-based/main.jsx +1 -1
  30. package/templates/architectures/feature-based/main.tsx +2 -2
  31. package/templates/architectures/feature-based/scripts/create-feature.mjs +2 -2
  32. package/templates/architectures/feature-based/src/app/App.jsx +15 -5
  33. package/templates/architectures/feature-based/src/app/App.tsx +15 -5
  34. package/templates/architectures/feature-based/src/app/contexts/themecontext.js +3 -0
  35. package/templates/architectures/feature-based/src/app/contexts/themecontext.ts +8 -0
  36. package/templates/architectures/feature-based/src/app/hooks/useTheme.js +10 -0
  37. package/templates/architectures/feature-based/src/app/hooks/useTheme.ts +10 -0
  38. package/templates/architectures/feature-based/src/app/providers/ThemeProvider.jsx +17 -2
  39. package/templates/architectures/feature-based/src/app/providers/ThemeProvider.tsx +20 -3
  40. package/templates/architectures/feature-based/src/features/home/pages/HomePage.jsx +18 -5
  41. package/templates/architectures/feature-based/src/features/home/pages/HomePage.tsx +18 -5
  42. package/templates/architectures/feature-based/src/shared/components/ui/Button.jsx +31 -0
  43. package/templates/architectures/feature-based/src/shared/components/ui/Button.tsx +36 -0
  44. package/templates/architectures/feature-based/src/{hooks → shared/hooks}/useLocalStorage.ts +5 -5
  45. package/templates/architectures/feature-based/src/shared/layouts/.gitkeep +0 -0
  46. package/templates/architectures/feature-based/src/shared/stores/.gitkeep +0 -0
  47. package/templates/architectures/feature-based/src/shared/styles/.gitkeep +0 -0
  48. package/templates/architectures/feature-based/src/shared/types/index.js +20 -0
  49. package/templates/architectures/feature-based/src/shared/types/index.ts +16 -0
  50. package/templates/architectures/feature-based/src/shared/utils/cn.ts +5 -0
  51. package/templates/conditional/axios/component-based/src/config/axios.config.js +7 -0
  52. package/templates/conditional/axios/component-based/src/config/axios.config.ts +7 -0
  53. package/templates/conditional/axios/component-based/src/services/axios.client.js +24 -0
  54. package/templates/conditional/axios/component-based/src/services/axios.client.ts +24 -0
  55. package/templates/conditional/axios/component-based/src/services/user.service.js +33 -0
  56. package/templates/conditional/axios/component-based/src/services/user.service.ts +29 -0
  57. package/templates/conditional/axios/feature-based/src/features/home/services/user.service.js +33 -0
  58. package/templates/conditional/axios/feature-based/src/features/home/services/user.service.ts +29 -0
  59. package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.client.js +24 -0
  60. package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.client.ts +24 -0
  61. package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.config.js +7 -0
  62. package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.config.ts +7 -0
  63. package/templates/conditional/axios/feature-based/src/shared/lib/axios/index.js +1 -0
  64. package/templates/conditional/axios/feature-based/src/shared/lib/axios/index.ts +1 -0
  65. package/templates/conditional/fetch/component-based/src/config/api.config.js +7 -0
  66. package/templates/conditional/fetch/component-based/src/config/api.config.ts +7 -0
  67. package/templates/conditional/fetch/component-based/src/services/api.client.js +51 -0
  68. package/templates/conditional/fetch/component-based/src/services/api.client.ts +55 -0
  69. package/templates/conditional/fetch/component-based/src/services/user.service.js +33 -0
  70. package/templates/conditional/fetch/component-based/src/services/user.service.ts +29 -0
  71. package/templates/conditional/fetch/feature-based/src/features/home/services/user.service.js +33 -0
  72. package/templates/conditional/fetch/feature-based/src/features/home/services/user.service.ts +29 -0
  73. package/templates/conditional/fetch/feature-based/src/shared/api/api.client.js +51 -0
  74. package/templates/conditional/fetch/feature-based/src/shared/api/api.client.ts +55 -0
  75. package/templates/conditional/fetch/feature-based/src/shared/api/api.config.js +7 -0
  76. package/templates/conditional/fetch/feature-based/src/shared/api/api.config.ts +7 -0
  77. package/templates/conditional/fetch/feature-based/src/shared/api/index.js +1 -0
  78. package/templates/conditional/fetch/feature-based/src/shared/api/index.ts +1 -0
  79. package/templates/conditional/formatter/oxfmt/.oxfmtrc.json +1 -1
  80. package/templates/conditional/formatter/prettier/.prettierrc +2 -2
  81. package/templates/conditional/icons/huge/component-based/bootstrap/src/pages/Home/Home.jsx +20 -0
  82. package/templates/conditional/icons/huge/component-based/bootstrap/src/pages/Home/Home.tsx +20 -0
  83. package/templates/conditional/icons/huge/component-based/src/pages/Home/Home.jsx +26 -10
  84. package/templates/conditional/icons/huge/component-based/src/pages/Home/Home.tsx +26 -10
  85. package/templates/conditional/icons/huge/component-based/tailwind/src/pages/Home/Home.jsx +20 -0
  86. package/templates/conditional/icons/huge/component-based/tailwind/src/pages/Home/Home.tsx +20 -0
  87. package/templates/conditional/icons/huge/feature-based/bootstrap/src/features/home/pages/HomePage.jsx +20 -0
  88. package/templates/conditional/icons/huge/feature-based/bootstrap/src/features/home/pages/HomePage.tsx +20 -0
  89. package/templates/conditional/icons/huge/feature-based/src/features/home/pages/HomePage.jsx +27 -11
  90. package/templates/conditional/icons/huge/feature-based/src/features/home/pages/HomePage.tsx +27 -11
  91. package/templates/conditional/icons/huge/feature-based/tailwind/src/features/home/pages/HomePage.jsx +20 -0
  92. package/templates/conditional/icons/huge/feature-based/tailwind/src/features/home/pages/HomePage.tsx +20 -0
  93. package/templates/conditional/icons/lucide/component-based/bootstrap/src/pages/Home/Home.jsx +19 -0
  94. package/templates/conditional/icons/lucide/component-based/bootstrap/src/pages/Home/Home.tsx +19 -0
  95. package/templates/conditional/icons/lucide/component-based/src/pages/Home/Home.jsx +25 -10
  96. package/templates/conditional/icons/lucide/component-based/src/pages/Home/Home.tsx +25 -10
  97. package/templates/conditional/icons/lucide/component-based/tailwind/src/pages/Home/Home.jsx +19 -0
  98. package/templates/conditional/icons/lucide/component-based/tailwind/src/pages/Home/Home.tsx +19 -0
  99. package/templates/conditional/icons/lucide/feature-based/bootstrap/src/features/home/pages/HomePage.jsx +19 -0
  100. package/templates/conditional/icons/lucide/feature-based/bootstrap/src/features/home/pages/HomePage.tsx +19 -0
  101. package/templates/conditional/icons/lucide/feature-based/src/features/home/pages/HomePage.jsx +26 -11
  102. package/templates/conditional/icons/lucide/feature-based/src/features/home/pages/HomePage.tsx +26 -11
  103. package/templates/conditional/icons/lucide/feature-based/tailwind/src/features/home/pages/HomePage.jsx +19 -0
  104. package/templates/conditional/icons/lucide/feature-based/tailwind/src/features/home/pages/HomePage.tsx +19 -0
  105. package/templates/conditional/linting/eslint/eslint.config.js +24 -2
  106. package/templates/conditional/linting/eslint/eslint.config.ts +25 -2
  107. package/templates/conditional/router/component-based/bootstrap/src/layouts/MainLayout.jsx +17 -0
  108. package/templates/conditional/router/component-based/bootstrap/src/layouts/MainLayout.tsx +17 -0
  109. package/templates/conditional/router/component-based/src/App.jsx +4 -5
  110. package/templates/conditional/router/component-based/src/App.tsx +4 -5
  111. package/templates/conditional/router/component-based/src/layouts/MainLayout.jsx +39 -0
  112. package/templates/conditional/router/component-based/src/layouts/MainLayout.tsx +39 -0
  113. package/templates/conditional/router/component-based/src/router/guards/AuthGuard.jsx +8 -0
  114. package/templates/conditional/router/component-based/src/router/guards/AuthGuard.tsx +14 -0
  115. package/templates/conditional/router/component-based/src/router/guards/GuestGuard.jsx +8 -0
  116. package/templates/conditional/router/component-based/src/router/guards/GuestGuard.tsx +14 -0
  117. package/templates/conditional/router/component-based/src/router/index.jsx +44 -0
  118. package/templates/conditional/router/component-based/src/router/index.tsx +44 -0
  119. package/templates/conditional/router/component-based/tailwind/src/layouts/MainLayout.jsx +17 -0
  120. package/templates/conditional/router/component-based/tailwind/src/layouts/MainLayout.tsx +17 -0
  121. package/templates/conditional/router/feature-based/bootstrap/src/shared/layouts/RootLayout.jsx +9 -0
  122. package/templates/conditional/router/feature-based/bootstrap/src/shared/layouts/RootLayout.tsx +9 -0
  123. package/templates/conditional/router/feature-based/src/app/App.jsx +6 -2
  124. package/templates/conditional/router/feature-based/src/app/App.tsx +6 -2
  125. package/templates/conditional/router/feature-based/src/app/router/guards/AuthGuard.jsx +8 -0
  126. package/templates/conditional/router/feature-based/src/app/router/guards/AuthGuard.tsx +14 -0
  127. package/templates/conditional/router/feature-based/src/app/router/guards/RoleGuard.jsx +8 -0
  128. package/templates/conditional/router/feature-based/src/app/router/guards/RoleGuard.tsx +15 -0
  129. package/templates/conditional/router/feature-based/src/app/router/index.jsx +16 -0
  130. package/templates/conditional/router/feature-based/src/app/router/index.tsx +16 -0
  131. package/templates/conditional/router/feature-based/src/app/router/routes/auth.routes.jsx +18 -0
  132. package/templates/conditional/router/feature-based/src/app/router/routes/auth.routes.tsx +18 -0
  133. package/templates/conditional/router/feature-based/src/app/router/routes/home.routes.jsx +8 -0
  134. package/templates/conditional/router/feature-based/src/app/router/routes/home.routes.tsx +8 -0
  135. package/templates/conditional/router/feature-based/src/shared/layouts/RootLayout.jsx +17 -0
  136. package/templates/conditional/router/feature-based/src/shared/layouts/RootLayout.tsx +17 -0
  137. package/templates/conditional/router/feature-based/tailwind/src/shared/layouts/RootLayout.jsx +9 -0
  138. package/templates/conditional/router/feature-based/tailwind/src/shared/layouts/RootLayout.tsx +9 -0
  139. package/templates/conditional/state/redux/component-based/src/pages/Home/counterSlice.ts +9 -3
  140. package/templates/conditional/state/redux/component-based/src/{context → providers}/StoreProvider.jsx +0 -1
  141. package/templates/conditional/state/redux/component-based/src/{context → providers}/StoreProvider.tsx +2 -2
  142. package/templates/conditional/state/redux/component-based/src/store/hooks.ts +4 -2
  143. package/templates/conditional/state/redux/component-based/src/store/index.ts +2 -2
  144. package/templates/conditional/state/redux/feature-based/src/app/providers/StoreProvider.jsx +1 -2
  145. package/templates/conditional/state/redux/feature-based/src/app/providers/StoreProvider.tsx +3 -3
  146. package/templates/conditional/state/redux/feature-based/src/features/home/store/counterSlice.ts +9 -3
  147. package/templates/conditional/state/redux/feature-based/src/shared/stores/hooks.ts +6 -0
  148. package/templates/conditional/state/redux/feature-based/src/{stores → shared/stores}/index.ts +2 -2
  149. package/templates/conditional/state/zustand/component-based/src/store/useCounterStore.ts +8 -1
  150. package/templates/conditional/state/zustand/feature-based/src/stores/useCounterStore.ts +8 -1
  151. package/templates/conditional/testing/jest/babel.config.cjs +7 -0
  152. package/templates/conditional/testing/jest/component-based/src/__tests__/App.test.jsx +10 -0
  153. package/templates/conditional/testing/jest/component-based/src/__tests__/App.test.tsx +11 -0
  154. package/templates/conditional/testing/jest/{src → feature-based/src}/__tests__/App.test.jsx +2 -1
  155. package/templates/conditional/testing/jest/feature-based/src/__tests__/App.test.tsx +11 -0
  156. package/templates/conditional/testing/jest/jest.config.js +2 -3
  157. package/templates/conditional/testing/jest/jest.config.ts +6 -4
  158. package/templates/conditional/testing/jest/jest.setup.js +6 -0
  159. package/templates/conditional/testing/jest/jest.setup.ts +6 -0
  160. package/templates/conditional/testing/vitest/component-based/src/__tests__/App.test.jsx +10 -0
  161. package/templates/conditional/testing/{jest → vitest/component-based}/src/__tests__/App.test.tsx +2 -1
  162. package/templates/css/bootstrap/src/themes.css +14 -0
  163. package/templates/css/component-styles/bootstrap/component-based/src/components/common/Button.jsx +17 -0
  164. package/templates/css/component-styles/bootstrap/component-based/src/components/common/Button.tsx +22 -0
  165. package/templates/css/component-styles/bootstrap/component-based/src/layouts/MainLayout.jsx +15 -0
  166. package/templates/css/component-styles/bootstrap/component-based/src/layouts/MainLayout.tsx +19 -0
  167. package/templates/css/component-styles/bootstrap/component-based/src/pages/Home/Home.jsx +13 -0
  168. package/templates/css/component-styles/bootstrap/component-based/src/pages/Home/Home.tsx +13 -0
  169. package/templates/css/component-styles/bootstrap/feature-based/src/app/App.jsx +9 -0
  170. package/templates/css/component-styles/bootstrap/feature-based/src/app/App.tsx +9 -0
  171. package/templates/css/component-styles/bootstrap/feature-based/src/features/home/pages/HomePage.jsx +13 -0
  172. package/templates/css/component-styles/bootstrap/feature-based/src/features/home/pages/HomePage.tsx +13 -0
  173. package/templates/css/component-styles/bootstrap/feature-based/src/shared/components/ui/Button.jsx +17 -0
  174. package/templates/css/component-styles/bootstrap/feature-based/src/shared/components/ui/Button.tsx +22 -0
  175. package/templates/{architectures/feature-based/src/components/ui → css/component-styles/tailwind/component-based/src/components/common}/Button.jsx +1 -3
  176. package/templates/{architectures/feature-based/src/components/ui → css/component-styles/tailwind/component-based/src/components/common}/Button.tsx +1 -3
  177. package/templates/css/component-styles/tailwind/component-based/src/layouts/MainLayout.jsx +15 -0
  178. package/templates/css/component-styles/tailwind/component-based/src/layouts/MainLayout.tsx +19 -0
  179. package/templates/css/component-styles/tailwind/component-based/src/pages/Home/Home.jsx +13 -0
  180. package/templates/css/component-styles/tailwind/component-based/src/pages/Home/Home.tsx +13 -0
  181. package/templates/css/component-styles/tailwind/feature-based/src/app/App.jsx +9 -0
  182. package/templates/css/component-styles/tailwind/feature-based/src/app/App.tsx +9 -0
  183. package/templates/css/component-styles/tailwind/feature-based/src/features/home/pages/HomePage.jsx +13 -0
  184. package/templates/css/component-styles/tailwind/feature-based/src/features/home/pages/HomePage.tsx +13 -0
  185. package/templates/css/component-styles/tailwind/feature-based/src/shared/components/ui/Button.jsx +21 -0
  186. package/templates/css/component-styles/tailwind/feature-based/src/shared/components/ui/Button.tsx +26 -0
  187. package/templates/css/none/src/{index.css → main.css} +2 -0
  188. package/templates/css/none/src/themes.css +19 -0
  189. package/templates/css/tailwind/src/themes.css +9 -0
  190. package/templates/architectures/component-based/src/config/constants.js +0 -2
  191. package/templates/architectures/component-based/src/config/constants.ts +0 -2
  192. package/templates/architectures/component-based/src/config/routes.js +0 -7
  193. package/templates/architectures/component-based/src/config/routes.ts +0 -7
  194. package/templates/architectures/component-based/src/context/AppContext.jsx +0 -13
  195. package/templates/architectures/component-based/src/context/AppContext.tsx +0 -13
  196. package/templates/architectures/component-based/src/hooks/index.js +0 -1
  197. package/templates/architectures/component-based/src/hooks/index.ts +0 -1
  198. package/templates/architectures/component-based/src/layouts/index.js +0 -1
  199. package/templates/architectures/component-based/src/layouts/index.ts +0 -1
  200. package/templates/architectures/component-based/src/routes/index.jsx +0 -11
  201. package/templates/architectures/component-based/src/routes/index.tsx +0 -11
  202. package/templates/architectures/component-based/src/styles/globals.css +0 -7
  203. package/templates/architectures/component-based/src/utils/index.js +0 -1
  204. package/templates/architectures/component-based/src/utils/index.ts +0 -1
  205. package/templates/architectures/feature-based/src/config/constants.js +0 -2
  206. package/templates/architectures/feature-based/src/config/constants.ts +0 -2
  207. package/templates/architectures/feature-based/src/hooks/index.js +0 -1
  208. package/templates/architectures/feature-based/src/hooks/index.ts +0 -1
  209. package/templates/architectures/feature-based/src/utils/cn.ts +0 -6
  210. package/templates/architectures/feature-based/src/utils/index.js +0 -1
  211. package/templates/architectures/feature-based/src/utils/index.ts +0 -1
  212. package/templates/conditional/axios/component-based/src/services/axios.jsx +0 -19
  213. package/templates/conditional/axios/component-based/src/services/axios.ts +0 -19
  214. package/templates/conditional/axios/component-based/src/services/index.js +0 -1
  215. package/templates/conditional/axios/component-based/src/services/index.ts +0 -1
  216. package/templates/conditional/axios/feature-based/src/lib/axios.jsx +0 -19
  217. package/templates/conditional/axios/feature-based/src/lib/axios.ts +0 -19
  218. package/templates/conditional/axios/feature-based/src/lib/index.js +0 -1
  219. package/templates/conditional/axios/feature-based/src/lib/index.ts +0 -1
  220. package/templates/conditional/fetch/component-based/src/services/api.jsx +0 -27
  221. package/templates/conditional/fetch/component-based/src/services/api.ts +0 -27
  222. package/templates/conditional/fetch/component-based/src/services/index.js +0 -1
  223. package/templates/conditional/fetch/component-based/src/services/index.ts +0 -1
  224. package/templates/conditional/fetch/feature-based/src/lib/api.jsx +0 -27
  225. package/templates/conditional/fetch/feature-based/src/lib/api.ts +0 -27
  226. package/templates/conditional/fetch/feature-based/src/lib/index.js +0 -1
  227. package/templates/conditional/fetch/feature-based/src/lib/index.ts +0 -1
  228. package/templates/conditional/router/component-based/src/routes/index.jsx +0 -13
  229. package/templates/conditional/router/component-based/src/routes/index.tsx +0 -13
  230. package/templates/conditional/router/feature-based/src/app/router.jsx +0 -13
  231. package/templates/conditional/router/feature-based/src/app/router.tsx +0 -13
  232. package/templates/conditional/state/redux/feature-based/src/stores/hooks.ts +0 -4
  233. package/templates/css/tailwind/src/index.css +0 -1
  234. /package/templates/architectures/component-based/src/{components/layout → config}/.gitkeep +0 -0
  235. /package/templates/architectures/{feature-based/src/features/home/interfaces → component-based/src/providers}/.gitkeep +0 -0
  236. /package/templates/architectures/{feature-based/src/lib → component-based/src/styles}/.gitkeep +0 -0
  237. /package/templates/architectures/feature-based/src/{stores → features/home/types}/.gitkeep +0 -0
  238. /package/templates/architectures/feature-based/src/{components → shared/components}/ui/index.js +0 -0
  239. /package/templates/architectures/feature-based/src/{components → shared/components}/ui/index.ts +0 -0
  240. /package/templates/architectures/feature-based/src/{hooks → shared/hooks}/useLocalStorage.jsx +0 -0
  241. /package/templates/architectures/feature-based/src/{utils → shared/utils}/cn.jsx +0 -0
  242. /package/templates/conditional/state/redux/feature-based/src/{stores → shared/stores}/hooks.js +0 -0
  243. /package/templates/conditional/state/redux/feature-based/src/{stores → shared/stores}/index.js +0 -0
  244. /package/templates/conditional/testing/vitest/{src → feature-based/src}/__tests__/App.test.jsx +0 -0
  245. /package/templates/conditional/testing/vitest/{src → feature-based/src}/__tests__/App.test.tsx +0 -0
  246. /package/templates/css/bootstrap/src/{index.css → globals.css} +0 -0
  247. /package/templates/{architectures/feature-based/src/styles → css/tailwind/src}/globals.css +0 -0
package/src/injector.js CHANGED
@@ -2,7 +2,25 @@ import { promises as fsp } from "fs";
2
2
  import path from "path";
3
3
  import { copyDirRecursive, writeFileRecursive } from "@/utils/fs.js";
4
4
 
5
- export async function injectArchitecture(projectPath, templatesDir, architecture, language) {
5
+ // Narrow a template tree copy to the selected language: .tsx/.ts for ts,
6
+ // .jsx/.js for js (keeps the opposite language's files out of the project).
7
+ function langFileFilter(language) {
8
+ return (name) => {
9
+ if (language === "ts") {
10
+ if (name.endsWith(".jsx")) return false;
11
+ if (name.endsWith(".js")) return false;
12
+ return true;
13
+ }
14
+ if (language === "js") {
15
+ if (name.endsWith(".tsx")) return false;
16
+ if (name.endsWith(".ts")) return false;
17
+ return true;
18
+ }
19
+ return true;
20
+ };
21
+ }
22
+
23
+ export async function injectArchitecture(projectPath, templatesDir, architecture, language, cssFramework) {
6
24
  const ext = language === "ts" ? "tsx" : "jsx";
7
25
  const srcDir = path.join(templatesDir, "architectures", architecture, "src");
8
26
 
@@ -11,17 +29,13 @@ export async function injectArchitecture(projectPath, templatesDir, architecture
11
29
  const defaultAppJsx = path.join(projectPath, "src", "App.jsx");
12
30
  try { await fsp.rm(defaultAppTsx, { force: true }); } catch {}
13
31
  try { await fsp.rm(defaultAppJsx, { force: true }); } catch {}
32
+ // Remove Vite's default index.css (framework CSS lives in src/styles/,
33
+ // copied below — never at the src/ root).
34
+ try { await fsp.rm(path.join(projectPath, "src", "index.css"), { force: true }); } catch {}
35
+ try { await fsp.rm(path.join(projectPath, "src", "App.css"), { force: true }); } catch {}
14
36
 
15
37
  // Copy the architecture tree into the project's src/
16
- await copyDirRecursive(srcDir, path.join(projectPath, "src"), (name) => {
17
- // Skip files that don't match the language
18
- if (language === "ts" && name.endsWith(".jsx")) return false;
19
- if (language === "js" && name.endsWith(".tsx")) return false;
20
- // Skip .ts files when JS, skip .js when TS (for non-component files)
21
- if (language === "ts" && name.endsWith(".js") && !name.endsWith(".config.js")) return false;
22
- if (language === "js" && name.endsWith(".ts") && !name.endsWith(".config.ts")) return false;
23
- return true;
24
- });
38
+ await copyDirRecursive(srcDir, path.join(projectPath, "src"), langFileFilter(language));
25
39
 
26
40
  // Copy the architecture's main.tsx/main.jsx to src/main.{ext}
27
41
  const mainSrc = path.join(
@@ -41,6 +55,31 @@ export async function injectArchitecture(projectPath, templatesDir, architecture
41
55
  const oppositeExt = language === "ts" ? "jsx" : "tsx";
42
56
  const oppositeMain = path.join(projectPath, "src", `main.${oppositeExt}`);
43
57
  try { await fsp.rm(oppositeMain, { force: true }); } catch {}
58
+
59
+ // Apply the chosen CSS framework's component styling on top of the base
60
+ // (only where the base ships framework-agnostic inline markup). Runs here,
61
+ // before conditional overlays, so icons/router can still override the files
62
+ // they own.
63
+ if (cssFramework === "tailwind" || cssFramework === "bootstrap") {
64
+ const variantSrc = path.join(
65
+ templatesDir,
66
+ "css",
67
+ "component-styles",
68
+ cssFramework,
69
+ architecture,
70
+ "src"
71
+ );
72
+ try {
73
+ await fsp.access(variantSrc);
74
+ await copyDirRecursive(
75
+ variantSrc,
76
+ path.join(projectPath, "src"),
77
+ langFileFilter(language)
78
+ );
79
+ } catch {
80
+ // no component-styles for this arch/framework
81
+ }
82
+ }
44
83
  }
45
84
 
46
85
  export async function injectFormatter(projectPath, templatesDir, responses) {
@@ -72,6 +111,7 @@ export async function injectFormatter(projectPath, templatesDir, responses) {
72
111
  pkg.scripts["format:check"] = "prettier --check .";
73
112
  } else if (responses.formatter === "oxfmt") {
74
113
  pkg.scripts.format = "oxfmt .";
114
+ pkg.scripts["format:check"] = "oxfmt --check .";
75
115
  }
76
116
  await fsp.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf8");
77
117
  } catch {}
@@ -105,11 +145,14 @@ async function wireEslintPrettier(projectPath, language) {
105
145
 
106
146
  let result = lines.join("\n");
107
147
 
108
- // Append ...prettier as the LAST element of the eslint config.
148
+ // Append prettier as the LAST element of the eslint config.
149
+ // eslint-config-prettier exports a flat-config object (not an iterable),
150
+ // so it must be passed by reference, not spread — passing `...prettier`
151
+ // breaks under ESLint's jiti-based TS config loading.
109
152
  // The JS template exports an array (`export default [...]`); the TS
110
153
  // template uses a function call (`export default tseslint.config(...)`).
111
154
  const pushLast = (_, head, tail) =>
112
- head.replace(/,\s*$/, "") + ",\n ...prettier," + tail;
155
+ head.replace(/,\s*$/, "") + ",\n prettier," + tail;
113
156
  if (result.includes("tseslint.config(")) {
114
157
  result = result.replace(
115
158
  /(export default tseslint\.config\([\s\S]*?)(\n\s*\);)/,
@@ -149,20 +192,22 @@ export async function injectConditionals(projectPath, templatesDir, responses, a
149
192
 
150
193
  // 2. Router (overwrites App.tsx with routed version)
151
194
  if (responses.router) {
152
- await injectOverlay(
195
+ await injectOverlayVariant(
153
196
  projectPath,
154
197
  templatesDir,
155
- `conditional/router/${architecture}`,
198
+ `router/${architecture}`,
199
+ responses.cssFramework,
156
200
  language
157
201
  );
158
202
  }
159
203
 
160
204
  // 3. Icons (overwrites home page)
161
205
  if (responses.iconLibrary && responses.iconLibrary !== "none") {
162
- await injectOverlay(
206
+ await injectOverlayVariant(
163
207
  projectPath,
164
208
  templatesDir,
165
- `conditional/icons/${responses.iconLibrary}/${architecture}`,
209
+ `icons/${responses.iconLibrary}/${architecture}`,
210
+ responses.cssFramework,
166
211
  language
167
212
  );
168
213
  }
@@ -202,19 +247,70 @@ export async function injectConditionals(projectPath, templatesDir, responses, a
202
247
  if (architecture === "feature-based") {
203
248
  await injectCreateFeatureScript(projectPath, templatesDir, language);
204
249
  }
250
+
251
+ // A .gitkeep only keeps a folder alive when that folder holds nothing else;
252
+ // once an overlay writes real files into it the placeholder is redundant.
253
+ await pruneRedundantGitkeeps(projectPath);
254
+ }
255
+
256
+ // Remove .gitkeep placeholders from src/ directories that now contain real
257
+ // files (e.g. component-based `services/.gitkeep` after the axios/fetch client
258
+ // overlay lands). A folder with nothing but its placeholder keeps it.
259
+ async function pruneRedundantGitkeeps(projectPath) {
260
+ const walk = async (dir) => {
261
+ let entries;
262
+ try {
263
+ entries = await fsp.readdir(dir, { withFileTypes: true });
264
+ } catch {
265
+ return;
266
+ }
267
+ for (const entry of entries) {
268
+ if (entry.isDirectory()) {
269
+ await walk(path.join(dir, entry.name));
270
+ }
271
+ }
272
+ if (entries.some((e) => e.name === ".gitkeep")) {
273
+ const hasRealFiles = entries.some((e) => e.isFile() && e.name !== ".gitkeep");
274
+ if (hasRealFiles) {
275
+ await fsp.rm(path.join(dir, ".gitkeep"), { force: true });
276
+ }
277
+ }
278
+ };
279
+ await walk(path.join(projectPath, "src"));
280
+ }
281
+
282
+ // Overlays that ship presentational components (router, icons) carry optional
283
+ // tailwind/bootstrap subfolders. Copy the root version first — it holds the
284
+ // framework-agnostic skeleton (routed App, route tables) plus the inline
285
+ // markup defaults used for cssFramework "none" — then overlay the framework's
286
+ // subfolder so its markup-specific files (transitive layouts, home pages)
287
+ // win; `copyDirRecursive` overwrites on name collision.
288
+ async function injectOverlayVariant(projectPath, templatesDir, rel, cssFramework, language) {
289
+ const base = `conditional/${rel}`;
290
+ await injectOverlay(projectPath, templatesDir, base, language);
291
+ const variant =
292
+ cssFramework === "tailwind" || cssFramework === "bootstrap"
293
+ ? cssFramework
294
+ : "";
295
+ if (variant) {
296
+ await injectOverlay(
297
+ projectPath,
298
+ templatesDir,
299
+ `${base}/${variant}`,
300
+ language
301
+ );
302
+ }
205
303
  }
206
304
 
207
305
  async function injectOverlay(projectPath, templatesDir, overlayPath, language) {
208
306
  const srcDir = path.join(templatesDir, overlayPath, "src");
209
307
  try {
210
308
  await fsp.access(srcDir);
211
- await copyDirRecursive(srcDir, path.join(projectPath, "src"), (name) => {
212
- if (language === "ts" && name.endsWith(".jsx")) return false;
213
- if (language === "js" && name.endsWith(".tsx")) return false;
214
- if (language === "ts" && name.endsWith(".js") && !name.endsWith(".config.js")) return false;
215
- if (language === "js" && name.endsWith(".ts") && !name.endsWith(".config.ts")) return false;
216
- return true;
217
- });
309
+ await copyDirRecursive(
310
+ srcDir,
311
+ path.join(projectPath, "src"),
312
+ langFileFilter(language)
313
+ );
218
314
  } catch {
219
315
  // overlay src dir doesn't exist
220
316
  }
@@ -247,11 +343,18 @@ async function injectTesting(projectPath, templatesDir, framework, language, arc
247
343
  await fsp.access(jestSetupSrc);
248
344
  await fsp.copyFile(jestSetupSrc, path.join(projectPath, `jest.setup.${configExt}`));
249
345
  } catch {}
346
+
347
+ // Unified Babel transform config for Jest (env + react + typescript presets).
348
+ const babelSrc = path.join(testingDir, "babel.config.cjs");
349
+ try {
350
+ await fsp.access(babelSrc);
351
+ await fsp.copyFile(babelSrc, path.join(projectPath, "babel.config.cjs"));
352
+ } catch {}
250
353
  }
251
354
 
252
- // Copy test file
355
+ // Copy test file (architecture-scoped so the App import path resolves)
253
356
  const testExt = language === "ts" ? "tsx" : "jsx";
254
- const testSrc = path.join(testingDir, `src/__tests__/App.test.${testExt}`);
357
+ const testSrc = path.join(testingDir, architecture, `src/__tests__/App.test.${testExt}`);
255
358
  try {
256
359
  await fsp.access(testSrc);
257
360
  const testDest = path.join(projectPath, "src", "__tests__", `App.test.${testExt}`);
@@ -321,11 +424,11 @@ async function injectCreateFeatureScript(projectPath, templatesDir, language) {
321
424
  if (language === "js") {
322
425
  // Replace .ts extensions with .js in the initialFiles
323
426
  content = content
324
- .replace(/interfaces\/index\.ts/g, "interfaces/index.js")
325
427
  .replace(/services\/index\.ts/g, "services/index.js")
326
428
  .replace(/store\/index\.ts/g, "store/index.js")
327
429
  .replace(/hooks\/index\.ts/g, "hooks/index.js")
328
- .replace(/pages\/index\.ts/g, "pages/index.js");
430
+ .replace(/pages\/index\.ts/g, "pages/index.js")
431
+ .replace(/types\/index\.ts/g, "types/index.js");
329
432
  }
330
433
 
331
434
  await writeFileRecursive(scriptDest, content);
@@ -362,7 +465,7 @@ async function updateMainWithProvider(projectPath, stateType, architecture, ext)
362
465
  if (!content.includes("StoreProvider")) {
363
466
  content = content.replace(
364
467
  /import App from ['"]\.\/App['"]\n?/,
365
- "import App from './App'\nimport { StoreProvider } from './context/StoreProvider'\n"
468
+ "import App from './App'\nimport { StoreProvider } from './providers/StoreProvider'\n"
366
469
  );
367
470
  content = content.replace(
368
471
  /<App \/>/,
package/src/main.js CHANGED
@@ -15,6 +15,7 @@ import { getUserInputs, onCancel } from "@/prompts.js";
15
15
  import { runBaseInstall, runGitInit, runViteCreate } from "@/scaffold.js";
16
16
  import { installAllDeps } from "@/dependencies.js";
17
17
  import { generateReadme } from "@/readme.js";
18
+ import { runProjectFormat } from "@/format.js";
18
19
 
19
20
  const __filename = fileURLToPath(import.meta.url);
20
21
  const __dirname = path.dirname(__filename);
@@ -110,7 +111,8 @@ export async function main(options = {}) {
110
111
  projectPath,
111
112
  TEMPLATES_DIR,
112
113
  responses.architecture,
113
- responses.language
114
+ responses.language,
115
+ responses.cssFramework
114
116
  );
115
117
  archSpin.stop(chalk.green("Architecture scaffolding complete."));
116
118
  } catch (err) {
@@ -174,6 +176,7 @@ export async function main(options = {}) {
174
176
  templatesDir: TEMPLATES_DIR,
175
177
  language: responses.language,
176
178
  cssFramework: responses.cssFramework,
179
+ architecture: responses.architecture,
177
180
  ext: responses.language === "ts" ? "tsx" : "jsx",
178
181
  pkg,
179
182
  });
@@ -215,6 +218,19 @@ export async function main(options = {}) {
215
218
  }
216
219
  }
217
220
 
221
+ // 13.5 Format the freshly generated project so it is canonical on init
222
+ if (responses.formatter && responses.formatter !== "none") {
223
+ const fmtPassSpin = spinner();
224
+ fmtPassSpin.start(`Formatting project with ${responses.formatter}...`);
225
+ try {
226
+ await runProjectFormat(projectPath, responses);
227
+ fmtPassSpin.stop(chalk.green("Project formatted."));
228
+ } catch (err) {
229
+ fmtPassSpin.stop(chalk.red("Failed to format project."));
230
+ throw err;
231
+ }
232
+ }
233
+
218
234
  log.step(chalk.green("\nProject setup complete!"));
219
235
  log.message(
220
236
  chalk.gray(
package/src/readme.js CHANGED
@@ -77,36 +77,79 @@ function buildScripts(responses) {
77
77
 
78
78
  if (responses.formatter === "prettier" || responses.formatter === "oxfmt") {
79
79
  rows.push("| `npm run format` | Format code |");
80
+ rows.push("| `npm run format:check` | Verify code is formatted |");
81
+ }
82
+
83
+ if (responses.language === "ts") {
84
+ rows.push("| `npm run typecheck` | Type-check the project (tsc -b) |");
80
85
  }
81
86
 
82
87
  return rows.join("\n");
83
88
  }
84
89
 
85
- function buildProjectStructure(architecture) {
86
- if (architecture === "feature-based") {
90
+ function buildProjectStructure(responses) {
91
+ if (responses.architecture === "feature-based") {
92
+ const shared = [];
93
+ if (responses.apiClient === "fetch") {
94
+ shared.push("api/ # HTTP client (fetch) — not an external dependency");
95
+ } else if (responses.apiClient === "axios") {
96
+ shared.push("lib/ # Third-party library init (axios client)");
97
+ }
98
+ shared.push(
99
+ "components/ # Shared UI components",
100
+ "hooks/ # Shared custom hooks",
101
+ "layouts/ # High-level layout wrappers",
102
+ "stores/ # Global state stores",
103
+ `styles/ # ${responses.cssFramework === "none" ? "main.css (reset) + themes.css (CSS variables)" : "globals.css (framework directives) + themes.css"}`,
104
+ "types/ # Global type definitions",
105
+ "utils/ # Pure utility functions"
106
+ );
107
+ const appChildren = [
108
+ "App.tsx",
109
+ "contexts/ # React context objects (createContext)",
110
+ "providers/ # Provider components (ThemeProvider, ...)",
111
+ "hooks/ # Hooks that read the contexts (useTheme, ...)"
112
+ ];
87
113
  return `src/
88
- ├── app/ # App shell and providers
89
- ├── components/ # Shared UI components
90
- ├── config/ # Constants and configuration
91
- ├── features/ # Feature modules (pages, hooks, api)
92
- ├── hooks/ # Shared custom hooks
93
- ├── stores/ # Global state stores
94
- ├── types/ # TypeScript type definitions
95
- └── utils/ # Utility functions`;
114
+ ├── app/ # App shell and global providers
115
+ ${nestedTree(appChildren)}
116
+ ├── features/ # Feature modules (pages, hooks, api, types)
117
+ │ └── home/ # Example feature (components, services, types, store)
118
+ └── shared/ # Reusable, business-agnostic resources
119
+ ${nestedTree(shared)}`;
96
120
  }
97
121
 
122
+ const rows = ["components/ # Reusable UI components (common, form)"];
123
+ if (responses.apiClient !== "none") {
124
+ rows.push("config/ # API configuration (axios/fetch)");
125
+ }
126
+ rows.push(
127
+ "hooks/ # Shared custom hooks",
128
+ "layouts/ # Page layout wrappers",
129
+ "pages/ # Page-level components",
130
+ "providers/ # Provider components (createContext in appcontext.{ts,js}, Provider in AppProvider.{tsx,jsx})"
131
+ );
132
+ if (responses.router) {
133
+ rows.push("router/ # Centralized data router (guards/, index)");
134
+ }
135
+ rows.push(
136
+ "services/ # API service layer",
137
+ "store/ # State store",
138
+ `styles/ # ${responses.cssFramework === "none" ? "main.css (reset) + themes.css (CSS variables)" : "globals.css (framework directives) + themes.css"}`,
139
+ "types/ # TypeScript type definitions",
140
+ "utils/ # Utility functions"
141
+ );
98
142
  return `src/
99
- ├── components/ # Reusable UI components (common, form, layout)
100
- ├── config/ # Constants and route definitions
101
- ├── context/ # React context providers
102
- ├── hooks/ # Shared custom hooks
103
- ├── layouts/ # Page layout wrappers
104
- ├── pages/ # Page-level components
105
- ├── routes/ # Route definitions
106
- ├── services/ # API service layer
107
- ├── store/ # State store
108
- ├── styles/ # Global styles
109
- └── utils/ # Utility functions`;
143
+ ${nestedTree(rows, "")}`;
144
+ }
145
+
146
+ function nestedTree(rows, indent = " ") {
147
+ return rows
148
+ .map((label, i) => {
149
+ const isLast = i === rows.length - 1;
150
+ return `${indent}${isLast ? "└── " : "├── "}${label}`;
151
+ })
152
+ .join("\n");
110
153
  }
111
154
 
112
155
  function buildLicense() {
@@ -152,7 +195,7 @@ function buildDescription(projectName, responses) {
152
195
  function buildReadme(projectName, responses) {
153
196
  const builtWith = buildBuiltWith(responses);
154
197
  const scripts = buildScripts(responses);
155
- const structure = buildProjectStructure(responses.architecture);
198
+ const structure = buildProjectStructure(responses);
156
199
 
157
200
  return `${buildDescription(projectName, responses)}
158
201
 
@@ -3,7 +3,7 @@ import ReactDOM from "react-dom/client";
3
3
  import App from "./App";
4
4
  import "./styles/globals.css";
5
5
 
6
- ReactDOM.createRoot(document.getElementById("root")).render(
6
+ ReactDOM.createRoot(document.getElementById("root")!).render(
7
7
  <React.StrictMode>
8
8
  <App />
9
9
  </React.StrictMode>
@@ -1,11 +1,13 @@
1
- import React from "react";
1
+ import { AppProvider } from "@/providers/AppProvider";
2
2
  import { MainLayout } from "@/layouts/MainLayout";
3
3
  import { HomePage } from "@/pages/Home/Home";
4
4
 
5
5
  export default function App() {
6
6
  return (
7
- <MainLayout>
8
- <HomePage />
9
- </MainLayout>
7
+ <AppProvider>
8
+ <MainLayout>
9
+ <HomePage />
10
+ </MainLayout>
11
+ </AppProvider>
10
12
  );
11
13
  }
@@ -1,11 +1,13 @@
1
- import React from "react";
1
+ import { AppProvider } from "@/providers/AppProvider";
2
2
  import { MainLayout } from "@/layouts/MainLayout";
3
3
  import { HomePage } from "@/pages/Home/Home";
4
4
 
5
5
  export default function App() {
6
6
  return (
7
- <MainLayout>
8
- <HomePage />
9
- </MainLayout>
7
+ <AppProvider>
8
+ <MainLayout>
9
+ <HomePage />
10
+ </MainLayout>
11
+ </AppProvider>
10
12
  );
11
13
  }
@@ -1,5 +1,3 @@
1
- import React from "react";
2
-
3
1
  export function Button({
4
2
  variant = "primary",
5
3
  children,
@@ -7,8 +5,11 @@ export function Button({
7
5
  ...props
8
6
  }) {
9
7
  const styles = {
10
- primary: { backgroundColor: "#2563eb", color: "white" },
11
- secondary: { backgroundColor: "#e5e7eb", color: "#1f2937" },
8
+ primary: { backgroundColor: "var(--color-primary)", color: "white" },
9
+ secondary: {
10
+ backgroundColor: "var(--color-border)",
11
+ color: "var(--color-fg)",
12
+ },
12
13
  };
13
14
 
14
15
  return (
@@ -1,5 +1,3 @@
1
- import React from "react";
2
-
3
1
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
4
2
  variant?: "primary" | "secondary";
5
3
  children: React.ReactNode;
@@ -12,8 +10,11 @@ export function Button({
12
10
  ...props
13
11
  }: ButtonProps) {
14
12
  const styles = {
15
- primary: { backgroundColor: "#2563eb", color: "white" },
16
- secondary: { backgroundColor: "#e5e7eb", color: "#1f2937" },
13
+ primary: { backgroundColor: "var(--color-primary)", color: "white" },
14
+ secondary: {
15
+ backgroundColor: "var(--color-border)",
16
+ color: "var(--color-fg)",
17
+ },
17
18
  };
18
19
 
19
20
  return (
@@ -0,0 +1,10 @@
1
+ import { useContext } from "react";
2
+ import { AppContext } from "@/providers/appcontext";
3
+
4
+ export function useApp() {
5
+ const ctx = useContext(AppContext);
6
+ if (!ctx) {
7
+ throw new Error("useApp must be used within an AppProvider");
8
+ }
9
+ return ctx;
10
+ }
@@ -0,0 +1,10 @@
1
+ import { useContext } from "react";
2
+ import { AppContext, type AppContextValue } from "@/providers/appcontext";
3
+
4
+ export function useApp(): AppContextValue {
5
+ const ctx = useContext(AppContext);
6
+ if (!ctx) {
7
+ throw new Error("useApp must be used within an AppProvider");
8
+ }
9
+ return ctx;
10
+ }
@@ -1,17 +1,17 @@
1
1
  import { useState, useCallback } from "react";
2
2
 
3
- export function useLocalStorage(key, initialValue) {
4
- const [storedValue, setStoredValue] = useState(() => {
3
+ export function useLocalStorage<T>(key: string, initialValue: T) {
4
+ const [storedValue, setStoredValue] = useState<T>(() => {
5
5
  try {
6
6
  const item = window.localStorage.getItem(key);
7
- return item ? JSON.parse(item) : initialValue;
7
+ return item ? (JSON.parse(item) as T) : initialValue;
8
8
  } catch {
9
9
  return initialValue;
10
10
  }
11
11
  });
12
12
 
13
13
  const setValue = useCallback(
14
- (value) => {
14
+ (value: T | ((prev: T) => T)) => {
15
15
  try {
16
16
  const valueToStore =
17
17
  value instanceof Function ? value(storedValue) : value;
@@ -24,5 +24,5 @@ export function useLocalStorage(key, initialValue) {
24
24
  [key, storedValue]
25
25
  );
26
26
 
27
- return [storedValue, setValue];
27
+ return [storedValue, setValue] as const;
28
28
  }
@@ -1,25 +1,31 @@
1
- import React from "react";
2
-
3
1
  export function MainLayout({ children }) {
4
2
  return (
5
3
  <div style={{ minHeight: "100vh", display: "flex", flexDirection: "column" }}>
6
4
  <header
7
5
  style={{
8
6
  padding: "16px 24px",
9
- borderBottom: "1px solid #e5e7eb",
7
+ borderBottom: "1px solid var(--color-border)",
10
8
  }}
11
9
  >
12
10
  <h2 style={{ fontSize: "1.25rem", fontWeight: 600 }}>Lumen</h2>
13
11
  </header>
14
- <main style={{ flex: 1, padding: "24px", display: "flex", alignItems: "center", justifyContent: "center" }}>
12
+ <main
13
+ style={{
14
+ flex: 1,
15
+ padding: "24px",
16
+ display: "flex",
17
+ alignItems: "center",
18
+ justifyContent: "center",
19
+ }}
20
+ >
15
21
  {children}
16
22
  </main>
17
23
  <footer
18
24
  style={{
19
25
  padding: "16px 24px",
20
- borderTop: "1px solid #e5e7eb",
26
+ borderTop: "1px solid var(--color-border)",
21
27
  textAlign: "center",
22
- color: "#6b7280",
28
+ color: "var(--color-muted)",
23
29
  }}
24
30
  >
25
31
  <p>Built with Lumen</p>
@@ -1,5 +1,3 @@
1
- import React from "react";
2
-
3
1
  interface MainLayoutProps {
4
2
  children: React.ReactNode;
5
3
  }
@@ -10,20 +8,28 @@ export function MainLayout({ children }: MainLayoutProps) {
10
8
  <header
11
9
  style={{
12
10
  padding: "16px 24px",
13
- borderBottom: "1px solid #e5e7eb",
11
+ borderBottom: "1px solid var(--color-border)",
14
12
  }}
15
13
  >
16
14
  <h2 style={{ fontSize: "1.25rem", fontWeight: 600 }}>Lumen</h2>
17
15
  </header>
18
- <main style={{ flex: 1, padding: "24px", display: "flex", alignItems: "center", justifyContent: "center" }}>
16
+ <main
17
+ style={{
18
+ flex: 1,
19
+ padding: "24px",
20
+ display: "flex",
21
+ alignItems: "center",
22
+ justifyContent: "center",
23
+ }}
24
+ >
19
25
  {children}
20
26
  </main>
21
27
  <footer
22
28
  style={{
23
29
  padding: "16px 24px",
24
- borderTop: "1px solid #e5e7eb",
30
+ borderTop: "1px solid var(--color-border)",
25
31
  textAlign: "center",
26
- color: "#6b7280",
32
+ color: "var(--color-muted)",
27
33
  }}
28
34
  >
29
35
  <p>Built with Lumen</p>
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import { Button } from "@/components/common";
3
2
 
4
3
  export function HomePage() {
@@ -7,7 +6,12 @@ export function HomePage() {
7
6
  <h1 style={{ fontSize: "2.25rem", fontWeight: 700, marginBottom: "1rem" }}>
8
7
  Welcome to Lumen
9
8
  </h1>
10
- <p style={{ color: "#6b7280", marginBottom: "2rem" }}>
9
+ <p
10
+ style={{
11
+ color: "var(--color-muted)",
12
+ marginBottom: "2rem",
13
+ }}
14
+ >
11
15
  Your React + Vite project is ready. Start building!
12
16
  </p>
13
17
  <Button>Get Started</Button>
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import { Button } from "@/components/common";
3
2
 
4
3
  export function HomePage() {
@@ -7,7 +6,12 @@ export function HomePage() {
7
6
  <h1 style={{ fontSize: "2.25rem", fontWeight: 700, marginBottom: "1rem" }}>
8
7
  Welcome to Lumen
9
8
  </h1>
10
- <p style={{ color: "#6b7280", marginBottom: "2rem" }}>
9
+ <p
10
+ style={{
11
+ color: "var(--color-muted)",
12
+ marginBottom: "2rem",
13
+ }}
14
+ >
11
15
  Your React + Vite project is ready. Start building!
12
16
  </p>
13
17
  <Button>Get Started</Button>