reroute-js 0.46.0 → 1.0.0-alpha.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 (214) hide show
  1. package/README.md +2 -4
  2. package/_/store/package.json +1 -3
  3. package/_/store/src/client/components/Header.tsx +8 -20
  4. package/_/store/src/client/components/ProductCard.tsx +9 -16
  5. package/_/store/src/client/routes/[404].tsx +20 -31
  6. package/_/store/src/client/routes/categories/[category].tsx +23 -28
  7. package/_/store/src/client/routes/categories/index.tsx +19 -27
  8. package/_/store/src/client/routes/index.tsx +27 -37
  9. package/_/store/src/client/routes/products/[id].tsx +35 -48
  10. package/_/store/src/client/routes/products/index.tsx +20 -50
  11. package/_/store/src/client/theme.css +907 -95
  12. package/cli/bin.d.ts +1 -1
  13. package/cli/bin.js +78 -176
  14. package/cli/bin.js.map +11 -11
  15. package/cli/index.d.ts +1 -1
  16. package/cli/index.js +17 -112
  17. package/cli/index.js.map +5 -5
  18. package/cli/src/cli.d.ts +1 -1
  19. package/cli/src/commands/analyze.d.ts +1 -1
  20. package/cli/src/commands/build.d.ts +1 -1
  21. package/cli/src/commands/dev.d.ts +1 -1
  22. package/cli/src/commands/gen.d.ts +1 -1
  23. package/cli/src/commands/gen.d.ts.map +1 -1
  24. package/cli/src/commands/index.d.ts +1 -1
  25. package/cli/src/commands/init.d.ts +1 -1
  26. package/cli/src/commands/lib/assets.d.ts +1 -1
  27. package/cli/src/commands/lib/bundler.d.ts +1 -1
  28. package/cli/src/commands/lib/command.d.ts +1 -1
  29. package/cli/src/commands/lib/env.d.ts +1 -1
  30. package/cli/src/commands/lib/index.d.ts +2 -2
  31. package/cli/src/commands/lib/index.d.ts.map +1 -1
  32. package/cli/src/commands/lib/log.d.ts +1 -1
  33. package/cli/src/commands/lib/markdown/availability.d.ts +1 -1
  34. package/cli/src/commands/lib/markdown/index.d.ts +1 -1
  35. package/cli/src/commands/lib/markdown/processor.d.ts +1 -1
  36. package/cli/src/commands/lib/production.d.ts +1 -1
  37. package/cli/src/commands/lib/server.d.ts +1 -1
  38. package/cli/src/commands/lib/streaming/analyzer.d.ts +1 -1
  39. package/cli/src/commands/lib/streaming/suspense.d.ts +1 -1
  40. package/cli/src/commands/lib/terminal-ui.d.ts +1 -1
  41. package/cli/src/commands/lib/theme.d.ts +20 -0
  42. package/cli/src/commands/lib/theme.d.ts.map +1 -0
  43. package/cli/src/commands/lib/version.d.ts +1 -1
  44. package/cli/src/commands/og.d.ts +1 -1
  45. package/cli/src/commands/start.d.ts +1 -1
  46. package/cli/src/index.d.ts +1 -1
  47. package/core/index.d.ts +1 -1
  48. package/core/index.js +12 -12
  49. package/core/index.js.map +6 -6
  50. package/core/src/bundler/hash.d.ts +1 -1
  51. package/core/src/bundler/index.d.ts +1 -1
  52. package/core/src/config.d.ts +1 -1
  53. package/core/src/content/discovery.d.ts +1 -1
  54. package/core/src/content/index.d.ts +1 -1
  55. package/core/src/content/metadata.d.ts +1 -1
  56. package/core/src/i18n/catalog.d.ts +1 -1
  57. package/core/src/i18n/discover.d.ts +1 -1
  58. package/core/src/i18n/index.d.ts +1 -1
  59. package/core/src/i18n/messages.d.ts +1 -1
  60. package/core/src/i18n/negotiate.d.ts +1 -1
  61. package/core/src/i18n/pathname.d.ts +1 -1
  62. package/core/src/i18n/resolve.d.ts +1 -1
  63. package/core/src/i18n/types.d.ts +1 -1
  64. package/core/src/index.d.ts +1 -1
  65. package/core/src/llms/extractor.d.ts +1 -1
  66. package/core/src/llms/formatter.d.ts +1 -1
  67. package/core/src/llms/full-generator.d.ts +1 -1
  68. package/core/src/llms/index-generator.d.ts +1 -1
  69. package/core/src/llms/index.d.ts +1 -1
  70. package/core/src/og/discovery.d.ts +1 -1
  71. package/core/src/og/index.d.ts +1 -1
  72. package/core/src/og/meta.d.ts +1 -1
  73. package/core/src/og/render.d.ts +1 -1
  74. package/core/src/og/types.d.ts +1 -1
  75. package/core/src/robots/discovery.d.ts +1 -1
  76. package/core/src/robots/generator.d.ts +1 -1
  77. package/core/src/robots/index.d.ts +1 -1
  78. package/core/src/robots/policies.d.ts +1 -1
  79. package/core/src/rss/discovery.d.ts +1 -1
  80. package/core/src/rss/generator.d.ts +1 -1
  81. package/core/src/rss/index.d.ts +1 -1
  82. package/core/src/sitemap/discovery.d.ts +1 -1
  83. package/core/src/sitemap/generator.d.ts +1 -1
  84. package/core/src/sitemap/index.d.ts +1 -1
  85. package/core/src/ssr/index.d.ts +1 -1
  86. package/core/src/ssr/lib/cache.d.ts +1 -1
  87. package/core/src/ssr/lib/cleanup.d.ts +1 -1
  88. package/core/src/ssr/lib/collections.d.ts +1 -1
  89. package/core/src/ssr/lib/compression.d.ts +1 -1
  90. package/core/src/ssr/lib/compute/content.d.ts +1 -1
  91. package/core/src/ssr/lib/compute/index.d.ts +1 -1
  92. package/core/src/ssr/lib/compute/layouts.d.ts +1 -1
  93. package/core/src/ssr/lib/compute/routes.d.ts +1 -1
  94. package/core/src/ssr/lib/content-path.d.ts +1 -1
  95. package/core/src/ssr/lib/data.d.ts +1 -1
  96. package/core/src/ssr/lib/html.d.ts +1 -1
  97. package/core/src/ssr/lib/imports.d.ts +1 -1
  98. package/core/src/ssr/lib/index.d.ts +1 -1
  99. package/core/src/ssr/lib/layouts.d.ts +1 -1
  100. package/core/src/ssr/lib/metadata.d.ts +1 -1
  101. package/core/src/ssr/lib/mime.d.ts +1 -1
  102. package/core/src/ssr/lib/modules.d.ts +1 -1
  103. package/core/src/ssr/lib/path.d.ts +1 -1
  104. package/core/src/ssr/lib/preload.d.ts +1 -1
  105. package/core/src/ssr/lib/route-match.d.ts +1 -1
  106. package/core/src/ssr/lib/scripts/collections.d.ts +1 -1
  107. package/core/src/ssr/lib/scripts/data.d.ts +1 -1
  108. package/core/src/ssr/lib/scripts/escape.d.ts +1 -1
  109. package/core/src/ssr/lib/scripts/feeds.d.ts +1 -1
  110. package/core/src/ssr/lib/scripts/index.d.ts +1 -1
  111. package/core/src/ssr/lib/seed.d.ts +1 -1
  112. package/core/src/ssr/lib/serialize.d.ts +1 -1
  113. package/core/src/ssr/lib/setup.d.ts +2 -2
  114. package/core/src/ssr/lib/setup.d.ts.map +1 -1
  115. package/core/src/ssr/lib/styles.d.ts +3 -3
  116. package/core/src/ssr/lib/styles.d.ts.map +1 -1
  117. package/core/src/ssr/lib/template.d.ts +1 -1
  118. package/core/src/ssr/lib/types.d.ts +1 -1
  119. package/core/src/ssr/render.d.ts +2 -2
  120. package/core/src/ssr/render.d.ts.map +1 -1
  121. package/core/src/ssr/stream.d.ts +2 -2
  122. package/core/src/ssr/stream.d.ts.map +1 -1
  123. package/elysia/index.d.ts +1 -1
  124. package/elysia/index.js +21 -21
  125. package/elysia/index.js.map +9 -9
  126. package/elysia/src/index.d.ts +1 -1
  127. package/elysia/src/libs/assets.d.ts +1 -1
  128. package/elysia/src/libs/cache.d.ts +1 -1
  129. package/elysia/src/libs/caching.d.ts +1 -1
  130. package/elysia/src/libs/http.d.ts +1 -1
  131. package/elysia/src/libs/i18n.d.ts +1 -1
  132. package/elysia/src/libs/image.d.ts +1 -1
  133. package/elysia/src/libs/index.d.ts +1 -1
  134. package/elysia/src/libs/llms.d.ts +1 -1
  135. package/elysia/src/libs/response.d.ts +1 -1
  136. package/elysia/src/libs/serving.d.ts +1 -1
  137. package/elysia/src/plugin.d.ts +1 -1
  138. package/elysia/src/routes/artifacts.d.ts +1 -1
  139. package/elysia/src/routes/content.d.ts +1 -1
  140. package/elysia/src/routes/image.d.ts +1 -1
  141. package/elysia/src/routes/index.d.ts +1 -1
  142. package/elysia/src/routes/internal.d.ts +1 -1
  143. package/elysia/src/routes/llms.d.ts +1 -1
  144. package/elysia/src/routes/og.d.ts +1 -1
  145. package/elysia/src/routes/redirects.d.ts +1 -1
  146. package/elysia/src/routes/robots.d.ts +1 -1
  147. package/elysia/src/routes/rss.d.ts +1 -1
  148. package/elysia/src/routes/search.d.ts +1 -1
  149. package/elysia/src/routes/sitemap.d.ts +1 -1
  150. package/elysia/src/routes/ssr.d.ts +2 -2
  151. package/elysia/src/routes/ssr.d.ts.map +1 -1
  152. package/elysia/src/routes/static.d.ts +1 -1
  153. package/elysia/src/types.d.ts +1 -1
  154. package/package.json +2 -5
  155. package/react/index.d.ts +1 -1
  156. package/react/index.js +2 -2
  157. package/react/index.js.map +1 -1
  158. package/react/src/components/ClientOnly.d.ts +1 -1
  159. package/react/src/components/ContentRoute.d.ts +1 -1
  160. package/react/src/components/Image.d.ts +1 -1
  161. package/react/src/components/LazyRoute.d.ts +1 -1
  162. package/react/src/components/Link.d.ts +1 -1
  163. package/react/src/components/Markdown.d.ts +1 -1
  164. package/react/src/components/Outlet.d.ts +1 -1
  165. package/react/src/components/index.d.ts +1 -1
  166. package/react/src/hooks/index.d.ts +1 -1
  167. package/react/src/hooks/useContent.d.ts +1 -1
  168. package/react/src/hooks/useData.d.ts +1 -1
  169. package/react/src/hooks/useFeed.d.ts +1 -1
  170. package/react/src/hooks/useLayoutData.d.ts +1 -1
  171. package/react/src/hooks/useLlms.d.ts +1 -1
  172. package/react/src/hooks/useNavigate.d.ts +1 -1
  173. package/react/src/hooks/useParams.d.ts +1 -1
  174. package/react/src/hooks/useRouter.d.ts +1 -1
  175. package/react/src/hooks/useSearch.d.ts +1 -1
  176. package/react/src/hooks/useSearchParams.d.ts +1 -1
  177. package/react/src/hooks/useToc.d.ts +1 -1
  178. package/react/src/i18n/LocaleProvider.d.ts +1 -1
  179. package/react/src/i18n/helpers.d.ts +1 -1
  180. package/react/src/i18n/index.d.ts +1 -1
  181. package/react/src/index.d.ts +1 -1
  182. package/react/src/lib/collection.d.ts +1 -1
  183. package/react/src/lib/content.d.ts +1 -1
  184. package/react/src/lib/head.d.ts +1 -1
  185. package/react/src/lib/index.d.ts +1 -1
  186. package/react/src/lib/lazy-route.d.ts +1 -1
  187. package/react/src/lib/route-loader.d.ts +1 -1
  188. package/react/src/providers/ContentProvider.d.ts +1 -1
  189. package/react/src/providers/RerouteProvider.d.ts +1 -1
  190. package/react/src/providers/RouterProvider.d.ts +1 -1
  191. package/react/src/providers/index.d.ts +1 -1
  192. package/react/src/types/any.d.ts +1 -1
  193. package/react/src/types/index.d.ts +1 -1
  194. package/react/src/types/router.d.ts +1 -1
  195. package/telemetry/react.d.ts +1 -1
  196. package/telemetry/react.js +2 -2
  197. package/telemetry/react.js.map +1 -1
  198. package/telemetry/server.d.ts +1 -1
  199. package/telemetry/server.js +2 -2
  200. package/telemetry/server.js.map +4 -4
  201. package/telemetry/src/react/api.d.ts +1 -1
  202. package/telemetry/src/react/context.d.ts +1 -1
  203. package/telemetry/src/react/index.d.ts +1 -1
  204. package/telemetry/src/react/telemetry.d.ts +1 -1
  205. package/telemetry/src/server/context.d.ts +1 -1
  206. package/telemetry/src/server/headers/extractor.d.ts +1 -1
  207. package/telemetry/src/server/headers/index.d.ts +1 -1
  208. package/telemetry/src/server/headers/presets.d.ts +1 -1
  209. package/telemetry/src/server/index.d.ts +1 -1
  210. package/telemetry/src/server/instrumentation.d.ts +1 -1
  211. package/telemetry/src/server/plugin.d.ts +1 -1
  212. package/telemetry/src/server/sourcemap.d.ts +1 -1
  213. package/cli/src/commands/lib/tailwind.d.ts +0 -20
  214. package/cli/src/commands/lib/tailwind.d.ts.map +0 -1
package/README.md CHANGED
@@ -179,11 +179,9 @@ Reroute is a feature-rich file-based routing framework for building fullstack Re
179
179
  - ⚡ **React 19 Streaming** - Native `renderToReadableStream` for optimal performance
180
180
 
181
181
  ### 🎨 Styling & Theming
182
- - 🎨 **Tailwind CSS v4 Support** - Automatic detection and compilation with CSS-first configuration
182
+ - 🎨 **Native CSS** - Author styles in `src/client/theme.css` with no CSS framework required
183
183
  - ⚡ **Live CSS Reload** - Instant style updates in development mode
184
- - 🎯 **Modern CSS Features** - `@theme` and `@utility` directives support
185
- - 🚀 **Oxide Engine** - 5x faster builds with the new Tailwind compiler
186
- - 🔧 **Zero Config** - Works out of the box when `@tailwindcss/cli` is installed
184
+ - 🔧 **Zero Config** - Theme CSS is synced automatically during `reroute gen`
187
185
 
188
186
  ### 🎨 Developer Experience
189
187
  - 📁 **Project Templates** - Quick start with `basic`, `blog`, or `store` templates
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "{{PROJECT_NAME}}",
3
3
  "version": "0.0.0",
4
- "description": "A Reroute store application with Tailwind CSS v4",
4
+ "description": "A Reroute store application",
5
5
  "private": true,
6
6
  "scripts": {
7
7
  "types": "tsc --noEmit",
@@ -23,8 +23,6 @@
23
23
  "@types/bun": "latest",
24
24
  "@types/react": "^19.2.2",
25
25
  "@types/react-dom": "^19.2.2",
26
- "@tailwindcss/cli": "^4.1.16",
27
- "tailwindcss": "^4.1.16",
28
26
  "typescript": "^5"
29
27
  }
30
28
  }
@@ -2,34 +2,22 @@ import { Link } from 'reroute-js/react';
2
2
 
3
3
  export default function Header() {
4
4
  return (
5
- <header className='sticky top-0 z-50 bg-white border-b border-gray-200 shadow-sm'>
5
+ <header className='site-header'>
6
6
  <div className='container-custom'>
7
- <div className='flex items-center justify-between h-16'>
8
- <Link
9
- to='/'
10
- className='flex items-center gap-2 text-2xl font-bold text-primary-600 hover:text-primary-700 transition-colors'
11
- >
12
- <span className='text-3xl'>🛒</span>
7
+ <div className='header-inner'>
8
+ <Link to='/' className='header-logo'>
9
+ <span className='header-logo-icon'>🛒</span>
13
10
  <span>Reroute Store</span>
14
11
  </Link>
15
12
 
16
- <nav className='flex items-center gap-8'>
17
- <Link
18
- to='/'
19
- className='link-muted font-medium hover:text-primary-600'
20
- >
13
+ <nav className='header-nav'>
14
+ <Link to='/' className='nav-link'>
21
15
  Home
22
16
  </Link>
23
- <Link
24
- to='/products'
25
- className='link-muted font-medium hover:text-primary-600'
26
- >
17
+ <Link to='/products' className='nav-link'>
27
18
  Products
28
19
  </Link>
29
- <Link
30
- to='/categories'
31
- className='link-muted font-medium hover:text-primary-600'
32
- >
20
+ <Link to='/categories' className='nav-link'>
33
21
  Categories
34
22
  </Link>
35
23
  </nav>
@@ -8,12 +8,9 @@ interface ProductCardProps {
8
8
 
9
9
  export default function ProductCard({ product }: ProductCardProps) {
10
10
  return (
11
- <div className='card card-hover group'>
12
- <Link
13
- to={`/products/${product.id}`}
14
- className='block h-full no-underline text-inherit'
15
- >
16
- <div className='w-full h-60 bg-gray-50 flex items-center justify-center p-4'>
11
+ <div className='card card-hover product-card'>
12
+ <Link to={`/products/${product.id}`} className='product-card-link'>
13
+ <div className='product-card-image-wrap'>
17
14
  <Image
18
15
  src={product.image}
19
16
  alt={product.title}
@@ -21,25 +18,21 @@ export default function ProductCard({ product }: ProductCardProps) {
21
18
  height={180}
22
19
  quality={75}
23
20
  sizes='(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 180px'
24
- className='max-w-full max-h-full object-contain relative z-10 bg-white'
21
+ className='product-card-image'
25
22
  style={{ viewTransitionName: `product-image-${product.id}` }}
26
23
  />
27
24
  </div>
28
25
 
29
- <div className='p-4 flex flex-col gap-2 flex-1'>
26
+ <div className='product-card-body'>
30
27
  <div className='badge-primary'>{product.category}</div>
31
28
 
32
- <h3 className='text-base font-semibold text-gray-900 leading-normal line-clamp-2 min-h-[3em] group-hover:text-primary-600 transition-colors'>
33
- {product.title}
34
- </h3>
29
+ <h3 className='product-card-title'>{product.title}</h3>
35
30
 
36
- <div className='flex justify-between items-center mt-auto pt-2'>
37
- <span className='text-xl font-bold text-primary-600'>
38
- ${product.price.toFixed(2)}
39
- </span>
31
+ <div className='product-card-footer'>
32
+ <span className='price'>${product.price.toFixed(2)}</span>
40
33
 
41
34
  {product.rating && (
42
- <div className='flex items-center gap-1 text-sm text-gray-600'>
35
+ <div className='product-rating'>
43
36
  <span>⭐</span>
44
37
  <span>
45
38
  {product.rating.rate} ({product.rating.count})
@@ -6,20 +6,18 @@ export default function NotFoundPage() {
6
6
  <>
7
7
  <Header />
8
8
 
9
- <main className='container-custom py-16'>
10
- <div className='max-w-2xl mx-auto text-center'>
11
- <div className='mb-8 animate-slide-up'>
12
- <div className='text-9xl font-bold text-primary-600 mb-4'>404</div>
13
- <h1 className='text-4xl font-bold text-gray-900 mb-4'>
14
- Page Not Found
15
- </h1>
16
- <p className='text-xl text-gray-600 mb-8'>
9
+ <main className='page-main page-main-lg'>
10
+ <div className='not-found-content'>
11
+ <div className='animate-slide-up'>
12
+ <div className='not-found-code'>404</div>
13
+ <h1 className='not-found-title'>Page Not Found</h1>
14
+ <p className='not-found-lead'>
17
15
  Oops! The page you're looking for doesn't exist. It might have
18
16
  been moved or deleted.
19
17
  </p>
20
18
  </div>
21
19
 
22
- <div className='flex flex-col sm:flex-row gap-4 justify-center mb-12 animate-in'>
20
+ <div className='not-found-actions animate-in'>
23
21
  <Link to='/' className='btn-primary btn-lg'>
24
22
  🏠 Go Home
25
23
  </Link>
@@ -28,32 +26,23 @@ export default function NotFoundPage() {
28
26
  </Link>
29
27
  </div>
30
28
 
31
- <div className='grid grid-cols-1 md:grid-cols-3 gap-6 mt-16 animate-scale'>
32
- <Link
33
- to='/categories'
34
- className='card card-hover p-6 no-underline text-gray-900'
35
- >
36
- <div className='text-4xl mb-3'>🏷️</div>
37
- <h3 className='font-semibold mb-2'>Categories</h3>
38
- <p className='text-sm text-gray-600'>Browse by category</p>
29
+ <div className='not-found-links animate-scale'>
30
+ <Link to='/categories' className='card card-hover card-padded'>
31
+ <div className='not-found-card-icon'>🏷️</div>
32
+ <h3 className='not-found-card-title'>Categories</h3>
33
+ <p className='not-found-card-desc'>Browse by category</p>
39
34
  </Link>
40
35
 
41
- <Link
42
- to='/products'
43
- className='card card-hover p-6 no-underline text-gray-900'
44
- >
45
- <div className='text-4xl mb-3'>📦</div>
46
- <h3 className='font-semibold mb-2'>All Products</h3>
47
- <p className='text-sm text-gray-600'>View our catalog</p>
36
+ <Link to='/products' className='card card-hover card-padded'>
37
+ <div className='not-found-card-icon'>📦</div>
38
+ <h3 className='not-found-card-title'>All Products</h3>
39
+ <p className='not-found-card-desc'>View our catalog</p>
48
40
  </Link>
49
41
 
50
- <Link
51
- to='/'
52
- className='card card-hover p-6 no-underline text-gray-900'
53
- >
54
- <div className='text-4xl mb-3'>⚡</div>
55
- <h3 className='font-semibold mb-2'>Featured</h3>
56
- <p className='text-sm text-gray-600'>See what's popular</p>
42
+ <Link to='/' className='card card-hover card-padded'>
43
+ <div className='not-found-card-icon'>⚡</div>
44
+ <h3 className='not-found-card-title'>Featured</h3>
45
+ <p className='not-found-card-desc'>See what's popular</p>
57
46
  </Link>
58
47
  </div>
59
48
  </div>
@@ -57,7 +57,6 @@ function CategoryPage() {
57
57
  const [loading, setLoading] = useState(!routeData);
58
58
  const [error, setError] = useState<string | null>(routeData?.error || null);
59
59
 
60
- // Load products on mount if not from SSR
61
60
  useEffect(() => {
62
61
  if (products.length > 0) {
63
62
  setLoading(false);
@@ -86,11 +85,9 @@ function CategoryPage() {
86
85
  });
87
86
  }, [category, products.length]);
88
87
 
89
- // Filter and sort products
90
88
  useEffect(() => {
91
89
  let result = [...products];
92
90
 
93
- // Apply search filter
94
91
  if (searchQuery.trim()) {
95
92
  const query = searchQuery.toLowerCase();
96
93
  result = result.filter(
@@ -100,7 +97,6 @@ function CategoryPage() {
100
97
  );
101
98
  }
102
99
 
103
- // Apply sorting
104
100
  switch (sortBy) {
105
101
  case 'price-asc':
106
102
  result.sort((a, b) => a.price - b.price);
@@ -112,7 +108,6 @@ function CategoryPage() {
112
108
  result.sort((a, b) => a.title.localeCompare(b.title));
113
109
  break;
114
110
  default:
115
- // Keep default order
116
111
  break;
117
112
  }
118
113
 
@@ -126,9 +121,8 @@ function CategoryPage() {
126
121
  <>
127
122
  <Header />
128
123
 
129
- <main className='container-custom py-8'>
130
- {/* Breadcrumbs */}
131
- <nav className='flex items-center gap-2 text-sm text-gray-600 mb-8'>
124
+ <main className='page-main'>
125
+ <nav className='breadcrumb'>
132
126
  <Link to='/' className='link'>
133
127
  Home
134
128
  </Link>
@@ -137,32 +131,32 @@ function CategoryPage() {
137
131
  Categories
138
132
  </Link>
139
133
  <span>/</span>
140
- <span className='text-gray-900'>{categoryLabel}</span>
134
+ <span className='breadcrumb-current'>{categoryLabel}</span>
141
135
  </nav>
142
136
 
143
- {/* Header */}
144
- <div className='mb-8'>
145
- <div className='flex items-center gap-3 mb-2'>
146
- <span className='text-5xl'>{icon}</span>
147
- <h1 className='section-heading mb-0'>{categoryLabel}</h1>
137
+ <div className='page-intro'>
138
+ <div className='category-header'>
139
+ <span className='category-header-icon'>{icon}</span>
140
+ <h1 className='section-heading section-heading-flush'>
141
+ {categoryLabel}
142
+ </h1>
148
143
  </div>
149
144
  <p className='section-subheading'>
150
145
  {products.length} products in this category
151
146
  </p>
152
147
  </div>
153
148
 
154
- {/* Controls */}
155
- <div className='flex flex-wrap items-center gap-4 mb-8 p-6 bg-white rounded-xl shadow-card'>
149
+ <div className='filter-bar'>
156
150
  <input
157
151
  type='search'
158
152
  placeholder='Search in this category...'
159
- className='input flex-1 min-w-[250px]'
153
+ className='input input-grow'
160
154
  value={searchQuery}
161
155
  onChange={(e) => setSearchQuery(e.target.value)}
162
156
  />
163
157
 
164
158
  <select
165
- className='select min-w-[200px]'
159
+ className='select select-min'
166
160
  value={sortBy}
167
161
  onChange={(e) => setSortBy(e.target.value as SortOption)}
168
162
  >
@@ -173,30 +167,31 @@ function CategoryPage() {
173
167
  </select>
174
168
 
175
169
  {!loading && (
176
- <div className='ml-auto text-sm text-gray-600'>
170
+ <div className='filter-count'>
177
171
  Showing {filteredProducts.length} of {products.length} products
178
172
  </div>
179
173
  )}
180
174
  </div>
181
175
 
182
- {/* Products Grid */}
183
176
  {loading ? (
184
- <div className='text-center py-16 text-gray-600 text-lg'>
185
- <div className='animate-pulse'>Loading products...</div>
177
+ <div className='state-loading'>
178
+ <div className='state-loading-pulse'>Loading products...</div>
186
179
  </div>
187
180
  ) : error ? (
188
- <div className='text-center py-16 bg-red-50 text-red-600 text-lg rounded-xl'>
181
+ <div className='state-error'>
189
182
  {error}
190
- <div className='mt-4'>
191
- <Link to='/categories' className='link font-semibold'>
183
+ <div className='state-error-action'>
184
+ <Link to='/categories' className='link link-semibold'>
192
185
  ← Back to Categories
193
186
  </Link>
194
187
  </div>
195
188
  </div>
196
189
  ) : filteredProducts.length === 0 ? (
197
- <div className='text-center py-16 text-gray-600 text-lg'>
198
- <div className='text-6xl mb-4'>🔍</div>
199
- <div className='mb-4'>No products found matching your criteria</div>
190
+ <div className='state-empty'>
191
+ <div className='state-empty-icon'>🔍</div>
192
+ <div className='state-empty-action'>
193
+ No products found matching your criteria
194
+ </div>
200
195
  {searchQuery && (
201
196
  <button
202
197
  type='button'
@@ -79,10 +79,10 @@ function CategoriesIndexPage() {
79
79
  return (
80
80
  <>
81
81
  <Header />
82
- <main className='container-custom py-8'>
82
+ <main className='page-main'>
83
83
  <h1 className='section-heading'>Shop by Category</h1>
84
- <div className='text-center py-16 text-gray-600 text-lg'>
85
- <div className='animate-pulse'>Loading categories...</div>
84
+ <div className='state-loading'>
85
+ <div className='state-loading-pulse'>Loading categories...</div>
86
86
  </div>
87
87
  </main>
88
88
  </>
@@ -93,10 +93,8 @@ function CategoriesIndexPage() {
93
93
  return (
94
94
  <>
95
95
  <Header />
96
- <main className='container-custom py-8'>
97
- <div className='text-center py-16 bg-red-50 text-red-600 text-lg rounded-xl'>
98
- {error}
99
- </div>
96
+ <main className='page-main'>
97
+ <div className='state-error'>{error}</div>
100
98
  </main>
101
99
  </>
102
100
  );
@@ -106,8 +104,8 @@ function CategoriesIndexPage() {
106
104
  <>
107
105
  <Header />
108
106
 
109
- <main className='container-custom py-8'>
110
- <div className='mb-12'>
107
+ <main className='page-main'>
108
+ <div className='page-intro-lg'>
111
109
  <h1 className='section-heading'>Shop by Category</h1>
112
110
  <p className='section-subheading'>
113
111
  Browse curated collections and jump straight into your favorite
@@ -115,7 +113,7 @@ function CategoriesIndexPage() {
115
113
  </p>
116
114
  </div>
117
115
 
118
- <div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-8 mb-12'>
116
+ <div className='category-grid'>
119
117
  {categories.map((category) => {
120
118
  const label = formatCategoryLabel(category);
121
119
  const description =
@@ -127,14 +125,12 @@ function CategoriesIndexPage() {
127
125
  <Link
128
126
  key={category}
129
127
  to={to}
130
- className='card card-hover group p-8 no-underline text-gray-900 block'
128
+ className='card card-hover category-card'
131
129
  >
132
- <div className='text-5xl mb-4'>{icon}</div>
133
- <h2 className='text-2xl font-bold mb-2 capitalize group-hover:text-primary-600 transition-colors'>
134
- {label}
135
- </h2>
136
- <p className='text-gray-600 text-sm mb-4'>{description}</p>
137
- <span className='inline-flex items-center gap-2 btn-primary btn-sm'>
130
+ <div className='category-card-icon'>{icon}</div>
131
+ <h2 className='category-card-title'>{label}</h2>
132
+ <p className='category-card-desc'>{description}</p>
133
+ <span className='category-card-cta btn-primary btn-sm'>
138
134
  View Products <span aria-hidden='true'>→</span>
139
135
  </span>
140
136
  </Link>
@@ -142,11 +138,9 @@ function CategoriesIndexPage() {
142
138
  })}
143
139
  </div>
144
140
 
145
- <div className='mt-16 p-8 bg-gray-50 rounded-xl text-center'>
146
- <h3 className='text-2xl font-bold mb-6 text-gray-900'>
147
- Why Shop With Us?
148
- </h3>
149
- <div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-8'>
141
+ <div className='why-shop'>
142
+ <h3 className='why-shop-title'>Why Shop With Us?</h3>
143
+ <div className='why-shop-grid'>
150
144
  {[
151
145
  {
152
146
  icon: '🚚',
@@ -170,11 +164,9 @@ function CategoriesIndexPage() {
170
164
  },
171
165
  ].map((item) => (
172
166
  <div key={item.title}>
173
- <div className='text-4xl mb-2'>{item.icon}</div>
174
- <div className='font-semibold text-gray-700 mb-1'>
175
- {item.title}
176
- </div>
177
- <div className='text-sm text-gray-600'>{item.desc}</div>
167
+ <div className='why-shop-item-icon'>{item.icon}</div>
168
+ <div className='why-shop-item-title'>{item.title}</div>
169
+ <div className='why-shop-item-desc'>{item.desc}</div>
178
170
  </div>
179
171
  ))}
180
172
  </div>
@@ -30,16 +30,16 @@ function HomePage() {
30
30
  <>
31
31
  <Header />
32
32
 
33
- <main className='container-custom py-8'>
34
- {/* Hero Section */}
35
- <section className='text-center py-12 mb-12 animate-slide-up'>
36
- <h1 className='text-5xl md:text-6xl font-bold text-gray-900 mb-4 leading-tight'>
33
+ <main className='page-main'>
34
+ <section className='hero animate-slide-up'>
35
+ <h1 className='hero-title'>
37
36
  Welcome to {import.meta.env.REROUTE_SITE_NAME || 'Reroute Store'}
38
37
  </h1>
39
- <p className='text-xl text-gray-600 mb-8 max-w-2xl mx-auto'>
40
- {import.meta.env.REROUTE_SITE_DESCRIPTION || 'A modern e-commerce demo built with Reroute, showcasing file-based routing, SSR, and seamless API integration with FakeStoreAPI'}
38
+ <p className='hero-lead'>
39
+ {import.meta.env.REROUTE_SITE_DESCRIPTION ||
40
+ 'A modern e-commerce demo built with Reroute, showcasing file-based routing, SSR, and seamless API integration with FakeStoreAPI'}
41
41
  </p>
42
- <div className='flex gap-4 justify-center flex-wrap'>
42
+ <div className='hero-actions'>
43
43
  <Link to='/products' className='btn-primary btn-lg'>
44
44
  Shop Now
45
45
  </Link>
@@ -49,19 +49,18 @@ function HomePage() {
49
49
  </div>
50
50
  </section>
51
51
 
52
- {/* Featured Products */}
53
- <section className='mb-16'>
54
- <div className='flex justify-between items-center mb-6'>
55
- <h2 className='section-heading mb-0'>Featured Products</h2>
56
- <Link to='/products' className='link font-semibold text-lg'>
52
+ <section className='section-block'>
53
+ <div className='section-header'>
54
+ <h2 className='section-heading section-heading-flush'>
55
+ Featured Products
56
+ </h2>
57
+ <Link to='/products' className='link link-semibold link-lg'>
57
58
  View All →
58
59
  </Link>
59
60
  </div>
60
61
 
61
62
  {error ? (
62
- <div className='text-center py-12 bg-red-50 text-red-600 text-lg rounded-xl'>
63
- {error}
64
- </div>
63
+ <div className='state-error'>{error}</div>
65
64
  ) : (
66
65
  <div className='product-grid'>
67
66
  {featuredProducts.map((product) => (
@@ -71,46 +70,37 @@ function HomePage() {
71
70
  )}
72
71
  </section>
73
72
 
74
- {/* Features */}
75
- <section className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 mt-12 pt-8'>
73
+ <section className='features-grid'>
76
74
  <div className='feature-card'>
77
- <div className='text-5xl mb-4'>⚡</div>
78
- <h3 className='text-xl font-semibold mb-2 text-gray-900'>
79
- Lightning Fast
80
- </h3>
81
- <p className='text-gray-600 leading-relaxed'>
75
+ <div className='feature-icon'>⚡</div>
76
+ <h3 className='feature-title'>Lightning Fast</h3>
77
+ <p className='feature-text'>
82
78
  Built on Bun for blazing fast performance, server-side rendering
83
79
  and image caching
84
80
  </p>
85
81
  </div>
86
82
 
87
83
  <div className='feature-card'>
88
- <div className='text-5xl mb-4'>🎯</div>
89
- <h3 className='text-xl font-semibold mb-2 text-gray-900'>
90
- File-Based Routing
91
- </h3>
92
- <p className='text-gray-600 leading-relaxed'>
84
+ <div className='feature-icon'>🎯</div>
85
+ <h3 className='feature-title'>File-Based Routing</h3>
86
+ <p className='feature-text'>
93
87
  Automatic route generation from your file structure with zero
94
88
  configuration
95
89
  </p>
96
90
  </div>
97
91
 
98
92
  <div className='feature-card'>
99
- <div className='text-5xl mb-4'>🔄</div>
100
- <h3 className='text-xl font-semibold mb-2 text-gray-900'>
101
- SSR Support
102
- </h3>
103
- <p className='text-gray-600 leading-relaxed'>
93
+ <div className='feature-icon'>🔄</div>
94
+ <h3 className='feature-title'>SSR Support</h3>
95
+ <p className='feature-text'>
104
96
  SEO-friendly with automatic hydration
105
97
  </p>
106
98
  </div>
107
99
 
108
100
  <div className='feature-card'>
109
- <div className='text-5xl mb-4'>📦</div>
110
- <h3 className='text-xl font-semibold mb-2 text-gray-900'>
111
- API Integration
112
- </h3>
113
- <p className='text-gray-600 leading-relaxed'>
101
+ <div className='feature-icon'>📦</div>
102
+ <h3 className='feature-title'>API Integration</h3>
103
+ <p className='feature-text'>
114
104
  Seamless integration with external APIs using serializable
115
105
  responses
116
106
  </p>