revine 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -81
- package/dist/commands/createProject.js +20 -2
- package/dist/config/package.js +4 -0
- package/dist/index.js +64 -2
- package/dist/prompts/project.js +11 -8
- package/dist/runtime/bundler/defaults/vite.js +17 -0
- package/dist/runtime/bundler/generateConfig.js +27 -0
- package/dist/runtime/bundler/revinePlugin.js +68 -0
- package/dist/runtime/bundler/utils/loadUserConfig.js +20 -0
- package/dist/runtime/bundler/vite.config.js +7 -0
- package/dist/runtime/bundler/viteLoggerPlugin.js +27 -0
- package/dist/runtime/routing/fileBased.js +29 -0
- package/dist/setup/dependencies.js +8 -0
- package/dist/setup/tailwind.js +128 -133
- package/package.json +44 -29
- package/src/commands/createProject.ts +88 -65
- package/src/config/package.ts +28 -23
- package/src/config/readme.ts +7 -7
- package/src/config/vite.ts +19 -19
- package/src/index.ts +91 -15
- package/src/prompts/git.ts +61 -61
- package/src/prompts/index.ts +3 -3
- package/src/prompts/project.ts +34 -31
- package/src/prompts/tailwind.ts +13 -13
- package/{template/.revine → src/runtime}/bundler/defaults/vite.ts +18 -18
- package/src/runtime/bundler/generateConfig.ts +36 -0
- package/src/runtime/bundler/revinePlugin.ts +71 -0
- package/src/runtime/bundler/utils/loadUserConfig.ts +19 -0
- package/{template/.revine → src/runtime}/bundler/vite.config.ts +8 -8
- package/{template/.revine → src/runtime}/bundler/viteLoggerPlugin.ts +33 -33
- package/{template/.revine → src/runtime}/routing/fileBased.tsx +46 -44
- package/src/setup/dependencies.ts +26 -16
- package/src/setup/tailwind.ts +151 -163
- package/src/utils/file.ts +9 -9
- package/src/utils/logger.ts +9 -9
- package/template/README.md +62 -62
- package/template/index.html +19 -19
- package/template/package.json +21 -24
- package/template/revine.config.ts +13 -13
- package/template/src/NotFound.tsx +13 -13
- package/template/src/pages/index.tsx +62 -62
- package/template/src/root.tsx +14 -14
- package/template/src/styles/global.css +191 -191
- package/template/tsconfig.json +20 -24
- package/tsconfig.json +15 -14
- package/dist/commands/create.js +0 -65
- package/dist/installers/dependencies.js +0 -15
- package/dist/lib/setup/directory.js +0 -21
- package/dist/lib/setup/package.js +0 -17
- package/dist/lib/setup/tailwind.js +0 -22
- package/dist/lib/utils/exec.js +0 -15
- package/dist/lib/utils/paths.js +0 -6
- package/template/.revine/bundler/generateConfig.ts +0 -18
- package/template/.revine/bundler/utils/loadUserConfig.ts +0 -13
- /package/{template/.revine → src/runtime}/bundler/types/vite-env.d.ts +0 -0
package/template/index.html
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<meta name="description" content="This project is built using Revine" />
|
|
7
|
-
<meta name="theme-color" content="#ffffff" />
|
|
8
|
-
<link rel="icon" href="/favicon.ico" />
|
|
9
|
-
<link rel="stylesheet" href="/assets/index.css" />
|
|
10
|
-
<title>Revine App</title>
|
|
11
|
-
</head>
|
|
12
|
-
<body>
|
|
13
|
-
<div id="root"></div>
|
|
14
|
-
<script type="module" src="/src/root.tsx"></script>
|
|
15
|
-
<noscript>
|
|
16
|
-
<h1>This application requires JavaScript to run.</h1>
|
|
17
|
-
</noscript>
|
|
18
|
-
</body>
|
|
19
|
-
</html>
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<meta name="description" content="This project is built using Revine" />
|
|
7
|
+
<meta name="theme-color" content="#ffffff" />
|
|
8
|
+
<link rel="icon" href="/favicon.ico" />
|
|
9
|
+
<link rel="stylesheet" href="/assets/index.css" />
|
|
10
|
+
<title>Revine App</title>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<div id="root"></div>
|
|
14
|
+
<script type="module" src="/src/root.tsx"></script>
|
|
15
|
+
<noscript>
|
|
16
|
+
<h1>This application requires JavaScript to run.</h1>
|
|
17
|
+
</noscript>
|
|
18
|
+
</body>
|
|
19
|
+
</html>
|
package/template/package.json
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{project-name}}",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
"react
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"@types/react
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"@types/lodash-es": "^4.17.9"
|
|
23
|
-
}
|
|
24
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "{{project-name}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "revine dev",
|
|
7
|
+
"build": "revine build",
|
|
8
|
+
"preview": "revine preview"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"revine": "latest",
|
|
12
|
+
"react": "^18.2.0",
|
|
13
|
+
"react-dom": "^18.2.0",
|
|
14
|
+
"react-router-dom": "^6.22.3"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/react": "^18.2.45",
|
|
18
|
+
"@types/react-dom": "^18.2.18",
|
|
19
|
+
"typescript": "^5.3.3"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
vite: {
|
|
3
|
-
server: {
|
|
4
|
-
open: true,
|
|
5
|
-
port: 3000,
|
|
6
|
-
host: true,
|
|
7
|
-
},
|
|
8
|
-
build: {
|
|
9
|
-
outDir: "build",
|
|
10
|
-
emptyOutDir: true,
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
};
|
|
1
|
+
export default {
|
|
2
|
+
vite: {
|
|
3
|
+
server: {
|
|
4
|
+
open: true,
|
|
5
|
+
port: 3000,
|
|
6
|
+
host: true,
|
|
7
|
+
},
|
|
8
|
+
build: {
|
|
9
|
+
outDir: "build",
|
|
10
|
+
emptyOutDir: true,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export default function NotFound() {
|
|
2
|
-
return (
|
|
3
|
-
<div className="notfound-container">
|
|
4
|
-
<div className="notfound-content">
|
|
5
|
-
<h1 className="notfound-title">404</h1>
|
|
6
|
-
<p className="notfound-text">Page Not Found</p>
|
|
7
|
-
<a href="/" className="notfound-link">
|
|
8
|
-
Go Back Home
|
|
9
|
-
</a>
|
|
10
|
-
</div>
|
|
11
|
-
</div>
|
|
12
|
-
);
|
|
13
|
-
}
|
|
1
|
+
export default function NotFound() {
|
|
2
|
+
return (
|
|
3
|
+
<div className="notfound-container">
|
|
4
|
+
<div className="notfound-content">
|
|
5
|
+
<h1 className="notfound-title">404</h1>
|
|
6
|
+
<p className="notfound-text">Page Not Found</p>
|
|
7
|
+
<a href="/" className="notfound-link">
|
|
8
|
+
Go Back Home
|
|
9
|
+
</a>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
export default function HomePage() {
|
|
2
|
-
return (
|
|
3
|
-
<main>
|
|
4
|
-
{/* Hero Section */}
|
|
5
|
-
<div>
|
|
6
|
-
<h1>
|
|
7
|
-
Welcome to <span>Revine</span>
|
|
8
|
-
</h1>
|
|
9
|
-
<p>The modern, powerful, and streamlined React framework.</p>
|
|
10
|
-
</div>
|
|
11
|
-
|
|
12
|
-
{/* CTA Buttons */}
|
|
13
|
-
<div className="cta">
|
|
14
|
-
<a href="#get-started" className="primary-btn">
|
|
15
|
-
Get Started
|
|
16
|
-
</a>
|
|
17
|
-
<a href="#docs" className="secondary-btn">
|
|
18
|
-
Read Docs
|
|
19
|
-
</a>
|
|
20
|
-
</div>
|
|
21
|
-
|
|
22
|
-
{/* Features Section */}
|
|
23
|
-
<div className="features">
|
|
24
|
-
<a href="#fast">
|
|
25
|
-
<h3>Lightning Fast</h3>
|
|
26
|
-
<p>Built on Vite for ultra-fast development and instant HMR.</p>
|
|
27
|
-
</a>
|
|
28
|
-
<a href="#routing">
|
|
29
|
-
<h3>Simple File-based Routing</h3>
|
|
30
|
-
<p>
|
|
31
|
-
Create pages in <code>src/pages</code> and Revine will handle the
|
|
32
|
-
rest.
|
|
33
|
-
</p>
|
|
34
|
-
</a>
|
|
35
|
-
<a href="#tailwind">
|
|
36
|
-
<h3>Tailwind Integration</h3>
|
|
37
|
-
<p>
|
|
38
|
-
Pre-configured for Tailwind CSS, so you can style quickly and
|
|
39
|
-
easily.
|
|
40
|
-
</p>
|
|
41
|
-
</a>
|
|
42
|
-
<a href="#dev-experience">
|
|
43
|
-
<h3>Great DX</h3>
|
|
44
|
-
<p>Minimal config, fast builds, custom logging, and more.</p>
|
|
45
|
-
</a>
|
|
46
|
-
<a href="#abstract">
|
|
47
|
-
<h3>Abstracted Internals</h3>
|
|
48
|
-
<p>
|
|
49
|
-
A .revine folder houses the complex Vite config. Keep your root
|
|
50
|
-
clean.
|
|
51
|
-
</p>
|
|
52
|
-
</a>
|
|
53
|
-
<a href="#customize">
|
|
54
|
-
<h3>Fully Customizable</h3>
|
|
55
|
-
<p>
|
|
56
|
-
Easily extend or override settings in <code>revine.config.ts</code>.
|
|
57
|
-
</p>
|
|
58
|
-
</a>
|
|
59
|
-
</div>
|
|
60
|
-
</main>
|
|
61
|
-
);
|
|
62
|
-
}
|
|
1
|
+
export default function HomePage() {
|
|
2
|
+
return (
|
|
3
|
+
<main>
|
|
4
|
+
{/* Hero Section */}
|
|
5
|
+
<div>
|
|
6
|
+
<h1>
|
|
7
|
+
Welcome to <span>Revine</span>
|
|
8
|
+
</h1>
|
|
9
|
+
<p>The modern, powerful, and streamlined React framework.</p>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
{/* CTA Buttons */}
|
|
13
|
+
<div className="cta">
|
|
14
|
+
<a href="#get-started" className="primary-btn">
|
|
15
|
+
Get Started
|
|
16
|
+
</a>
|
|
17
|
+
<a href="#docs" className="secondary-btn">
|
|
18
|
+
Read Docs
|
|
19
|
+
</a>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
{/* Features Section */}
|
|
23
|
+
<div className="features">
|
|
24
|
+
<a href="#fast">
|
|
25
|
+
<h3>Lightning Fast</h3>
|
|
26
|
+
<p>Built on Vite for ultra-fast development and instant HMR.</p>
|
|
27
|
+
</a>
|
|
28
|
+
<a href="#routing">
|
|
29
|
+
<h3>Simple File-based Routing</h3>
|
|
30
|
+
<p>
|
|
31
|
+
Create pages in <code>src/pages</code> and Revine will handle the
|
|
32
|
+
rest.
|
|
33
|
+
</p>
|
|
34
|
+
</a>
|
|
35
|
+
<a href="#tailwind">
|
|
36
|
+
<h3>Tailwind Integration</h3>
|
|
37
|
+
<p>
|
|
38
|
+
Pre-configured for Tailwind CSS, so you can style quickly and
|
|
39
|
+
easily.
|
|
40
|
+
</p>
|
|
41
|
+
</a>
|
|
42
|
+
<a href="#dev-experience">
|
|
43
|
+
<h3>Great DX</h3>
|
|
44
|
+
<p>Minimal config, fast builds, custom logging, and more.</p>
|
|
45
|
+
</a>
|
|
46
|
+
<a href="#abstract">
|
|
47
|
+
<h3>Abstracted Internals</h3>
|
|
48
|
+
<p>
|
|
49
|
+
A .revine folder houses the complex Vite config. Keep your root
|
|
50
|
+
clean.
|
|
51
|
+
</p>
|
|
52
|
+
</a>
|
|
53
|
+
<a href="#customize">
|
|
54
|
+
<h3>Fully Customizable</h3>
|
|
55
|
+
<p>
|
|
56
|
+
Easily extend or override settings in <code>revine.config.ts</code>.
|
|
57
|
+
</p>
|
|
58
|
+
</a>
|
|
59
|
+
</div>
|
|
60
|
+
</main>
|
|
61
|
+
);
|
|
62
|
+
}
|
package/template/src/root.tsx
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { createRoot } from "react-dom/client";
|
|
3
|
-
import { RouterProvider } from "react-router-dom";
|
|
4
|
-
import { router } from "
|
|
5
|
-
import "./styles/global.css";
|
|
6
|
-
|
|
7
|
-
const container = document.getElementById("root")!;
|
|
8
|
-
const root = createRoot(container);
|
|
9
|
-
|
|
10
|
-
root.render(
|
|
11
|
-
<React.StrictMode>
|
|
12
|
-
<RouterProvider router={router} />;
|
|
13
|
-
</React.StrictMode>
|
|
14
|
-
);
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import { RouterProvider } from "react-router-dom";
|
|
4
|
+
import { router } from "revine/routing";
|
|
5
|
+
import "./styles/global.css";
|
|
6
|
+
|
|
7
|
+
const container = document.getElementById("root")!;
|
|
8
|
+
const root = createRoot(container);
|
|
9
|
+
|
|
10
|
+
root.render(
|
|
11
|
+
<React.StrictMode>
|
|
12
|
+
<RouterProvider router={router} />;
|
|
13
|
+
</React.StrictMode>
|
|
14
|
+
);
|
|
@@ -1,191 +1,191 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
--gradient-from: #ffffff;
|
|
3
|
-
--gradient-via: #ffffff;
|
|
4
|
-
--gradient-to: #d1d5db;
|
|
5
|
-
|
|
6
|
-
--text-primary: #111827;
|
|
7
|
-
--text-secondary: #4b5563;
|
|
8
|
-
--background-primary: #ffffff;
|
|
9
|
-
--border-color: #d1d5db;
|
|
10
|
-
|
|
11
|
-
--primary-color: #4f46e5;
|
|
12
|
-
--primary-hover: #4338ca;
|
|
13
|
-
--button-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
|
14
|
-
--button-hover-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
body {
|
|
18
|
-
margin: 0;
|
|
19
|
-
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
20
|
-
"Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif;
|
|
21
|
-
line-height: 1.5;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
main {
|
|
25
|
-
display: flex;
|
|
26
|
-
min-height: 100vh;
|
|
27
|
-
flex-direction: column;
|
|
28
|
-
align-items: center;
|
|
29
|
-
justify-content: center;
|
|
30
|
-
padding: 1.5rem;
|
|
31
|
-
background: linear-gradient(
|
|
32
|
-
to bottom,
|
|
33
|
-
var(--gradient-from),
|
|
34
|
-
var(--gradient-via),
|
|
35
|
-
var(--gradient-to)
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
h1 {
|
|
40
|
-
font-size: 3rem;
|
|
41
|
-
line-height: 1.25;
|
|
42
|
-
font-weight: 800;
|
|
43
|
-
color: var(--text-primary);
|
|
44
|
-
text-align: center;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
h1 span {
|
|
48
|
-
background: linear-gradient(
|
|
49
|
-
to right,
|
|
50
|
-
var(--primary-color),
|
|
51
|
-
var(--primary-hover),
|
|
52
|
-
#000
|
|
53
|
-
);
|
|
54
|
-
-webkit-background-clip: text;
|
|
55
|
-
color: transparent;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
p {
|
|
59
|
-
font-size: 1.25rem;
|
|
60
|
-
color: var(--text-secondary);
|
|
61
|
-
text-align: center;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.cta {
|
|
65
|
-
display: flex;
|
|
66
|
-
gap: 1rem;
|
|
67
|
-
margin-top: 2rem;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.cta a {
|
|
71
|
-
padding: 0.75rem 1.5rem;
|
|
72
|
-
border-radius: 0.375rem;
|
|
73
|
-
font-weight: 600;
|
|
74
|
-
text-align: center;
|
|
75
|
-
text-decoration: none;
|
|
76
|
-
display: inline-block;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
.cta .primary-btn {
|
|
80
|
-
background-color: var(--primary-color);
|
|
81
|
-
color: white;
|
|
82
|
-
box-shadow: var(--button-shadow);
|
|
83
|
-
transition: background-color 0.2s, box-shadow 0.2s;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.cta .primary-btn:hover {
|
|
87
|
-
background-color: var(--primary-hover);
|
|
88
|
-
box-shadow: var(--button-hover-shadow);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.cta .secondary-btn {
|
|
92
|
-
background-color: var(--background-primary);
|
|
93
|
-
color: var(--primary-color);
|
|
94
|
-
border: 1px solid var(--border-color);
|
|
95
|
-
box-shadow: var(--button-shadow);
|
|
96
|
-
transition: background-color 0.2s, box-shadow 0.2s;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.cta .secondary-btn:hover {
|
|
100
|
-
background-color: #f9fafb;
|
|
101
|
-
box-shadow: var(--button-hover-shadow);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.features {
|
|
105
|
-
display: grid;
|
|
106
|
-
grid-template-columns: repeat(1, 1fr);
|
|
107
|
-
gap: 1.5rem;
|
|
108
|
-
margin-top: 3rem;
|
|
109
|
-
max-width: 64rem;
|
|
110
|
-
width: 100%;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
@media (min-width: 640px) {
|
|
114
|
-
.features {
|
|
115
|
-
grid-template-columns: repeat(2, 1fr);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
@media (min-width: 1024px) {
|
|
120
|
-
.features {
|
|
121
|
-
grid-template-columns: repeat(3, 1fr);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.features a {
|
|
126
|
-
display: block;
|
|
127
|
-
padding: 1.5rem;
|
|
128
|
-
border: 1px solid var(--border-color);
|
|
129
|
-
border-radius: 0.75rem;
|
|
130
|
-
background-color: var(--background-primary);
|
|
131
|
-
text-decoration: none;
|
|
132
|
-
transition: box-shadow 0.2s, transform 0.2s;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
.features a:hover {
|
|
136
|
-
box-shadow: var(--button-hover-shadow);
|
|
137
|
-
transform: translateY(-0.25rem);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
.features h3 {
|
|
141
|
-
margin-bottom: 0.5rem;
|
|
142
|
-
font-size: 1.125rem;
|
|
143
|
-
font-weight: 600;
|
|
144
|
-
color: var(--text-primary);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.features p {
|
|
148
|
-
font-size: 0.875rem;
|
|
149
|
-
color: var(--text-secondary);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/* notfound.css */
|
|
153
|
-
.notfound-container {
|
|
154
|
-
min-height: 100vh;
|
|
155
|
-
display: flex;
|
|
156
|
-
align-items: center;
|
|
157
|
-
justify-content: center;
|
|
158
|
-
background-color: #f5f5f5; /* Light gray */
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
.notfound-content {
|
|
162
|
-
text-align: center;
|
|
163
|
-
margin: auto;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.notfound-title {
|
|
167
|
-
font-size: 4rem; /* 64px */
|
|
168
|
-
font-weight: bold;
|
|
169
|
-
color: #1a202c; /* Gray-900 */
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
.notfound-text {
|
|
173
|
-
font-size: 1.25rem; /* 20px */
|
|
174
|
-
color: #4a5568; /* Gray-600 */
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
.notfound-link {
|
|
178
|
-
margin-top: 1.5rem;
|
|
179
|
-
display: inline-block;
|
|
180
|
-
padding: 0.75rem 1.5rem;
|
|
181
|
-
font-weight: 600;
|
|
182
|
-
background-color: #5a67d8; /* Indigo-600 */
|
|
183
|
-
color: #ffffff;
|
|
184
|
-
text-decoration: none;
|
|
185
|
-
border-radius: 0.375rem;
|
|
186
|
-
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
.notfound-link:hover {
|
|
190
|
-
background-color: #4c51bf; /* Indigo-700 */
|
|
191
|
-
}
|
|
1
|
+
:root {
|
|
2
|
+
--gradient-from: #ffffff;
|
|
3
|
+
--gradient-via: #ffffff;
|
|
4
|
+
--gradient-to: #d1d5db;
|
|
5
|
+
|
|
6
|
+
--text-primary: #111827;
|
|
7
|
+
--text-secondary: #4b5563;
|
|
8
|
+
--background-primary: #ffffff;
|
|
9
|
+
--border-color: #d1d5db;
|
|
10
|
+
|
|
11
|
+
--primary-color: #4f46e5;
|
|
12
|
+
--primary-hover: #4338ca;
|
|
13
|
+
--button-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
|
14
|
+
--button-hover-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
body {
|
|
18
|
+
margin: 0;
|
|
19
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
20
|
+
"Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif;
|
|
21
|
+
line-height: 1.5;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
main {
|
|
25
|
+
display: flex;
|
|
26
|
+
min-height: 100vh;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
align-items: center;
|
|
29
|
+
justify-content: center;
|
|
30
|
+
padding: 1.5rem;
|
|
31
|
+
background: linear-gradient(
|
|
32
|
+
to bottom,
|
|
33
|
+
var(--gradient-from),
|
|
34
|
+
var(--gradient-via),
|
|
35
|
+
var(--gradient-to)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
h1 {
|
|
40
|
+
font-size: 3rem;
|
|
41
|
+
line-height: 1.25;
|
|
42
|
+
font-weight: 800;
|
|
43
|
+
color: var(--text-primary);
|
|
44
|
+
text-align: center;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
h1 span {
|
|
48
|
+
background: linear-gradient(
|
|
49
|
+
to right,
|
|
50
|
+
var(--primary-color),
|
|
51
|
+
var(--primary-hover),
|
|
52
|
+
#000
|
|
53
|
+
);
|
|
54
|
+
-webkit-background-clip: text;
|
|
55
|
+
color: transparent;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
p {
|
|
59
|
+
font-size: 1.25rem;
|
|
60
|
+
color: var(--text-secondary);
|
|
61
|
+
text-align: center;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.cta {
|
|
65
|
+
display: flex;
|
|
66
|
+
gap: 1rem;
|
|
67
|
+
margin-top: 2rem;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.cta a {
|
|
71
|
+
padding: 0.75rem 1.5rem;
|
|
72
|
+
border-radius: 0.375rem;
|
|
73
|
+
font-weight: 600;
|
|
74
|
+
text-align: center;
|
|
75
|
+
text-decoration: none;
|
|
76
|
+
display: inline-block;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.cta .primary-btn {
|
|
80
|
+
background-color: var(--primary-color);
|
|
81
|
+
color: white;
|
|
82
|
+
box-shadow: var(--button-shadow);
|
|
83
|
+
transition: background-color 0.2s, box-shadow 0.2s;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.cta .primary-btn:hover {
|
|
87
|
+
background-color: var(--primary-hover);
|
|
88
|
+
box-shadow: var(--button-hover-shadow);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.cta .secondary-btn {
|
|
92
|
+
background-color: var(--background-primary);
|
|
93
|
+
color: var(--primary-color);
|
|
94
|
+
border: 1px solid var(--border-color);
|
|
95
|
+
box-shadow: var(--button-shadow);
|
|
96
|
+
transition: background-color 0.2s, box-shadow 0.2s;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.cta .secondary-btn:hover {
|
|
100
|
+
background-color: #f9fafb;
|
|
101
|
+
box-shadow: var(--button-hover-shadow);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.features {
|
|
105
|
+
display: grid;
|
|
106
|
+
grid-template-columns: repeat(1, 1fr);
|
|
107
|
+
gap: 1.5rem;
|
|
108
|
+
margin-top: 3rem;
|
|
109
|
+
max-width: 64rem;
|
|
110
|
+
width: 100%;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@media (min-width: 640px) {
|
|
114
|
+
.features {
|
|
115
|
+
grid-template-columns: repeat(2, 1fr);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@media (min-width: 1024px) {
|
|
120
|
+
.features {
|
|
121
|
+
grid-template-columns: repeat(3, 1fr);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.features a {
|
|
126
|
+
display: block;
|
|
127
|
+
padding: 1.5rem;
|
|
128
|
+
border: 1px solid var(--border-color);
|
|
129
|
+
border-radius: 0.75rem;
|
|
130
|
+
background-color: var(--background-primary);
|
|
131
|
+
text-decoration: none;
|
|
132
|
+
transition: box-shadow 0.2s, transform 0.2s;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.features a:hover {
|
|
136
|
+
box-shadow: var(--button-hover-shadow);
|
|
137
|
+
transform: translateY(-0.25rem);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.features h3 {
|
|
141
|
+
margin-bottom: 0.5rem;
|
|
142
|
+
font-size: 1.125rem;
|
|
143
|
+
font-weight: 600;
|
|
144
|
+
color: var(--text-primary);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.features p {
|
|
148
|
+
font-size: 0.875rem;
|
|
149
|
+
color: var(--text-secondary);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* notfound.css */
|
|
153
|
+
.notfound-container {
|
|
154
|
+
min-height: 100vh;
|
|
155
|
+
display: flex;
|
|
156
|
+
align-items: center;
|
|
157
|
+
justify-content: center;
|
|
158
|
+
background-color: #f5f5f5; /* Light gray */
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.notfound-content {
|
|
162
|
+
text-align: center;
|
|
163
|
+
margin: auto;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.notfound-title {
|
|
167
|
+
font-size: 4rem; /* 64px */
|
|
168
|
+
font-weight: bold;
|
|
169
|
+
color: #1a202c; /* Gray-900 */
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.notfound-text {
|
|
173
|
+
font-size: 1.25rem; /* 20px */
|
|
174
|
+
color: #4a5568; /* Gray-600 */
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.notfound-link {
|
|
178
|
+
margin-top: 1.5rem;
|
|
179
|
+
display: inline-block;
|
|
180
|
+
padding: 0.75rem 1.5rem;
|
|
181
|
+
font-weight: 600;
|
|
182
|
+
background-color: #5a67d8; /* Indigo-600 */
|
|
183
|
+
color: #ffffff;
|
|
184
|
+
text-decoration: none;
|
|
185
|
+
border-radius: 0.375rem;
|
|
186
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.notfound-link:hover {
|
|
190
|
+
background-color: #4c51bf; /* Indigo-700 */
|
|
191
|
+
}
|