diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b66077 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# OS +.DS_Store +Thumbs.db +*~ + +# Editor +*.swp +*.swo +.vscode/ +.idea/ \ No newline at end of file diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..ff40dba --- /dev/null +++ b/.htaccess @@ -0,0 +1,133 @@ +# ArcaneNeko Website - .htaccess Configuration +# Apache server configuration rules + +# Enable Rewrite Engine +RewriteEngine On +RewriteBase / + +# ============================================ +# Remove .html extension from URLs +# ============================================ +RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f +RewriteRule ^(.*)$ $1.html [L] + +# ============================================ +# SECURITY & BASIC PROTECTION +# ============================================ + +# Block access to hidden files (dotfiles) + + Require all denied + + +# Block access to config and environment files + + Require all denied + + +# ============================================ +# CUSTOM ERROR PAGES +# ============================================ +ErrorDocument 400 /400 +ErrorDocument 403 /403 +ErrorDocument 404 /404 +ErrorDocument 500 /500 +ErrorDocument 502 /502 +ErrorDocument 503 /503 + +# ============================================ +# CACHE CONTROL & PERFORMANCE +# ============================================ + +# Static assets caching - 1 year + + Header set Cache-Control "max-age=31536000, public" + + +# HTML documents - no cache + + Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" + Header set Pragma "no-cache" + Header set Expires "0" + + +# ============================================ +# BROWSER CACHING & COMPRESSION +# ============================================ + +# Enable Gzip compression (mod_deflate) + + AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/x-javascript application/json application/rss+xml font/ttf font/otf + + +# ============================================ +# MIME TYPES & FONT ACCESS +# ============================================ + +# Allow CORS for web fonts + + Header set Access-Control-Allow-Origin "*" + + +# ============================================ +# SECURITY HEADERS +# ============================================ + +Header set X-Content-Type-Options "nosniff" +Header set X-Frame-Options "DENY" +Header set X-XSS-Protection "1; mode=block" +Header set Referrer-Policy "strict-origin-when-cross-origin" +Header set Permissions-Policy "geolocation=(), microphone=(), camera=()" + +# ============================================ +# SITEMAP +# ============================================ +RewriteRule ^sitemap\.xml$ /sitemap.xml [L] + +# ============================================ +# ROBOTS.TXT +# ============================================ +RewriteRule ^robots\.txt$ /robots.txt [L] + +# ============================================ +# HTTPS & FORCE SSL (optional) +# ============================================ +# Uncomment the next 3 lines to force HTTPS redirect +# RewriteCond %{HTTPS} off +# RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] + +# ============================================ +# PHP & SERVER-SIDE PROCESSING (optional) +# ============================================ +# If your site needs PHP, uncomment: +# AddType application/x-httpd-php .php +# DirectoryIndex index.php index.html + +# ============================================ +# CLIENT SIDE ROUTING (SPA support - optional) +# ============================================ +# For single-page applications, route all non-file/non-api requests to index.html +# Uncomment if you implement client-side routing +# +# RewriteCond %{REQUEST_FILENAME} !-f +# RewriteCond %{REQUEST_FILENAME} !-d +# RewriteRule ^ index.html [L] + +# ============================================ +# NGINX COMPATIBILITY NOTES +# ============================================ +# This .htaccess is for Apache. If running with Nginx: +# - Nginx does not support .htaccess; rules must be in server config +# - ErrorDocument directives need server-level config in Nginx +# - Header directives need 'add_header' in Nginx context +# - Rewrite rules need 'rewrite' directive in Nginx +# +# Example Nginx config for static assets: +# location ~* \.(ico|pdf|flv|jpg|jpeg|png|gif|webp|svg|eot|otf|woff|woff2|ttf|css|js)$ { +# expires 1y; +# add_header Cache-Control "public"; +# try_files $uri =404; +# } +# +# Example Nginx config for sitemap: +# rewrite ^/sitemap.xml$ /sitemap.xml break; \ No newline at end of file diff --git a/400.html b/400.html new file mode 100644 index 0000000..ea9fcf6 --- /dev/null +++ b/400.html @@ -0,0 +1,109 @@ + + + + + + 400 - Bad Request | ArcaneNeko + + + + + + + + + + + + + + + +
+
+
+
400
+

Bad Request

+

The request could not be processed due to a client error.

+ +
+
+ + + + \ No newline at end of file diff --git a/403.html b/403.html new file mode 100644 index 0000000..9176d6a --- /dev/null +++ b/403.html @@ -0,0 +1,109 @@ + + + + + + 403 - Forbidden | ArcaneNeko + + + + + + + + + + + + + + + +
+
+
+
403
+

Access Denied

+

You don't have permission to access this resource.

+ +
+
+ + + + \ No newline at end of file diff --git a/404.html b/404.html new file mode 100644 index 0000000..7006511 --- /dev/null +++ b/404.html @@ -0,0 +1,109 @@ + + + + + + 404 - Page Not Found | ArcaneNeko + + + + + + + + + + + + + + + +
+
+
+
404
+

Page Not Found

+

The page you're looking for doesn't exist.

+ +
+
+ + + + \ No newline at end of file diff --git a/422.html b/422.html new file mode 100644 index 0000000..3b573d8 --- /dev/null +++ b/422.html @@ -0,0 +1,109 @@ + + + + + + 422 - Unprocessable Entity | ArcaneNeko + + + + + + + + + + + + + + + +
+
+
+
422
+

Unprocessable Entity

+

The request could not be processed due to semantic errors.

+ +
+
+ + + + \ No newline at end of file diff --git a/500.html b/500.html new file mode 100644 index 0000000..82acaaa --- /dev/null +++ b/500.html @@ -0,0 +1,109 @@ + + + + + + 500 - Internal Server Error | ArcaneNeko + + + + + + + + + + + + + + + +
+
+
+
500
+

Internal Server Error

+

Something went wrong on our end.

+ +
+
+ + + + \ No newline at end of file diff --git a/502.html b/502.html new file mode 100644 index 0000000..a127296 --- /dev/null +++ b/502.html @@ -0,0 +1,109 @@ + + + + + + 502 - Bad Gateway | ArcaneNeko + + + + + + + + + + + + + + + +
+
+
+
502
+

Bad Gateway

+

The server, while acting as a gateway or proxy, received an invalid response from the upstream server.

+ +
+
+ + + + \ No newline at end of file diff --git a/503.html b/503.html new file mode 100644 index 0000000..d41f4e8 --- /dev/null +++ b/503.html @@ -0,0 +1,109 @@ + + + + + + 503 - Service Unavailable | ArcaneNeko + + + + + + + + + + + + + + + +
+
+
+
503
+

Service Unavailable

+

The server is temporarily unable to handle the request. This is often due to maintenance or temporary overload.

+ +
+
+ + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index eab6767..0000000 --- a/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -MIT License - -Copyright (c) 2026 ArcaneNeko - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the -following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO -EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 749ab6a..e182a8e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,193 @@ -# Website +# ArcaneNeko Website +The official ArcaneNeko website - open source and available under the MIT License. + +## License + +MIT License - see [LICENSE](../LICENSE) for details. + +## Overview + +This is a static HTML/CSS/JS website showcasing ArcaneNeko's services and projects. It's designed to be simple, fast, and easily customizable. + +## Features + +- **Static HTML** — No frameworks, just clean semantic HTML +- **Responsive Design** — Works on mobile, tablet, and desktop +- **Theme System** — Three built-in themes: crimson (default), dark, light +- **Theme Toggle** — Users can switch between themes with persisted preference +- **Modular CSS** — Easy to add custom themes +- **No Dependencies** — Plain CSS and vanilla JavaScript +- **Accessible** — ARIA labels and keyboard navigation support +- **Self-contained Error Pages** — Error pages include header/footer and all CSS/JS + +## File Structure + +``` +ArcaneNekoWebsite/ +├── index.html # Main landing page +├── status.html # Arcane Status product page +├── privacy.html # Privacy policy +├── terms.html # Terms of service +├── contact.html # Contact page +├── coming-soon.html # Coming soon page +├── 400.html # Bad Request error page +├── 403.html # Forbidden error page +├── 404.html # Not Found error page +├── 422.html # Unprocessable Entity error page +├── 500.html # Internal Server Error page +├── 502.html # Bad Gateway error page +├── 503.html # Service Unavailable error page +├── favicon.svg # Favicon +├── robots.txt # Robots.txt +├── sitemap.xml # XML sitemap for search engines +├── .htaccess # Apache configuration +├── css/ +│ ├── index.css # Main CSS (imports all others) +│ ├── themes.css # Theme CSS variables +│ ├── base.css # Base reset and styles +│ ├── navbar.css # Navbar styles +│ ├── hero.css # Hero section styles +│ ├── buttons.css # Button styles +│ ├── stats.css # Stats bar styles +│ ├── about.css # About section styles +│ ├── sections.css # Generic section styles +│ ├── cards.css # Card & feature styles +│ ├── footer.css # Footer styles +│ ├── legal.css # Legal page styles +│ ├── contact.css # Contact page styles +│ ├── utility.css # Utility styles +│ └── responsive.css # Mobile/tablet breakpoints +├── js/ +│ ├── theme.js # Theme switching logic +│ └── main.js # Main initialization +└── README.md +``` + +## Error Pages + +The website includes 7 self-contained error pages: + +| Page | Description | +|------|-----------| +| `400.html` | Bad Request | +| `403.html` | Forbidden/Access Denied | +| `404.html` | Page Not Found | +| `422.html` | Unprocessable Entity | +| `500.html` | Internal Server Error | +| `502.html` | Bad Gateway | +| `503.html` | Service Unavailable | + +Each error page includes: +- Full website header (navbar with navigation links, theme toggle, mobile hamburger menu) +- Full website footer (brand, community links, services links, legal links) +- Embedded CSS (themes, navbar, footer, error content, responsive styles) +- Embedded JavaScript (theme switching, mobile menu) +- Theme selection that persists via localStorage +- Responsive design for all screen sizes + +The error pages are configured in `.htaccess` - see the [Apache Configuration](#apache-configuration) section below. + +## Customization + +### Creating a Custom Theme + +1. Edit `css/themes.css` to add your theme: + +```css +[data-theme="custom"] { + --bg: #your-bg-color; + --bg-alt: #your-bg-alt-color; + --accent: #your-accent-color; + /* ... add other variables */ +} +``` + +2. Update the `THEMES` array in `js/theme.js` to include your theme: + +```javascript +const THEMES = ['crimson', 'dark', 'light', 'custom']; +``` + +3. Add theme icons and labels in `js/theme.js`: + +```javascript +const THEME_ICONS = { + custom: '...', +}; + +const THEME_LABELS = { + custom: 'Switch to custom theme', +}; +``` + +### Adding New Pages + +1. Copy an existing page (e.g., `contact.html`) +2. Update the navbar links in all HTML files to include your new page +3. Add footer links in the same way + +### Modifying CSS + +Each CSS file contains specific component styles: +- **themes.css** - Theme variables +- **navbar.css** - Navbar and mobile menu +- **hero.css** - Hero section +- **buttons.css** - Button styles +- **cards.css** - Cards and features +- **footer.css** - Footer +- **legal.css** - Legal pages +- **contact.css** - Contact & coming soon + +## Apache Configuration + +The `.htaccess` file provides: + +### URL Rewriting +- Removes `.html` extension from URLs (e.g., `/about` instead of `/about.html`) + +### Custom Error Pages +- Maps HTTP errors to error pages: + - `400` → `/400` + - `403` → `/403` + - `404` → `/404` + - `500` → `/500` + - `502` → `/502` + - `503` → `/503` + +### Security +- Blocks access to hidden files (dotfiles) +- Blocks access to config/environment files (`.env`, `.config`, `.log`, etc.) +- Sets security headers (X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy, Permissions-Policy) + +### Performance +- Static assets caching (1 year for images, fonts, CSS, JS) +- No cache for HTML documents +- Gzip compression for HTML, CSS, JS, text, fonts + +### Sitemap & Robots.txt +- `sitemap.xml` - XML sitemap for search engines +- `robots.txt` - Robots.txt allowing all crawlers and pointing to sitemap + +### HTTPS (Optional) +- Uncomment lines to force HTTPS redirect + +### Nginx Compatibility + +If using Nginx instead of Apache: +- These rules must be translated to Nginx config or handled upstream +- ErrorDocument directives need server-level configuration in Nginx +- Header directives need `add_header` in Nginx context +- Rewrite rules need `rewrite` directive in Nginx + +The `.htaccess` file contains notes for Nginx compatibility at the bottom. + +## Browser Support + +- Chrome/Edge 90+ +- Firefox 88+ +- Safari 14+ + +## Deployment + +Simply upload all files to any web server or static hosting service. No server-side code required. \ No newline at end of file diff --git a/coming-soon.html b/coming-soon.html new file mode 100644 index 0000000..f7d8bbc --- /dev/null +++ b/coming-soon.html @@ -0,0 +1,169 @@ + + + + + + Coming Soon | ArcaneNeko + + + + + + + + + + + + + +
+ + +
+
Coming Soon
+

Something Exciting Is Brewing

+

We're working on something new. Stay tuned for updates.

+ +
+
+ + + + + + + + + \ No newline at end of file diff --git a/contact.html b/contact.html new file mode 100644 index 0000000..f27b5e2 --- /dev/null +++ b/contact.html @@ -0,0 +1,206 @@ + + + + + + Contact Us | ArcaneNeko + + + + "> + + + + + + + + + + + + + + + + + + + + +
+
+
+ +

How to reach us

+ +
+ +
+ +

General Enquiries

+

Questions about ArcaneNeko, our projects, or anything else? We'd love to hear from you.

+ + hello@arcaneneko.com → + +
+ +
+ +

Support

+

Need help with your Git account, Neovoxis, or any of our services? Support enquiries go here.

+ + support@arcaneneko.com → + +
+ +
+ +

Security Reports

+

Found a vulnerability? Please report it responsibly before public disclosure. We take all reports seriously.

+ + security@arcaneneko.com → + +
+ +
+ +

Abuse Reports

+

Report content or accounts that violate our Terms of Service, including harassment, spam, or illegal content.

+ + abuse@arcaneneko.com → + +
+ +
+ +

Legal & Privacy

+

Data access requests, GDPR/UK GDPR rights, or legal enquiries. See our Privacy Policy for your rights.

+ + legal@arcaneneko.com → + +
+ +
+ +

Community

+

Want to chat with us and the community in real time? Join us on Neovoxis, it's our own platform and we're active there.

+ + Join Neovoxis → + +
+ +
+ +

+ Response times: We're a small, volunteer-run team. We aim to reply to all emails within a few days. Security reports are prioritised and will receive a response within 48 hours where possible. We don't have a support ticket system, a plain email is all you need. +

+ +
+
+
+ + + + + + + + + + diff --git a/css/about.css b/css/about.css new file mode 100644 index 0000000..785e7c6 --- /dev/null +++ b/css/about.css @@ -0,0 +1,42 @@ +/* + * About Section Styles + */ + +.about { + padding: 8rem 0; +} + +.about-inner { + max-width: 680px; + margin: 0 auto; + text-align: center; +} + +.about-eyebrow { + font-size: 0.75rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--accent); + margin-bottom: 1rem; + display: block; +} + +.about h2 { + font-size: 2.5rem; + font-weight: 800; + letter-spacing: -1px; + margin-bottom: 1.75rem; + color: var(--text); +} + +.about p { + color: var(--text-muted); + font-size: 1.05rem; + line-height: 1.85; + margin-bottom: 1rem; +} + +.about p:last-child { + margin-bottom: 0; +} diff --git a/css/base.css b/css/base.css new file mode 100644 index 0000000..67b90a5 --- /dev/null +++ b/css/base.css @@ -0,0 +1,57 @@ +/* + * Base Styles - Reset and foundational styles + */ + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: 'Inter', 'Segoe UI', system-ui, sans-serif; + background-color: var(--bg); + color: var(--text); + line-height: 1.6; + overflow-x: hidden; + transition: background-color 0.3s ease, color 0.3s ease; +} + +.container { + max-width: 1100px; + margin: 0 auto; + padding: 0 2rem; +} + +a { + color: var(--accent); + text-decoration: none; +} + +a:hover { + text-decoration: underline; + color: var(--accent-light); +} + +.skip-link { + position: absolute; + left: 1rem; + top: -3rem; + z-index: 2000; + background: var(--accent); + color: #fff; + text-decoration: none; + font-weight: 700; + padding: 0.75rem 1rem; + border-radius: 10px; + box-shadow: 0 8px 24px var(--accent-glow); + transition: top 0.2s ease; +} + +.skip-link:focus { + top: 1rem; +} diff --git a/css/buttons.css b/css/buttons.css new file mode 100644 index 0000000..33777d8 --- /dev/null +++ b/css/buttons.css @@ -0,0 +1,67 @@ +/* + * Button Styles + */ + +.btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.875rem 2rem; + background: var(--accent); + color: #fff; + text-decoration: none; + border-radius: 10px; + font-weight: 600; + font-size: 0.95rem; + transition: all 0.25s ease; + box-shadow: 0 4px 24px var(--accent-glow); + border: none; + cursor: pointer; +} + +.btn:hover { + background: var(--accent-light); + transform: translateY(-2px); + box-shadow: 0 8px 32px var(--accent-glow); + color: #fff; + text-decoration: none; +} + +.btn-outline { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.875rem 2rem; + background: var(--bg-card); + border: 1px solid var(--glass-border); + color: var(--text-2); + text-decoration: none; + border-radius: 10px; + font-weight: 600; + font-size: 0.95rem; + transition: all 0.25s ease; + backdrop-filter: blur(10px); + cursor: pointer; +} + +.btn-outline:hover { + border-color: var(--accent); + color: var(--accent-light); + background: var(--bg-card-hover); + transform: translateY(-2px); + box-shadow: 0 4px 16px var(--accent-glow-sm); + text-decoration: none; +} + +a:focus-visible, +button:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 3px; + border-radius: 4px; +} + +.btn:focus-visible, +.btn-outline:focus-visible { + outline: 2px solid var(--accent-light); + outline-offset: 3px; +} diff --git a/css/cards.css b/css/cards.css new file mode 100644 index 0000000..175cc20 --- /dev/null +++ b/css/cards.css @@ -0,0 +1,171 @@ +/* + * Card Styles + */ + +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 1.5rem; +} + +.card { + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 20px; + padding: 2.5rem; + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + box-shadow: + 0 4px 24px var(--shadow-deep), + inset 0 1px 0 var(--inset-shine); + transition: all 0.35s ease; + position: relative; + overflow: hidden; +} + +.card::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, transparent, var(--accent), transparent); + opacity: 0; + transition: opacity 0.3s ease; +} + +.card:hover { + border-color: var(--glass-border-hover); + transform: translateY(-6px); + box-shadow: + 0 20px 48px var(--shadow-deep), + 0 0 0 1px var(--accent-glow-sm), + inset 0 1px 0 var(--inset-shine); +} + +.card:hover::after { + opacity: 1; +} + +.card-icon { + width: 52px; + height: 52px; + background: linear-gradient(135deg, var(--accent-dark) 0%, var(--accent) 100%); + border-radius: 14px; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 1.5rem; + box-shadow: 0 4px 16px var(--accent-glow); +} + +.card-icon svg { + width: 24px; + height: 24px; + stroke: #fff; +} + +.card .badge { + display: inline-block; + padding: 0.3rem 0.85rem; + background: var(--accent-glow-sm); + border: 1px solid var(--accent-glow); + color: var(--accent-light); + font-size: 0.7rem; + font-weight: 700; + border-radius: 6px; + text-transform: uppercase; + letter-spacing: 0.1em; + margin-bottom: 1.25rem; +} + +.card h3 { + font-size: 1.4rem; + font-weight: 700; + margin-bottom: 0.75rem; + color: var(--text); + letter-spacing: -0.3px; +} + +.card p { + color: var(--text-muted); + font-size: 0.95rem; + line-height: 1.8; + margin-bottom: 2rem; +} + +.card-link { + color: var(--accent); + text-decoration: none; + font-weight: 600; + font-size: 0.9rem; + display: inline-flex; + align-items: center; + gap: 0.4rem; + transition: all 0.2s; +} + +.card-link:hover { + color: var(--accent-light); + gap: 0.8rem; + text-decoration: none; +} + +/* Feature cards */ +.feature-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); + gap: 1.5rem; +} + +.feature-card { + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 16px; + padding: 2rem; + backdrop-filter: blur(16px); + transition: all 0.3s ease; +} + +.feature-card:hover { + border-color: var(--glass-border-hover); + transform: translateY(-4px); +} + +.feature-card h3 { + font-size: 1.15rem; + font-weight: 700; + color: var(--accent); + margin-bottom: 0.6rem; +} + +.feature-card p { + color: var(--text-muted); + font-size: 0.9rem; + line-height: 1.7; +} + +/* Scroll reveal */ +.reveal { + opacity: 0; + transform: translateY(28px) scale(0.98); + transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.22, 1, 0.36, 1); +} + +.reveal.visible { + opacity: 1; + transform: translateY(0) scale(1); +} + +.reveal:nth-child(2) { transition-delay: 0.12s; } +.reveal:nth-child(3) { transition-delay: 0.24s; } +.reveal:nth-child(4) { transition-delay: 0.36s; } + +@media (prefers-reduced-motion: reduce) { + .reveal { + opacity: 1; + transform: none; + transition: none; + } +} diff --git a/css/contact.css b/css/contact.css new file mode 100644 index 0000000..ec1b4f5 --- /dev/null +++ b/css/contact.css @@ -0,0 +1,143 @@ +/* + * Contact Page Styles + */ + +.contact-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 1.5rem; + margin-bottom: 4rem; +} + +.contact-card { + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 20px; + padding: 2rem; + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.contact-card::after { + content: ''; + position: absolute; + top: 0; left: 0; right: 0; + height: 2px; + background: linear-gradient(90deg, transparent, var(--accent), transparent); + opacity: 0; + transition: opacity 0.3s; +} + +.contact-card:hover { + border-color: var(--glass-border-hover); + transform: translateY(-4px); + box-shadow: 0 16px 40px var(--shadow-deep); +} + +.contact-card:hover::after { opacity: 1; } + +.contact-card-icon { + width: 44px; + height: 44px; + background: linear-gradient(135deg, var(--accent-dark) 0%, var(--accent) 100%); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 1.25rem; + box-shadow: 0 4px 12px var(--accent-glow); +} + +.contact-card-icon svg { + width: 20px; + height: 20px; + stroke: #fff; +} + +.contact-card h3 { + font-size: 1.1rem; + font-weight: 700; + color: var(--text); + margin-bottom: 0.5rem; +} + +.contact-card p { + color: var(--text-muted); + font-size: 0.9rem; + line-height: 1.65; + margin-bottom: 1.25rem; +} + +.contact-card a.contact-email { + display: inline-flex; + align-items: center; + gap: 0.4rem; + color: var(--accent); + text-decoration: none; + font-weight: 600; + font-size: 0.9rem; + transition: all 0.2s; +} + +.contact-card a.contact-email:hover { + color: var(--accent-light); + gap: 0.7rem; +} + +.contact-note { + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-left: 3px solid var(--accent); + border-radius: 0 12px 12px 0; + padding: 1.25rem 1.5rem; + color: var(--text-muted); + font-size: 0.9rem; + line-height: 1.7; +} + +.contact-note strong { + color: var(--text-2); +} + +/* Coming soon */ +.coming-soon-hero { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + position: relative; + padding: 8rem 2rem 6rem; + overflow: hidden; +} + +.coming-soon-content { + position: relative; + z-index: 1; + max-width: 600px; +} + +.coming-soon-badge { + display: inline-block; + padding: 0.5rem 1.25rem; + background: var(--accent-glow-sm); + border: 1px solid var(--accent-glow); + color: var(--accent-light); + font-size: 0.75rem; + font-weight: 700; + border-radius: 100px; + text-transform: uppercase; + letter-spacing: 0.1em; + margin-bottom: 2rem; +} + +.coming-soon-cta { + display: flex; + gap: 1rem; + justify-content: center; + flex-wrap: wrap; + margin-top: 2.5rem; +} diff --git a/css/footer.css b/css/footer.css new file mode 100644 index 0000000..6f0bc51 --- /dev/null +++ b/css/footer.css @@ -0,0 +1,107 @@ +/* + * Footer Styles + */ + +.footer { + padding: 5rem 0 2.5rem; + border-top: 1px solid var(--divider); +} + +.footer-inner { + display: grid; + grid-template-columns: 1fr auto auto; + gap: 4rem; + margin-bottom: 3.5rem; + align-items: start; +} + +.footer-logo { + font-size: 1.35rem; + font-weight: 800; + color: var(--text); + letter-spacing: -0.5px; + display: block; + margin-bottom: 0.6rem; + text-decoration: none; +} + +.footer-logo span { + color: var(--accent); +} + +.footer-brand p { + color: var(--text-muted); + font-size: 0.9rem; + max-width: 260px; + line-height: 1.7; +} + +.footer-links-col { + display: flex; + flex-direction: column; + gap: 0.5rem; + min-width: 140px; +} + +.footer-links-col h4 { + font-size: 0.75rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--text-muted); + margin-bottom: 0.75rem; +} + +.footer-links-col a { + color: var(--text-2); + text-decoration: none; + font-size: 0.9rem; + font-weight: 500; + transition: color 0.2s; +} + +.footer-links-col a:hover { + color: var(--accent-light); +} + +.footer-bottom { + padding-top: 2rem; + border-top: 1px solid var(--divider); +} + +.footer-bottom p { + color: var(--text-muted); + font-size: 0.85rem; +} + +/* Footer community links */ +.footer-community { + display: flex; + gap: 0.75rem; + margin-top: 1rem; +} + +.footer-community a { + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 8px; + color: var(--text-muted); + text-decoration: none; + transition: all 0.2s; +} + +.footer-community a:hover { + border-color: var(--accent-glow); + color: var(--accent-light); + background: var(--bg-card-hover); +} + +.footer-community svg { + width: 16px; + height: 16px; +} diff --git a/css/hero.css b/css/hero.css new file mode 100644 index 0000000..bd96176 --- /dev/null +++ b/css/hero.css @@ -0,0 +1,118 @@ +/* + * Hero Styles + */ + +.hero { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + position: relative; + padding: 8rem 2rem 6rem; + overflow: hidden; +} + +.hero-bg { + position: absolute; + inset: 0; + background: + radial-gradient(ellipse 90% 65% at 50% -5%, var(--hero-glow-1) 0%, transparent 55%), + radial-gradient(ellipse 50% 40% at 85% 85%, var(--hero-glow-2) 0%, transparent 55%), + radial-gradient(ellipse 40% 35% at 10% 80%, var(--hero-glow-2) 0%, transparent 55%), + var(--bg); + z-index: 0; +} + +.hero-grid { + position: absolute; + inset: 0; + background-image: radial-gradient(circle, var(--accent-glow-sm) 1px, transparent 1px); + background-size: 48px 48px; + opacity: 0; + animation: gridFadeIn 2s ease 0.4s forwards, gridDrift 40s ease-in-out 2.4s infinite; + pointer-events: none; + -webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 50%, black 20%, transparent 80%); + mask-image: radial-gradient(ellipse 80% 70% at 50% 50%, black 20%, transparent 80%); +} + +.hero-content { + position: relative; + z-index: 1; + max-width: 820px; + animation: heroEntrance 0.9s cubic-bezier(0.22, 1, 0.36, 1) both; +} + +.hero-tag { + display: inline-block; + padding: 0.4rem 1.1rem; + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 100px; + font-size: 0.75rem; + font-weight: 600; + color: var(--text-muted); + letter-spacing: 0.08em; + text-transform: uppercase; + margin-bottom: 2rem; + backdrop-filter: blur(10px); +} + +.hero h1 { + font-size: 5.5rem; + font-weight: 900; + line-height: 1; + letter-spacing: -3px; + color: var(--text); + margin-bottom: 1.5rem; +} + +.hero h1 span { + color: var(--accent); + filter: drop-shadow(0 0 28px var(--accent-glow)); +} + +.hero-subtitle { + font-size: 1.2rem; + color: var(--text-muted); + max-width: 520px; + margin: 0 auto 2.75rem; + line-height: 1.75; +} + +.hero-cta { + display: flex; + gap: 1.25rem; + justify-content: center; + flex-wrap: wrap; + align-items: center; +} + +/* Hero animation keyframes */ +@keyframes gridFadeIn { + to { opacity: 0.35; } +} + +@keyframes gridDrift { + 0%, 100% { transform: translate(0, 0); } + 33% { transform: translate(6px, -8px); } + 66% { transform: translate(-6px, 4px); } +} + +@keyframes heroEntrance { + from { opacity: 0; transform: translateY(24px); } + to { opacity: 1; transform: translateY(0); } +} + +/* Reduced motion - hero */ +@media (prefers-reduced-motion: reduce) { + .hero-grid { + animation: none; + opacity: 0.2; + } + .hero-content { + animation: none; + opacity: 1; + transform: none; + } +} diff --git a/css/index.css b/css/index.css new file mode 100644 index 0000000..7de5d6b --- /dev/null +++ b/css/index.css @@ -0,0 +1,46 @@ +/* + * ArcaneNeko Website Styles + * Import order matters - later files can override earlier ones + */ + +/* Theme variables (must come first) */ +@import url('./themes.css'); + +/* Base styles */ +@import url('./base.css'); + +/* Navbar */ +@import url('./navbar.css'); + +/* Hero */ +@import url('./hero.css'); + +/* Buttons */ +@import url('./buttons.css'); + +/* Stats */ +@import url('./stats.css'); + +/* About */ +@import url('./about.css'); + +/* Sections */ +@import url('./sections.css'); + +/* Cards */ +@import url('./cards.css'); + +/* Footer */ +@import url('./footer.css'); + +/* Legal pages */ +@import url('./legal.css'); + +/* Contact & Coming Soon */ +@import url('./contact.css'); + +/* Utilities */ +@import url('./utility.css'); + +/* Responsive (must come last) */ +@import url('./responsive.css'); diff --git a/css/legal.css b/css/legal.css new file mode 100644 index 0000000..d0af4df --- /dev/null +++ b/css/legal.css @@ -0,0 +1,432 @@ +/* + * Legal Page Styles + */ + +/* Hero */ +.legal-hero { + padding: 9rem 2rem 4rem; + background: + radial-gradient(ellipse 70% 50% at 50% -10%, var(--hero-glow-1) 0%, transparent 55%), + var(--bg); + border-bottom: 1px solid var(--divider); + text-align: center; +} + +.legal-hero .legal-tag { + display: inline-block; + padding: 0.35rem 1rem; + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 100px; + font-size: 0.75rem; + font-weight: 600; + color: var(--text-muted); + letter-spacing: 0.08em; + text-transform: uppercase; + margin-bottom: 1.25rem; +} + +.legal-hero h1 { + font-size: 2.75rem; + font-weight: 900; + letter-spacing: -1.5px; + margin-bottom: 0.75rem; + color: var(--text); +} + +.legal-hero h1 span { + color: var(--accent); +} + +.legal-hero .legal-meta { + color: var(--text-muted); + font-size: 0.9rem; + margin-bottom: 0; +} + +/* Layout */ +.legal-wrap { + display: grid; + grid-template-columns: 220px 1fr; + gap: 4rem; + max-width: 1100px; + margin: 0 auto; + padding: 4rem 2rem 6rem; + align-items: start; +} + +/* TOC */ +.legal-toc { + position: sticky; + top: 90px; +} + +.legal-toc h4 { + font-size: 0.7rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.12em; + color: var(--text-muted); + margin-bottom: 1rem; +} + +.legal-toc ul { + list-style: none; + display: flex; + flex-direction: column; + gap: 0.15rem; +} + +.legal-toc a { + display: block; + color: var(--text-muted); + text-decoration: none; + font-size: 0.85rem; + font-weight: 500; + padding: 0.45rem 0.75rem; + border-radius: 7px; + border-left: 2px solid transparent; + transition: all 0.2s; + line-height: 1.4; +} + +.legal-toc a:hover, +.legal-toc a.active { + color: var(--accent-light); + background: var(--bg-card); + border-left-color: var(--accent); +} + +/* Content */ +.legal-content { + min-width: 0; + scroll-margin-top: 90px; +} + +.legal-section { + margin-bottom: 3.5rem; + padding-bottom: 3.5rem; + border-bottom: 1px solid var(--divider); + scroll-margin-top: 92px; +} + +.legal-section:last-child { + border-bottom: none; + margin-bottom: 0; + padding-bottom: 0; +} + +.legal-section h2 { + font-size: 1.4rem; + font-weight: 700; + color: var(--text); + margin-bottom: 1.25rem; + letter-spacing: -0.3px; + display: flex; + align-items: center; + gap: 0.75rem; +} + +.legal-section h2 .section-num { + font-size: 0.75rem; + font-weight: 700; + color: var(--accent); + background: var(--accent-glow-sm); + border: 1px solid var(--accent-glow); + border-radius: 5px; + padding: 0.2rem 0.55rem; + letter-spacing: 0; + flex-shrink: 0; +} + +.legal-section h3 { + font-size: 1.05rem; + font-weight: 700; + color: var(--text); + margin: 1.75rem 0 0.6rem; +} + +.legal-section p { + color: var(--text-2); + font-size: 0.98rem; + line-height: 1.85; + margin-bottom: 1rem; +} + +.legal-section p:last-child { + margin-bottom: 0; +} + +.legal-section ul, +.legal-section ol { + color: var(--text-2); + font-size: 0.98rem; + line-height: 1.85; + padding-left: 1.5rem; + margin-bottom: 1rem; +} + +.legal-section ul li, +.legal-section ol li { + margin-bottom: 0.4rem; +} + +.legal-section a { + color: var(--accent); + text-decoration: none; +} + +.legal-section a:hover { + text-decoration: underline; + color: var(--accent-light); +} + +/* Callouts */ +.callout { + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 12px; + padding: 1.25rem 1.5rem; + margin: 1.5rem 0; + backdrop-filter: blur(10px); +} + +.callout.callout--info { + border-left: 3px solid var(--accent); +} + +.callout.callout--lock { + border-left: 3px solid #22c55e; +} + +.callout .callout-title { + font-size: 0.8rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.08em; + margin-bottom: 0.5rem; +} + +.callout.callout--info .callout-title { color: var(--accent); } +.callout.callout--lock .callout-title { color: #22c55e; } + +.callout p { + margin-bottom: 0 !important; + font-size: 0.9rem !important; +} + +/* Data table */ +.data-table { + width: 100%; + border-collapse: collapse; + margin: 1.25rem 0; + font-size: 0.875rem; +} + +.data-table th { + text-align: left; + padding: 0.75rem 1rem; + background: var(--bg-card); + color: var(--text-muted); + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.08em; + border-bottom: 1px solid var(--divider); +} + +.data-table th:first-child { border-radius: 8px 0 0 0; } +.data-table th:last-child { border-radius: 0 8px 0 0; } + +.data-table td { + padding: 0.85rem 1rem; + color: var(--text-2); + border-bottom: 1px solid var(--divider); + vertical-align: top; + line-height: 1.6; +} + +.data-table tr:last-child td { border-bottom: none; } + +.data-table td:first-child { + font-weight: 600; + white-space: nowrap; +} + +/* Section kicker */ +.section-kicker { + display: inline-block; + margin-bottom: 0.75rem; + font-size: 0.75rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--accent); +} + +.legal-at-a-glance, +.legal-overview { + margin-bottom: 3.5rem; +} + +.legal-at-a-glance h2, +.legal-overview h2 { + font-size: 1.65rem; + letter-spacing: -0.4px; + margin-bottom: 1rem; +} + +/* Summary/Comparison grids */ +.summary-grid, +.comparison-grid, +.action-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 1rem; +} + +.summary-card, +.comparison-card, +.action-card { + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 16px; + padding: 1.15rem 1.1rem; + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + box-shadow: 0 8px 24px var(--shadow-deep), inset 0 1px 0 var(--inset-shine); +} + +.summary-card h3, +.comparison-card h3, +.action-card strong { + color: var(--text); + font-size: 1rem; + margin-bottom: 0.45rem; + display: block; +} + +.summary-card p, +.comparison-card p, +.action-card p { + color: var(--text-2); + font-size: 0.92rem; + line-height: 1.7; + margin: 0; +} + +.comparison-card h3, +.summary-card h3 { + margin-top: 0; +} + +.answer-strip { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 0.9rem; + margin: 1.1rem 0 0; +} + +.answer-strip > div { + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 12px; + padding: 0.9rem 1rem; +} + +.answer-strip strong { + display: block; + color: var(--text); + font-size: 0.88rem; + margin-bottom: 0.25rem; +} + +.answer-strip span, +.answer-strip a { + color: var(--text-2); + font-size: 0.88rem; + line-height: 1.55; +} + +.mini-summary { + margin: 0 0 1rem; + padding: 0.95rem 1rem; + border-radius: 12px; + background: linear-gradient(180deg, var(--bg-card), transparent), var(--bg-card); + border: 1px solid var(--glass-border); + color: var(--text-2); + line-height: 1.7; +} + +.mini-summary strong { + color: var(--text); +} + +.action-card { + text-decoration: none; + transition: transform 0.2s ease, border-color 0.2s ease, background 0.2s ease; +} + +.action-card:hover { + transform: translateY(-2px); + border-color: var(--glass-border-hover); + background: var(--bg-card-hover); +} + +.action-label { + display: inline-block; + margin-bottom: 0.5rem; + font-size: 0.74rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--accent); +} + +/* TOC toggle */ +.legal-toc-toggle { + display: none; + width: 100%; + align-items: center; + justify-content: space-between; + background: var(--bg-card); + border: 1px solid var(--glass-border); + color: var(--text); + border-radius: 12px; + padding: 0.95rem 1rem; + font: inherit; + font-weight: 700; + cursor: pointer; +} + +.legal-toc-panel { + display: block; +} + +.legal-toc-toggle::after { + content: '\25BE'; + color: var(--accent); + font-size: 0.95rem; + transition: transform 0.2s ease; +} + +.legal-toc-toggle[aria-expanded="true"]::after { + transform: rotate(180deg); +} + +/* Demo section */ +.demo { + padding: 8rem 0; + text-align: center; +} + +.demo-desc { + color: var(--text-muted); + margin-bottom: 2.5rem; + font-size: 1.1rem; +} + +.features { + padding: 8rem 0; + background: var(--bg-alt); +} diff --git a/css/navbar.css b/css/navbar.css new file mode 100644 index 0000000..b9904bf --- /dev/null +++ b/css/navbar.css @@ -0,0 +1,162 @@ +/* + * Navbar Styles + */ + +.navbar { + position: fixed; + top: 0; + left: 0; + right: 0; + background: var(--nav-bg); + backdrop-filter: blur(24px); + -webkit-backdrop-filter: blur(24px); + border-bottom: 1px solid var(--nav-border); + z-index: 1000; +} + +.nav-container { + max-width: 1100px; + margin: 0 auto; + padding: 0.9rem 2rem; + display: flex; + justify-content: space-between; + align-items: center; +} + +.nav-logo { + font-size: 1.35rem; + font-weight: 800; + color: var(--text); + text-decoration: none; + letter-spacing: -0.5px; +} + +.nav-logo span { + color: var(--accent); +} + +.nav-links { + display: flex; + list-style: none; + gap: 2.25rem; +} + +.nav-links a { + color: var(--text-muted); + text-decoration: none; + font-weight: 500; + font-size: 0.9rem; + transition: color 0.2s; + position: relative; +} + +.nav-links a::after { + content: ''; + position: absolute; + bottom: -4px; + left: 0; + width: 0; + height: 2px; + background: var(--accent); + border-radius: 2px; + transition: width 0.25s ease; + box-shadow: 0 0 8px var(--accent-glow); +} + +.nav-links a:hover { + color: var(--text); +} + +.nav-links a:hover::after { + width: 100%; +} + +.nav-actions { + display: flex; + align-items: center; + gap: 0.75rem; +} + +.theme-toggle { + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 8px; + padding: 0; + cursor: pointer; + color: var(--text-muted); + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s; + width: 36px; + height: 36px; + flex-shrink: 0; +} + +.theme-toggle:hover { + color: var(--accent); + border-color: var(--accent-glow); + background: var(--bg-card-hover); + box-shadow: 0 0 12px var(--accent-glow-sm); +} + +.theme-toggle svg { + width: 16px; + height: 16px; +} + +.hamburger { + display: none; + flex-direction: column; + gap: 5px; + background: none; + border: none; + cursor: pointer; + padding: 4px; +} + +.hamburger span { + display: block; + width: 22px; + height: 2px; + background: var(--text-2); + border-radius: 2px; + transition: all 0.3s ease; +} + +.hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); } +.hamburger.open span:nth-child(2) { opacity: 0; transform: scaleX(0); } +.hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); } + +.mobile-menu { + display: none; + flex-direction: column; + border-top: 1px solid var(--nav-border); + background: var(--nav-bg); + backdrop-filter: blur(24px); + -webkit-backdrop-filter: blur(24px); +} + +.mobile-menu.open { + display: flex; +} + +.mobile-menu a { + color: var(--text-2); + text-decoration: none; + font-size: 1rem; + font-weight: 500; + padding: 1rem 2rem; + border-bottom: 1px solid var(--divider); + transition: all 0.2s; +} + +.mobile-menu a:last-child { + border-bottom: none; +} + +.mobile-menu a:hover { + color: var(--accent); + background: var(--bg-card); + padding-left: 2.5rem; +} diff --git a/css/responsive.css b/css/responsive.css new file mode 100644 index 0000000..8b59bb8 --- /dev/null +++ b/css/responsive.css @@ -0,0 +1,146 @@ +/* + * Responsive Styles - Mobile/tablet breakpoints + */ + +@media (max-width: 768px) { + .nav-links { + display: none; + } + + .hamburger { + display: flex; + } + + .hero h1 { + font-size: 3.5rem; + letter-spacing: -2px; + } + + .hero-subtitle { + font-size: 1rem; + } + + .stats-grid { + grid-template-columns: repeat(2, 1fr); + gap: 1.5rem; + } + + .about h2, + .section-title { + font-size: 2rem; + } + + .card-grid { + grid-template-columns: 1fr; + } + + .footer-inner { + grid-template-columns: 1fr 1fr; + gap: 2rem; + } + + .footer-brand { + grid-column: 1 / -1; + } + + /* Legal pages */ + .legal-wrap { + grid-template-columns: 1fr; + } + + .legal-toc { + position: static; + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 12px; + padding: 1.25rem 1.5rem; + } + + .legal-toc ul { + flex-direction: row; + flex-wrap: wrap; + gap: 0.35rem; + } + + .legal-toc a { + border-left: none; + border-bottom: 2px solid transparent; + padding: 0.3rem 0.5rem; + font-size: 0.8rem; + } + + .legal-toc a:hover, + .legal-toc a.active { + border-left-color: transparent; + border-bottom-color: var(--accent); + } + + .data-table { + display: block; + overflow-x: auto; + } + + .summary-grid, + .comparison-grid, + .action-grid, + .answer-strip { + grid-template-columns: 1fr; + } + + .legal-toc { + padding: 0; + background: transparent; + border: none; + } + + .legal-toc-toggle { + display: flex; + } + + .legal-toc-panel { + display: none; + margin-top: 0.75rem; + background: var(--bg-card); + border: 1px solid var(--glass-border); + border-radius: 12px; + padding: 1rem; + } + + .legal-toc.open .legal-toc-panel { + display: block; + } + + .legal-toc ul { + flex-direction: column; + gap: 0.2rem; + } + + .legal-toc a { + border-bottom: none; + padding: 0.5rem 0.6rem; + font-size: 0.88rem; + } + + .legal-hero h1 { + font-size: 2rem; + letter-spacing: -1px; + } +} + +@media (max-width: 480px) { + .hero h1 { + font-size: 2.75rem; + letter-spacing: -1.5px; + } + + .hero-cta { + flex-direction: column; + align-items: center; + } + + .btn, + .btn-outline { + width: 100%; + justify-content: center; + } +} diff --git a/css/sections.css b/css/sections.css new file mode 100644 index 0000000..0952447 --- /dev/null +++ b/css/sections.css @@ -0,0 +1,53 @@ +/* + * Generic Section Styles + */ + +.section { + padding: 6rem 0; + position: relative; +} + +.alt-bg { + background: var(--bg-alt); +} + +.alt-bg::before, +.section::before { + content: ''; + position: absolute; + top: 0; + left: 5%; + right: 5%; + height: 1px; + background: linear-gradient(90deg, transparent, var(--divider), transparent); +} + +.section-label { + font-size: 0.75rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--accent); + display: block; + margin-bottom: 0.75rem; +} + +.section-title { + font-size: 2.5rem; + font-weight: 800; + letter-spacing: -1px; + margin-bottom: 3rem; + color: var(--text); + position: relative; +} + +.section-title::after { + content: ''; + display: block; + width: 36px; + height: 3px; + background: var(--accent); + border-radius: 2px; + margin-top: 0.85rem; + box-shadow: 0 0 12px var(--accent-glow); +} diff --git a/css/stats.css b/css/stats.css new file mode 100644 index 0000000..da5adaf --- /dev/null +++ b/css/stats.css @@ -0,0 +1,59 @@ +/* + * Stats Bar Styles + */ + +.stats-bar { + background: var(--stats-bg); + border-top: 1px solid var(--stats-border); + border-bottom: 1px solid var(--stats-border); + padding: 1.25rem 0; +} + +.stats-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 0.75rem; + text-align: center; +} + +.stat { + display: flex; + flex-direction: column; + gap: 0.15rem; +} + +.stat-value { + font-size: 1.6rem; + font-weight: 900; + color: var(--accent); + letter-spacing: -0.5px; + line-height: 1; +} + +.stat-label { + font-size: 0.75rem; + font-weight: 600; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.1em; + margin-top: 0.25rem; +} + +.stat { + animation: statPop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both; + animation-play-state: paused; +} + +.stat.animated { + animation-play-state: running; +} + +.stat:nth-child(1) { animation-delay: 0s; } +.stat:nth-child(2) { animation-delay: 0.1s; } +.stat:nth-child(3) { animation-delay: 0.2s; } +.stat:nth-child(4) { animation-delay: 0.3s; } + +@keyframes statPop { + from { opacity: 0; transform: translateY(12px) scale(0.9); } + to { opacity: 1; transform: translateY(0) scale(1); } +} diff --git a/css/themes.css b/css/themes.css new file mode 100644 index 0000000..6803ba3 --- /dev/null +++ b/css/themes.css @@ -0,0 +1,82 @@ +/* + * Theme Variables - Edit these to create new themes + */ + +:root, +[data-theme="crimson"] { + --bg: #07040a; + --bg-alt: #0d070c; + --bg-card: rgba(255, 255, 255, 0.04); + --bg-card-hover: rgba(255, 255, 255, 0.07); + --glass-border: rgba(255, 255, 255, 0.08); + --glass-border-hover: rgba(220, 20, 60, 0.45); + --accent: #dc143c; + --accent-light: #ff1744; + --accent-dark: #960f2c; + --accent-glow: rgba(220, 20, 60, 0.35); + --accent-glow-sm: rgba(220, 20, 60, 0.18); + --text: #ffffff; + --text-2: #ddd0d4; + --text-muted: #8c7a80; + --nav-bg: rgba(7, 4, 10, 0.85); + --nav-border: rgba(255, 255, 255, 0.06); + --stats-bg: rgba(220, 20, 60, 0.07); + --stats-border: rgba(220, 20, 60, 0.18); + --divider: rgba(255, 255, 255, 0.06); + --shadow-deep: rgba(0, 0, 0, 0.6); + --inset-shine: rgba(255, 255, 255, 0.04); + --hero-glow-1: rgba(220, 20, 60, 0.22); + --hero-glow-2: rgba(220, 20, 60, 0.1); +} + +[data-theme="dark"] { + --bg: #080808; + --bg-alt: #0f0f0f; + --bg-card: rgba(255, 255, 255, 0.04); + --bg-card-hover: rgba(255, 255, 255, 0.07); + --glass-border: rgba(255, 255, 255, 0.08); + --glass-border-hover: rgba(255, 255, 255, 0.22); + --accent: #dc143c; + --accent-light: #ff1744; + --accent-dark: #960f2c; + --accent-glow: rgba(220, 20, 60, 0.28); + --accent-glow-sm: rgba(220, 20, 60, 0.1); + --text: #ffffff; + --text-2: #c8c8c8; + --text-muted: #707070; + --nav-bg: rgba(8, 8, 8, 0.88); + --nav-border: rgba(255, 255, 255, 0.07); + --stats-bg: rgba(255, 255, 255, 0.03); + --stats-border: rgba(255, 255, 255, 0.08); + --divider: rgba(255, 255, 255, 0.07); + --shadow-deep: rgba(0, 0, 0, 0.7); + --inset-shine: rgba(255, 255, 255, 0.03); + --hero-glow-1: rgba(220, 20, 60, 0.1); + --hero-glow-2: rgba(220, 20, 60, 0.04); +} + +[data-theme="light"] { + --bg: #f5f4f6; + --bg-alt: #eeecef; + --bg-card: rgba(255, 255, 255, 0.72); + --bg-card-hover: rgba(255, 255, 255, 0.95); + --glass-border: rgba(0, 0, 0, 0.08); + --glass-border-hover: rgba(192, 18, 48, 0.35); + --accent: #c0122e; + --accent-light: #e0153a; + --accent-dark: #8b0020; + --accent-glow: rgba(192, 18, 48, 0.22); + --accent-glow-sm: rgba(192, 18, 48, 0.1); + --text: #0d0a0e; + --text-2: #2e2830; + --text-muted: #6a6068; + --nav-bg: rgba(245, 244, 246, 0.88); + --nav-border: rgba(0, 0, 0, 0.08); + --stats-bg: rgba(192, 18, 48, 0.06); + --stats-border: rgba(192, 18, 48, 0.16); + --divider: rgba(0, 0, 0, 0.07); + --shadow-deep: rgba(0, 0, 0, 0.1); + --inset-shine: rgba(255, 255, 255, 0.8); + --hero-glow-1: rgba(192, 18, 48, 0.12); + --hero-glow-2: rgba(192, 18, 48, 0.06); +} diff --git a/css/utility.css b/css/utility.css new file mode 100644 index 0000000..f60aa31 --- /dev/null +++ b/css/utility.css @@ -0,0 +1,92 @@ +/* + * Utility Styles - Back to top, scroll progress, focus states, etc. + */ + +/* Back to top button */ +.back-to-top { + position: fixed; + bottom: 2rem; + right: 2rem; + width: 44px; + height: 44px; + min-width: 44px; + min-height: 44px; + background: var(--accent); + border: none; + border-radius: 10px; + color: #fff; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transform: translateY(12px); + transition: opacity 0.3s ease, transform 0.3s ease, background 0.2s; + pointer-events: none; + box-shadow: 0 4px 20px var(--accent-glow); + z-index: 900; +} + +.back-to-top.visible { + opacity: 1; + transform: translateY(0); + pointer-events: auto; +} + +.back-to-top:hover { + background: var(--accent-light); + transform: translateY(-3px); + box-shadow: 0 8px 28px var(--accent-glow); +} + +.back-to-top:focus-visible { + outline: 2px solid var(--accent-light); + outline-offset: 3px; +} + +/* Scroll progress bar */ +.scroll-progress { + position: fixed; + top: 0; + left: 0; + height: 3px; + width: 0%; + background: linear-gradient(90deg, var(--accent-dark), var(--accent), var(--accent-light)); + z-index: 1100; + box-shadow: 0 0 10px var(--accent-glow); + transition: width 0.08s linear; + pointer-events: none; +} + +/* Touch targets */ +.theme-toggle, +.hamburger { + min-width: 44px; + min-height: 44px; + width: 44px; + height: 44px; +} + +.theme-toggle { + border-radius: 10px; +} + +/* Reduced motion */ +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } + + .stat { + animation: none; + opacity: 1; + } + + .back-to-top { + transition: opacity 0.01ms; + } +} diff --git a/favicon.svg b/favicon.svg new file mode 100644 index 0000000..490ae45 --- /dev/null +++ b/favicon.svg @@ -0,0 +1,12 @@ + + + A + diff --git a/index.html b/index.html new file mode 100644 index 0000000..e6cc234 --- /dev/null +++ b/index.html @@ -0,0 +1,223 @@ + + + + + + ArcaneNeko | Open Source Software & Services + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +

ArcaneNeko

+

Building free, open source tools for developers and creators, no strings attached.

+ +
+
+ + +
+
+
+
+ 100% + Free +
+
+ Open + Source +
+
+ MIT + Licensed +
+
+ 0 + Paywalls* +
+
+
+

* Neovoxis hosted instance may include paid features. Self-hosted instances include all features free.

+
+ + +
+
+
+ Who we are +

Software for everyone

+

ArcaneNeko is a small team building free, open source software for developers and the broader tech community. We believe software should be accessible to everyone.

+

From git hosting to status pages and a modern communication platform, every project we ship is open for anyone to use, contribute to, or self-host.

+
+
+
+ + +
+
+ +

What we offer

+
+ +
+ +

Git Hosting

+

Free and open git hosting powered by Gitea at git.arcaneneko.com. Open to everyone - create repos, collaborate, and host your code with no limits.

+ Visit Git Instance → +
+ +
+ +

Arcane Status

+

Free status page software under MIT License. Monitor your services and keep users informed with a clean, minimal status page you can self-host.

+ Learn More → +
+ +
+
+
+ + +
+
+ +

What we're building

+
+ +
+ Early Preview + +

Neovoxis

+

A modern Discord-like chat platform with text channels, forums, and a clean interface. Currently in early preview with active development ongoing.

+ Visit Neovoxis +
+ +
+ MIT License + +

Arcane Status

+

Free and open source status page software. Minimal setup, easy to customize, and ready to deploy. Keep your users informed about service health.

+ View Details +
+ +
+
+
+ + + + + + + + + + + diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..0ffa96b --- /dev/null +++ b/js/main.js @@ -0,0 +1,230 @@ +/** + * ArcaneNeko Website - Main Initialization + * + * Handles: mobile menu, scroll reveal, stat counters, + * back-to-top, scroll progress, smooth scroll + */ + +// ---------------------- +// Mobile Hamburger Menu +// ---------------------- +function initMobileMenu() { + const hamburger = document.getElementById('hamburger'); + const mobileMenu = document.getElementById('mobileMenu'); + if (!hamburger || !mobileMenu) return; + + hamburger.addEventListener('click', () => { + const open = hamburger.classList.toggle('open'); + mobileMenu.classList.toggle('open', open); + hamburger.setAttribute('aria-expanded', String(open)); + }); + + mobileMenu.querySelectorAll('a').forEach(link => { + link.addEventListener('click', () => { + hamburger.classList.remove('open'); + mobileMenu.classList.remove('open'); + hamburger.setAttribute('aria-expanded', 'false'); + }); + }); +} + +// ---------------------- +// Scroll Reveal (cards) +// ---------------------- +function initScrollReveal() { + const observer = new IntersectionObserver(entries => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add('visible'); + observer.unobserve(entry.target); + } + }); + }, { threshold: 0.1 }); + + document.querySelectorAll('.reveal').forEach(el => observer.observe(el)); +} + +// ---------------------- +// Stat Counter Animation +// ---------------------- +function animateCount(el, target, suffix, duration) { + const start = performance.now(); + const from = 0; + + function step(now) { + const elapsed = now - start; + const progress = Math.min(elapsed / duration, 1); + const eased = 1 - Math.pow(1 - progress, 3); + const current = Math.round(from + (target - from) * eased); + el.textContent = current + suffix; + if (progress < 1) requestAnimationFrame(step); + } + requestAnimationFrame(step); +} + +function initStatCounters() { + const statsBar = document.querySelector('.stats-bar'); + if (!statsBar) return; + + const observer = new IntersectionObserver(entries => { + if (!entries[0].isIntersecting) return; + observer.disconnect(); + + document.querySelectorAll('.stat').forEach(el => el.classList.add('animated')); + + document.querySelectorAll('.stat-value[data-count]').forEach(el => { + const target = parseFloat(el.dataset.count); + const suffix = el.dataset.suffix || ''; + const duration = 1400; + animateCount(el, target, suffix, duration); + }); + + }, { threshold: 0.5 }); + + observer.observe(statsBar); +} + +// ---------------------- +// Back to Top Button +// ---------------------- +function initBackToTop() { + const btn = document.getElementById('backToTop'); + if (!btn) return; + + window.addEventListener('scroll', () => { + btn.classList.toggle('visible', window.scrollY > 450); + }, { passive: true }); + + btn.addEventListener('click', () => { + window.scrollTo({ top: 0, behavior: 'smooth' }); + }); +} + +// ---------------------- +// Scroll Progress Bar (legal pages) +// ---------------------- +function initScrollProgress() { + const bar = document.getElementById('scrollProgress'); + if (!bar) return; + + const updateProgress = () => { + const total = document.documentElement.scrollHeight - window.innerHeight; + const progress = total > 0 ? (window.scrollY / total) * 100 : 0; + const rounded = Math.round(progress); + bar.style.width = progress + '%'; + bar.setAttribute('aria-valuenow', String(rounded)); + }; + + updateProgress(); + window.addEventListener('scroll', updateProgress, { passive: true }); + window.addEventListener('resize', updateProgress); +} + +// ---------------------- +// Navbar scroll shadow +// ---------------------- +function initNavShadow() { + const navbar = document.querySelector('.navbar'); + if (!navbar) return; + window.addEventListener('scroll', () => { + navbar.style.boxShadow = window.scrollY > 10 + ? '0 4px 24px rgba(0,0,0,0.3)' + : 'none'; + }, { passive: true }); +} + +// ---------------------- +// Smooth scroll (hash links) +// ---------------------- +function initSmoothScroll() { + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', e => { + const href = anchor.getAttribute('href'); + if (href === '#') return; + const target = document.querySelector(href); + if (target) { + e.preventDefault(); + const offset = 80; + window.scrollTo({ + top: target.getBoundingClientRect().top + window.scrollY - offset, + behavior: 'smooth' + }); + } + }); + }); +} + +// ---------------------- +// Legal page TOC highlight +// ---------------------- +function initTocHighlight() { + const sections = document.querySelectorAll('.legal-section'); + const tocLinks = document.querySelectorAll('.legal-toc a'); + if (!sections.length || !tocLinks.length) return; + + const observer = new IntersectionObserver(entries => { + entries.forEach(entry => { + if (entry.isIntersecting) { + tocLinks.forEach(l => l.classList.remove('active')); + const active = document.querySelector(`.legal-toc a[href="#${entry.target.id}"]`); + if (active) active.classList.add('active'); + } + }); + }, { rootMargin: '-20% 0px -70% 0px' }); + + sections.forEach(s => observer.observe(s)); +} + +// ---------------------- +// Legal page mobile TOC +// ---------------------- +function initLegalTocToggle() { + document.querySelectorAll('.legal-toc').forEach(toc => { + const button = toc.querySelector('.legal-toc-toggle'); + const panel = toc.querySelector('.legal-toc-panel'); + if (!button || !panel) return; + + button.addEventListener('click', () => { + const open = toc.classList.toggle('open'); + button.setAttribute('aria-expanded', String(open)); + }); + + panel.querySelectorAll('a').forEach(link => { + link.addEventListener('click', () => { + if (window.innerWidth <= 768) { + toc.classList.remove('open'); + button.setAttribute('aria-expanded', 'false'); + } + }); + }); + }); +} + +// ---------------------- +// Init on DOM ready +// ---------------------- +document.addEventListener('DOMContentLoaded', () => { + // Apply saved theme before anything renders + if (window.ThemeUtils) { + window.ThemeUtils.applyTheme(window.ThemeUtils.getCurrentTheme()); + } + + // Theme toggle + document.querySelectorAll('.theme-toggle').forEach(btn => { + btn.addEventListener('click', () => { + if (window.ThemeUtils) { + window.ThemeUtils.applyTheme(window.ThemeUtils.nextTheme()); + } + }); + }); + + initMobileMenu(); + initScrollReveal(); + initStatCounters(); + initBackToTop(); + initScrollProgress(); + initNavShadow(); + initSmoothScroll(); + initTocHighlight(); + initLegalTocToggle(); +}); diff --git a/js/theme.js b/js/theme.js new file mode 100644 index 0000000..3e65868 --- /dev/null +++ b/js/theme.js @@ -0,0 +1,44 @@ +/** + * Theme Switcher Utility + */ + +// Theme configuration +const THEMES = ['crimson', 'dark', 'light']; + +const THEME_ICONS = { + crimson: ``, + dark: ``, + light: ``, +}; + +const THEME_LABELS = { + crimson: 'Switch to dark mode', + dark: 'Switch to light mode', + light: 'Switch to crimson theme', +}; + +let currentTheme = localStorage.getItem('an-theme') || 'crimson'; + +function applyTheme(theme) { + document.documentElement.setAttribute('data-theme', theme); + document.querySelectorAll('.theme-toggle').forEach(btn => { + btn.innerHTML = THEME_ICONS[theme]; + btn.setAttribute('title', THEME_LABELS[theme]); + btn.setAttribute('aria-label', THEME_LABELS[theme]); + }); + localStorage.setItem('an-theme', theme); + currentTheme = theme; +} + +function nextTheme() { + const idx = THEMES.indexOf(currentTheme); + return THEMES[(idx + 1) % THEMES.length]; +} + +// Export for use in other files +window.ThemeUtils = { + THEMES, + applyTheme, + nextTheme, + getCurrentTheme: () => currentTheme, +}; diff --git a/privacy.html b/privacy.html new file mode 100644 index 0000000..1cd0eea --- /dev/null +++ b/privacy.html @@ -0,0 +1,519 @@ + + + + + + +Privacy Policy | ArcaneNeko + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + diff --git a/robots.txt b/robots.txt new file mode 100644 index 0000000..77f179f --- /dev/null +++ b/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://arcaneneko.com/sitemap.xml \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..b84af2b --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,73 @@ + + + + https://arcaneneko.com/ + weekly + 1.0 + + + https://arcaneneko.com/index + weekly + 1.0 + + + https://arcaneneko.com/status + monthly + 0.8 + + + https://arcaneneko.com/privacy + yearly + 0.3 + + + https://arcaneneko.com/terms + yearly + 0.3 + + + https://arcaneneko.com/contact + monthly + 0.5 + + + https://arcaneneko.com/coming-soon + weekly + 0.5 + + + https://arcaneneko.com/400 + yearly + 0.1 + + + https://arcaneneko.com/403 + yearly + 0.1 + + + https://arcaneneko.com/404 + yearly + 0.1 + + + https://arcaneneko.com/422 + yearly + 0.1 + + + https://arcaneneko.com/500 + yearly + 0.1 + + + https://arcaneneko.com/502 + yearly + 0.1 + + + https://arcaneneko.com/503 + yearly + 0.1 + + \ No newline at end of file diff --git a/status.html b/status.html new file mode 100644 index 0000000..4415285 --- /dev/null +++ b/status.html @@ -0,0 +1,173 @@ + + + + + + Arcane Status | Free Open Source Status Pages + + + + "> + + + + + + + + + + + + + + + + + + +
+ + +
+ +

ArcaneStatus

+

Free and open source status page software. Monitor your services and keep your users informed, self-hosted, no subscriptions.

+ +
+
+ + +
+
+ +

Everything you need

+
+
+

Real-time Monitoring

+

Monitor HTTP/HTTPS endpoints, TCP ports, and ICMP ping with configurable check intervals from 10 seconds to 1 hour.

+
+
+

Live Updates

+

WebSocket-powered real-time updates pushed to both the public status page and admin dashboard.

+
+
+

Incident Management

+

Create, update, and resolve incidents with severity levels. Link incidents to affected endpoints and write post-mortems.

+
+
+

Scheduled Maintenance

+

Schedule maintenance windows to pause monitoring and display notices to visitors.

+
+
+

Email Notifications

+

SMTP-based notifications with per-user preferences. Subscribe to all endpoints or specific categories.

+
+
+

API Access

+

Generate API keys for programmatic access. Rate-limited public API with status.json endpoint for integration.

+
+
+

Uptime Analytics

+

Automatic uptime calculation with SLA tracking, heatmaps, response time charts, and jitter/packet loss metrics.

+
+
+

Zero Dependencies

+

SQLite database only - no Redis or Postgres required. Just Node.js and you're ready to go.

+
+
+
+
+ + +
+
+ +

See it in action

+

Visit our live instance or grab the source code and host your own.

+ +
+
+ + + + + + + + + + diff --git a/terms.html b/terms.html new file mode 100644 index 0000000..c7cccd7 --- /dev/null +++ b/terms.html @@ -0,0 +1,334 @@ + + + + + + +Terms of Service | ArcaneNeko + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +