This commit is contained in:
spitkov 2024-10-07 17:26:47 +02:00
commit 424068648a
28 changed files with 28122 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

12
craco.config.js Normal file
View File

@ -0,0 +1,12 @@
const path = require('path');
module.exports = {
style: {
postcss: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
},
};

17
index.html Normal file
View 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

File diff suppressed because it is too large Load Diff

37
package.json Normal file
View 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
View File

@ -0,0 +1,6 @@
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
]
}

27
public/index.html Normal file
View 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
View 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
View File

@ -0,0 +1,9 @@
.app {
min-height: 100vh;
background-color: #1a202c;
color: #f0f4f8;
}
.main {
padding: 2rem 0;
}

View 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;

View 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;

View 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
View 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>&copy; 2024 NebulaOS. All rights reserved.</p>
</div>
</div>
</footer>
);
}
export default Footer;

View 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
View 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;

View 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
View 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;

View 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
View 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
View 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
View 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;

View 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
View 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;

View 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
View 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;

View 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
View 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
View File

@ -0,0 +1,11 @@
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
darkMode: 'class',
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}