inital
This commit is contained in:
commit
424068648a
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules
|
12
craco.config.js
Normal file
12
craco.config.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
style: {
|
||||||
|
postcss: {
|
||||||
|
plugins: [
|
||||||
|
require('tailwindcss'),
|
||||||
|
require('autoprefixer'),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
17
index.html
Normal file
17
index.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>NebulaOS - The Future of Android</title>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
|
||||||
|
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
|
||||||
|
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
|
||||||
|
<script type="text/babel" src="src/App.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
26910
package-lock.json
generated
Normal file
26910
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
37
package.json
Normal file
37
package.json
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "nebulaos-site",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Website for NebulaOS Android operating system",
|
||||||
|
"main": "src/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "react-scripts --openssl-legacy-provider start",
|
||||||
|
"build": "react-scripts --openssl-legacy-provider build",
|
||||||
|
"test": "react-scripts test",
|
||||||
|
"eject": "react-scripts eject"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"framer-motion": "^4.1.17",
|
||||||
|
"react": "^17.0.2",
|
||||||
|
"react-dom": "^17.0.2",
|
||||||
|
"react-icons": "^4.2.0",
|
||||||
|
"react-router-dom": "^6.26.2",
|
||||||
|
"react-scroll": "^1.9.0",
|
||||||
|
"web-vitals": "^1.1.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||||
|
"react-scripts": "4.0.3"
|
||||||
|
},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 1 chrome version",
|
||||||
|
"last 1 firefox version",
|
||||||
|
"last 1 safari version"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
6
postcss.config.js
Normal file
6
postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
require('tailwindcss'),
|
||||||
|
require('autoprefixer'),
|
||||||
|
]
|
||||||
|
}
|
27
public/index.html
Normal file
27
public/index.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="theme-color" content="#000000" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="NebulaOS - The Future of Android"
|
||||||
|
/>
|
||||||
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
|
<title>NebulaOS - The Future of Android</title>
|
||||||
|
<script>
|
||||||
|
window.process = {
|
||||||
|
env: {
|
||||||
|
NODE_ENV: 'development'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
38
src/App.js
Normal file
38
src/App.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import Header from './components/Header';
|
||||||
|
import Hero from './components/Hero';
|
||||||
|
import Features from './components/Features';
|
||||||
|
import Footer from './components/Footer';
|
||||||
|
import Download from './pages/Download';
|
||||||
|
import Donate from './pages/Donate'; // Renamed from Support
|
||||||
|
import styles from './App.module.css';
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<Router>
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className={styles.app}
|
||||||
|
>
|
||||||
|
<Header />
|
||||||
|
<Routes>
|
||||||
|
<Route path="/" element={
|
||||||
|
<main className={styles.main}>
|
||||||
|
<Hero />
|
||||||
|
<Features />
|
||||||
|
</main>
|
||||||
|
} />
|
||||||
|
<Route path="/download" element={<Download />} />
|
||||||
|
<Route path="/donate" element={<Donate />} /> {/* Changed to Donate */}
|
||||||
|
</Routes>
|
||||||
|
<Footer />
|
||||||
|
</motion.div>
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
9
src/App.module.css
Normal file
9
src/App.module.css
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.app {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #1a202c;
|
||||||
|
color: #f0f4f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
padding: 2rem 0;
|
||||||
|
}
|
16
src/components/Download.js
Normal file
16
src/components/Download.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
function Download() {
|
||||||
|
return (
|
||||||
|
<section id="download" className="py-20 bg-gray-100">
|
||||||
|
<div className="container mx-auto px-4 text-center">
|
||||||
|
<h2 className="text-4xl font-bold mb-8">Download NebulaOS</h2>
|
||||||
|
<p className="text-xl mb-8">Experience the next generation of Android on your device today.</p>
|
||||||
|
<a href="#" className="bg-purple-700 text-white px-8 py-3 rounded-full font-semibold hover:bg-purple-800 transition duration-300">Download Now</a>
|
||||||
|
<p className="mt-4 text-sm text-gray-600">Compatible with most Android devices</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Download;
|
65
src/components/Features.js
Normal file
65
src/components/Features.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import styles from './Features.module.css';
|
||||||
|
|
||||||
|
const features = [
|
||||||
|
{ title: 'Sleek Design', description: 'Modern and intuitive user interface' },
|
||||||
|
{ title: 'Enhanced Performance', description: 'Optimized for speed and efficiency' },
|
||||||
|
{ title: 'Advanced Security', description: 'Cutting-edge protection for your device' },
|
||||||
|
{ title: 'Customization', description: 'Tailor your experience to your preferences' },
|
||||||
|
];
|
||||||
|
|
||||||
|
function Features() {
|
||||||
|
const starryBackgroundRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const starryBackground = starryBackgroundRef.current;
|
||||||
|
const numberOfStars = 100;
|
||||||
|
|
||||||
|
for (let i = 0; i < numberOfStars; i++) {
|
||||||
|
const star = document.createElement('div');
|
||||||
|
star.className = styles.star;
|
||||||
|
star.style.width = `${Math.random() * 3}px`;
|
||||||
|
star.style.height = star.style.width;
|
||||||
|
star.style.left = `${Math.random() * 100}%`;
|
||||||
|
star.style.top = `${Math.random() * 100}%`;
|
||||||
|
star.style.animationDelay = `${Math.random() * 4}s`;
|
||||||
|
starryBackground.appendChild(star);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section id="features" className={styles.features}>
|
||||||
|
<div ref={starryBackgroundRef} className={styles.starryBackground}></div>
|
||||||
|
<div className={styles.floatingElement}></div>
|
||||||
|
<div className={styles.floatingElement}></div>
|
||||||
|
<div className={styles.floatingElement}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<motion.h2
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className={styles.title}
|
||||||
|
>
|
||||||
|
Key Features
|
||||||
|
</motion.h2>
|
||||||
|
<div className={styles.featureGrid}>
|
||||||
|
{features.map((feature, index) => (
|
||||||
|
<motion.div
|
||||||
|
key={index}
|
||||||
|
className={styles.featureCard}
|
||||||
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.5, delay: index * 0.1 }}
|
||||||
|
>
|
||||||
|
<h3>{feature.title}</h3>
|
||||||
|
<p>{feature.description}</p>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Features;
|
112
src/components/Features.module.css
Normal file
112
src/components/Features.module.css
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
.features {
|
||||||
|
background: linear-gradient(135deg, rgba(26, 32, 44, 0.9) 0%, rgba(45, 55, 72, 0.9) 100%);
|
||||||
|
padding: 2rem 0; /* Reduced padding */
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.starryBackground {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.star {
|
||||||
|
position: absolute;
|
||||||
|
background: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
opacity: 0.3;
|
||||||
|
animation: twinkle 4s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes twinkle {
|
||||||
|
0%, 100% { opacity: 0.3; }
|
||||||
|
50% { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement {
|
||||||
|
position: absolute;
|
||||||
|
background: linear-gradient(135deg, rgba(129, 230, 217, 0.2), rgba(79, 209, 197, 0.2));
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
box-shadow: 0 0 20px rgba(129, 230, 217, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement:nth-child(2) {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
top: 20%;
|
||||||
|
right: 10%;
|
||||||
|
animation: float 12s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement:nth-child(3) {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
bottom: 15%;
|
||||||
|
left: 5%;
|
||||||
|
animation: float 10s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement:nth-child(4) {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
top: 40%;
|
||||||
|
left: 15%;
|
||||||
|
animation: float 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translate(0, 0) rotate(0deg); }
|
||||||
|
25% { transform: translate(10px, -10px) rotate(5deg); }
|
||||||
|
50% { transform: translate(0, -20px) rotate(0deg); }
|
||||||
|
75% { transform: translate(-10px, -10px) rotate(-5deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 2rem; /* Reduced font size */
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1.5rem; /* Reduced margin */
|
||||||
|
color: #81e6d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); /* Reduced minmax width */
|
||||||
|
gap: 1.5rem; /* Reduced gap */
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureCard {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 1rem; /* Reduced padding */
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureCard:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureCard h3 {
|
||||||
|
font-size: 1.3rem; /* Reduced font size */
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
color: #81e6d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.featureCard p {
|
||||||
|
font-size: 0.9rem; /* Reduced font size */
|
||||||
|
color: #e2e8f0;
|
||||||
|
}
|
39
src/components/Footer.js
Normal file
39
src/components/Footer.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styles from './Footer.module.css';
|
||||||
|
|
||||||
|
function Footer() {
|
||||||
|
return (
|
||||||
|
<footer className={styles.footer}>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<div className={styles.section}>
|
||||||
|
<h3>NebulaOS</h3>
|
||||||
|
<p>Revolutionizing mobile experiences</p>
|
||||||
|
</div>
|
||||||
|
<div className={styles.section}>
|
||||||
|
<h4>Resources</h4>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#features">Features</a></li>
|
||||||
|
<li><a href="#download">Download</a></li>
|
||||||
|
<li><a href="#support">Support</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div className={styles.section}>
|
||||||
|
<h4>Connect</h4>
|
||||||
|
<ul>
|
||||||
|
<li><a href="#">Twitter</a></li>
|
||||||
|
<li><a href="#">Facebook</a></li>
|
||||||
|
<li><a href="#">Instagram</a></li>
|
||||||
|
<li><a href="#">GitHub</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.copyright}>
|
||||||
|
<p>© 2024 NebulaOS. All rights reserved.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Footer;
|
61
src/components/Footer.module.css
Normal file
61
src/components/Footer.module.css
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
.footer {
|
||||||
|
background-color: #2d3748;
|
||||||
|
color: #e2e8f0;
|
||||||
|
padding: 4rem 0 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 200px;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h3 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: #81e6d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h4 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: #81e6d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section li {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section a {
|
||||||
|
color: #e2e8f0;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section a:hover {
|
||||||
|
color: #81e6d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 2rem;
|
||||||
|
padding-top: 2rem;
|
||||||
|
border-top: 1px solid #4a5568;
|
||||||
|
}
|
28
src/components/Header.js
Normal file
28
src/components/Header.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import styles from './Header.module.css';
|
||||||
|
|
||||||
|
function Header() {
|
||||||
|
return (
|
||||||
|
<motion.header
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className={styles.header}
|
||||||
|
>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<Link to="/" className={styles.logo}>NebulaOS</Link>
|
||||||
|
<nav className={styles.nav}>
|
||||||
|
<ul>
|
||||||
|
<li><Link to="/#features" className={styles.navLink}>Features</Link></li>
|
||||||
|
<li><Link to="/download" className={styles.navLink}>Download</Link></li>
|
||||||
|
<li><Link to="/donate" className={styles.navLink}>Donate</Link></li> {/* Changed to Donate */}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</motion.header>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Header;
|
68
src/components/Header.module.css
Normal file
68
src/components/Header.module.css
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
.header {
|
||||||
|
background: linear-gradient(to right, rgba(74, 85, 104, 0.7), rgba(45, 55, 72, 0.7));
|
||||||
|
color: white;
|
||||||
|
padding: 1rem 0;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: bold;
|
||||||
|
background: linear-gradient(45deg, #81e6d9, #4fd1c5, #38b2ac);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
text-shadow: 0 0 10px rgba(129, 230, 217, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav ul {
|
||||||
|
display: flex;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav li {
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav a, .navLink {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 9999px;
|
||||||
|
background: linear-gradient(45deg, rgba(129, 230, 217, 0.1), rgba(79, 209, 197, 0.1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav a:hover, .navLink:hover {
|
||||||
|
background: linear-gradient(45deg, rgba(129, 230, 217, 0.3), rgba(79, 209, 197, 0.3));
|
||||||
|
color: #81e6d9;
|
||||||
|
box-shadow: 0 0 15px rgba(129, 230, 217, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.themeToggle {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
71
src/components/Hero.js
Normal file
71
src/components/Hero.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import styles from './Hero.module.css';
|
||||||
|
|
||||||
|
function Hero() {
|
||||||
|
const starryBackgroundRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const starryBackground = starryBackgroundRef.current;
|
||||||
|
const numberOfStars = 100;
|
||||||
|
|
||||||
|
for (let i = 0; i < numberOfStars; i++) {
|
||||||
|
const star = document.createElement('div');
|
||||||
|
star.className = styles.star;
|
||||||
|
star.style.width = `${Math.random() * 3}px`;
|
||||||
|
star.style.height = star.style.width;
|
||||||
|
star.style.left = `${Math.random() * 100}%`;
|
||||||
|
star.style.top = `${Math.random() * 100}%`;
|
||||||
|
star.style.animationDelay = `${Math.random() * 4}s`;
|
||||||
|
starryBackground.appendChild(star);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.section
|
||||||
|
initial={{ opacity: 0, y: 50 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className={styles.hero}
|
||||||
|
>
|
||||||
|
<div ref={starryBackgroundRef} className={styles.starryBackground}></div>
|
||||||
|
<div className={styles.floatingElement}></div>
|
||||||
|
<div className={styles.floatingElement}></div>
|
||||||
|
<div className={styles.floatingElement}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<motion.h2
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ delay: 0.2, duration: 0.5 }}
|
||||||
|
className={styles.comingSoon}
|
||||||
|
>
|
||||||
|
Coming Soon
|
||||||
|
</motion.h2>
|
||||||
|
<motion.h1
|
||||||
|
initial={{ scale: 0.5 }}
|
||||||
|
animate={{ scale: 1 }}
|
||||||
|
transition={{ type: 'spring', stiffness: 260, damping: 20 }}
|
||||||
|
>
|
||||||
|
NebulaOS
|
||||||
|
</motion.h1>
|
||||||
|
<motion.p
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ delay: 0.4, duration: 0.5 }}
|
||||||
|
>
|
||||||
|
Get ready for the future of Android with our sleek and powerful operating system.
|
||||||
|
</motion.p>
|
||||||
|
<motion.div className={styles.ctaContainer}>
|
||||||
|
<Link to="/download" className={styles.cta}>
|
||||||
|
Download Beta
|
||||||
|
</Link>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Hero;
|
146
src/components/Hero.module.css
Normal file
146
src/components/Hero.module.css
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
.hero {
|
||||||
|
background: linear-gradient(135deg, rgba(26, 32, 44, 0.9) 0%, rgba(45, 55, 72, 0.9) 100%);
|
||||||
|
color: white;
|
||||||
|
padding: 2rem 0; /* Reduced padding */
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 60vh; /* Reduced height */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.starryBackground {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.star {
|
||||||
|
position: absolute;
|
||||||
|
background: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
opacity: 0.3;
|
||||||
|
animation: twinkle 4s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes twinkle {
|
||||||
|
0%, 100% { opacity: 0.3; }
|
||||||
|
50% { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement {
|
||||||
|
position: absolute;
|
||||||
|
background: linear-gradient(135deg, rgba(129, 230, 217, 0.2), rgba(79, 209, 197, 0.2));
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
box-shadow: 0 0 20px rgba(129, 230, 217, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement:nth-child(1) {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
top: 10%;
|
||||||
|
left: 10%;
|
||||||
|
animation: float 12s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement:nth-child(2) {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
top: 20%;
|
||||||
|
right: 20%;
|
||||||
|
animation: float 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement:nth-child(3) {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
bottom: 15%;
|
||||||
|
left: 15%;
|
||||||
|
animation: float 10s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translate(0, 0) rotate(0deg); }
|
||||||
|
25% { transform: translate(10px, -10px) rotate(5deg); }
|
||||||
|
50% { transform: translate(0, -20px) rotate(0deg); }
|
||||||
|
75% { transform: translate(-10px, -10px) rotate(-5deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 2rem;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
|
||||||
|
padding: 1.5rem; /* Reduced padding */
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 8px 32px rgba(31, 38, 135, 0.2);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||||
|
transform: translateY(0); /* Remove vertical translation */
|
||||||
|
}
|
||||||
|
|
||||||
|
.content h1 {
|
||||||
|
font-size: 3.5rem; /* Reduced font size */
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background: linear-gradient(45deg, #ffffff, #81e6d9, #4fd1c5);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.comingSoon {
|
||||||
|
font-size: 1.5rem; /* Reduced font size */
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
color: #81e6d9;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content p {
|
||||||
|
font-size: 1.1rem; /* Reduced font size */
|
||||||
|
margin-bottom: 1.5rem; /* Reduced margin */
|
||||||
|
text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctaContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 1rem; /* Add gap between buttons */
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta {
|
||||||
|
display: inline-block;
|
||||||
|
background: linear-gradient(45deg, rgba(129, 230, 217, 0.8), rgba(79, 209, 197, 0.8));
|
||||||
|
color: #2d3748;
|
||||||
|
padding: 1rem 2rem; /* Adjust padding */
|
||||||
|
border-radius: 9999px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1rem;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
|
||||||
|
background: linear-gradient(45deg, rgba(129, 230, 217, 1), rgba(79, 209, 197, 1));
|
||||||
|
}
|
19
src/index.css
Normal file
19
src/index.css
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||||
|
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||||
|
sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||||
|
monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
14
src/index.js
Normal file
14
src/index.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import './index.css';
|
||||||
|
import App from './App';
|
||||||
|
import reportWebVitals from './reportWebVitals';
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
||||||
|
|
||||||
|
reportWebVitals();
|
45
src/pages/Donate.js
Normal file
45
src/pages/Donate.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import styles from './Donate.module.css';
|
||||||
|
|
||||||
|
function Donate() {
|
||||||
|
const starryBackgroundRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const starryBackground = starryBackgroundRef.current;
|
||||||
|
const numberOfStars = 100;
|
||||||
|
|
||||||
|
for (let i = 0; i < numberOfStars; i++) {
|
||||||
|
const star = document.createElement('div');
|
||||||
|
star.className = styles.star;
|
||||||
|
star.style.width = `${Math.random() * 3}px`;
|
||||||
|
star.style.height = star.style.width;
|
||||||
|
star.style.left = `${Math.random() * 100}%`;
|
||||||
|
star.style.top = `${Math.random() * 100}%`;
|
||||||
|
star.style.animationDelay = `${Math.random() * 4}s`;
|
||||||
|
starryBackground.appendChild(star);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
exit={{ opacity: 0 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className={styles.donatePage}
|
||||||
|
>
|
||||||
|
<div ref={starryBackgroundRef} className={styles.starryBackground}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<h1 className={styles.title}>Donate to NebulaOS</h1>
|
||||||
|
<p className={styles.description}>
|
||||||
|
Your support helps us continue developing and improving NebulaOS.
|
||||||
|
Thank you for considering a donation!
|
||||||
|
</p>
|
||||||
|
{/* Add donation options or links here */}
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Donate;
|
11
src/pages/Donate.module.css
Normal file
11
src/pages/Donate.module.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.donatePage {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: linear-gradient(135deg, rgba(26, 32, 44, 0.9) 0%, rgba(45, 55, 72, 0.9) 100%);
|
||||||
|
color: white;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
48
src/pages/Download.js
Normal file
48
src/pages/Download.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import styles from './Download.module.css';
|
||||||
|
|
||||||
|
function Download() {
|
||||||
|
const starryBackgroundRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const starryBackground = starryBackgroundRef.current;
|
||||||
|
const numberOfStars = 100;
|
||||||
|
|
||||||
|
for (let i = 0; i < numberOfStars; i++) {
|
||||||
|
const star = document.createElement('div');
|
||||||
|
star.className = styles.star;
|
||||||
|
star.style.width = `${Math.random() * 3}px`;
|
||||||
|
star.style.height = star.style.width;
|
||||||
|
star.style.left = `${Math.random() * 100}%`;
|
||||||
|
star.style.top = `${Math.random() * 100}%`;
|
||||||
|
star.style.animationDelay = `${Math.random() * 4}s`;
|
||||||
|
starryBackground.appendChild(star);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className={styles.downloadPage}
|
||||||
|
>
|
||||||
|
<div ref={starryBackgroundRef} className={styles.starryBackground}></div>
|
||||||
|
<div className={`${styles.floatingElement} ${styles.floatingElement1}`}></div>
|
||||||
|
<div className={`${styles.floatingElement} ${styles.floatingElement2}`}></div>
|
||||||
|
<div className={`${styles.floatingElement} ${styles.floatingElement3}`}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<h1 className={styles.title}>NebulaOS Download</h1>
|
||||||
|
<p className={styles.comingSoon}>Coming Soon</p>
|
||||||
|
<p className={styles.description}>
|
||||||
|
We're working hard to bring you the future of Android.
|
||||||
|
Stay tuned for the release of NebulaOS!
|
||||||
|
</p>
|
||||||
|
<a href="/" className={styles.backButton}>Back to Home</a>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Download;
|
125
src/pages/Download.module.css
Normal file
125
src/pages/Download.module.css
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
.downloadPage {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: linear-gradient(135deg, rgba(26, 32, 44, 0.9) 0%, rgba(45, 55, 72, 0.9) 100%);
|
||||||
|
color: white;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.starryBackground {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.star {
|
||||||
|
position: absolute;
|
||||||
|
background: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
opacity: 0.3;
|
||||||
|
animation: twinkle 4s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes twinkle {
|
||||||
|
0%, 100% { opacity: 0.3; }
|
||||||
|
50% { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 2rem;
|
||||||
|
max-width: 600px;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 8px 32px rgba(31, 38, 135, 0.2);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 3rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background: linear-gradient(45deg, #ffffff, #81e6d9, #4fd1c5);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.comingSoon {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: #81e6d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backButton {
|
||||||
|
display: inline-block;
|
||||||
|
background: linear-gradient(45deg, rgba(129, 230, 217, 0.8), rgba(79, 209, 197, 0.8));
|
||||||
|
color: #2d3748;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border-radius: 9999px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.backButton:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
|
||||||
|
background: linear-gradient(45deg, rgba(129, 230, 217, 1), rgba(79, 209, 197, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement {
|
||||||
|
position: absolute;
|
||||||
|
background: linear-gradient(135deg, rgba(129, 230, 217, 0.2), rgba(79, 209, 197, 0.2));
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
box-shadow: 0 0 20px rgba(129, 230, 217, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement1 {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
top: 10%;
|
||||||
|
left: 10%;
|
||||||
|
animation: float 12s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement2 {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
top: 20%;
|
||||||
|
right: 20%;
|
||||||
|
animation: float 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement3 {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
bottom: 15%;
|
||||||
|
left: 15%;
|
||||||
|
animation: float 10s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translate(0, 0) rotate(0deg); }
|
||||||
|
25% { transform: translate(10px, -10px) rotate(5deg); }
|
||||||
|
50% { transform: translate(0, -20px) rotate(0deg); }
|
||||||
|
75% { transform: translate(-10px, -10px) rotate(-5deg); }
|
||||||
|
}
|
48
src/pages/Support.js
Normal file
48
src/pages/Support.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import styles from './Support.module.css';
|
||||||
|
|
||||||
|
function Support() {
|
||||||
|
const starryBackgroundRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const starryBackground = starryBackgroundRef.current;
|
||||||
|
const numberOfStars = 100;
|
||||||
|
|
||||||
|
for (let i = 0; i < numberOfStars; i++) {
|
||||||
|
const star = document.createElement('div');
|
||||||
|
star.className = styles.star;
|
||||||
|
star.style.width = `${Math.random() * 3}px`;
|
||||||
|
star.style.height = star.style.width;
|
||||||
|
star.style.left = `${Math.random() * 100}%`;
|
||||||
|
star.style.top = `${Math.random() * 100}%`;
|
||||||
|
star.style.animationDelay = `${Math.random() * 4}s`;
|
||||||
|
starryBackground.appendChild(star);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
className={styles.supportPage}
|
||||||
|
>
|
||||||
|
<div ref={starryBackgroundRef} className={styles.starryBackground}></div>
|
||||||
|
<div className={`${styles.floatingElement} ${styles.floatingElement1}`}></div>
|
||||||
|
<div className={`${styles.floatingElement} ${styles.floatingElement2}`}></div>
|
||||||
|
<div className={`${styles.floatingElement} ${styles.floatingElement3}`}></div>
|
||||||
|
<div className={styles.container}>
|
||||||
|
<h1 className={styles.title}>NebulaOS Support</h1>
|
||||||
|
<p className={styles.comingSoon}>Coming Soon</p>
|
||||||
|
<p className={styles.description}>
|
||||||
|
We're working on building a comprehensive support system for NebulaOS.
|
||||||
|
Stay tuned for updates on how you can get help and contribute to our project!
|
||||||
|
</p>
|
||||||
|
<a href="/" className={styles.backButton}>Back to Home</a>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Support;
|
125
src/pages/Support.module.css
Normal file
125
src/pages/Support.module.css
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
.supportPage {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: linear-gradient(135deg, rgba(26, 32, 44, 0.9) 0%, rgba(45, 55, 72, 0.9) 100%);
|
||||||
|
color: white;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.starryBackground {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.star {
|
||||||
|
position: absolute;
|
||||||
|
background: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
opacity: 0.3;
|
||||||
|
animation: twinkle 4s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes twinkle {
|
||||||
|
0%, 100% { opacity: 0.3; }
|
||||||
|
50% { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 2rem;
|
||||||
|
max-width: 600px;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 8px 32px rgba(31, 38, 135, 0.2);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 3rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background: linear-gradient(45deg, #ffffff, #81e6d9, #4fd1c5);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.comingSoon {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: #81e6d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backButton {
|
||||||
|
display: inline-block;
|
||||||
|
background: linear-gradient(45deg, rgba(129, 230, 217, 0.8), rgba(79, 209, 197, 0.8));
|
||||||
|
color: #2d3748;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border-radius: 9999px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.backButton:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: 0 6px 12px rgba(0,0,0,0.15);
|
||||||
|
background: linear-gradient(45deg, rgba(129, 230, 217, 1), rgba(79, 209, 197, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement {
|
||||||
|
position: absolute;
|
||||||
|
background: linear-gradient(135deg, rgba(129, 230, 217, 0.2), rgba(79, 209, 197, 0.2));
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
box-shadow: 0 0 20px rgba(129, 230, 217, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement1 {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
top: 10%;
|
||||||
|
left: 10%;
|
||||||
|
animation: float 12s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement2 {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
top: 20%;
|
||||||
|
right: 20%;
|
||||||
|
animation: float 8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatingElement3 {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
bottom: 15%;
|
||||||
|
left: 15%;
|
||||||
|
animation: float 10s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translate(0, 0) rotate(0deg); }
|
||||||
|
25% { transform: translate(10px, -10px) rotate(5deg); }
|
||||||
|
50% { transform: translate(0, -20px) rotate(0deg); }
|
||||||
|
75% { transform: translate(-10px, -10px) rotate(-5deg); }
|
||||||
|
}
|
13
src/reportWebVitals.js
Normal file
13
src/reportWebVitals.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';
|
||||||
|
|
||||||
|
const reportWebVitals = (onPerfEntry) => {
|
||||||
|
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||||
|
getCLS(onPerfEntry);
|
||||||
|
getFID(onPerfEntry);
|
||||||
|
getFCP(onPerfEntry);
|
||||||
|
getLCP(onPerfEntry);
|
||||||
|
getTTFB(onPerfEntry);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default reportWebVitals;
|
11
tailwind.config.js
Normal file
11
tailwind.config.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module.exports = {
|
||||||
|
content: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
|
||||||
|
darkMode: 'class',
|
||||||
|
theme: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
extend: {},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user