radiance: new home page — WebGL orb hero, DG cube loader, white dropdown menu
Replaces the Crush landing page with a single-screen hero (no scroll): gradient sky, particle orb with corona, 'Welcome to dangrubb.net' title, top-left DG logo and a numbered menu. Raw WebGL (no three.js), self-hosted Instrument Sans + Geist Mono. ~10 KB of JS.
This commit is contained in:
@ -1,182 +1,97 @@
|
||||
---
|
||||
import CrushBase from '../layouts/CrushBase.astro';
|
||||
import '@fontsource/instrument-sans/latin-400.css';
|
||||
import '@fontsource/instrument-sans/latin-500.css';
|
||||
import '@fontsource/geist-mono/latin-500.css';
|
||||
import '../styles/radiance.css';
|
||||
|
||||
const nav = [
|
||||
{ label: 'Intelligence Platform', href: 'https://ai.dangrubb.net' },
|
||||
{ label: 'Exclusive Music', href: '/music' },
|
||||
{ label: 'Multimedia Entertainment', href: 'https://pi.dangrubb.net/jellyfin' },
|
||||
{ label: 'Crypto', href: '#' },
|
||||
{ label: 'Storage Solutions', href: 'https://pi.dangrubb.net/nextcloud' },
|
||||
];
|
||||
const links = [
|
||||
{ label: 'Blog', href: '/blog' },
|
||||
{ label: 'CV', href: '/cv' },
|
||||
{ label: 'Git', href: 'https://pi.dangrubb.net/dangit' },
|
||||
];
|
||||
---
|
||||
|
||||
<CrushBase title="dangrubb.net">
|
||||
<div class="crush-page">
|
||||
<header class="top-banner">
|
||||
<div class="brand">
|
||||
<span class="brand-name">dangrubb</span><span class="brand-dot">.</span><span class="brand-tld">net</span>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>dangrubb.net</title>
|
||||
<meta name="description" content="Welcome to dangrubb.net" />
|
||||
<meta name="theme-color" content="#fff6f4" />
|
||||
<link rel="icon" href="/src/img/favicon.ico" type="image/x-icon" />
|
||||
<link rel="preload" as="image" href="/src/img/DanGrubbLogoWhite.png" />
|
||||
</head>
|
||||
<body class="is-loading">
|
||||
<div class="loader" id="loader" aria-hidden="true">
|
||||
<div class="loader__stage">
|
||||
<div class="scene">
|
||||
<div class="cube">
|
||||
<div class="cube__face cube__face--front"><img src="/src/img/DanGrubbLogoWhite.png" alt="" width="140" height="140" /></div>
|
||||
<div class="cube__face cube__face--back"><img src="/src/img/DanGrubbLogoWhite.png" alt="" width="140" height="140" /></div>
|
||||
<div class="cube__face cube__face--right"></div>
|
||||
<div class="cube__face cube__face--left"></div>
|
||||
<div class="cube__face cube__face--top"></div>
|
||||
<div class="cube__face cube__face--bottom"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="tagline">OFFICIAL SITE</p>
|
||||
<p class="loader__count" id="loader-count">000%</p>
|
||||
</div>
|
||||
|
||||
<header class="bar">
|
||||
<a class="bar__logo" href="/">
|
||||
<span class="sr-only">dangrubb.net home</span>
|
||||
<img src="/src/img/DanGrubbLogoDark.png" alt="" width="48" height="48" />
|
||||
</a>
|
||||
|
||||
<nav class="menu" id="menu" aria-label="Site">
|
||||
<button class="menu__btn" id="menu-btn" type="button" aria-expanded="false" aria-controls="menu-panel">
|
||||
<span class="sr-only">Site navigation</span>
|
||||
<svg class="menu__icon menu__icon--open" viewBox="0 0 18 14" width="18" height="14" aria-hidden="true">
|
||||
<path d="M0 1h2M5 1h13M0 7h10M13 7h5M0 13h2M5 13h13" stroke="currentColor" stroke-width="1.5" fill="none" />
|
||||
</svg>
|
||||
<svg class="menu__icon menu__icon--close" viewBox="0 0 18 18" width="18" height="18" aria-hidden="true">
|
||||
<path d="M1 1l16 16M17 1L1 17" stroke="currentColor" stroke-width="1.5" fill="none" />
|
||||
</svg>
|
||||
</button>
|
||||
<div class="menu__panel" id="menu-panel">
|
||||
<ul class="menu__list">
|
||||
{nav.map((item, i) => (
|
||||
<li>
|
||||
<a href={item.href}>
|
||||
<span class="menu__num">{String(i + 1).padStart(2, '0')}</span>
|
||||
<span class="menu__label">{item.label}</span>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div class="menu__links">
|
||||
{links.map((l) => (
|
||||
<a class="menu__link" href={l.href}><span>{l.label}</span></a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="logo-section">
|
||||
<img src="/src/img/pack-splatter.png" alt="" class="splatter-img">
|
||||
<div class="logo-center">
|
||||
<img src="/src/img/DanGrubbLogoTeal.png" alt="DanGrubb" class="logo-img">
|
||||
</div>
|
||||
<main class="hero">
|
||||
<canvas class="hero__orb" id="orb" aria-hidden="true"></canvas>
|
||||
<h1 class="hero__title" id="title">Welcome to dangrubb.net</h1>
|
||||
</main>
|
||||
|
||||
<footer class="bottom-nav">
|
||||
<a href="https://ai.dangrubb.net" class="nav-item">AI</a>
|
||||
<span class="nav-dot">•</span>
|
||||
<a href="/blog" class="nav-item">BLOG</a>
|
||||
<span class="nav-dot">•</span>
|
||||
<a href="/music" class="nav-item">MUSIC</a>
|
||||
<span class="nav-dot">•</span>
|
||||
<a href="https://pi.dangrubb.net/jellyfin" class="nav-item">MEDIA</a>
|
||||
<span class="nav-dot">•</span>
|
||||
<a href="https://pi.dangrubb.net/nextcloud" class="nav-item">STORAGE</a>
|
||||
<span class="nav-dot">•</span>
|
||||
<a href="/cv" class="nav-item">CV</a>
|
||||
<span class="nav-dot">•</span>
|
||||
<a href="https://pi.dangrubb.net/dangit" class="nav-item">GIT</a>
|
||||
</footer>
|
||||
</div>
|
||||
</CrushBase>
|
||||
<script>
|
||||
import { startOrb } from '../scripts/orb.js';
|
||||
import { initUI } from '../scripts/ui.js';
|
||||
|
||||
<style>
|
||||
.crush-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
margin: 0;
|
||||
background: var(--crush-white);
|
||||
}
|
||||
|
||||
.top-banner {
|
||||
text-align: center;
|
||||
padding: 16px 20px 10px;
|
||||
background: linear-gradient(180deg, #e8f5f5 0%, transparent 100%);
|
||||
border-bottom: 3px solid var(--crush-teal);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.brand {
|
||||
font-family: 'Alfa Slab One', 'Georgia', serif;
|
||||
font-size: clamp(3rem, 10vw, 5rem);
|
||||
color: var(--crush-teal);
|
||||
letter-spacing: -2px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.brand-dot { color: var(--crush-teal-light); }
|
||||
.brand-tld { color: var(--crush-teal-dark); }
|
||||
|
||||
.tagline {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 4px;
|
||||
color: var(--crush-teal);
|
||||
margin-top: 8px;
|
||||
text-transform: uppercase;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.logo-section {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.splatter-img {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.logo-center {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.logo-img {
|
||||
width: 12%;
|
||||
max-width: 160px;
|
||||
aspect-ratio: 1;
|
||||
object-fit: contain;
|
||||
filter: drop-shadow(0 3px 8px rgba(0, 102, 102, 0.3));
|
||||
}
|
||||
|
||||
.bottom-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
padding: 20px 20px 28px;
|
||||
background: linear-gradient(0deg, #e8f5f5 0%, transparent 100%);
|
||||
border-top: 3px solid var(--crush-teal);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: var(--crush-teal);
|
||||
letter-spacing: 2px;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
background: rgba(0, 139, 139, 0.05);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
background: rgba(0, 139, 139, 0.15);
|
||||
color: var(--crush-teal-dark);
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 4px 12px rgba(0, 139, 139, 0.2);
|
||||
}
|
||||
|
||||
.nav-dot {
|
||||
font-size: 20px;
|
||||
color: var(--crush-teal);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.brand { font-size: 2.5rem; }
|
||||
.top-banner {
|
||||
flex: 1;
|
||||
flex-shrink: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 12px 15px;
|
||||
}
|
||||
.logo-section {
|
||||
aspect-ratio: 3 / 4;
|
||||
flex: none;
|
||||
}
|
||||
.splatter-img {
|
||||
object-fit: cover;
|
||||
}
|
||||
.logo-img { width: 36%; }
|
||||
.nav-item { font-size: 16px; padding: 8px 14px; }
|
||||
.bottom-nav {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 3px;
|
||||
padding: 4px 12px;
|
||||
}
|
||||
.nav-dot { display: none; }
|
||||
}
|
||||
</style>
|
||||
initUI(startOrb);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user