Compare commits

...
3 Commits
10 changed files with 5918 additions and 0 deletions
+11
View File
@@ -1611,6 +1611,17 @@
<a href="experiments.html" style="color:var(--accent);text-decoration:none;">Internet History</a>
</div>
Built by Miles · 2026 · Powered by too much coffee and the Konami code
<div style="margin-top:28px;">
<a href="redesign/hub.html" style="
display:inline-flex;align-items:center;gap:10px;
font-family:var(--font-pixel);font-size:9px;text-transform:uppercase;letter-spacing:.06em;
padding:14px 22px;border:2px solid rgba(255,255,255,.2);color:var(--muted);
transition:all .2s;
" onmouseover="this.style.borderColor='var(--accent)';this.style.color='var(--accent)';this.style.transform='translateY(-2px)';"
onmouseout="this.style.borderColor='rgba(255,255,255,.2)';this.style.color='var(--muted)';this.style.transform='';">
✦ VIEW REDESIGNS
</a>
</div>
</footer>
<script src="projects/script.js"></script>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

+463
View File
@@ -0,0 +1,463 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Redesign Lab — Miles Wolf Allen</title>
<meta name="description" content="A collection of experimental redesigns of milesallen.site — work in progress.">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' fill='%23F7FF00'/%3E%3Ctext x='50' y='72' font-size='60' font-family='Arial Black' font-weight='900' text-anchor='middle' fill='%23000'%3ER%3C/text%3E%3C/svg%3E">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Archivo+Black&family=Press+Start+2P&family=Space+Mono:wght@400;700&family=Playfair+Display:ital,wght@0,900;1,700&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--bg: #08080a;
--bg2: #111116;
--ink: #fff;
--muted: #666672;
--dim: #232329;
--yellow: #F7FF00;
--pink: #FF2EA6;
--cyan: #00F4FF;
--orange: #FF5C00;
--green: #00FF85;
--rule: rgba(255,255,255,.08);
--serif: 'Archivo Black', sans-serif;
--mono: 'Space Mono', monospace;
--pixel: 'Press Start 2P', monospace;
--elegant:'Playfair Display', serif;
}
html { scroll-behavior: smooth; overflow-x: hidden; }
html, html::-webkit-scrollbar { scrollbar-width: none; }
html::-webkit-scrollbar { display: none; }
body {
background: var(--bg);
color: var(--ink);
font-family: var(--mono);
font-size: 14px;
line-height: 1.6;
-webkit-font-smoothing: antialiased;
}
::selection { background: var(--yellow); color: #000; }
a { color: inherit; text-decoration: none; }
/* ── grid bg ── */
body::before {
content: '';
position: fixed; inset: 0; z-index: 0; pointer-events: none;
background-image:
linear-gradient(rgba(255,255,255,.025) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,.025) 1px, transparent 1px);
background-size: 52px 52px;
}
/* ── NAV ── */
.nav {
position: sticky; top: 0; z-index: 100;
padding: 16px 5vw;
display: flex; align-items: center; justify-content: space-between;
background: rgba(8,8,10,.9); border-bottom: 3px solid #000;
backdrop-filter: blur(8px); box-shadow: 0 3px 0 #000;
}
.nav-back {
font-family: var(--pixel); font-size: 8px; text-transform: uppercase;
letter-spacing: .06em; color: var(--muted);
display: flex; align-items: center; gap: 8px;
padding: 9px 14px; border: 2px solid var(--dim);
transition: all .15s;
}
.nav-back:hover { color: #fff; border-color: #fff; background: rgba(255,255,255,.05); }
.nav-title { font-family: var(--pixel); font-size: 9px; text-transform: uppercase; letter-spacing: .08em; color: var(--yellow); }
.nav-count { font-family: var(--pixel); font-size: 8px; color: var(--muted); }
/* ── HERO ── */
.hero {
position: relative; z-index: 1;
padding: clamp(60px,10vw,120px) 5vw clamp(40px,6vw,70px);
border-bottom: 3px solid #000;
overflow: hidden;
}
.hero-tag {
font-family: var(--pixel); font-size: 8px; text-transform: uppercase;
letter-spacing: .1em; color: #000; background: var(--yellow);
display: inline-block; padding: 9px 14px; border: 3px solid #000;
box-shadow: 4px 4px 0 #000; transform: rotate(-1.5deg);
margin-bottom: 28px;
}
.hero-title {
font-family: var(--serif);
font-size: clamp(52px, 12vw, 160px);
line-height: .88; letter-spacing: -.03em; text-transform: uppercase;
position: relative; z-index: 2;
}
.hero-title .row-2 { display: block; margin-left: .5em; color: transparent; -webkit-text-stroke: 2px rgba(255,255,255,.5); }
.hero-sub {
font-family: var(--mono); font-size: clamp(12px, 1.1vw, 15px);
color: var(--muted); max-width: 52ch; line-height: 1.8;
margin-top: 24px; padding-left: 16px; border-left: 4px solid var(--pink);
}
/* big ghost text */
.hero-ghost {
position: absolute; right: -2vw; bottom: -0.1em; z-index: 0;
font-family: var(--serif); font-size: clamp(100px, 22vw, 280px);
font-weight: 900; text-transform: uppercase;
color: transparent; -webkit-text-stroke: 1.5px rgba(255,255,255,.05);
user-select: none; pointer-events: none; line-height: .85;
}
/* ── GRID ── */
.grid-section {
position: relative; z-index: 1;
padding: clamp(48px,7vw,88px) 5vw;
}
.grid-label {
font-family: var(--pixel); font-size: 8px; text-transform: uppercase;
letter-spacing: .1em; color: var(--muted);
display: flex; align-items: center; gap: 12px;
margin-bottom: 32px;
}
.grid-label::after { content: ''; flex: 1; height: 1px; background: var(--rule); }
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(100%, 380px), 1fr));
gap: 24px;
}
/* ── CARD ── */
.card {
display: block; position: relative;
border: 4px solid #000; background: var(--bg2);
box-shadow: 8px 8px 0 #000;
transition: transform .18s, box-shadow .18s;
overflow: hidden;
}
.card:hover { transform: translate(-3px,-3px); box-shadow: 12px 12px 0 var(--pink); }
/* tape decoration */
.card::before {
content: ''; position: absolute; top: -7px; right: 24px;
width: 50px; height: 18px; opacity: .85;
transform: rotate(2deg); box-shadow: 0 0 0 2px #000; z-index: 2;
}
/* tape colours per variant */
.card:nth-child(6n+1)::before { background: var(--yellow); }
.card:nth-child(6n+2)::before { background: var(--pink); }
.card:nth-child(6n+3)::before { background: var(--cyan); }
.card:nth-child(6n+4)::before { background: var(--orange); }
.card:nth-child(6n+5)::before { background: var(--green); }
.card:nth-child(6n)::before { background: #fff; }
/* slight tilts */
.card:nth-child(odd) { transform: rotate(-.6deg); }
.card:nth-child(even) { transform: rotate(.5deg) translateY(4px); }
.card:nth-child(3n) { transform: rotate(-.3deg); }
.card:hover { transform: rotate(0) translate(-3px,-3px) !important; }
/* preview area */
.card-preview {
width: 100%; aspect-ratio: 16/9;
background: var(--dim); overflow: hidden; position: relative;
border-bottom: 3px solid #000;
}
.card-preview iframe {
width: 200%; height: 200%;
transform: scale(.5); transform-origin: top left;
border: 0; pointer-events: none;
position: absolute; top: 0; left: 0;
}
/* fallback solid color when no iframe */
.card-preview.solid { display: flex; align-items: center; justify-content: center; }
.card-preview.solid .preview-label {
font-family: var(--serif); font-size: clamp(32px,6vw,72px);
font-weight: 900; text-transform: uppercase; letter-spacing: -.03em;
opacity: .18; user-select: none;
}
/* card body */
.card-body { padding: 22px 24px 26px; }
.card-num {
font-family: var(--pixel); font-size: 7px; color: var(--muted);
letter-spacing: .08em; margin-bottom: 10px;
}
.card-name {
font-family: var(--serif); font-size: clamp(20px,2.4vw,28px);
font-weight: 900; text-transform: uppercase; line-height: 1;
margin-bottom: 10px; letter-spacing: -.01em;
}
.card-desc { font-size: 12px; color: var(--muted); line-height: 1.75; margin-bottom: 16px; }
.card-footer {
display: flex; align-items: center; justify-content: space-between;
border-top: 2px dashed rgba(255,255,255,.1); padding-top: 14px;
}
.card-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.ctag {
font-family: var(--pixel); font-size: 6px; text-transform: uppercase;
padding: 5px 8px; border: 2px solid #000; box-shadow: 2px 2px 0 #000; color: #000;
}
.ctag-y { background: var(--yellow); }
.ctag-p { background: var(--pink); }
.ctag-c { background: var(--cyan); }
.ctag-w { background: #fff; }
.ctag-g { background: var(--green); }
.card-arrow {
font-size: 18px; color: var(--muted);
transition: transform .2s, color .2s;
}
.card:hover .card-arrow { transform: translate(3px,-3px); color: var(--pink); }
/* ── FEATURED (full-width) ── */
.card.featured {
grid-column: 1 / -1;
display: grid; grid-template-columns: 1fr 1fr;
transform: none !important;
}
.card.featured:hover { transform: translate(-3px,-3px) !important; }
.card.featured .card-preview {
aspect-ratio: unset; height: 100%; border-bottom: 0; border-right: 3px solid #000;
}
.card.featured .card-body {
padding: 32px 36px 36px;
display: flex; flex-direction: column; justify-content: space-between;
}
.card.featured .card-name { font-size: clamp(26px,4vw,52px); }
@media (max-width: 700px) {
.card.featured { grid-template-columns: 1fr; }
.card.featured .card-preview { height: auto; aspect-ratio: 16/9; border-right: 0; border-bottom: 3px solid #000; }
}
/* ── FOOTER ── */
.foot {
position: relative; z-index: 1;
border-top: 3px solid #000; padding: 28px 5vw;
display: flex; align-items: center; justify-content: space-between;
flex-wrap: wrap; gap: 12px;
background: #000;
}
.foot-copy { font-family: var(--pixel); font-size: 7px; color: var(--muted); letter-spacing: .06em; text-transform: uppercase; }
.foot-link { font-family: var(--pixel); font-size: 7px; color: var(--yellow); letter-spacing: .06em; text-transform: uppercase; transition: opacity .2s; }
.foot-link:hover { opacity: .6; }
/* ── ENTRY ANIMATIONS ── */
html.js .card { opacity: 0; transform: translateY(30px) rotate(-.5deg); }
html.js .card.visible { animation: cardIn .6s cubic-bezier(.16,1,.3,1) forwards; }
@keyframes cardIn {
to { opacity: 1; transform: translateY(0) rotate(0); }
}
/* restore the slight tilt after entrance */
html.js .card.visible:nth-child(odd) { animation-name: cardInOdd; }
html.js .card.visible:nth-child(even) { animation-name: cardInEven; }
html.js .card.visible:nth-child(3n) { animation-name: cardIn3n; }
@keyframes cardInOdd { to { opacity: 1; transform: rotate(-.6deg); } }
@keyframes cardInEven { to { opacity: 1; transform: rotate(.5deg) translateY(4px); } }
@keyframes cardIn3n { to { opacity: 1; transform: rotate(-.3deg); } }
html.js .card.featured { animation-name: cardIn !important; }
html.js .card.featured:hover { transform: translate(-3px,-3px) !important; }
@media (prefers-reduced-motion: reduce) {
html.js .card { opacity: 1; transform: none; animation: none !important; }
}
</style>
</head>
<body>
<!-- nav -->
<nav class="nav">
<a class="nav-back" href="../index.html">← Back to site</a>
<span class="nav-title">Redesign Lab</span>
<span class="nav-count">6 experiments</span>
</nav>
<!-- hero -->
<div class="hero">
<div class="hero-ghost" aria-hidden="true">LAB</div>
<div class="hero-tag">Work in progress</div>
<h1 class="hero-title">
Redesign<span class="row-2">Lab.</span>
</h1>
<p class="hero-sub">
Experimental redesigns of milesallen.site — exploring different design languages,
animation approaches, and visual directions. None of these are "the" answer, just iterations.
</p>
</div>
<!-- cards -->
<section class="grid-section">
<div class="grid-label">All experiments — newest first</div>
<div class="cards" id="cards">
<!-- index-four-max: featured -->
<a class="card featured" href="index-four-max.html">
<div class="card-preview">
<iframe src="index-four-max.html" title="index-four-max preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe>
</div>
<div class="card-body">
<div>
<div class="card-num">06 — Latest</div>
<div class="card-name">Cinematic Max</div>
<p class="card-desc">
The award-quality editorial design of index-four — same loader, inertia scroll, pinned horizontal devlog, GSAP parallax — but rebuilt as full maximalism. Dark bg, neon palette, Archivo Black, hard box shadows, glitch on the hero title, neo-brutalist project rows that fill with yellow/pink/cyan on hover.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<span class="ctag ctag-p">Maximalist</span>
<span class="ctag ctag-y">GSAP</span>
<span class="ctag ctag-c">Horizontal scroll</span>
<span class="ctag ctag-w">Glitch</span>
</div>
<span class="card-arrow"></span>
</div>
</div>
</a>
<!-- index-four -->
<a class="card" href="index-four.html">
<div class="card-preview">
<iframe src="index-four.html" title="index-four preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe>
</div>
<div class="card-body">
<div class="card-num">05</div>
<div class="card-name">Cinematic Minimal</div>
<p class="card-desc">
Warm parchment palette, Playfair Display serif, smooth wheel inertia, counter loader, custom morphing cursor, pinned horizontal devlog scroll, GSAP parallax on the hero, project rows with ink-fill hover wipe.
</p>
<div class="card-footer">
<div class="card-tags">
<span class="ctag ctag-w">Minimal</span>
<span class="ctag ctag-y">GSAP</span>
<span class="ctag ctag-g">Serif</span>
</div>
<span class="card-arrow"></span>
</div>
</div>
</a>
<!-- try-three -->
<a class="card" href="try-three.html">
<div class="card-preview">
<iframe src="try-three.html" title="try-three preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe>
</div>
<div class="card-body">
<div class="card-num">04</div>
<div class="card-name">Maximus v3</div>
<p class="card-desc">
Polished Maximus language with orbital hero rings, scroll progress bar, sticky chip nav, 4 marquee bands, GSAP project card choreography, count-up stats, and Konami confetti.
</p>
<div class="card-footer">
<div class="card-tags">
<span class="ctag ctag-p">Maximalist</span>
<span class="ctag ctag-y">GSAP</span>
</div>
<span class="card-arrow"></span>
</div>
</div>
</a>
<!-- index-three -->
<a class="card" href="index-three.html">
<div class="card-preview">
<iframe src="index-three.html" title="index-three preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe>
</div>
<div class="card-body">
<div class="card-num">03</div>
<div class="card-name">Deep Green Editorial</div>
<p class="card-desc">
Dark green + beige palette, Anton display type, custom cursor with label, expand/collapse project rows, sticky nav that color-switches between sections, and a full-screen yellow contact footer.
</p>
<div class="card-footer">
<div class="card-tags">
<span class="ctag ctag-g">Editorial</span>
<span class="ctag ctag-w">Custom cursor</span>
</div>
<span class="card-arrow"></span>
</div>
</div>
</a>
<!-- index-two -->
<a class="card" href="index-two.html">
<div class="card-preview">
<iframe src="index-two.html" title="index-two preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe>
</div>
<div class="card-body">
<div class="card-num">02</div>
<div class="card-name">Multi-Theme System</div>
<p class="card-desc">
Three switchable themes — dark, light, and MAX — with a live clock, mouse coordinate tracker, SVG signature draw animation, ambient audio toggle, and scroll progress bar.
</p>
<div class="card-footer">
<div class="card-tags">
<span class="ctag ctag-c">Multi-theme</span>
<span class="ctag ctag-y">Audio</span>
<span class="ctag ctag-w">SVG draw</span>
</div>
<span class="card-arrow"></span>
</div>
</div>
</a>
<!-- index (original redesign) -->
<a class="card" href="index.html">
<div class="card-preview">
<iframe src="index.html" title="index redesign preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe>
</div>
<div class="card-body">
<div class="card-num">01 — First</div>
<div class="card-name">Maximus OG</div>
<p class="card-desc">
The original Maximus design language. Dark bg, neon palette, Archivo Black + Press Start 2P, hard box shadows, splash screen, cursor glow, GSAP scroll choreography, project card parallax, and Konami party mode.
</p>
<div class="card-footer">
<div class="card-tags">
<span class="ctag ctag-p">Maximalist</span>
<span class="ctag ctag-y">GSAP</span>
<span class="ctag ctag-c">Original</span>
</div>
<span class="card-arrow"></span>
</div>
</div>
</a>
</div>
</section>
<!-- footer -->
<footer class="foot">
<span class="foot-copy">© 2026 Miles Wolf Allen — Redesign Lab</span>
<a class="foot-link" href="../index.html">← Back to site</a>
</footer>
<script>
(function () {
// staggered card entrance on scroll
var cards = document.querySelectorAll('.card');
if ('IntersectionObserver' in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
if (e.isIntersecting) {
e.target.classList.add('visible');
e.target.style.animationDelay = (Array.prototype.indexOf.call(cards, e.target) % 3) * 0.08 + 's';
io.unobserve(e.target);
}
});
}, { threshold: 0.08 });
cards.forEach(function (c) { io.observe(c); });
} else {
cards.forEach(function (c) { c.classList.add('visible'); });
}
// hover — expand card shadow with correct colour cycling
cards.forEach(function (card) {
card.addEventListener('mouseenter', function () {
card.style.zIndex = '10';
});
card.addEventListener('mouseleave', function () {
card.style.zIndex = '';
});
});
})();
</script>
</body>
</html>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+445
View File
@@ -0,0 +1,445 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light">
<meta name="theme-color" content="#083D2A">
<title>Miles Wolf Allen — Developer &amp; Interactive Builder</title>
<meta name="description" content="Miles Wolf Allen — Developer & 3D artist. I make software feel good to use — games, tools, websites, and a world without bundled Chromium.">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' fill='%23083D2A'/%3E%3Ctext x='50' y='74' font-size='60' font-family='Anton' font-weight='900' text-anchor='middle' fill='%23F6E016'%3EM%3C/text%3E%3C/svg%3E">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Anton&family=Space+Grotesk:wght@400;500;700&display=swap" rel="stylesheet">
<script>document.documentElement.className='js';</script>
<style>
:root{
--green:#083D2A; --beige:#EED6C8; --paper:#F7F7F7; --ink:#022016;
--yellow:#F6E016; --dot:#008841; --rule:rgba(0,0,0,.1);
--t:'Anton','Archivo Black',sans-serif; --b:'Space Grotesk','Neue Haas Grotesk',sans-serif;
}
*{margin:0;padding:0;box-sizing:border-box;}
html{font-size:clamp(12px,.9722222222vw,28px);scroll-behavior:smooth;}
@media(min-width:1920px){html{font-size:1vw;}}
body{background:var(--paper);color:var(--ink);font-family:var(--b);line-height:1.5;overflow-x:hidden;-webkit-font-smoothing:antialiased;text-size-adjust:none;}
body,html{scrollbar-width:none;}
body::-webkit-scrollbar{display:none;}
a{color:inherit;text-decoration:none;}
::selection{background:var(--yellow);color:var(--ink);}
img{max-width:100%;display:block;}
.grid{width:100%;max-width:2560px;margin:0 auto;display:grid;grid-template-columns:repeat(12,1fr);grid-column-gap:clamp(8px,1.39vw,40px);padding:0 clamp(16px,2.857vw,80px);}
.meta{font-family:var(--b);font-size:.9722222222vw;font-size:clamp(10px,.972vw,16px);text-transform:uppercase;letter-spacing:.04em;}
.star{font-size:2.36vw;font-size:clamp(18px,2.36vw,40px);line-height:.6;color:inherit;}
/* ---------- custom cursor ---------- */
.cursor{position:fixed;z-index:2000;left:0;top:0;pointer-events:none;display:flex;align-items:center;justify-content:center;width:4.2rem;height:4.2rem;border-radius:3.57rem;background:var(--yellow);color:var(--ink);font-family:var(--b);font-size:.76vw;font-size:clamp(9px,.76vw,14px);text-transform:uppercase;letter-spacing:.04em;transform:translate(-50%,-50%) scale(0);transition:transform .35s cubic-bezier(.16,1,.1,1),width .35s cubic-bezier(.16,1,.1,1),height .35s cubic-bezier(.16,1,.1,1);will-change:transform;}
.cursor.show{transform:translate(-50%,-50%) scale(1);}
.cursor.big{width:7rem;height:7rem;}
@media(pointer:coarse){.cursor{display:none;}}
/* ---------- navbar ---------- */
.nav{position:fixed;top:0;left:0;width:100%;z-index:4;margin-top:2.85rem;padding:0 clamp(16px,2.857vw,80px);display:flex;align-items:center;justify-content:space-between;color:var(--beige);opacity:0;animation:fadeNav 1s .5s ease forwards;transition:color .4s ease;}
@keyframes fadeNav{to{opacity:1;}}
body.nav-ink .nav{color:var(--ink);}
body.nav-ink .nav-link::before,body.nav-ink .foot-socials a::before{background:currentColor;}
.nav-logo{font-family:var(--t);font-size:1.1rem;letter-spacing:.03em;text-transform:uppercase;}
.nav-links{display:flex;gap:1.5rem;align-items:center;}
.nav-link{position:relative;padding-bottom:.25rem;text-transform:uppercase;font-size:.72rem;letter-spacing:.06em;}
.nav-link::before{content:'';position:absolute;left:0;bottom:0;width:100%;height:1px;background:currentColor;transform:scaleX(0);transform-origin:right;transition:transform .75s cubic-bezier(.16,1,.1,1);}
.nav-link:hover::before{transform:scaleX(1);transform-origin:left;}
.nav-pill{display:inline-flex;align-items:center;gap:.45rem;background:var(--yellow);color:var(--ink);border-radius:7.14rem;padding:.45rem .9rem;font-size:.68rem;text-transform:uppercase;letter-spacing:.04em;}
.nav-pill i{width:.55rem;height:.55rem;border-radius:50%;background:var(--dot);}
/* ---------- hero ---------- */
.hero{position:relative;min-height:100dvh;background:var(--green);color:var(--beige);display:flex;flex-direction:column;justify-content:center;overflow:hidden;}
.hero::after{content:'';position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse at 78% 30%,rgba(238,214,200,.05),transparent 55%);}
.hero-meta{position:absolute;top:6.8rem;left:0;right:0;display:flex;justify-content:space-between;align-items:center;color:var(--beige);opacity:.75;}
.hero-meta .meta:nth-child(2){text-align:center;}
.hero-grid{position:relative;z-index:1;padding-top:4rem;padding-bottom:6rem;}
.hero-title{grid-column:1 / -1;font-family:var(--t);font-weight:400;text-transform:uppercase;line-height:.9;letter-spacing:.005em;}
.hero-title .line{overflow:hidden;}
.hero-title .line>span{display:block;font-size:11.25vw;font-size:clamp(52px,11.25vw,320px);transform:translateY(112%);transition:transform 1.2s cubic-bezier(.16,1,.1,1);}
html.js .in .hero-title .line>span{transform:translateY(0);}
html.js .hero-title .line:nth-child(2)>span{transition-delay:.12s;}
.hero-title .l2{color:var(--yellow);}
.hero-sub{grid-column:1 / 9;margin-top:2.2rem;font-size:clamp(15px,1.25vw,34px);line-height:1.3;opacity:.9;}
.hero-cta{grid-column:1 / 13;display:flex;justify-content:space-between;align-items:flex-end;margin-top:2.8rem;}
.hero-cta .meta{opacity:.7;}
.scroll-cue{display:inline-flex;align-items:center;gap:.6rem;font-size:.68rem;text-transform:uppercase;letter-spacing:.06em;opacity:.8;}
.scroll-cue .bar{width:1px;height:3.4rem;background:var(--beige);opacity:.5;animation:cue 2.2s cubic-bezier(.16,1,.1,1) infinite;}
@keyframes cue{0%{transform:scaleY(0);transform-origin:top;}45%{transform:scaleY(1);transform-origin:top;}55%{transform:scaleY(1);transform-origin:bottom;}100%{transform:scaleY(0);transform-origin:bottom;}}
/* ---------- statement (sticky) ---------- */
.statement{height:220dvh;background:var(--paper);color:var(--ink);}
.statement-in{position:sticky;top:0;height:100dvh;display:flex;align-items:center;justify-content:center;text-align:center;}
.statement p{max-width:34.7vw;font-size:clamp(20px,1.66vw,48px);line-height:1.25;}
.statement .star{display:block;margin:0 auto 1.4rem;}
@media(max-width:900px){.statement p{max-width:80vw;}}
/* ---------- about ---------- */
.about{background:var(--green);color:var(--beige);padding-top:11.8vw;padding-bottom:11.8vw;}
.about-title{grid-column:1 / -1;font-family:var(--t);font-size:clamp(40px,6vw,160px);text-transform:uppercase;line-height:.9;}
.about-col{grid-column:2 / 7;margin-top:6rem;font-size:clamp(15px,1.25vw,34px);line-height:1.45;}
.about-col p+p{margin-top:1.4rem;}
.about-body{grid-column:8 / 13;margin-top:6rem;}
.about-body .meta{opacity:.75;margin-bottom:1.2rem;}
.about-line{padding:1.1rem 0;border-top:1px solid rgba(238,214,200,.18);display:flex;justify-content:space-between;gap:2rem;font-size:clamp(14px,1vw,28px);}
.about-line span:last-child{opacity:.55;text-align:right;}
.about-badge{margin-top:2.6rem;}
@media(max-width:900px){.about-col{grid-column:1 / -1;margin-top:3rem;} .about-body{grid-column:1 / -1;margin-top:3rem;} .about{padding-top:6rem;padding-bottom:6rem;}}
/* ---------- work archive ---------- */
.work{background:var(--paper);color:var(--ink);padding-top:11.8vw;padding-bottom:8vw;}
.work-head{grid-column:1 / -1;display:flex;justify-content:space-between;align-items:baseline;margin-bottom:2rem;}
.work-head h2{font-family:var(--t);font-size:clamp(30px,3.6vw,104px);text-transform:uppercase;line-height:.9;}
.work-head .meta{opacity:.5;}
.prow{grid-column:1 / -1;border-top:1px solid var(--rule);}
.prow:last-child{border-bottom:1px solid var(--rule);}
.prow-head{display:grid;grid-template-columns:1fr 7fr 2fr 2fr .5fr;align-items:center;gap:1rem;padding:1.1rem 0;cursor:pointer;position:relative;}
.prow-num{font-size:clamp(12px,.83vw,22px);opacity:.4;}
.prow-name{font-family:var(--t);font-size:clamp(20px,2.63vw,76px);text-transform:uppercase;line-height:1;letter-spacing:.005em;}
.prow-type{font-size:clamp(11px,.83vw,20px);opacity:.3;}
.prow-year{font-size:clamp(11px,.83vw,20px);opacity:.5;}
.prow-arrow{width:.75rem;height:.75rem;position:relative;transition:transform .6s cubic-bezier(.16,1,.1,1);}
.prow-arrow::before,.prow-arrow::after{content:'';position:absolute;inset:0;background:var(--ink);transition:transform .6s cubic-bezier(.16,1,.1,1);}
.prow-arrow::before{-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Crect width='12' height='2' y='5'/%3E%3Crect width='2' height='12' x='5'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Crect width='12' height='2' y='5'/%3E%3Crect width='2' height='12' x='5'/%3E%3C/svg%3E") center/contain no-repeat;background:var(--ink);}
.prow-arrow::after{background:var(--yellow);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Crect width='12' height='2' y='5'/%3E%3Crect width='2' height='12' x='5'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Crect width='12' height='2' y='5'/%3E%3Crect width='2' height='12' x='5'/%3E%3C/svg%3E") center/contain no-repeat;transform:translate(-100%,100%);}
.prow:hover .prow-arrow::before{transform:translate(100%,-100%);}
.prow:hover .prow-arrow::after{transform:translate(0,0);}
.prow-body{max-height:0;overflow:hidden;transition:max-height 1s cubic-bezier(.16,1,.1,1);}
.prow-body-in{display:flex;flex-wrap:wrap;align-items:baseline;gap:1.2rem 2.5rem;padding:0 0 1.6rem;opacity:.75;}
.prow.open .prow-body{max-height:14rem;}
.prow-desc{font-size:clamp(13px,.97vw,26px);line-height:1.4;}
.prow-visit{font-size:.72rem;text-transform:uppercase;letter-spacing:.06em;position:relative;padding-bottom:.2rem;}
.prow-visit::before{content:'';position:absolute;left:0;bottom:0;width:100%;height:1px;background:currentColor;transform:scaleX(0);transform-origin:right;transition:transform .75s cubic-bezier(.16,1,.1,1);}
.prow-visit:hover::before{transform:scaleX(1);transform-origin:left;}
@media(max-width:768px){.prow-head{grid-template-columns:1fr 4fr 1.2fr;}.prow-type{display:none;} .prow-year{display:none;}}
.work-foot{grid-column:1 / -1;margin-top:3rem;display:flex;justify-content:space-between;align-items:baseline;opacity:.6;}
.work-foot .meta{opacity:.7;}
/* ---------- stats ---------- */
.stats{background:var(--paper);color:var(--ink);padding-bottom:8vw;}
.stats .grid{border-top:1px solid var(--rule);}
.stat{padding:2.4rem 0;grid-column:span 3;border-right:1px solid var(--rule);text-align:center;}
.stat:first-child{border-left:1px solid var(--rule);}
.stat b{display:block;font-family:var(--t);font-weight:400;font-size:clamp(34px,3.6vw,104px);line-height:1;}
.stat span{display:block;margin-top:.6rem;text-transform:uppercase;font-size:.72rem;letter-spacing:.06em;opacity:.5;}
@media(max-width:768px){.stat{grid-column:span 6;margin-top:-1px;} .stat:nth-child(3){border-left:1px solid var(--rule);} .stat:nth-child(odd){border-right:1px solid var(--rule);}}
@media(max-width:480px){.stat{grid-column:span 12;}}
/* ---------- marquee ---------- */
.mq{background:var(--green);color:var(--beige);overflow:hidden;padding:4rem 0;border-top:1px solid rgba(238,214,200,.18);border-bottom:1px solid rgba(238,214,200,.18);}
.mq-track{display:flex;width:max-content;animation:mq 28s linear infinite;white-space:nowrap;font-family:var(--t);text-transform:uppercase;font-size:clamp(28px,5.2vw,150px);line-height:1;}
.mq-track span{display:inline-flex;align-items:center;gap:2rem;padding-right:2rem;}
.mq-track .star{color:var(--yellow);}
@keyframes mq{to{transform:translateX(-50%);}}
/* ---------- footer ---------- */
footer{background:var(--yellow);color:var(--ink);min-height:100dvh;display:flex;flex-direction:column;justify-content:flex-end;padding:11.8vw clamp(16px,2.857vw,80px) 2.85rem;overflow:hidden;}
.foot-title{font-family:var(--t);text-transform:uppercase;line-height:.85;font-size:clamp(42px,8.19vw,236px);}
.foot-title .line{overflow:hidden;}
.foot-title .line>span{display:block;transform:translateY(112%);transition:transform 1.2s cubic-bezier(.16,1,.1,1);}
html.js .in .foot-title .line>span{transform:translateY(0);}
.foot-mail{display:inline-block;margin-top:3rem;font-family:var(--t);text-transform:uppercase;font-size:clamp(20px,2.63vw,76px);line-height:1;}
.foot-mail{position:relative;padding-bottom:.15em;}
.foot-mail::before{content:'';position:absolute;left:0;bottom:0;width:100%;height:2px;background:currentColor;transform:scaleX(0);transform-origin:right;transition:transform .9s cubic-bezier(.16,1,.1,1);}
.foot-mail:hover::before{transform:scaleX(1);transform-origin:left;}
.foot-meta{display:flex;justify-content:space-between;align-items:baseline;margin-top:4rem;border-top:1px solid rgba(2,32,22,.25);padding-top:1.4rem;gap:2rem;flex-wrap:wrap;}
.foot-socials{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;}
.foot-socials a{text-transform:uppercase;font-size:.72rem;letter-spacing:.06em;position:relative;padding-bottom:.2rem;}
.foot-socials a::before{content:'';position:absolute;left:0;bottom:0;width:100%;height:1px;background:currentColor;transform:scaleX(0);transform-origin:right;transition:transform .75s cubic-bezier(.16,1,.1,1);}
.foot-socials a:hover::before{transform:scaleX(1);transform-origin:left;}
.foot-socials i{width:.32rem;height:.32rem;border-radius:50%;background:currentColor;}
@media(max-width:768px){
.hero-meta .meta:nth-child(2){display:none;}
.hero-sub{grid-column:1 / -1;}
.nav-links .nav-link{display:none;}
.work-head{flex-direction:column;align-items:flex-start;gap:1rem;}
}
@media(prefers-reduced-motion:reduce){
html{scroll-behavior:auto;}
*,*::before,*::after{animation-duration:.001s !important;transition-duration:.001s !important;}
html.js .hero-title .line>span,html.js .foot-title .line>span{transform:none;}
.cursor{display:none;}
.statement{height:auto;} .statement-in{position:static;height:auto;padding:8rem 0;}
}
</style>
</head>
<body>
<div class="cursor" id="cursor" aria-hidden="true"><span>scroll</span></div>
<nav class="nav" aria-label="Main">
<a class="nav-logo" href="#top" data-cursor="home">miles<span style="opacity:.55">.site</span></a>
<div class="nav-links">
<a class="nav-link" href="#work" data-cursor="work">Work</a>
<a class="nav-link" href="#about" data-cursor="about">About</a>
<a class="nav-pill" href="mailto:[email protected]" data-cursor="hello"><i></i>Open to work</a>
</div>
</nav>
<header class="hero rv" id="top">
<div class="grid hero-meta">
<span class="meta">Miles Wolf Allen — Developer &amp; 3D Artist</span>
<span class="meta">Games · Tools · Websites</span>
<span class="meta">Est. 2008</span>
</div>
<div class="grid hero-grid">
<h1 class="hero-title">
<span class="line"><span>Miles</span></span>
<span class="line"><span class="l2">Wolf Allen</span></span>
</h1>
<p class="hero-sub">I make software feel good to use — games, tools and websites built with craft and a little chaos. Co-founder of Diskette Labs.</p>
<div class="hero-cta">
<span class="meta">✦ 160 repos &amp; counting</span>
<span class="scroll-cue">Scroll<span class="bar"></span></span>
</div>
</div>
</header>
<section class="statement rv">
<div class="statement-in">
<p><span class="star"></span>I explore how to make software feel good to use — a full Electron replacement, emulators, rhythm games, and way too many other repos.</p>
</div>
</section>
<section class="about rv" id="about">
<div class="grid">
<h2 class="about-title">About</h2>
<div class="about-col">
<p>I'm <b>Miles Wolf Allen</b>, a developer &amp; 3D artist still in school — and currently co-founder of <a class="prow-visit" href="https://diskettelabs.com/" target="_blank" rel="noopener">Diskette Labs</a>.</p>
<p>Right now I'm building <b>Gelectron</b>, a drop-in Electron replacement that uses native web views instead of bundling an entire Chromium. I've also built FEDL, OmniEmu, CommandMove, and 160+ other repos.</p>
<p>I believe pancakes are better than waffles, cereal is soup, and software should feel good to use.</p>
</div>
<div class="about-body">
<div class="meta">Currently</div>
<div class="about-line"><span>Building</span><span>Gelectron — native web views, no bundled Chromium</span></div>
<div class="about-line"><span>Co-founder</span><span>Diskette Labs</span></div>
<div class="about-line"><span>Habit</span><span>Geometry Dash addict · Pull shark ×2</span></div>
<div class="about-line"><span>Mode</span><span>Full maximalism, still debugging</span></div>
<a class="nav-pill about-badge" href="https://github.com/mileswolfallen2" target="_blank" rel="noopener" data-cursor="gh"><i></i>github.com/mileswolfallen2</a>
</div>
</div>
</section>
<section class="work rv" id="work">
<div class="grid">
<div class="work-head">
<h2>Selected work</h2>
<span class="meta">✦ 2022 — 2026 · tap to expand</span>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">01</span><span class="prow-name">OmniEmu 2.0</span><span class="prow-type">App</span><span class="prow-year">2024—2026</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A multi-system emulator wrapping several cores in one clean desktop shell. Active.</span><a class="prow-visit" href="https://milesallen.site/projects/omniemu.html">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">02</span><span class="prow-name">Gelectron</span><span class="prow-type">App</span><span class="prow-year">2025—2026</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A drop-in Electron replacement using native web views instead of bundled Chromium. Early days.</span><a class="prow-visit" href="https://milesallen.site/projects/gelectron.html">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">03</span><span class="prow-name">Vanilla</span><span class="prow-type">Framework</span><span class="prow-year">2025</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A clean, modern framework with Diskette Labs. Unreleased — building quietly.</span><a class="prow-visit" href="https://vanilla.milesallen.site/" target="_blank" rel="noopener">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">04</span><span class="prow-name">FEDL</span><span class="prow-type">Ecosystem</span><span class="prow-year">2024—2026</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A fast, lightweight package manager and dev tool ecosystem. Live.</span><a class="prow-visit" href="https://me.fedl.site/" target="_blank" rel="noopener">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">05</span><span class="prow-name">CommandMove</span><span class="prow-type">Tool</span><span class="prow-year">2023</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A tool for moving commands and workflows around your terminal.</span><a class="prow-visit" href="https://milesallen.site/projects/command-move.html">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">06</span><span class="prow-name">Noto</span><span class="prow-type">AI</span><span class="prow-year">2025—2026</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">AI note-taking that actually understands what you meant.</span><a class="prow-visit" href="https://milesallen.site/projects/noto.html">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">07</span><span class="prow-name">Nova AI</span><span class="prow-type">Local AI</span><span class="prow-year">2024—2025</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A local-first AI assistant that runs entirely on your machine.</span><a class="prow-visit" href="https://milesallen.site/projects/nova.html">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">08</span><span class="prow-name">Music App</span><span class="prow-type">Web</span><span class="prow-year">2023—2024</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A web music player that makes listening feel like the whole point.</span><a class="prow-visit" href="https://milesallen.site/projects/music-app.html">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">09</span><span class="prow-name">Rhythm Game</span><span class="prow-type">Game</span><span class="prow-year">2022—2023</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A rhythm game experiment in timing, feedback and juice.</span><a class="prow-visit" href="https://milesallen.site/projects/rhythm-game.html">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">10</span><span class="prow-name">FEDL Geode Mod</span><span class="prow-type">Mod</span><span class="prow-year">2025—2026</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">The FEDL mod for Geometry Dash's Geode — extensions for the modding scene.</span><a class="prow-visit" href="https://milesallen.site/projects/geode-mod.html">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">11</span><span class="prow-name">Decompilations</span><span class="prow-type">Tool</span><span class="prow-year">2023—2024</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A tool for exploring and documenting decompiled game code.</span><a class="prow-visit" href="https://milesallen.site/projects/decompilations.html">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">12</span><span class="prow-name">Issue Tracker</span><span class="prow-type">Tool</span><span class="prow-year">2024</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A no-nonsense issue tracker that gets out of your way.</span><a class="prow-visit" href="https://milesallen.site/projects/issue-tracker.html">visit →</a></div></div>
</div>
<div class="prow" data-cursor="open">
<div class="prow-head">
<span class="prow-num">13</span><span class="prow-name">Moon Gaming</span><span class="prow-type">Game</span><span class="prow-year">2022—2026</span><span class="prow-arrow"></span>
</div>
<div class="prow-body"><div class="prow-body-in"><span class="prow-desc">A long-running gaming project — mods, tools and experiments since 2022.</span><a class="prow-visit" href="https://milesallen.site/projects/moon-gaming.html">visit →</a></div></div>
</div>
<div class="work-foot"><span class="meta">and 160+ more on GitHub</span><span class="meta">Miles Wolf Allen © 2026</span></div>
</div>
</section>
<section class="stats rv">
<div class="grid">
<div class="stat"><b data-count="160">0</b><span>Repos online</span></div>
<div class="stat"><b data-count="91">0</b><span>Stars earned</span></div>
<div class="stat"><b data-count="13">0</b><span>Watching me</span></div>
<div class="stat"><b data-count="37">0</b><span>I watch</span></div>
</div>
</section>
<div class="mq" aria-hidden="true">
<div class="mq-track">
<span>✦ Geometry Dash addict</span><span>✦ Cereal is soup</span><span>✦ Send help</span><span>✦ Full maximalism</span><span>✦ Usually online</span><span>✦ Pancakes &gt; waffles</span>
<span>✦ Geometry Dash addict</span><span>✦ Cereal is soup</span><span>✦ Send help</span><span>✦ Full maximalism</span><span>✦ Usually online</span><span>✦ Pancakes &gt; waffles</span>
</div>
</div>
<footer class="rv" id="contact">
<div class="foot-title">
<span class="line"><span>Let's</span></span>
<span class="line"><span>Make</span></span>
<span class="line"><span>Something</span></span>
<span class="line"><span>Great</span></span>
</div>
<a class="foot-mail" href="mailto:[email protected]" data-cursor="mail">[email protected]</a>
<div class="foot-meta">
<span class="meta">© 2026 Miles Wolf Allen — built by hand</span>
<div class="foot-socials">
<a href="https://github.com/mileswolfallen2" target="_blank" rel="noopener" data-cursor="gh">GitHub</a><i></i>
<a href="https://replit.com/@MilesAllen1" target="_blank" rel="noopener" data-cursor="go">Replit</a><i></i>
<a href="https://codepen.io/mileswolfallen2-the-typescripter" target="_blank" rel="noopener" data-cursor="go">CodePen</a><i></i>
<a href="https://me.fedl.site" target="_blank" rel="noopener" data-cursor="go">Website</a>
</div>
</div>
</footer>
<script>
(function(){
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var io=('IntersectionObserver' in window)?new IntersectionObserver(function(es){
es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('in');io.unobserve(e.target);}});
},{threshold:.12}):null;
var reveal=document.querySelectorAll('.rv');
for(var i=0;i<reveal.length;i++){if(io)io.observe(reveal[i]);else reveal[i].classList.add('in');}
var rows=document.querySelectorAll('.prow');
for(var r=0;r<rows.length;r++){(function(row){
var head=row.querySelector('.prow-head');
head.addEventListener('click',function(){
var was=row.classList.contains('open');
for(var x=0;x<rows.length;x++)rows[x].classList.remove('open');
if(!was)row.classList.add('open');
});
})(rows[r]);}
var counts=document.querySelectorAll('[data-count]');
if(counts.length&&io&&!reduce){
var cio=new IntersectionObserver(function(es){
es.forEach(function(e){
if(e.isIntersecting){
var el=e.target,target=parseInt(el.getAttribute('data-count'),10),t0=null;
var run=function(ts){
if(!t0)t0=ts;
var p=Math.min((ts-t0)/1300,1);
var eased=1-Math.pow(1-p,3);
el.textContent=Math.round(target*eased);
if(p<1)requestAnimationFrame(run);
};
requestAnimationFrame(run);
cio.unobserve(el);
}
});
},{threshold:.5});
for(var c=0;c<counts.length;c++)cio.observe(counts[c]);
}else{
for(var c2=0;c2<counts.length;c2++)counts[c2].textContent=counts[c2].getAttribute('data-count');
}
if(window.matchMedia&&window.matchMedia('(pointer:fine)').matches&&!reduce){
var cursor=document.getElementById('cursor');
var label=cursor.querySelector('span');
var px=0,py=0,cx=0,cy=0,shown=false,raf=null;
document.addEventListener('mousemove',function(ev){
px=ev.clientX;py=ev.clientY;
if(!shown){cursor.classList.add('show');shown=true;}
var t=ev.target;
while(t&&t!==document){
if(t.hasAttribute&&t.hasAttribute('data-cursor'))break;
t=t.parentNode;
}
if(t&&t!==document){
label.textContent=t.getAttribute('data-cursor');
cursor.classList.add('big');
}else{
label.textContent='scroll';
cursor.classList.remove('big');
}
if(!raf){
raf=requestAnimationFrame(function(){
cx+=(px-cx)*.22;cy+=(py-cy)*.22;
cursor.style.left=cx+'px';
cursor.style.top=cy+'px';
raf=null;
});
}
});
document.addEventListener('mouseleave',function(){cursor.classList.remove('show');shown=false;});
}
var nav=document.querySelector('.nav');
if(nav){
var secs=[['.hero',0],['.statement',1],['.about',0],['.work',1],['.stats',1],['.mq',0],['footer',1]];
var cache=secs.map(function(s){return {el:document.querySelector(s[0]),ink:s[1]};}).filter(function(s){return s.el;});
var paint=function(){
var y=window.scrollY+1,found=0;
for(var i=0;i<cache.length;i++){
if(cache[i].el.offsetTop<=y)found=cache[i].ink;
}
document.body.classList.toggle('nav-ink',!!found);
};
var tick=null;
window.addEventListener('scroll',function(){
if(tick)return;
tick=requestAnimationFrame(function(){paint();tick=null;});
},{passive:true});
paint();
}
})();
</script>
</body>
</html>
+637
View File
@@ -0,0 +1,637 @@
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MILES WOLF ALLEN © 2026</title>
<meta name="description" content="Miles Wolf Allen — developer & 3D artist. Games, tools, websites, and a world without bundled Chromium.">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' fill='%23F7FF00'/%3E%3Ctext x='50' y='72' font-size='60' font-family='Arial Black' font-weight='900' text-anchor='middle' fill='%23000'%3EM%3C/text%3E%3C/svg%3E">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Archivo:wdth,[email protected],100..900&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">
<script>document.documentElement.className='js';</script>
<style>
:root{
--bg:#0b0b0e; --bg2:#121217; --fg:#f2f2f5; --mut:#8f8f98; --ln:#26262e;
--acc:#F7FF00; --sig:#F7FF00; --hov:#FF2EA6;
--d:'Archivo',sans-serif; --m:'Space Mono',monospace;
}
[data-theme="light"]{
--bg:#f4f4f1; --bg2:#e9e9e5; --fg:#131316; --mut:#6d6d75; --ln:#d3d3d9;
--acc:#131316; --sig:#131316; --hov:#cf005c;
}
[data-theme="max"]{
--bg:#0d0b12; --bg2:#171023; --fg:#ffffff; --mut:#b9a7c8; --ln:#3a2f4a;
--acc:#F7FF00; --sig:#F7FF00; --hov:#FF2EA6;
--pink:#FF2EA6; --yellow:#F7FF00; --cyan:#00F4FF; --orange:#FF5C00; --purple:#8A2BFF; --green:#00FF85;
}
*{margin:0;padding:0;box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{background:var(--bg);color:var(--fg);font-family:var(--d);font-size:15px;line-height:1.55;overflow-x:hidden;-webkit-font-smoothing:antialiased;}
::selection{background:var(--acc);color:var(--bg);}
a{color:inherit;text-decoration:none;}
::-webkit-scrollbar{width:10px;}
::-webkit-scrollbar-track{background:var(--bg);}
::-webkit-scrollbar-thumb{background:var(--mut);border:2px solid var(--bg);}
.dsp{font-family:var(--d);font-stretch:125%;font-variation-settings:'wdth' 125;font-weight:750;text-transform:uppercase;line-height:.96;letter-spacing:.005em;}
.mono{font-family:var(--m);font-size:11px;letter-spacing:.06em;text-transform:uppercase;}
/* ---------- fixed layers ---------- */
.prog{position:fixed;top:0;left:50%;transform:translateX(-50%);width:150px;height:4px;z-index:70;background:var(--ln);}
.prog-i{height:100%;width:0;background:var(--sig);transition:width .2s linear;}
/* ---------- header ---------- */
.hdr{position:fixed;inset:0;z-index:60;display:flex;flex-direction:column;justify-content:space-between;pointer-events:none;color:var(--fg);}
.hdr-top{display:flex;align-items:center;justify-content:space-between;padding:18px clamp(16px,4vw,56px);}
.hdr-bot{display:flex;align-items:center;justify-content:space-between;padding:18px clamp(16px,4vw,56px);color:var(--mut);}
.logo{font-family:var(--d);font-stretch:125%;font-variation-settings:'wdth' 125;font-weight:700;text-transform:uppercase;font-size:20px;letter-spacing:.02em;pointer-events:auto;}
.logo .o{opacity:.45;}
.hdr-nav{display:flex;gap:2px;pointer-events:auto;}
.hdr-mid{position:absolute;left:50%;bottom:20px;transform:translateX(-50%);color:var(--mut);pointer-events:none;}
.hl{position:relative;padding:8px 10px;font-family:var(--m);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--fg);background:none;border:0;cursor:pointer;transition:color .18s;}
.hl::before{content:'';position:absolute;inset:0;border:2px dashed transparent;transition:border-color .18s;}
a.hl:hover,button.hl:hover{color:var(--hov);}
a.hl:hover::before,button.hl:hover::before{border-color:var(--mut);}
.hdr-mid{font-size:10px;}
@media(max-width:900px){.hdr-mid{display:none;}}
@media(max-width:768px){.hdr-nav{display:none;}}
/* ---------- line mask reveal ---------- */
.mask .ln{display:block;overflow:hidden;}
html.js .mask .ln>span{display:inline-block;transform:translateY(120%);transition:transform 1.1s cubic-bezier(.16,1,.3,1) var(--dl,0s);will-change:transform;}
html.js .mask.in .ln>span{transform:translateY(0);}
.ln{display:block;}
/* ---------- generic reveal ---------- */
html.js .rv{opacity:0;transform:translateY(34px);transition:opacity .8s ease,transform 1s cubic-bezier(.16,1,.3,1);}
html.js .rv.in{opacity:1;transform:none;}
/* ---------- inline links ---------- */
a.l{color:var(--fg);text-decoration:underline;text-decoration-color:var(--mut);text-decoration-thickness:1px;text-underline-offset:.16em;transition:color .15s,text-decoration-color .15s;}
a.l:hover{color:var(--hov);text-decoration-color:var(--hov);}
/* ---------- hero ---------- */
.hero{min-height:100svh;display:flex;flex-direction:column;padding:20vh clamp(16px,4vw,56px) 7vh;}
.hero-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:10px 12px;flex:1;align-content:start;}
.hero-role{grid-column:1 / span 3;font-size:clamp(18px,1.8vw,30px);}
.hero-think{grid-column:4 / span 2;color:var(--mut);padding-top:6px;font-size:11px;line-height:1.7;}
.hero-bio{grid-column:6 / span 5;color:var(--mut);font-size:15px;line-height:1.7;padding-top:2px;}
.hero-bio b{color:var(--fg);font-weight:700;}
.hero-tag{grid-column:1 / -1;margin-top:auto;align-self:end;padding-top:60px;font-size:clamp(38px,8.4vw,120px);}
.hero-tag .ln>span{font-size:inherit;}
@media(max-width:768px){
.hero{padding-top:22vh;}
.hero-role{grid-column:1 / -1;}
.hero-think{grid-column:1 / -1;margin-top:14px;}
.hero-bio{grid-column:1 / -1;margin-top:14px;max-width:46ch;}
.hero-tag{font-size:clamp(34px,11vw,64px);}
}
/* ---------- statement / signature ---------- */
.stmt{display:grid;grid-template-columns:repeat(12,1fr);gap:12px;padding:20vh clamp(16px,4vw,56px) 6vh;}
.sign-col{grid-column:1 / span 4;align-self:start;}
.sign{width:100%;max-width:380px;display:block;}
.sign .p{opacity:0;fill:none;stroke:var(--sig);stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:700;stroke-dashoffset:700;}
.sign.in .p{animation:show 0s linear var(--pd,0s) forwards,draw var(--dr,1.4s) cubic-bezier(.65,0,.35,1) var(--pd,0s) forwards;}
.sign-gh{display:flex;align-items:center;gap:10px;margin-top:14px;font-size:12px;}
.gh-av{width:24px;height:24px;border-radius:50%;border:1px solid var(--ln);display:block;flex:none;}
.sign-cap{color:var(--mut);margin-top:12px;font-size:9px;letter-spacing:.05em;text-transform:uppercase;max-width:300px;line-height:1.7;}
@keyframes draw{to{stroke-dashoffset:0;}}
@keyframes show{to{opacity:1;}}
.stmt-copy{grid-column:6 / span 6;}
.stmt-1{font-size:clamp(22px,3vw,40px);line-height:1.25;margin-bottom:26px;}
.stmt-2{color:var(--mut);font-size:15px;line-height:1.75;max-width:52ch;}
@media(max-width:768px){.sign-col{grid-column:1 / -1;margin-bottom:20px;} .stmt-copy{grid-column:1 / -1;}}
/* ---------- selected work ---------- */
.work{padding:16vh clamp(16px,4vw,56px) 0;}
.work-head{display:flex;justify-content:space-between;align-items:baseline;color:var(--mut);padding-bottom:30px;border-bottom:1px solid var(--ln);margin-bottom:16px;}
.work-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:8px;}
.pcard{display:block;padding:6px;transition:transform .4s cubic-bezier(.2,.8,.2,1);}
.pcard:nth-child(1){grid-column:span 8;}
.pcard:nth-child(2){grid-column:span 6;}
.pcard:nth-child(3){grid-column:span 6;}
.pcard:nth-child(4),.pcard:nth-child(5),.pcard:nth-child(6){grid-column:span 4;}
.pcard:nth-child(7),.pcard:nth-child(8),.pcard:nth-child(9){grid-column:span 4;}
.pcard:nth-child(10),.pcard:nth-child(11),.pcard:nth-child(12),.pcard:nth-child(13){grid-column:span 3;}
.ptile{position:relative;aspect-ratio:1 / 1;overflow:hidden;transition:transform .6s cubic-bezier(.2,.8,.2,1),box-shadow .6s;}
.pcard:hover .ptile{transform:scale(.965) rotate(1deg);box-shadow:0 22px 44px rgba(0,0,0,.35);}
.pchip{position:absolute;top:10px;right:10px;background:var(--acc);color:var(--bg);font-family:var(--m);font-size:9px;letter-spacing:.06em;text-transform:uppercase;padding:5px 8px;pointer-events:none;transition:transform .4s;}
.pcard:hover .pchip{transform:rotate(4deg);}
.pnum{position:absolute;bottom:6px;left:10px;font-family:var(--m);font-size:clamp(34px,5vw,64px);color:rgba(255,255,255,.30);pointer-events:none;line-height:1;}
.pcard.neutral .pnum{color:var(--mut);}
.pmeta{display:flex;justify-content:space-between;align-items:baseline;gap:14px;padding:12px 4px 0;min-width:0;}
.ptitle{font-family:var(--d);font-stretch:125%;font-variation-settings:'wdth' 125;font-weight:700;text-transform:uppercase;font-size:15px;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .18s;}
.pcard:hover .ptitle{color:var(--hov);}
.pyear{font-family:var(--m);font-size:10px;letter-spacing:.06em;color:var(--mut);white-space:nowrap;}
.t1{background:linear-gradient(135deg,#FF2EA6,#8A2BFF);}
.t2{background:linear-gradient(135deg,#F7FF00,#00FF85);}
.t3{background:var(--bg2);}
.t4{background:linear-gradient(135deg,#FF1F1F,#FF5C00);}
.t5{background:linear-gradient(135deg,#8A2BFF,#1a1a22);}
.t6{background:linear-gradient(135deg,#00F4FF,#8A2BFF);}
.t7{background:linear-gradient(135deg,#00FF85,#00F4FF);}
.t8{background:var(--bg2);}
.t9{background:linear-gradient(135deg,#FF2EA6,#FF5C00);}
.t10{background:linear-gradient(135deg,#00F4FF,#00FF85);}
.t11{background:var(--bg2);}
.t12{background:linear-gradient(135deg,#F7FF00,#FF5C00);}
.t13{background:linear-gradient(135deg,#8A2BFF,#FF2EA6);}
.ptile.frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0;z-index:0;pointer-events:none;}
.ptile.frame::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;background:linear-gradient(180deg,rgba(10,10,14,.12) 0%,rgba(10,10,14,.18) 45%,rgba(10,10,14,.55) 100%);}
.ptile.frame .pchip,.ptile.frame .pnum{z-index:2;}
@media(max-width:768px){
.pcard:nth-child(n){grid-column:span 6;}
}
@media(max-width:480px){
.pcard:nth-child(n){grid-column:span 12;}
}
/* ---------- sticky slogan ---------- */
.slogan{position:sticky;top:0;height:100svh;display:grid;place-items:center;padding:0 clamp(16px,4vw,56px);z-index:1;}
.slogan-in{font-size:clamp(44px,10vw,150px);text-align:center;line-height:1.05;}
.slogan-in .ln{color:var(--mut);}
.slogan-in .ln:nth-child(2){color:var(--fg);}
.slogan-in .ln:nth-child(3){color:var(--mut);}
/* ---------- footer ---------- */
.footer{position:relative;z-index:2;height:100svh;display:flex;flex-direction:column;justify-content:center;padding:0 clamp(16px,4vw,56px);background:var(--bg);overflow:hidden;}
.f-head{font-size:clamp(44px,9.5vw,140px);}
.f-head .ln:nth-child(1){text-align:left;}
.f-head .ln:nth-child(2){text-align:right;padding-right:7vw;}
.f-head .ln:nth-child(3){text-align:left;padding-left:11vw;}
.f-head .ln:nth-child(4){text-align:right;padding-right:3vw;}
.f-row{position:absolute;inset:auto clamp(16px,4vw,56px) 5vh;display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;}
.f-links{display:flex;gap:0;}
.f-copy{color:var(--mut);font-size:10px;}
/* ---------- stats ---------- */
.stats{max-width:1160px;margin:0 auto;padding:6vh clamp(16px,4vw,56px) 4vh;}
.stats-grid{display:grid;grid-template-columns:repeat(4,1fr);}
.sstat{border-left:1px solid var(--ln);padding:6px 22px 6px 26px;}
.sstat:first-child{border-left:0;}
.snum{font-family:var(--d);font-stretch:125%;font-variation-settings:'wdth' 125;font-weight:750;font-size:clamp(46px,6vw,86px);line-height:1;display:block;transition:color .2s;}
.sstat:hover .snum{color:var(--hov);}
.sdesc{color:var(--mut);}
@media(max-width:768px){.stats-grid{grid-template-columns:repeat(2,1fr);gap:34px 0;} .sstat:nth-child(3){border-left:0;}}
/* ---------- loadout ---------- */
.loadout{max-width:1160px;margin:0 auto;padding:8vh clamp(16px,4vw,56px) 4vh;}
.load-grid{display:grid;grid-template-columns:1fr 1fr;gap:42px;}
.lg-label{color:var(--mut);margin-bottom:18px;padding-bottom:12px;border-bottom:1px solid var(--ln);}
.skill-list{list-style:none;}
.skill{display:flex;align-items:baseline;gap:16px;padding:12px 3px;border-bottom:1px solid var(--ln);transition:color .15s;}
.skill:hover{color:var(--hov);}
.sk-num{color:var(--mut);font-size:10px;}
.sk-name{font-family:var(--d);font-stretch:115%;font-variation-settings:'wdth' 115;font-weight:650;text-transform:uppercase;font-size:15px;letter-spacing:.02em;}
@media(max-width:768px){.load-grid{grid-template-columns:1fr;}}
/* ---------- devlog ---------- */
.devlog{max-width:1160px;margin:0 auto;padding:8vh clamp(16px,4vw,56px) 8vh;}
.post-list{display:flex;flex-direction:column;}
.post{display:grid;grid-template-columns:130px 1fr auto;gap:22px;align-items:baseline;padding:28px 8px;border-bottom:1px solid var(--ln);transition:padding-left .2s,background .2s;}
.post:first-child{border-top:1px solid var(--ln);}
.post:hover{padding-left:16px;}
.p-date{color:var(--mut);font-size:10px;}
.p-title{font-family:var(--d);font-stretch:125%;font-variation-settings:'wdth' 125;font-weight:700;text-transform:uppercase;font-size:clamp(18px,2.6vw,30px);transition:color .18s;}
.post:hover .p-title{color:var(--hov);}
.p-desc{color:var(--mut);font-size:13px;margin-top:5px;max-width:60ch;}
.p-go{font-size:20px;transition:transform .2s,color .2s;color:var(--mut);}
.post:hover .p-go{transform:translateX(8px);color:var(--hov);}
@media(max-width:768px){.post{grid-template-columns:1fr;gap:8px;} .p-go{display:none;}}
/* ---------- badges ---------- */
.stmt-badges{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px;}
.sb{font-family:var(--m);font-size:9px;letter-spacing:.06em;text-transform:uppercase;color:var(--mut);border:1px solid var(--ln);padding:6px 10px;transition:color .15s,border-color .15s;}
.sb:hover{color:var(--hov);border-color:var(--hov);}
/* ---------- marquee (max mode) ---------- */
.mq{display:none;overflow:hidden;white-space:nowrap;border-top:3px solid #000;border-bottom:3px solid #000;position:relative;}
[data-theme="max"] .mq{display:block;}
.mq-track{display:inline-flex;white-space:nowrap;animation:mqScroll 26s linear infinite;font-family:var(--m);font-size:12px;letter-spacing:.05em;}
.mq-track span{padding:12px 22px;color:#000;}
.mq-y{background:var(--yellow);}
.mq-p{background:var(--pink);}
@keyframes mqScroll{to{transform:translateX(-50%);}}
/* ---------- MAX mode overrides ---------- */
[data-theme="max"] .logo{color:var(--acc);}
[data-theme="max"] .hero-role{color:var(--acc);}
[data-theme="max"] .hero-tag .ln:nth-child(1) span{color:var(--pink);}
[data-theme="max"] .hero-tag .ln:nth-child(2) span{color:var(--yellow);}
[data-theme="max"] .hero-tag .ln:nth-child(3) span{color:var(--cyan);}
[data-theme="max"] .stmt-1{color:var(--acc);}
[data-theme="max"] .work-head{border-bottom:2px solid var(--acc);}
[data-theme="max"] .slogan-in .ln:nth-child(1){color:var(--pink);}
[data-theme="max"] .slogan-in .ln:nth-child(2){color:var(--yellow);}
[data-theme="max"] .slogan-in .ln:nth-child(3){color:var(--cyan);}
[data-theme="max"] .f-head .ln:nth-child(1){color:var(--pink);}
[data-theme="max"] .f-head .ln:nth-child(2){color:var(--yellow);}
[data-theme="max"] .f-head .ln:nth-child(3){color:var(--cyan);}
[data-theme="max"] .f-head .ln:nth-child(4){color:var(--orange);}
[data-theme="max"] .ptile{border:3px solid #000;box-shadow:8px 8px 0 #000;}
[data-theme="max"] .pcard:nth-child(odd) .ptile{transform:rotate(-1.2deg);}
[data-theme="max"] .pcard:nth-child(even) .ptile{transform:rotate(1deg);}
[data-theme="max"] .pcard:hover .ptile{transform:rotate(0) scale(1.02);box-shadow:12px 12px 0 var(--hov);}
[data-theme="max"] .pchip{border:2px solid #000;box-shadow:3px 3px 0 #000;}
[data-theme="max"] .sstat{border:3px solid #000;background:var(--bg2);box-shadow:6px 6px 0 #000;margin:0 8px 8px 0;}
[data-theme="max"] .sstat:first-child{border-left:3px solid #000;}
[data-theme="max"] .sstat:nth-child(odd){transform:rotate(-1deg);}
[data-theme="max"] .sstat:nth-child(even){transform:rotate(1.2deg) translateY(4px);}
[data-theme="max"] .skill{border:3px solid #000;background:var(--bg2);box-shadow:4px 4px 0 #000;margin-bottom:10px;padding:13px 16px;}
[data-theme="max"] .skill:nth-child(3n){transform:rotate(-.6deg);}
[data-theme="max"] .skill:nth-child(3n+2){transform:rotate(.7deg);}
[data-theme="max"] .skill:hover{color:var(--acc);}
[data-theme="max"] .lg-label{border-bottom:2px solid var(--acc);color:var(--acc);}
[data-theme="max"] .post{border:3px solid #000;box-shadow:6px 6px 0 #000;margin-bottom:16px;background:var(--bg2);border-bottom:3px solid #000;}
[data-theme="max"] .post:first-child{border-top:3px solid #000;}
[data-theme="max"] .post:hover{background:var(--pink);padding-left:16px;}
[data-theme="max"] .post:hover .p-title,[data-theme="max"] .post:hover .p-desc{color:#000;}
[data-theme="max"] .post:hover .p-go{color:#000;}
[data-theme="max"] .post:hover .p-date{color:#000;}
[data-theme="max"] .sb{border:2px solid #000;color:#000;box-shadow:3px 3px 0 #000;}
[data-theme="max"] .sb:nth-child(4n+1){background:var(--pink);}
[data-theme="max"] .sb:nth-child(4n+2){background:var(--yellow);}
[data-theme="max"] .sb:nth-child(4n+3){background:var(--cyan);}
[data-theme="max"] .sb:nth-child(4n){background:var(--green);}
[data-theme="max"] .f-row a.hl{color:var(--acc);}
@media(prefers-reduced-motion:reduce){
*,*::before,*::after{animation:none!important;transition:none!important;}
html.js .mask .ln>span,html.js .rv{transform:none;opacity:1;}
html.js .sign.in .p{opacity:1;stroke-dashoffset:0;}
}
</style>
</head>
<body>
<div class="prog" aria-hidden="true"><div class="prog-i" id="pbar"></div></div>
<header class="hdr">
<div class="hdr-top">
<a class="logo hl" href="#top"><span>miles</span><span class="o">.site</span></a>
<nav class="hdr-nav">
<a class="hl" href="#work">Work</a>
<a class="hl" href="#contact">Contact</a>
<button class="hl" id="themeBtn" type="button" aria-label="Theme: dark, click to toggle">THEME[A]</button>
<button class="hl" id="soundBtn" type="button" aria-label="Sound paused, click to play" aria-pressed="false">SOUND[&gt;]</button>
</nav>
</div>
<span class="hdr-mid mono" id="coords">0000 X 0000 Y</span>
<div class="hdr-bot">
<span class="mono" id="clock">--:--</span>
<span class="mono" style="color:var(--mut)">© 2026</span>
</div>
</header>
<main>
<section class="hero" id="top">
<div class="hero-grid">
<div class="hero-role dsp mask" data-mask>
<span class="ln"><span>Developer &amp;</span></span>
<span class="ln"><span style="--dl:.06s">3D Artist</span></span>
</div>
<p class="hero-think mono rv">Thinking in systems.<br>Building with intent.</p>
<p class="hero-bio rv">I'm <b>Miles Wolf Allen</b>, developer &amp; 3D artist. Co-founder of <a class="l" href="https://diskettelabs.com/" target="_blank" rel="noopener">Diskette Labs</a>, still in school, and building a full <b>Electron replacement</b> — send help. 160 repos and counting.</p>
<div class="hero-tag dsp mask" data-mask>
<span class="ln"><span>I build</span></span>
<span class="ln"><span style="--dl:.06s">games, tools</span></span>
<span class="ln"><span style="--dl:.12s">&amp; websites</span></span>
</div>
</div>
</section>
<section class="stmt" id="about">
<div class="sign-col rv">
<svg class="sign" id="sign" viewBox="0 0 320 160" aria-hidden="true">
<path class="p" style="--pd:.1s;--dr:1.1s" d="M30 38 L44 108 L62 72 L80 108 L94 38"/>
<path class="p" style="--pd:.7s;--dr:.8s" d="M120 38 L144 38 M144 30 L144 108 M134 108 L154 108"/>
<path class="p" style="--pd:1s;--dr:.8s" d="M170 40 L170 108 L212 108"/>
<path class="p" style="--pd:1.3s;--dr:.9s" d="M230 40 L262 40 M230 40 L230 108 M230 108 L262 108 M230 74 L256 74"/>
<path class="p" style="--pd:1.6s;--dr:1.2s" d="M278 46 C300 40 308 60 290 68 C276 74 268 84 274 98 C278 108 296 114 308 106"/>
<path class="p" style="--pd:2.1s;--dr:1.2s" d="M26 128 C100 142 220 134 312 126"/>
</svg>
<div class="sign-gh">
<img class="gh-av" src="https://avatars.githubusercontent.com/u/115095719?v=4" alt="Miles Wolf Allen" width="24" height="24" loading="lazy">
<a class="l" href="https://github.com/mileswolfallen2" target="_blank" rel="noopener">github.com/mileswolfallen2</a>
</div>
<p class="sign-cap">I believe pancakes are better than waffles, cereal is soup, and software should feel good to use.</p>
</div>
<div class="stmt-copy">
<p class="stmt-1 rv">I explore how to make software feel good to use — games, tools, and websites built with craft and a little chaos.</p>
<p class="stmt-2 rv">I'm co-founder of <a class="l" href="https://diskettelabs.com/" target="_blank" rel="noopener">Diskette Labs</a>, currently building <a class="l" href="https://milesallen.site/projects/gelectron.html">Gelectron</a> — a drop-in Electron replacement using native web views instead of bundled Chromium — and previously built <a class="l" href="https://milesallen.site/projects/fedl.html">FEDL</a>, <a class="l" href="https://milesallen.site/projects/omniemu.html">OmniEmu</a>, <a class="l" href="https://milesallen.site/projects/command-move.html">CommandMove</a>, and way too many other repos.</p>
<div class="stmt-badges rv">
<span class="sb">Pull shark ×2</span>
<span class="sb">YOLO</span>
<span class="sb">Quickdraw</span>
<span class="sb">Geometry dash addict</span>
</div>
</div>
</section>
<section class="stats" id="stats">
<div class="stats-grid">
<div class="sstat rv"><span class="snum" data-count="160">0</span><span class="sdesc mono">Repos online</span></div>
<div class="sstat rv"><span class="snum" data-count="91">0</span><span class="sdesc mono">Stars earned</span></div>
<div class="sstat rv"><span class="snum" data-count="13">0</span><span class="sdesc mono">Watching me</span></div>
<div class="sstat rv"><span class="snum" data-count="37">0</span><span class="sdesc mono">I watch</span></div>
</div>
</section>
<section class="work" id="work">
<div class="work-head mono"><span>Selected work</span><span>2022 — 2026</span></div>
<div class="work-grid">
<a class="pcard rv" href="https://milesallen.site/projects/omniemu.html">
<div class="ptile t1 frame"><iframe src="https://milesallen.site/projects/omniemu" title="Project 1 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Active</span><span class="pnum">01</span></div>
<div class="pmeta"><span class="ptitle">OmniEmu 2.0</span><span class="pyear">2024-2026</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/gelectron.html">
<div class="ptile t2 frame"><iframe src="https://milesallen.site/projects/gelectron" title="Project 2 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Early</span><span class="pnum">02</span></div>
<div class="pmeta"><span class="ptitle">Gelectron</span><span class="pyear">2025-2026</span></div>
</a>
<a class="pcard rv" href="https://vanilla.milesallen.site/" target="_blank" rel="noopener">
<div class="ptile t3 frame"><iframe src="https://vanilla.milesallen.site/" title="Project 3 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Unreleased ↗</span><span class="pnum">03</span></div>
<div class="pmeta"><span class="ptitle">Vanilla</span><span class="pyear">2025</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/fedl.html">
<div class="ptile t4 frame"><iframe src="https://me.fedl.site/" title="Project 4 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Live</span><span class="pnum">04</span></div>
<div class="pmeta"><span class="ptitle">FEDL</span><span class="pyear">2024-2026</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/command-move.html">
<div class="ptile t5 frame"><iframe src="https://milesallen.site/projects/command-move" title="Project 5 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Tool</span><span class="pnum">05</span></div>
<div class="pmeta"><span class="ptitle">CommandMove</span><span class="pyear">2023</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/noto.html">
<div class="ptile t6 frame"><iframe src="https://milesallen.site/projects/noto" title="Project 6 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">AI</span><span class="pnum">06</span></div>
<div class="pmeta"><span class="ptitle">Noto</span><span class="pyear">2025-2026</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/nova.html">
<div class="ptile t7 frame"><iframe src="https://milesallen.site/projects/nova" title="Project 7 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Local AI</span><span class="pnum">07</span></div>
<div class="pmeta"><span class="ptitle">Nova AI</span><span class="pyear">2024-2025</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/music-app.html">
<div class="ptile t8 frame"><iframe src="https://milesallen.site/projects/music-app" title="Project 8 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Web</span><span class="pnum">08</span></div>
<div class="pmeta"><span class="ptitle">Music App</span><span class="pyear">2023-2024</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/rhythm-game.html">
<div class="ptile t9 frame"><iframe src="https://milesallen.site/projects/rhythm-game" title="Project 9 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Game</span><span class="pnum">09</span></div>
<div class="pmeta"><span class="ptitle">Rhythm Game</span><span class="pyear">2022-2023</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/geode-mod.html">
<div class="ptile t10 frame"><iframe src="https://milesallen.site/projects/geode-mod" title="Project 10 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Mod</span><span class="pnum">10</span></div>
<div class="pmeta"><span class="ptitle">FEDL Geode Mod</span><span class="pyear">2025-2026</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/decompilations.html">
<div class="ptile t11 frame"><iframe src="https://milesallen.site/projects/decompilations" title="Project 11 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Tool</span><span class="pnum">11</span></div>
<div class="pmeta"><span class="ptitle">Decompilations</span><span class="pyear">2023-2024</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/issue-tracker.html">
<div class="ptile t12 frame"><iframe src="https://milesallen.site/projects/issue-tracker" title="Project 12 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Tool</span><span class="pnum">12</span></div>
<div class="pmeta"><span class="ptitle">Issue Tracker</span><span class="pyear">2024</span></div>
</a>
<a class="pcard rv" href="https://milesallen.site/projects/moon-gaming.html">
<div class="ptile t13 frame"><iframe src="https://milesallen.site/projects/moon-gaming" title="Project 13 preview" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true"></iframe><span class="pchip">Game</span><span class="pnum">13</span></div>
<div class="pmeta"><span class="ptitle">Moon Gaming</span><span class="pyear">2022-2026</span></div>
</a>
</div>
</section>
<div class="mq mq-y" aria-hidden="true">
<div class="mq-track">
<span>★ 160 REPOS AND COUNTING</span><span>★ SEND HELP</span><span>★ CEREAL IS SOUP</span><span>★ GEOMETRY DASH ADDICT</span><span>★ USUALLY ONLINE</span><span>★ FULL MAXIMALISM</span><span>★ STILL DEBUGGING</span><span>★ EST. 2008</span>
<span>★ 160 REPOS AND COUNTING</span><span>★ SEND HELP</span><span>★ CEREAL IS SOUP</span><span>★ GEOMETRY DASH ADDICT</span><span>★ USUALLY ONLINE</span><span>★ FULL MAXIMALISM</span><span>★ STILL DEBUGGING</span><span>★ EST. 2008</span>
</div>
</div>
<section class="loadout" id="loadout">
<div class="work-head mono"><span>Loadout</span><span>skills</span></div>
<div class="load-grid">
<div>
<div class="lg-label mono">Ready to use</div>
<ul class="skill-list">
<li class="skill rv"><span class="sk-num">01</span><span class="sk-name">JavaScript</span></li>
<li class="skill rv"><span class="sk-num">02</span><span class="sk-name">Backend JS</span></li>
<li class="skill rv"><span class="sk-num">03</span><span class="sk-name">HTML / CSS</span></li>
<li class="skill rv"><span class="sk-num">04</span><span class="sk-name">Python</span></li>
<li class="skill rv"><span class="sk-num">05</span><span class="sk-name">Git</span></li>
<li class="skill rv"><span class="sk-num">06</span><span class="sk-name">Blender</span></li>
<li class="skill rv"><span class="sk-num">07</span><span class="sk-name">Unity / Unreal</span></li>
<li class="skill rv"><span class="sk-num">08</span><span class="sk-name">Cloudflare</span></li>
<li class="skill rv"><span class="sk-num">09</span><span class="sk-name">Linux / Bash</span></li>
<li class="skill rv"><span class="sk-num">10</span><span class="sk-name">Electron</span></li>
</ul>
</div>
<div>
<div class="lg-label mono">Currently unlocking</div>
<ul class="skill-list">
<li class="skill rv"><span class="sk-num">11</span><span class="sk-name">Rust</span></li>
<li class="skill rv"><span class="sk-num">12</span><span class="sk-name">Swift</span></li>
<li class="skill rv"><span class="sk-num">13</span><span class="sk-name">Flutter</span></li>
<li class="skill rv"><span class="sk-num">14</span><span class="sk-name">PHP</span></li>
<li class="skill rv"><span class="sk-num">15</span><span class="sk-name">.NET</span></li>
<li class="skill rv"><span class="sk-num">16</span><span class="sk-name">Nix</span></li>
</ul>
</div>
</div>
</section>
<section class="devlog" id="devlog">
<div class="work-head mono"><span>Devlog</span><span>6 entries</span></div>
<div class="post-list">
<a class="post rv" href="https://milesallen.site/blog/diskette-devlog.html">
<span class="p-date">2026 // 001</span>
<div><div class="p-title">Focusing on Diskette Labs</div><p class="p-desc">Co-founder of a product design collective. Where my focus is now — still open to collabs.</p></div>
<span class="p-go"></span>
</a>
<a class="post rv" href="https://milesallen.site/blog/gelectron-devlog.html">
<span class="p-date">2026 // 002</span>
<div><div class="p-title">Why I built Gelectron</div><p class="p-desc">Electron bundles Chromium with every app. Native web views fix that.</p></div>
<span class="p-go"></span>
</a>
<a class="post rv" href="https://milesallen.site/blog/omniemu-devlog.html">
<span class="p-date">2026 // 003</span>
<div><div class="p-title">Why I built OmniEmu</div><p class="p-desc">I got tired of opening 15 emulator apps. So I built one that manages them all.</p></div>
<span class="p-go"></span>
</a>
<a class="post rv" href="https://milesallen.site/blog/command-move-devlog.html">
<span class="p-date">2026 // 004</span>
<div><div class="p-title">CommandMove: cut &amp; paste</div><p class="p-desc">macOS doesn't have Cmd+X for files. I fixed that. Global event taps and AppleScript.</p></div>
<span class="p-go"></span>
</a>
<a class="post rv" href="https://milesallen.site/blog/fedl-devlog.html">
<span class="p-date">2025 // 005</span>
<div><div class="p-title">Running the FEDL</div><p class="p-desc">What it takes to maintain a Geometry Dash demon list. 3,800+ verified runs.</p></div>
<span class="p-go"></span>
</a>
<a class="post rv" href="https://milesallen.site/blog/nova-devlog.html">
<span class="p-date">2025 // 006</span>
<div><div class="p-title">Building Nova AI</div><p class="p-desc">Local AI that doesn't phone home. Desktop GUI, web interface, CLI — no subscriptions.</p></div>
<span class="p-go"></span>
</a>
</div>
</section>
<div class="mq mq-p" aria-hidden="true">
<div class="mq-track">
<span>★ EMAIL ME</span><span>★ GITHUB ↗</span><span>★ REPLIT ↗</span><span>★ CODEPEN ↗</span><span>★ I RESPOND MAYBE FAST</span><span>★ COFFEE COUNT: UNKNOWN</span><span>★ BUGS: INFINITE</span><span>★ OVERCLOCKED</span>
<span>★ EMAIL ME</span><span>★ GITHUB ↗</span><span>★ REPLIT ↗</span><span>★ CODEPEN ↗</span><span>★ I RESPOND MAYBE FAST</span><span>★ COFFEE COUNT: UNKNOWN</span><span>★ BUGS: INFINITE</span><span>★ OVERCLOCKED</span>
</div>
</div>
<section class="slogan">
<div class="slogan-in dsp mask" data-mask>
<span class="ln"><span>Build</span></span>
<span class="ln"><span style="--dl:.08s">with</span></span>
<span class="ln"><span style="--dl:.16s">intent</span></span>
</div>
</section>
<footer class="footer" id="contact">
<div class="f-head dsp mask" data-mask>
<span class="ln"><span>Let's</span></span>
<span class="ln"><span style="--dl:.07s">Make</span></span>
<span class="ln"><span style="--dl:.14s">Something</span></span>
<span class="ln"><span style="--dl:.21s">Great</span></span>
</div>
<div class="f-row">
<a class="hl" href="mailto:[email protected]">[email protected]</a>
<div class="f-links">
<a class="hl" href="https://github.com/mileswolfallen2" target="_blank" rel="noopener">GitHub</a>
<a class="hl" href="https://replit.com/@MilesAllen1" target="_blank" rel="noopener">Replit</a>
<a class="hl" href="https://codepen.io/mileswolfallen2-the-typescripter" target="_blank" rel="noopener">CodePen</a>
<a class="hl" href="https://me.fedl.site" target="_blank" rel="noopener">Website</a>
</div>
<span class="f-copy mono">©2026</span>
</div>
</footer>
</main>
<script>
(function(){
'use strict';
var body=document.body;
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
/* ---------- theme ---------- */
var themeBtn=document.getElementById('themeBtn');
var THEMES=['dark','light','max'];
function themeLabel(t){ return t==='max'?'MAX':(t==='light'?'THEME[B]':'THEME[A]'); }
function setTheme(t){
document.documentElement.setAttribute('data-theme',t);
themeBtn.textContent=themeLabel(t);
themeBtn.setAttribute('aria-label','Theme: '+t+', click to toggle');
try{localStorage.setItem('miles-theme',t);}catch(e){}
}
try{var savedTheme=localStorage.getItem('miles-theme');}catch(e){}
setTheme(THEMES.indexOf(savedTheme)>-1?savedTheme:'dark');
themeBtn.addEventListener('click',function(){
var cur=document.documentElement.getAttribute('data-theme')||'dark';
setTheme(THEMES[(THEMES.indexOf(cur)+1)%THEMES.length]);
});
/* ---------- clock ---------- */
var clock=document.getElementById('clock');
var tz='';
try{tz=new Date().toLocaleTimeString('en-US',{timeZoneName:'short'}).match(/[A-Z]{2,6}$/)[0]||'';}catch(e){}
function tick(){
var d=new Date();
var hh=('0'+d.getHours()).slice(-2),mm=('0'+d.getMinutes()).slice(-2);
clock.textContent=(tz?tz+' ':'')+hh+':'+mm;
}
tick();
setInterval(tick,1000);
/* ---------- mouse coordinates ---------- */
var coords=document.getElementById('coords');
if(window.matchMedia&&window.matchMedia('(pointer: fine)').matches){
document.addEventListener('mousemove',function(e){
coords.textContent=('000'+e.clientX).slice(-4)+' X '+('000'+e.clientY).slice(-4)+' Y';
},{passive:true});
}
/* ---------- progress bar ---------- */
var pbar=document.getElementById('pbar');
function prog(){
var h=document.documentElement;
pbar.style.width=((window.scrollY/(h.scrollHeight-window.innerHeight))*100)+'%';
}
window.addEventListener('scroll',prog,{passive:true});
prog();
/* ---------- stats count-up ---------- */
function countUp(el){
var target=parseInt(el.getAttribute('data-count'),10)||0;
var t0=null;
function fmt(n){return Math.round(n).toLocaleString('en-US');}
function step(ts){
if(t0===null)t0=ts;
var p=Math.min(1,(ts-t0)/1000);
var ease=1-Math.pow(1-p,3);
el.textContent=fmt(target*ease);
if(p<1)requestAnimationFrame(step);else el.textContent=fmt(target);
}
requestAnimationFrame(step);
}
if('IntersectionObserver' in window&&!reduce){
var cio=new IntersectionObserver(function(es){
es.forEach(function(e){
if(e.isIntersecting){countUp(e.target);cio.unobserve(e.target);}
});
},{threshold:0.4});
document.querySelectorAll('[data-count]').forEach(function(el){cio.observe(el);});
} else {
document.querySelectorAll('[data-count]').forEach(function(el){
el.textContent=(parseInt(el.getAttribute('data-count'),10)||0).toLocaleString('en-US');
});
}
/* ---------- reveal system ---------- */
function revealAll(){
document.querySelectorAll('.rv,[data-mask],#sign').forEach(function(el){ el.classList.add('in'); });
}
if('IntersectionObserver' in window&&!reduce){
var io=new IntersectionObserver(function(es){
es.forEach(function(e){
if(e.isIntersecting){ e.target.classList.add('in'); io.unobserve(e.target); }
});
},{threshold:0.16,rootMargin:'0px 0px -8% 0px'});
document.querySelectorAll('.rv,[data-mask],#sign').forEach(function(el){ io.observe(el); });
} else {
revealAll();
}
/* ---------- sound ---------- */
var soundBtn=document.getElementById('soundBtn');
var snd=null;
function stopSound(){
if(!snd)return;
snd._g.gain.linearRampToValueAtTime(0,snd.currentTime+0.35);
setTimeout(function(){
if(!snd)return;
snd._o.forEach(function(o){try{o.stop();}catch(e){}});
snd.close();snd=null;
},500);
}
soundBtn.addEventListener('click',function(){
var AC=window.AudioContext||window.webkitAudioContext;
if(!AC)return;
if(snd){ stopSound(); soundBtn.setAttribute('aria-pressed','false'); soundBtn.innerHTML='SOUND[&gt;]'; return; }
snd=new AC();
var o1=snd.createOscillator(),o2=snd.createOscillator(),g=snd.createGain();
var lfo=snd.createOscillator(),lg=snd.createGain();
o1.type='sine';o1.frequency.value=55;
o2.type='triangle';o2.frequency.value=110.5;
lfo.frequency.value=0.13;lg.gain.value=0.015;
g.gain.value=0;
lfo.connect(lg);lg.connect(g.gain);
o1.connect(g);o2.connect(g);g.connect(snd.destination);
o1.start();o2.start();lfo.start();
g.gain.linearRampToValueAtTime(0.035,snd.currentTime+1.2);
snd._o=[o1,o2,lfo];snd._g=g;
soundBtn.setAttribute('aria-pressed','true');
soundBtn.innerHTML='SOUND[|]';
});
})();
</script>
</body>
</html>
+896
View File
@@ -0,0 +1,896 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MILES WOLF ALLEN // VERY MAXIMALIST</title>
<meta name="description" content="Miles Wolf Allen — developer, 3D artist, and the guy trying to replace Electron. Games, tools, websites, and way too many repos.">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' fill='%23F7FF00'/%3E%3Ctext x='50' y='72' font-size='60' font-family='Arial Black' font-weight='900' text-anchor='middle' fill='%23000'%3EM%3C/text%3E%3C/svg%3E">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Archivo+Black&family=Press+Start+2P&family=Space+Mono:ital,wght@0,400;0,700&display=swap" rel="stylesheet">
<style>
:root{
--bg:#0b0b0d; --bg2:#121215; --ink:#ffffff; --muted:#9a9aa2;
--pink:#FF2EA6; --yellow:#F7FF00; --cyan:#00F4FF; --orange:#FF5C00;
--purple:#8A2BFF; --red:#FF1F1F; --green:#00FF85;
--d:'Archivo Black',Impact,sans-serif;
--m:'Space Mono',monospace;
--p:'Press Start 2P',monospace;
--blk:#000;
}
*{margin:0;padding:0;box-sizing:border-box;}
html{scroll-behavior:smooth;overflow-x:hidden;}
body{
background:var(--bg);color:var(--ink);
font-family:var(--m);font-size:15px;line-height:1.6;
overflow-x:hidden;-webkit-font-smoothing:antialiased;
}
::selection{background:var(--yellow);color:#000;}
a{color:inherit;text-decoration:none;}
::-webkit-scrollbar{width:12px;}
::-webkit-scrollbar-track{background:#000;}
::-webkit-scrollbar-thumb{background:var(--pink);border:3px solid #000;}
/* ---------- fixed layers ---------- */
.bg-grid{
position:fixed;inset:0;z-index:-3;pointer-events:none;
background-image:
linear-gradient(rgba(255,255,255,0.045) 1px,transparent 1px),
linear-gradient(90deg,rgba(255,255,255,0.045) 1px,transparent 1px);
background-size:44px 44px;
}
.noise{
position:fixed;inset:0;z-index:-2;pointer-events:none;opacity:.06;
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
}
.vignette{position:fixed;inset:0;z-index:-1;pointer-events:none;
background:radial-gradient(ellipse at center,transparent 55%,rgba(0,0,0,0.55) 100%);}
.progress{position:fixed;top:0;left:0;height:5px;width:0;background:var(--yellow);z-index:600;box-shadow:0 0 12px var(--yellow);}
/* ---------- cursor ---------- */
.cursor,.glow{position:fixed;top:0;left:0;pointer-events:none;z-index:900;border-radius:50%;}
.cursor{width:12px;height:12px;background:#fff;transform:translate(-50%,-50%);mix-blend-mode:difference;}
.glow{width:320px;height:320px;background:radial-gradient(circle,rgba(255,46,166,0.18),transparent 65%);transform:translate(-50%,-50%);z-index:800;transition:opacity .3s;}
.cursor.on{width:44px;height:44px;border:2px solid #fff;background:transparent;transition:width .18s,height .18s;mix-blend-mode:difference;}
@media(pointer:coarse){.cursor,.glow{display:none;}}
/* ---------- splash ---------- */
.splash{
position:fixed;inset:0;z-index:1000;background:var(--bg);
display:flex;align-items:center;justify-content:center;gap:0;
pointer-events:none;
animation:splashOut .55s ease forwards .95s;
}
.splash span{
font-family:var(--d);font-size:clamp(64px,18vw,220px);color:#fff;
display:inline-block;opacity:0;
animation:splashIn .6s cubic-bezier(.2,1.6,.3,1) forwards;
}
.splash span:nth-child(1){animation-delay:.05s;color:var(--yellow);-webkit-text-stroke:3px #000;}
.splash span:nth-child(2){animation-delay:.15s;}
.splash span:nth-child(3){animation-delay:.25s;color:var(--pink);-webkit-text-stroke:3px #000;}
.splash span:nth-child(4){animation-delay:.35s;}
.splash span:nth-child(5){animation-delay:.45s;color:var(--cyan);-webkit-text-stroke:3px #000;}
.splash .splash-tag{
position:absolute;bottom:12%;left:50%;transform:translateX(-50%) rotate(-3deg);
font-family:var(--p);font-size:9px;background:var(--yellow);color:#000;
padding:10px 16px;border:3px solid #000;box-shadow:5px 5px 0 var(--pink);
}
@keyframes splashIn{0%{opacity:0;transform:translateY(120%) rotate(4deg);}100%{opacity:1;transform:translateY(0) rotate(0);}}
@keyframes splashOut{0%{opacity:1;}100%{opacity:0;visibility:hidden;}}
/* ---------- nav ---------- */
.nav{
position:fixed;top:14px;left:14px;right:14px;z-index:500;
display:flex;align-items:center;justify-content:space-between;gap:14px;
background:rgba(11,11,13,0.78);border:3px solid #000;box-shadow:5px 5px 0 #000;
padding:10px 14px;backdrop-filter:blur(6px);
}
.nav-logo{font-family:var(--d);font-size:20px;display:flex;align-items:center;gap:9px;letter-spacing:.5px;}
.nav-logo .dot{width:12px;height:12px;background:var(--green);border:2px solid #000;animation:blink 1.6s steps(1) infinite;}
.nav-links{display:flex;gap:6px;flex-wrap:wrap;}
.nav-links a{font-family:var(--p);font-size:8px;color:#fff;padding:9px 12px;border:2px solid #fff;text-transform:uppercase;transition:all .15s;}
.nav-links a:hover{background:var(--pink);color:#000;transform:translate(-2px,-2px);box-shadow:3px 3px 0 #fff;}
.nav-status{display:flex;align-items:center;gap:8px;font-family:var(--p);font-size:8px;color:var(--yellow);}
.nav-status b{width:9px;height:9px;background:var(--yellow);border-radius:50%;animation:blink 1s steps(1) infinite;}
@keyframes blink{50%{opacity:.2;}}
@media(max-width:720px){.nav-links{display:none;}}
/* ---------- utility ---------- */
.btn{
display:inline-flex;align-items:center;gap:10px;cursor:pointer;
font-family:var(--p);font-size:11px;text-transform:uppercase;letter-spacing:.05em;
padding:16px 22px;border:3px solid #000;color:#000;
box-shadow:5px 5px 0 #000;transition:transform .12s,box-shadow .12s,background .12s;
user-select:none;
}
.btn:hover{transform:translate(-2px,-2px);box-shadow:8px 8px 0 #000;}
.btn:active{transform:translate(3px,3px);box-shadow:1px 1px 0 #000;}
.btn-pink{background:var(--pink);}
.btn-yellow{background:var(--yellow);}
.btn-cyan{background:var(--cyan);}
.btn-ghost{background:transparent;color:#fff;}
.btn-ghost:hover{background:#fff;color:#000;box-shadow:8px 8px 0 var(--pink);}
.chip{
display:inline-flex;align-items:center;gap:8px;
font-family:var(--p);font-size:8px;text-transform:uppercase;
border:2px solid #000;padding:8px 12px;background:#fff;color:#000;
box-shadow:3px 3px 0 #000;
}
.chip-y{background:var(--yellow);} .chip-p{background:var(--pink);} .chip-c{background:var(--cyan);} .chip-o{background:var(--orange);}
.marquee{overflow:hidden;white-space:nowrap;position:relative;z-index:3;border-top:3px solid #000;border-bottom:3px solid #000;}
.marquee .mq-track{display:inline-flex;white-space:nowrap;animation:mq 22s linear infinite;}
.marquee.mq-rev .mq-track{animation:mq 22s linear infinite reverse;}
.marquee span{font-family:var(--p);font-size:12px;padding:14px 0;margin:0 22px;flex-shrink:0;}
.mq-y{background:var(--yellow);} .mq-y span{color:#000;}
.mq-p{background:var(--pink);} .mq-p span{color:#000;}
.mq-c{background:var(--cyan);} .mq-c span{color:#000;}
.mq-b{background:#fff;} .mq-b span{color:#000;}
@keyframes mq{0%{transform:translateX(0);}100%{transform:translateX(-50%);}}
.stick{
position:absolute;z-index:5;pointer-events:none;display:flex;align-items:center;justify-content:center;
font-family:var(--p);font-size:9px;text-transform:uppercase;text-align:center;line-height:1.5;
border:3px solid #000;box-shadow:5px 5px 0 #000;padding:10px 14px;
}
.stick-s{font-size:7px;border-radius:50%;width:120px;height:120px;box-shadow:none;}
.star{display:inline-block;color:var(--yellow);filter:drop-shadow(2px 2px 0 #000);}
.sec{position:relative;padding:110px 5vw 90px;}
.sec-index{
font-family:var(--d);font-size:clamp(120px,26vw,300px);line-height:.8;
color:transparent;-webkit-text-stroke:1.5px rgba(255,255,255,0.10);
position:absolute;top:30px;right:-2vw;z-index:0;user-select:none;pointer-events:none;
}
.sec-band{
position:relative;z-index:2;margin-bottom:56px;overflow:hidden;
}
.sec-band .band-inner{display:flex;align-items:baseline;gap:20px;flex-wrap:nowrap;}
.sec-tag{
font-family:var(--p);font-size:9px;color:#000;background:var(--yellow);
border:3px solid #000;padding:8px 12px;box-shadow:3px 3px 0 #000;
transform:rotate(-2deg);white-space:nowrap;
}
.sec-title{
font-family:var(--d);font-size:clamp(44px,10vw,130px);line-height:.9;letter-spacing:-.02em;
white-space:nowrap;text-transform:uppercase;position:relative;display:inline-block;
}
.sec-title .out{color:transparent;-webkit-text-stroke:2px #fff;}
.sec-sub{font-family:var(--m);color:var(--muted);font-size:15px;margin-top:14px;max-width:520px;}
/* ---------- hero ---------- */
.hero{position:relative;min-height:100vh;display:flex;flex-direction:column;justify-content:center;padding:120px 5vw 40px;overflow:hidden;}
.hero-top{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:26px;position:relative;z-index:2;}
.hero-title{
position:relative;z-index:2;font-family:var(--d);line-height:.88;letter-spacing:-.03em;
font-size:clamp(72px,22vw,300px);text-transform:uppercase;
}
.hero-title .l{display:block;}
.hero-title .l2{margin-left:1.1em;}
.hero-title em{font-style:normal;color:transparent;-webkit-text-stroke:2.5px #fff;}
.hero-title .dot{color:var(--yellow);}
.hero-rings{position:absolute;top:50%;right:4vw;transform:translateY(-55%);width:min(46vw,560px);height:min(46vw,560px);z-index:0;pointer-events:none;}
.hero-rings .ring{position:absolute;inset:0;border-radius:50%;border:3px dashed rgba(255,255,255,0.35);animation:spin 30s linear infinite;}
.hero-rings .ring.r2{inset:9%;border:3px solid rgba(255,46,166,0.5);animation-duration:20s;animation-direction:reverse;}
.hero-rings .ring.r3{inset:18%;border:3px dashed rgba(0,244,255,0.5);animation-duration:45s;}
.hero-rings .ring-star{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:64px;animation:pop 1s cubic-bezier(.2,1.6,.3,1) 1.2s both;}
.hero-ring-mid{position:absolute;top:50%;right:4vw;transform:translateY(-55%);width:14px;height:14px;background:var(--yellow);border:3px solid #000;z-index:1;animation:blink 1s steps(1) infinite;}
.hero-sub{position:relative;z-index:2;font-family:var(--m);font-size:clamp(14px,1.6vw,19px);color:var(--muted);max-width:560px;line-height:1.7;margin:26px 0 30px;padding-left:18px;border-left:6px solid var(--pink);}
.hero-sub b{color:#fff;}
.hero-cta{display:flex;gap:14px;flex-wrap:wrap;position:relative;z-index:2;}
.hero-float{position:absolute;z-index:2;}
.hf-1{top:22%;left:6%;}
.hf-2{top:32%;right:6%;}
.hf-3{bottom:16%;left:44%;}
.hf-4{bottom:30%;left:12%;}
.hero-scroll{position:absolute;bottom:24px;left:50%;transform:translateX(-50%);font-family:var(--p);font-size:9px;color:var(--muted);display:flex;flex-direction:column;align-items:center;gap:8px;z-index:2;}
.hero-scroll .a{font-size:18px;animation:bob 1.4s ease-in-out infinite;}
@keyframes bob{50%{transform:translateY(6px);}}
@keyframes spin{to{transform:rotate(360deg);}}
@keyframes pop{0%{opacity:0;transform:scale(0) rotate(-40deg);}100%{opacity:1;transform:scale(1) rotate(0);}}
@media(max-width:720px){.hero-rings,.hero-ring-mid{display:none;} .hero-title .l2{margin-left:.6em;}}
/* ---------- stats ---------- */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;padding:0 5vw 30px;position:relative;z-index:2;}
.stat{
border:4px solid #000;padding:34px 18px;text-align:center;position:relative;
box-shadow:8px 8px 0 #000;transition:transform .15s,box-shadow .15s;
}
.stat:hover{transform:translate(-3px,-3px);box-shadow:12px 12px 0 #000;}
.stat .n{font-family:var(--d);font-size:clamp(40px,6vw,84px);line-height:1;display:block;}
.stat .l{font-family:var(--p);font-size:8px;text-transform:uppercase;margin-top:12px;display:block;letter-spacing:.06em;}
.st-pink{background:var(--pink);} .st-yellow{background:var(--yellow);} .st-cyan{background:var(--cyan);} .st-orange{background:var(--orange);}
.st-yellow .n,.st-pink .n{color:#000;} .st-cyan .n,.st-orange .n{color:#000;}
.st-pink{transform:rotate(-2deg);} .st-yellow{transform:rotate(1.5deg) translateY(10px);} .st-cyan{transform:rotate(-1deg) translateY(-6px);} .st-orange{transform:rotate(2deg) translateY(6px);}
.stat .tick{position:absolute;top:-12px;right:-12px;width:34px;height:34px;background:#fff;border:3px solid #000;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;box-shadow:3px 3px 0 #000;}
@media(max-width:860px){.stats{grid-template-columns:repeat(2,1fr);gap:26px 14px;} .st-yellow,.st-cyan,.st-orange{transform:none;}}
/* ---------- about ---------- */
.about-grid{display:grid;grid-template-columns:280px 1fr;gap:40px;position:relative;z-index:2;}
.avatar-wrap{position:relative;align-self:start;}
.avatar{width:100%;border:5px solid #000;box-shadow:10px 10px 0 var(--pink);transform:rotate(-3deg);display:block;filter:grayscale(.2) contrast(1.1);transition:transform .2s;}
.avatar:hover{transform:rotate(0) scale(1.02);box-shadow:12px 12px 0 var(--pink);}
.avatar-sticker{position:absolute;bottom:-20px;left:-16px;background:var(--yellow);border:3px solid #000;padding:10px 14px;font-family:var(--p);font-size:8px;transform:rotate(-5deg);box-shadow:4px 4px 0 #000;text-transform:uppercase;}
.card{
background:var(--bg2);border:4px solid #000;box-shadow:10px 10px 0 #000;padding:34px;position:relative;
}
.card::before{content:'';position:absolute;top:-14px;right:30px;width:70px;height:26px;background:var(--tape,#FFC93C);opacity:.85;transform:rotate(3deg);box-shadow:0 0 0 2px #000;}
.card h3{font-family:var(--d);font-size:clamp(24px,3vw,40px);margin-bottom:16px;}
.card p{color:var(--muted);margin-bottom:18px;font-size:14.5px;}
.badges{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:22px;}
.badge{font-family:var(--p);font-size:8px;padding:10px 14px;border:2px solid #000;box-shadow:3px 3px 0 #000;text-transform:uppercase;}
.bg-pink{background:var(--pink);} .bg-cyan{background:var(--cyan);} .bg-green{background:var(--green);} .bg-orange{background:var(--orange);} .bg-purple{background:var(--purple);} .bg-yellow{background:var(--yellow);} .bg-red{background:var(--red);}
.bg-pink,.bg-green,.bg-orange,.bg-yellow,.bg-cyan{color:#000;}
.about-links{display:flex;gap:12px;flex-wrap:wrap;border-top:3px dashed rgba(255,255,255,0.2);padding-top:20px;margin-top:6px;}
@media(max-width:860px){.about-grid{grid-template-columns:1fr;} .avatar{max-width:240px;}}
/* ---------- skills ---------- */
.skills-wrap{position:relative;z-index:2;display:flex;flex-direction:column;gap:40px;}
.skill-group{display:flex;flex-direction:column;gap:16px;}
.skill-group .gl{font-family:var(--p);font-size:10px;text-transform:uppercase;color:var(--yellow);display:flex;align-items:center;gap:12px;}
.skill-group .gl::after{content:'';flex:1;height:3px;background:rgba(255,255,255,0.12);}
.skill-pills{display:flex;flex-wrap:wrap;gap:12px;}
.pill{
font-family:var(--m);font-weight:700;font-size:14px;text-transform:uppercase;letter-spacing:.02em;
padding:13px 18px;background:#fff;color:#000;border:3px solid #000;box-shadow:4px 4px 0 #000;
display:inline-flex;align-items:center;gap:10px;transition:transform .12s,box-shadow .12s,background .12s,color .12s;
}
.pill:nth-child(5n){transform:rotate(-2deg);} .pill:nth-child(5n+2){transform:rotate(1.5deg);} .pill:nth-child(5n+4){transform:rotate(-1deg);}
.pill:hover{transform:translate(-2px,-3px) rotate(0) scale(1.04);box-shadow:8px 8px 0 var(--pink);}
.pill .si{width:20px;height:20px;flex-shrink:0;}
.pill.learn{background:var(--bg2);color:#fff;border-style:dashed;box-shadow:none;}
.pill.learn:hover{background:var(--orange);color:#000;border-style:solid;box-shadow:8px 8px 0 #000;}
/* ---------- projects ---------- */
.proj-list{display:flex;flex-direction:column;gap:26px;position:relative;z-index:2;}
.proj{
background:var(--bg2);border:4px solid #000;box-shadow:10px 10px 0 #000;padding:30px 32px;position:relative;
transition:transform .16s,box-shadow .16s;display:block;overflow:hidden;
}
.proj:nth-child(odd){transform:rotate(-1.2deg);}
.proj:nth-child(even){transform:rotate(1deg);}
.proj:nth-child(3n){transform:rotate(-0.5deg);}
.proj:hover{transform:rotate(0) translate(-3px,-3px);box-shadow:16px 16px 0 var(--pink);}
.proj .num{
position:absolute;top:14px;right:20px;font-family:var(--d);font-size:clamp(56px,9vw,110px);line-height:1;
color:transparent;-webkit-text-stroke:1.5px rgba(255,255,255,0.14);user-select:none;pointer-events:none;
}
.proj-top{display:flex;align-items:center;gap:12px;margin-bottom:18px;flex-wrap:wrap;position:relative;z-index:2;}
.tag{font-family:var(--p);font-size:8px;padding:8px 12px;border:2px solid #000;box-shadow:3px 3px 0 #000;text-transform:uppercase;color:#000;}
.proj-title{font-family:var(--d);font-size:clamp(26px,4.5vw,52px);line-height:1;text-transform:uppercase;position:relative;z-index:2;display:flex;align-items:baseline;gap:14px;}
.proj-title .go{font-family:var(--p);font-size:16px;color:var(--yellow);transition:transform .15s;}
.proj:hover .go{transform:translate(4px,-4px);}
.proj-desc{color:var(--muted);margin-top:14px;max-width:640px;position:relative;z-index:2;font-size:14px;}
.proj:hover .proj-desc{color:#fff;}
/* ---------- scoreboard ---------- */
.score-block{margin-bottom:40px;position:relative;z-index:2;}
.score-head{display:flex;align-items:center;gap:14px;margin-bottom:18px;}
.score-head h3{font-family:var(--d);font-size:clamp(22px,3vw,36px);text-transform:uppercase;}
.score-head .lvl{font-family:var(--p);font-size:9px;background:var(--cyan);color:#000;border:3px solid #000;padding:8px 12px;box-shadow:3px 3px 0 #000;}
.score-cells{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;}
.scell{border:4px solid #000;padding:26px 18px;text-align:center;box-shadow:6px 6px 0 #000;background:var(--bg2);}
.scell .v{font-family:var(--d);font-size:clamp(26px,4vw,48px);display:block;line-height:1;}
.scell .k{font-family:var(--p);font-size:7px;margin-top:10px;display:block;color:var(--muted);text-transform:uppercase;}
.scell.filled{background:var(--pink);color:#000;} .scell.filled .k{color:#000;}
.scell.filled.s2{background:var(--yellow);} .scell.filled.s3{background:var(--cyan);} .scell.filled.s4{background:var(--orange);}
@media(max-width:860px){.score-cells{grid-template-columns:repeat(2,1fr);}}
/* ---------- blog ---------- */
.blog-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:22px;position:relative;z-index:2;}
.blog{border:4px solid #000;background:var(--bg2);box-shadow:8px 8px 0 #000;padding:26px;display:block;position:relative;transition:transform .15s,box-shadow .15s;}
.blog:nth-child(3n+1){transform:rotate(-1deg);} .blog:nth-child(3n+2){transform:rotate(0.8deg) translateY(6px);} .blog:nth-child(3n){transform:rotate(-0.6deg);}
.blog:hover{transform:translate(-3px,-3px) rotate(0);box-shadow:14px 14px 0 var(--cyan);}
.blog .date{font-family:var(--p);font-size:8px;color:var(--pink);display:block;margin-bottom:12px;}
.blog h3{font-family:var(--d);font-size:19px;line-height:1.15;text-transform:uppercase;margin-bottom:10px;}
.blog p{font-size:13px;color:var(--muted);margin-bottom:16px;}
.blog .tags{display:flex;gap:8px;flex-wrap:wrap;}
.blog .bt{font-family:var(--p);font-size:7px;background:#fff;color:#000;border:2px solid #000;padding:6px 9px;box-shadow:2px 2px 0 #000;}
/* ---------- contact ---------- */
.contact-rows{position:relative;z-index:2;display:flex;flex-direction:column;border-top:4px solid #000;}
.crow{
display:flex;align-items:center;justify-content:space-between;gap:20px;
padding:26px 20px;border:4px solid #000;border-top:none;margin-top:-4px;position:relative;background:var(--bg2);
transition:background .12s,color .12s,padding-left .15s;box-shadow:6px 6px 0 #000;margin-bottom:8px;
}
.crow .k{font-family:var(--p);font-size:10px;color:var(--yellow);text-transform:uppercase;}
.crow .v{font-family:var(--d);font-size:clamp(18px,3vw,30px);text-transform:lowercase;display:flex;align-items:center;gap:10px;}
.crow .arrow{font-size:22px;transition:transform .15s;color:var(--pink);}
.crow:hover{background:var(--pink);color:#000;padding-left:30px;}
.crow:hover .k,.crow:hover .arrow{color:#000;}
.crow:hover .arrow{transform:translate(6px,0);}
/* ---------- footer ---------- */
.footer{position:relative;padding:90px 5vw 40px;text-align:center;overflow:hidden;}
.footer .fword{font-family:var(--d);font-size:clamp(70px,20vw,280px);line-height:.9;color:transparent;-webkit-text-stroke:2px rgba(255,255,255,0.14);text-transform:uppercase;user-select:none;}
.footer .fmeta{font-family:var(--p);font-size:9px;color:var(--muted);margin-top:26px;display:flex;justify-content:center;gap:18px;flex-wrap:wrap;}
.footer .fmeta a{color:#fff;text-decoration:underline;text-underline-offset:4px;}
.footer .fmeta a:hover{color:var(--pink);}
.top-btn{margin-top:30px;}
/* ---------- reveal system ---------- */
html.js [data-in]{opacity:0;transition:opacity .7s ease,transform .7s cubic-bezier(.2,1.3,.3,1);will-change:transform,opacity;}
html.js [data-in="up"]{transform:translateY(60px) rotate(-1.2deg);}
html.js [data-in="down"]{transform:translateY(-60px) rotate(1deg);}
html.js [data-in="left"]{transform:translateX(-80px) rotate(-1.5deg);}
html.js [data-in="right"]{transform:translateX(80px) rotate(1.5deg);}
html.js [data-in="pop"]{transform:scale(.6) rotate(-6deg);}
html.js [data-in="flip"]{transform:translateY(40px) rotateX(-60deg);transform-style:preserve-3d;}
html.js [data-in].in{opacity:1;transform:none;}
@media(max-width:720px){
.sec{padding:80px 5vw 70px;}
.sec-band .band-inner{flex-direction:column;align-items:flex-start;gap:10px;}
.sec-title{white-space:normal;}
.proj .num{font-size:60px;}
}
@media(prefers-reduced-motion:reduce){
*,*::before,*::after{animation:none!important;transition:none!important;}
.splash{display:none;}
}
</style>
</head>
<body>
<div class="splash" aria-hidden="true"><span>M</span><span>I</span><span>L</span><span>E</span><span>S</span><div class="splash-tag">MAXIMALISM ON</div></div>
<div class="bg-grid" aria-hidden="true"></div>
<div class="noise" aria-hidden="true"></div>
<div class="vignette" aria-hidden="true"></div>
<div class="cursor" id="cursor"></div>
<div class="glow" id="glow"></div>
<div class="progress" id="progress"></div>
<nav class="nav">
<a class="nav-logo" href="#top"><span class="dot"></span>MILES</a>
<div class="nav-links">
<a href="#about">About</a>
<a href="#skills">Skills</a>
<a href="#projects">Builds</a>
<a href="#blog">Devlog</a>
<a href="#contact">Contact</a>
</div>
<span class="nav-status"><b></b> USUALLY ONLINE</span>
</nav>
<header class="hero" id="top">
<div class="hero-rings" aria-hidden="true">
<div class="ring"></div>
<div class="ring r2"></div>
<div class="ring r3"></div>
<div class="ring-star"><span class="star"></span></div>
</div>
<div class="hero-ring-mid" aria-hidden="true"></div>
<div class="hero-top">
<span class="chip chip-y">★ MILES WOLF ALLEN</span>
<span class="chip chip-p">DEVELOPER &amp; 3D ARTIST</span>
<span class="chip chip-c">DISKETTE LABS CO-FOUNDER</span>
</div>
<h1 class="hero-title" id="heroTitle">
<span class="l"><em>MI</em>L</span>
<span class="l l2"><em>E</em>S<span class="dot">.</span></span>
</h1>
<div class="hero-float hf-1 stick" data-speed="18">★ EST. 2008</div>
<div class="hero-float hf-2 stick stick-s"><span class="star"></span></div>
<div class="hero-float hf-3 stick" style="background:var(--yellow);color:#000;" data-speed="-14">THE WOW</div>
<div class="hero-float hf-4 stick stick-s" style="border-radius:50%;background:var(--pink);"><span class="star"></span></div>
<p class="hero-sub">I make <b>games</b>, <b>tools</b>, and <b>websites</b>. Still in school, currently building a full <b>Electron replacement</b> — send help. 160 repos and counting.</p>
<div class="hero-cta">
<a class="btn btn-pink" href="#projects">SEE THE BUILDS ↓</a>
<a class="btn btn-ghost" href="https://github.com/mileswolfallen2" target="_blank" rel="noopener">GITHUB ↗</a>
</div>
<div class="hero-scroll">SCROLL<div class="a"></div></div>
</header>
<div class="marquee mq-y" data-mq="build"> </div>
<section class="sec" id="stats">
<div class="sec-index" data-par="12">000</div>
<div class="sec-band">
<div class="band-inner">
<span class="sec-tag">LEVEL 00</span>
<h2 class="sec-title" data-band="1">THE <span class="out">NUMBERS</span>.</h2>
</div>
</div>
<div class="stats">
<div class="stat st-pink" data-in="left"><span class="tick"></span><span class="n num" data-count="160">0</span><span class="l">REPOS ONLINE</span></div>
<div class="stat st-yellow" data-in="pop"><span class="tick"></span><span class="n num" data-count="91">0</span><span class="l">STARS EARNED</span></div>
<div class="stat st-cyan" data-in="right"><span class="tick"></span><span class="n num" data-count="13">0</span><span class="l">WATCHING ME</span></div>
<div class="stat st-orange" data-in="down"><span class="tick"></span><span class="n num" data-count="37">0</span><span class="l">I WATCH</span></div>
</div>
</section>
<section class="sec" id="about">
<div class="sec-index" data-par="8">01</div>
<div class="sec-band">
<div class="band-inner">
<span class="sec-tag">LEVEL 01 // IDENTITY</span>
<h2 class="sec-title" data-band="-1"><span class="out">WHO'S</span> MILES<span class="dot">?</span></h2>
</div>
<p class="sec-sub">the human behind the commits. pancakes &gt; waffles, cereal is soup, software should feel good to use.</p>
</div>
<div class="about-grid">
<div class="avatar-wrap" data-in="left">
<img class="avatar" src="https://avatars.githubusercontent.com/u/115095719?v=4" alt="Miles Wolf Allen" loading="lazy" width="280" height="280">
<span class="avatar-sticker">@mileswolfallen2</span>
</div>
<div class="card" data-in="up">
<h3>// PLAYER BIO</h3>
<p>I build things on the internet. Some are games, some are tools, and some are just because I thought it'd be fun. I'm co-founder of <b style="color:#fff">Diskette Labs</b>, still in school, and chasing the dream of a world without bundled Chromium.</p>
<div class="badges">
<span class="badge bg-pink">PULL SHARK ×2</span>
<span class="badge bg-yellow">YOLO</span>
<span class="badge bg-green">QUICKDRAW</span>
<span class="badge bg-orange">GEOMETRY DASH ADDICT</span>
</div>
<div class="about-links">
<a class="btn btn-yellow" href="https://diskettelabs.com/" target="_blank" rel="noopener">DISKETTE LABS ↗</a>
<a class="btn btn-ghost" href="about-me.html">MORE ABOUT ME →</a>
</div>
</div>
</div>
</section>
<div class="marquee mq-p mq-rev" data-mq="warn"> </div>
<section class="sec" id="skills">
<div class="sec-index" data-par="10">02</div>
<div class="sec-band">
<div class="band-inner">
<span class="sec-tag">LEVEL 02 // LOADOUT</span>
<h2 class="sec-title" data-band="1">MY <span class="out">LOADOUT</span>.</h2>
</div>
<p class="sec-sub">what I actually know how to use (and what I'm currently failing at).</p>
</div>
<div class="skills-wrap">
<div class="skill-group" data-in="up">
<span class="gl">READY TO USE</span>
<div class="skill-pills" id="skillPills">
<span class="pill" data-si="javascript">JS</span>
<span class="pill" data-si="nodedotjs">BACKEND JS</span>
<span class="pill" data-si="html5">HTML</span>
<span class="pill" data-si="css3">CSS</span>
<span class="pill" data-si="python">PYTHON</span>
<span class="pill" data-si="git">GIT</span>
<span class="pill" data-si="blender">BLENDER</span>
<span class="pill" data-si="unity">UNITY</span>
<span class="pill" data-si="unrealengine">UNREAL</span>
<span class="pill" data-si="cloudflare">CLOUDFLARE</span>
<span class="pill" data-si="linux">LINUX</span>
<span class="pill" data-si="netlify">NETLIFY</span>
<span class="pill" data-si="gnubash">BASH</span>
<span class="pill" data-si="github">GITHUB</span>
<span class="pill" data-si="electron">ELECTRON</span>
<span class="pill" data-si="c">GELECTRON</span>
</div>
</div>
<div class="skill-group" data-in="up">
<span class="gl">CURRENTLY UNLOCKING</span>
<div class="skill-pills">
<span class="pill learn" data-si="php">PHP</span>
<span class="pill learn" data-si="dotnet">.NET</span>
<span class="pill learn" data-si="nixos">NIX</span>
<span class="pill learn" data-si="yarn">YARN</span>
</div>
</div>
</div>
</section>
<section class="sec" id="projects">
<div class="sec-index" data-par="14">03</div>
<div class="sec-band">
<div class="band-inner">
<span class="sec-tag">LEVEL 03 // BUILDS</span>
<h2 class="sec-title" data-band="-1">THE <span class="out">BUILDS</span>.</h2>
</div>
<p class="sec-sub">stuff I've made (and some I forked). every one of these was at least 80% 2am.</p>
</div>
<div class="proj-list">
<a class="proj" href="https://milesallen.site/projects/omniemu.html" data-par="-8">
<span class="num">01</span>
<div class="proj-top"><span class="tag" style="background:var(--green);">ACTIVE</span><span class="chip" style="font-size:7px;">MIT · v0.3.2 · TS</span></div>
<div class="proj-title">OmniEmu 2.0 <span class="go"></span></div>
<div class="proj-desc">All your emulators in one place. Install 20+ emulators, scan your ROMs, launch games without opening 15 apps.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/gelectron.html" data-par="10">
<span class="num">02</span>
<div class="proj-top"><span class="tag" style="background:var(--yellow);">EARLY</span><span class="chip" style="font-size:7px;">RUST + NODE · MIT</span></div>
<div class="proj-title">Gelectron <span class="go"></span></div>
<div class="proj-desc">Drop-in Electron replacement using native web views (WKWebView / WebView2 / WebKitGTK) instead of bundling Chromium. The send-help project.</div>
</a>
<a class="proj" href="https://vanilla.milesallen.site/" target="_blank" rel="noopener" data-par="-12">
<span class="num">03</span>
<div class="proj-top"><span class="tag" style="background:var(--cyan);">UNRELEASED</span><span class="chip" style="font-size:7px;">VANILLA JS</span></div>
<div class="proj-title">Vanilla <span class="go"></span></div>
<div class="proj-desc">A clean, minimal web experiment. Pure vanilla JS, no frameworks, no cruft.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/fedl.html" data-par="6">
<span class="num">04</span>
<div class="proj-top"><span class="tag" style="background:var(--red);">LIVE</span><span class="chip" style="font-size:7px;">2196 COMMITS</span></div>
<div class="proj-title">FEDL <span class="go"></span></div>
<div class="proj-desc">The demon list for Geometry Dash. Ranked levels, run submissions, and a community way better at the game than me.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/command-move.html" data-par="-10">
<span class="num">05</span>
<div class="proj-top"><span class="tag" style="background:var(--purple);">SWIFT</span><span class="chip" style="font-size:7px;">MACOS · MIT</span></div>
<div class="proj-title">CommandMove <span class="go"></span></div>
<div class="proj-desc">True cut-and-paste for Finder on macOS. Select files, Cmd+X, navigate, Cmd+V. What Apple forgot to build.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/noto.html" data-par="8">
<span class="num">06</span>
<div class="proj-top"><span class="tag" style="background:var(--green);">ACTIVE</span><span class="chip" style="font-size:7px;">FLUTTER · AI</span></div>
<div class="proj-title">Noto <span class="go"></span></div>
<div class="proj-desc">Note-taking with AI built in. Flutter, powered by Cortex AI, actually good at organizing my chaos.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/nova.html" data-par="-6">
<span class="num">07</span>
<div class="proj-top"><span class="tag" style="background:var(--yellow);">PYTHON</span><span class="chip" style="font-size:7px;">MIT · LOCAL AI</span></div>
<div class="proj-title">Nova AI <span class="go"></span></div>
<div class="proj-desc">AI that runs on your machine. Desktop GUI, web interface, CLI. No cloud, no subscriptions, just vibes.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/music-app.html" data-par="12">
<span class="num">08</span>
<div class="proj-top"><span class="tag" style="background:var(--cyan);">JS</span><span class="chip" style="font-size:7px;">APACHE-2.0</span></div>
<div class="proj-title">Music App <span class="go"></span></div>
<div class="proj-desc">Music player that doesn't interrupt you with ads. YouTube Music minus the annoying parts.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/rhythm-game.html" data-par="-8">
<span class="num">09</span>
<div class="proj-top"><span class="tag" style="background:var(--pink);">HTML</span><span class="chip" style="font-size:7px;">MPL-2.0</span></div>
<div class="proj-title">Rhythm Game <span class="go"></span></div>
<div class="proj-desc">Hit keys to the beat. Song selection, real-time notes, keyboard controls. My fingers hurt.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/geode-mod.html" data-par="9">
<span class="num">10</span>
<div class="proj-top"><span class="tag" style="background:var(--orange);">WIP</span><span class="chip" style="font-size:7px;">MIT</span></div>
<div class="proj-title">FEDL Geode Mod <span class="go"></span></div>
<div class="proj-desc">Geometry Dash mod that shows the demon list in-game. Roulette mode, banned mod detection, more.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/decompilations.html" data-par="-9">
<span class="num">11</span>
<div class="proj-top"><span class="tag" style="background:var(--pink);">HTML</span><span class="chip" style="font-size:7px;">MIT</span></div>
<div class="proj-title">Decompilations <span class="go"></span></div>
<div class="proj-desc">Native PC ports and decompilations of games. Progress tracking for projects that probably shouldn't exist.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/issue-tracker.html" data-par="7">
<span class="num">12</span>
<div class="proj-top"><span class="tag" style="background:var(--cyan);">HTML</span><span class="chip" style="font-size:7px;">MIT · NODE</span></div>
<div class="proj-title">Issue Tracker <span class="go"></span></div>
<div class="proj-desc">Built my own issue tracker because why not. Node.js backend, no frameworks, raw determination.</div>
</a>
<a class="proj" href="https://milesallen.site/projects/moon-gaming.html" data-par="-11">
<span class="num">13</span>
<div class="proj-top"><span class="tag" style="background:var(--yellow);">HTML</span><span class="chip" style="font-size:7px;">1542 COMMITS</span></div>
<div class="proj-title">Moon Gaming <span class="go"></span></div>
<div class="proj-desc">Game hub with 1,500+ commits. A growing library of browser games I made at 2am.</div>
</a>
</div>
</section>
<div class="marquee mq-c" data-mq="project"> </div>
<section class="sec" id="highlights">
<div class="sec-index" data-par="9">04</div>
<div class="sec-band">
<div class="band-inner">
<span class="sec-tag">LEVEL 04 // SCOREBOARD</span>
<h2 class="sec-title" data-band="1">SCORE<span class="out">BOARD</span>.</h2>
</div>
<p class="sec-sub">what my projects have achieved. all numbers real, some embarrassing.</p>
</div>
<div class="score-block" data-in="up">
<div class="score-head"><span class="lvl">HIGH SCORE</span><h3>FEDL</h3></div>
<div class="score-cells">
<div class="scell filled"><span class="v num" data-count="3839">0</span><span class="k">VERIFIED RUNS</span></div>
<div class="scell filled s2"><span class="v num" data-count="341">0</span><span class="k">RANKED LEVELS</span></div>
<div class="scell filled s3"><span class="v num" data-count="250" data-suffix="+">0</span><span class="k">ACTIVE PLAYERS</span></div>
<div class="scell filled s4"><span class="v num" data-count="3800" data-suffix="+">0</span><span class="k">YOUTUBE VIDEOS</span></div>
</div>
</div>
<div class="score-block" data-in="up">
<div class="score-head"><span class="lvl">STAGE CLEAR</span><h3>OmniEmu 2.0</h3></div>
<div class="score-cells">
<div class="scell filled"><span class="v num" data-count="20" data-suffix="+">0</span><span class="k">EMULATORS</span></div>
<div class="scell filled s2"><span class="v num" data-count="3">0</span><span class="k">PLATFORMS</span></div>
<div class="scell"><span class="v">v0.3.2</span><span class="k">LATEST</span></div>
<div class="scell"><span class="v">TS</span><span class="k">BUILT WITH</span></div>
</div>
</div>
<div class="score-block" data-in="up">
<div class="score-head"><span class="lvl">SIDE QUESTS</span><h3>Other projects</h3></div>
<div class="score-cells">
<div class="scell filled"><span class="v num" data-count="3">0</span><span class="k">NOVA INTERFACES</span></div>
<div class="scell filled s2"><span class="v num" data-count="5">0</span><span class="k">NOTO AI FEATURES</span></div>
<div class="scell filled s3"><span class="v num" data-count="1542">0</span><span class="k">MOON GAMING COMMITS</span></div>
<div class="scell"><span class="v">MIT</span><span class="k">LICENSED</span></div>
</div>
</div>
</section>
<section class="sec" id="blog">
<div class="sec-index" data-par="13">05</div>
<div class="sec-band">
<div class="band-inner">
<span class="sec-tag">LEVEL 05 // DEVLOG</span>
<h2 class="sec-title" data-band="-1">THE <span class="out">DEVLOG</span>.</h2>
</div>
<p class="sec-sub">things I've learned, broken, and fixed.</p>
</div>
<div class="blog-grid">
<a class="blog" href="https://milesallen.site/blog/diskette-devlog.html" data-in="up">
<span class="date">2026 // 001</span><h3>Focusing on Diskette Labs</h3>
<p>I'm co-founder of Diskette Labs, a product design collective started by Owen. It's where my focus is now — still open to collabs.</p>
<div class="tags"><span class="bt">DESIGN</span><span class="bt">COLLECTIVE</span></div>
</a>
<a class="blog" href="https://milesallen.site/blog/gelectron-devlog.html" data-in="up">
<span class="date">2026 // 002</span><h3>Why I Built Gelectron</h3>
<p>Electron bundles Chromium with every app. 150-300MB per app, hundreds of MB of RAM. Native web views fix that.</p>
<div class="tags"><span class="bt">RUST</span><span class="bt">NATIVE</span></div>
</a>
<a class="blog" href="https://milesallen.site/blog/omniemu-devlog.html" data-in="up">
<span class="date">2026 // 003</span><h3>Why I Built OmniEmu</h3>
<p>I got tired of opening 15 different emulator apps. So I built one that manages them all. Here's how it started.</p>
<div class="tags"><span class="bt">TYPESCRIPT</span><span class="bt">ELECTRON</span></div>
</a>
<a class="blog" href="https://milesallen.site/blog/command-move-devlog.html" data-in="up">
<span class="date">2026 // 004</span><h3>CommandMove: Cut &amp; Paste</h3>
<p>macOS doesn't have Cmd+X for files. I fixed that. Global event taps, AppleScript, and a lot of Accessibility permissions.</p>
<div class="tags"><span class="bt">SWIFT</span><span class="bt">MACOS</span></div>
</a>
<a class="blog" href="https://milesallen.site/blog/fedl-devlog.html" data-in="up">
<span class="date">2025 // 005</span><h3>Running the FEDL</h3>
<p>What it takes to maintain a Geometry Dash demon list. 3,800+ verified runs, ranked levels, a community that never sleeps.</p>
<div class="tags"><span class="bt">NODE.JS</span><span class="bt">COMMUNITY</span></div>
</a>
<a class="blog" href="https://milesallen.site/blog/nova-devlog.html" data-in="up">
<span class="date">2025 // 006</span><h3>Building Nova AI</h3>
<p>Local AI that doesn't phone home. Desktop GUI, web interface, CLI — no subscriptions, no cloud, no nonsense.</p>
<div class="tags"><span class="bt">PYTHON</span><span class="bt">AI</span></div>
</a>
</div>
</section>
<div class="marquee mq-b mq-rev" data-mq="final"> </div>
<section class="sec" id="contact">
<div class="sec-index" data-par="7">06</div>
<div class="sec-band">
<div class="band-inner">
<span class="sec-tag">LEVEL 06 // REACH OUT</span>
<h2 class="sec-title" data-band="1">GET IN <span class="out">TOUCH</span>.</h2>
</div>
<p class="sec-sub">unless you're a bot, then please go away.</p>
</div>
<div class="contact-rows" data-in="up">
<a class="crow" href="mailto:[email protected]"><span class="k">EMAIL</span><span class="v">[email protected]<span class="arrow"></span></span></a>
<a class="crow" href="https://github.com/mileswolfallen2" target="_blank" rel="noopener"><span class="k">GITHUB</span><span class="v">mileswolfallen2<span class="arrow"></span></span></a>
<a class="crow" href="https://replit.com/@MilesAllen1" target="_blank" rel="noopener"><span class="k">REPLIT</span><span class="v">@MilesAllen1<span class="arrow"></span></span></a>
<a class="crow" href="https://codepen.io/mileswolfallen2-the-typescripter" target="_blank" rel="noopener"><span class="k">CODEPEN</span><span class="v">mileswolfallen2<span class="arrow"></span></span></a>
<a class="crow" href="https://me.fedl.site" target="_blank" rel="noopener"><span class="k">WEBSITE</span><span class="v">me.fedl.site<span class="arrow"></span></span></a>
</div>
</section>
<footer class="footer">
<div class="fword">MILES</div>
<div class="fmeta">
<a href="#top">BACK TO TOP ↑</a>
<a href="https://milesallen.site/uses.html">USES</a>
<a href="https://milesallen.site/now.html">NOW</a>
<a href="https://milesallen.site/colophon.html">COLOPHON</a>
<span>BUILT BY MILES © 2026</span>
</div>
<div class="top-btn"><button class="btn btn-yellow" onclick="document.getElementById('top').scrollIntoView({behavior:'smooth'})"></button></div>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>
<script>
(function(){
'use strict';
var body=document.body, html=document.documentElement;
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var fine=window.matchMedia&&window.matchMedia('(pointer: fine)').matches;
/* ---------- marquees: render track ---------- */
function renderMarquees(){
var sets={
build:['BUILDING EMULATORS','SEND HELP','160 REPOS AND COUNTING','STILL DEBUGGING','GEOMETRY DASH ADDICT','USUALLY ONLINE','FULL MAXIMALISM','CEREAL IS SOUP'],
warn:['RATED ★★★★★','EST. 2008','PULL SHARK ×2','OVERCLOCKED','DISKETTE LABS','COFFEE COUNT: UNKNOWN','BUGS: INFINITE'],
project:['OMNIEMU 2.0','GELECTRON','FEDL','NOTO','NOVA AI','COMMANDMOVE','MOON GAMING','1,500+ COMMITS','MIT LICENSE'],
final:['EMAIL ME','PLEASE','GITHUB ↗','REPLIT ↗','CODEPEN ↗','I RESPOND','MAYBE','FAST'],
};
Object.keys(sets).forEach(function(k){
document.querySelectorAll('[data-mq="'+k+'"]').forEach(function(wrap){
var track=document.createElement('div');
track.className='mq-track';
var half='';
sets[k].forEach(function(t){ half+='<span>★ '+t+'</span>'; });
track.innerHTML=half+half;
wrap.appendChild(track);
});
});
}
renderMarquees();
/* ---------- skill icons ---------- */
function addSkillIcons(){
document.querySelectorAll('.pill[data-si]').forEach(function(pill){
var img=document.createElement('img');
img.className='si';
img.alt='';
img.loading='lazy';
img.src='https://cdn.simpleicons.org/'+pill.getAttribute('data-si')+'/000000';
pill.insertBefore(img,pill.firstChild);
});
}
addSkillIcons();
/* ---------- cursor ---------- */
var cur=document.getElementById('cursor'), glow=document.getElementById('glow');
if (cur && fine){
var cx=-100,cy=-100,tx=-100,ty=-100,gx=-100,gy=-100,gtx=-100,gty=-100;
document.addEventListener('mousemove',function(e){ tx=e.clientX; ty=e.clientY; },{passive:true});
function loop(){
cx+=(tx-cx)*0.35; cy+=(ty-cy)*0.35;
gx+=(tx-gx)*0.08; gy+=(ty-gy)*0.08;
cur.style.transform='translate('+(cx-6)+'px,'+(cy-6)+'px)';
glow.style.transform='translate('+(gx-160)+'px,'+(gy-160)+'px)';
requestAnimationFrame(loop);
}
loop();
document.addEventListener('mouseover',function(e){
if (e.target.closest&&e.target.closest('a,button,.btn,.pill,.proj,.crow')){
cur.classList.add('on');
document.documentElement.style.setProperty('--mouse','auto');
}
},{passive:true});
document.addEventListener('mouseout',function(e){
if (e.target.closest&&e.target.closest('a,button,.btn,.pill,.proj,.crow')){
cur.classList.remove('on');
}
},{passive:true});
}
/* ---------- scroll progress ---------- */
var prog=document.getElementById('progress');
function onScroll(){ prog.style.width=(window.scrollY/(document.body.scrollHeight-window.innerHeight)*100)+'%'; }
window.addEventListener('scroll',onScroll,{passive:true});
onScroll();
/* ---------- count-up ---------- */
function countUp(el){
var target=parseInt(el.getAttribute('data-count'),10)||0;
var suffix=el.getAttribute('data-suffix')||'';
var t0=null;
function fmt(n){ return Math.round(n).toLocaleString('en-US')+suffix; }
function step(ts){
if(t0===null) t0=ts;
var p=Math.min(1,(ts-t0)/1200);
var ease=1-Math.pow(1-p,3);
el.textContent=fmt(target*ease);
if(p<1) requestAnimationFrame(step);
else el.textContent=fmt(target);
}
if(reduce){ el.textContent=fmt(target); return; }
requestAnimationFrame(step);
}
if('IntersectionObserver' in window){
var io=new IntersectionObserver(function(entries){
entries.forEach(function(e){
if(e.isIntersecting){
countUp(e.target);
io.unobserve(e.target);
}
});
},{threshold:0.5});
document.querySelectorAll('.num[data-count]').forEach(function(el){ io.observe(el); });
}
/* ---------- reveal system ---------- */
function revealAll(){
document.querySelectorAll('[data-in]').forEach(function(el){ el.classList.add('in'); });
}
if('IntersectionObserver' in window && !reduce){
var rio=new IntersectionObserver(function(entries){
entries.forEach(function(e){
if(e.isIntersecting){
e.target.classList.add('in');
rio.unobserve(e.target);
}
});
},{threshold:0.15,rootMargin:'0px 0px -40px 0px'});
document.querySelectorAll('[data-in]').forEach(function(el){ rio.observe(el); });
} else {
revealAll();
}
/* ---------- konami ---------- */
(function(){
var seq=[38,38,40,40,37,39,37,39,66,65];
var pos=0;
document.addEventListener('keydown',function(e){
if(e.keyCode===seq[pos]){ pos++; if(pos===seq.length){ pos=0; party(); } }
else pos=0;
});
function party(){
var colors=['#FF2EA6','#F7FF00','#00F4FF','#FF5C00','#00FF85','#FF1F1F'];
for(var i=0;i<36;i++){
var s=document.createElement('div');
s.style.cssText='position:fixed;left:50%;top:50%;width:'+(6+Math.random()*16)+'px;height:'+(6+Math.random()*16)+'px;z-index:950;pointer-events:none;border:2px solid #000;background:'+colors[i%colors.length]+';box-shadow:3px 3px 0 #000;';
document.body.appendChild(s);
var ang=Math.random()*Math.PI*2;
var dist=60+Math.random()*360;
var dx=Math.cos(ang)*dist, dy=Math.sin(ang)*dist;
s.animate([
{transform:'translate(-50%,-50%) rotate(0deg)',opacity:1},
{transform:'translate(calc(-50% + '+dx+'px), calc(-50% + '+dy+'px)) rotate('+(Math.random()*720-360)+'deg)',opacity:0}
],{duration:900+Math.random()*500,easing:'cubic-bezier(.2,.8,.2,1)'}).onfinish=function(){ s.remove(); };
}
}
})();
/* ---------- GSAP scroll choreography ---------- */
if (window.gsap && window.ScrollTrigger && !reduce){
gsap.registerPlugin(ScrollTrigger);
/* hero parallax */
gsap.to('#heroTitle',{yPercent:-18,scale:.96,opacity:.25,ease:'none',
scrollTrigger:{trigger:'#top',start:'top top',end:'bottom top',scrub:1}});
gsap.to('.hero-sub',{yPercent:-60,opacity:0,ease:'none',
scrollTrigger:{trigger:'#top',start:'10% top',end:'bottom top',scrub:1}});
gsap.to('.hero-rings',{scale:1.15,opacity:.3,ease:'none',
scrollTrigger:{trigger:'#top',start:'top top',end:'bottom top',scrub:1}});
/* floating stickers: parallax via data-speed */
gsap.utils.toArray('[data-par]').forEach(function(el){
if(el.classList && el.classList.contains('proj'))return;
var rate=parseFloat(el.getAttribute('data-par'))||0;
if(!rate)return;
gsap.to(el,{y:rate*10,ease:'none',
scrollTrigger:{trigger:el,start:'top bottom',end:'bottom top',scrub:1}});
});
gsap.utils.toArray('[data-speed]').forEach(function(el){
var rate=parseFloat(el.getAttribute('data-speed'))||0;
gsap.to(el,{y:rate*12,ease:'none',
scrollTrigger:{trigger:el,start:'top bottom',end:'bottom top',scrub:1}});
});
/* section title bands slide */
gsap.utils.toArray('[data-band]').forEach(function(t){
var dir=parseFloat(t.getAttribute('data-band'))||0;
gsap.fromTo(t,{xPercent:dir*8},{xPercent:dir*-8,ease:'none',
scrollTrigger:{trigger:t,start:'top bottom',end:'bottom top',scrub:1}});
});
/* project cards: flip + rise */
gsap.utils.toArray('.proj').forEach(function(card){
var side=(parseFloat(card.getAttribute('data-par'))||0)>0?-1:1;
gsap.set(card,{transition:'none'});
gsap.fromTo(card,
{y:80,rotation:side*4,opacity:0},
{y:0,rotation:0,opacity:1,duration:1,ease:'power3.out',
scrollTrigger:{trigger:card,start:'top 94%'},
onComplete:function(){ gsap.set(card,{clearProps:'transform,opacity,transition'}); }});
});
ScrollTrigger.refresh();
}
/* if no gsap, still make sure proj cards visible */
else if(!reduce){
setTimeout(function(){
document.querySelectorAll('.proj').forEach(function(c){ c.style.opacity='1'; });
},1200);
}
})();
</script>
</body>
</html>
+991
View File
@@ -0,0 +1,991 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MILES WOLF ALLEN // TRY THREE</title>
<meta name="description" content="Miles Wolf Allen — developer, 3D artist, and the guy trying to replace Electron.">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' fill='%23F7FF00'/%3E%3Ctext x='50' y='72' font-size='60' font-family='Arial Black' font-weight='900' text-anchor='middle' fill='%23000'%3EM%3C/text%3E%3C/svg%3E">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Archivo+Black&family=Press+Start+2P&family=Space+Mono:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
<script>document.documentElement.className='js';</script>
<style>
:root {
--bg: #08080a;
--bg2: #111114;
--bg3: #1a1a1f;
--ink: #ffffff;
--muted: #7a7a85;
--dim: #3a3a45;
--pink: #FF2EA6;
--yellow: #F7FF00;
--cyan: #00F4FF;
--orange: #FF5C00;
--purple: #8A2BFF;
--green: #00FF85;
--red: #FF1F1F;
--d: 'Archivo Black', Impact, sans-serif;
--m: 'Space Mono', monospace;
--p: 'Press Start 2P', monospace;
}
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; overflow-x: hidden; }
body {
background: var(--bg);
color: var(--ink);
font-family: var(--m);
font-size: 14px;
line-height: 1.65;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
}
::selection { background: var(--yellow); color: #000; }
a { color: inherit; text-decoration: none; }
/* scrollbar */
::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: #000; }
::-webkit-scrollbar-thumb { background: var(--pink); border: 3px solid #000; }
/* progress */
#progress {
position: fixed; top: 0; left: 0; height: 4px; width: 0;
background: linear-gradient(90deg, var(--pink), var(--yellow), var(--cyan));
z-index: 700; box-shadow: 0 0 10px var(--pink);
transition: width .1s linear;
}
/* fixed bg layers */
.bg-grid {
position: fixed; inset: 0; z-index: -3; pointer-events: none;
background-image:
linear-gradient(rgba(255,255,255,.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,.03) 1px, transparent 1px);
background-size: 52px 52px;
}
.noise {
position: fixed; inset: 0; z-index: -2; pointer-events: none; opacity: .05;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
.vignette {
position: fixed; inset: 0; z-index: -1; pointer-events: none;
background: radial-gradient(ellipse at center, transparent 50%, rgba(0,0,0,.65) 100%);
}
/* cursor */
.cursor { position: fixed; z-index: 900; pointer-events: none; border-radius: 50%; top: 0; left: 0; }
.cursor-dot { width: 10px; height: 10px; background: #fff; transform: translate(-50%,-50%); mix-blend-mode: difference; transition: width .15s, height .15s; }
.cursor-halo { width: 300px; height: 300px; background: radial-gradient(circle, rgba(255,46,166,.14), transparent 65%); transform: translate(-50%,-50%); z-index: 800; }
.cursor-dot.big { width: 40px; height: 40px; border: 2px solid #fff; background: transparent; }
@media (pointer: coarse) { .cursor { display: none; } }
/* splash */
.splash {
position: fixed; inset: 0; z-index: 1000; background: var(--bg);
display: flex; align-items: center; justify-content: center;
pointer-events: none;
animation: splashOut .5s ease forwards 1.1s;
}
.splash-letters { display: flex; }
.splash-letters span {
font-family: var(--d); font-size: clamp(72px, 20vw, 240px); display: inline-block;
opacity: 0; animation: splashPop .55s cubic-bezier(.18,1.4,.3,1) forwards;
}
.splash-letters span:nth-child(1) { animation-delay: .05s; color: var(--yellow); -webkit-text-stroke: 3px #000; }
.splash-letters span:nth-child(2) { animation-delay: .14s; }
.splash-letters span:nth-child(3) { animation-delay: .23s; color: var(--pink); -webkit-text-stroke: 3px #000; }
.splash-letters span:nth-child(4) { animation-delay: .32s; }
.splash-letters span:nth-child(5) { animation-delay: .41s; color: var(--cyan); -webkit-text-stroke: 3px #000; }
.splash-tag {
position: absolute; bottom: 14%; left: 50%; transform: translateX(-50%) rotate(-2deg);
font-family: var(--p); font-size: 8px; background: var(--yellow); color: #000;
padding: 10px 18px; border: 3px solid #000; box-shadow: 5px 5px 0 var(--pink);
}
@keyframes splashPop { 0% { opacity: 0; transform: translateY(100%) rotate(5deg); } 100% { opacity: 1; transform: none; } }
@keyframes splashOut { 0% { opacity: 1; } 100% { opacity: 0; visibility: hidden; } }
/* nav */
.nav {
position: fixed; top: 12px; left: 12px; right: 12px; z-index: 500;
display: flex; align-items: center; justify-content: space-between; gap: 12px;
background: rgba(8,8,10,.82); border: 3px solid #000;
box-shadow: 5px 5px 0 #000; padding: 10px 16px;
backdrop-filter: blur(8px);
}
.nav-logo { font-family: var(--d); font-size: 18px; display: flex; align-items: center; gap: 8px; }
.nav-logo .live { width: 10px; height: 10px; background: var(--green); border: 2px solid #000; border-radius: 50%; animation: blink 1.4s steps(1) infinite; }
.nav-links { display: flex; gap: 4px; flex-wrap: wrap; }
.nav-links a {
font-family: var(--p); font-size: 7px; color: #fff; padding: 8px 11px;
border: 2px solid rgba(255,255,255,.25); text-transform: uppercase;
transition: all .14s;
}
.nav-links a:hover { background: var(--pink); color: #000; border-color: #000; transform: translate(-2px,-2px); box-shadow: 3px 3px 0 #000; }
.nav-right { display: flex; align-items: center; gap: 8px; font-family: var(--p); font-size: 7px; color: var(--yellow); }
.nav-right .pulse { width: 8px; height: 8px; background: var(--yellow); border-radius: 50%; animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { opacity: .15; } }
@media (max-width: 700px) { .nav-links { display: none; } }
/* buttons */
.btn {
display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
font-family: var(--p); font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
padding: 15px 22px; border: 3px solid #000; box-shadow: 5px 5px 0 #000;
transition: transform .12s, box-shadow .12s; user-select: none;
}
.btn:hover { transform: translate(-2px,-2px); box-shadow: 8px 8px 0 #000; }
.btn:active { transform: translate(3px,3px); box-shadow: 1px 1px 0 #000; }
.btn-pink { background: var(--pink); color: #000; }
.btn-yellow { background: var(--yellow); color: #000; }
.btn-ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.4); }
.btn-ghost:hover { background: #fff; color: #000; border-color: #000; box-shadow: 8px 8px 0 var(--pink); }
/* chips */
.chip {
display: inline-flex; align-items: center; gap: 7px;
font-family: var(--p); font-size: 7px; text-transform: uppercase;
border: 2px solid #000; padding: 7px 11px; box-shadow: 3px 3px 0 #000;
}
.chip-y { background: var(--yellow); color: #000; }
.chip-p { background: var(--pink); color: #000; }
.chip-c { background: var(--cyan); color: #000; }
.chip-g { background: var(--green); color: #000; }
.chip-o { background: var(--orange); color: #000; }
/* marquee */
.mq { overflow: hidden; white-space: nowrap; border-top: 3px solid #000; border-bottom: 3px solid #000; position: relative; z-index: 3; }
.mq-track { display: inline-flex; white-space: nowrap; }
.mq-track.fwd { animation: mqFwd 24s linear infinite; }
.mq-track.rev { animation: mqRev 28s linear infinite; }
.mq span { font-family: var(--p); font-size: 11px; padding: 13px 0; margin: 0 20px; flex-shrink: 0; color: #000; }
.mq-y { background: var(--yellow); }
.mq-p { background: var(--pink); }
.mq-c { background: var(--cyan); }
.mq-o { background: var(--orange); }
@keyframes mqFwd { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } }
@keyframes mqRev { 0% { transform: translateX(-50%); } 100% { transform: translateX(0); } }
/* section shell */
.sec { position: relative; padding: 100px 5vw 80px; }
.sec-ghost {
position: absolute; top: 20px; right: -1vw; z-index: 0; pointer-events: none; user-select: none;
font-family: var(--d); font-size: clamp(110px, 22vw, 260px); line-height: .8;
color: transparent; -webkit-text-stroke: 1.5px rgba(255,255,255,.07);
}
.sec-header { position: relative; z-index: 2; margin-bottom: 52px; }
.sec-eyebrow {
display: inline-block; font-family: var(--p); font-size: 8px; color: #000;
background: var(--yellow); border: 3px solid #000; padding: 7px 12px;
box-shadow: 3px 3px 0 #000; transform: rotate(-1.5deg); margin-bottom: 18px;
}
.sec-title {
font-family: var(--d); font-size: clamp(44px, 9.5vw, 120px);
line-height: .9; letter-spacing: -.02em; text-transform: uppercase;
display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 .2em;
}
.sec-title .out { color: transparent; -webkit-text-stroke: 2px #fff; }
.sec-title .acc-pink { color: var(--pink); }
.sec-title .acc-yellow { color: var(--yellow); }
.sec-title .dot { color: var(--yellow); }
.sec-sub { font-family: var(--m); color: var(--muted); font-size: 13px; margin-top: 12px; max-width: 500px; }
/* reveal system */
html.js [data-in] { opacity: 0; transition: opacity .7s ease, transform .75s cubic-bezier(.18,1.3,.3,1); will-change: transform, opacity; }
html.js [data-in="up"] { transform: translateY(55px) rotate(-1deg); }
html.js [data-in="left"] { transform: translateX(-70px) rotate(-1.5deg); }
html.js [data-in="right"] { transform: translateX(70px) rotate(1.5deg); }
html.js [data-in="pop"] { transform: scale(.55) rotate(-8deg); }
html.js [data-in="flip"] { transform: translateY(40px) rotateX(-55deg); transform-style: preserve-3d; }
html.js [data-in].in { opacity: 1; transform: none; }
/* ── HERO ── */
.hero {
position: relative; min-height: 100vh;
display: flex; flex-direction: column; justify-content: flex-end;
padding: 130px 5vw 60px; overflow: hidden;
}
.hero-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 28px; position: relative; z-index: 2; }
.hero-title {
font-family: var(--d); line-height: .86; letter-spacing: -.03em;
font-size: clamp(76px, 22vw, 290px); text-transform: uppercase;
position: relative; z-index: 2;
}
.hero-title .row { display: block; }
.hero-title .row-2 { margin-left: .9em; }
.hero-title em { font-style: normal; color: transparent; -webkit-text-stroke: 2.5px #fff; }
.hero-title .star-dot { color: var(--yellow); }
/* hero orbital rings */
.hero-orb {
position: absolute; top: 50%; right: 3vw;
transform: translateY(-52%);
width: min(44vw, 540px); height: min(44vw, 540px);
z-index: 0; pointer-events: none;
}
.ring { position: absolute; inset: 0; border-radius: 50%; }
.ring-1 { border: 3px dashed rgba(255,255,255,.25); animation: spin 32s linear infinite; }
.ring-2 { inset: 10%; border: 3px solid rgba(255,46,166,.45); animation: spin 22s linear infinite reverse; }
.ring-3 { inset: 20%; border: 3px dashed rgba(0,244,255,.45); animation: spin 48s linear infinite; }
.ring-core {
position: absolute; inset: 38%; border-radius: 50%;
background: radial-gradient(circle, rgba(247,255,0,.22), transparent 70%);
animation: pulse 3s ease-in-out infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 0%,100% { opacity: .6; transform: scale(.95); } 50% { opacity: 1; transform: scale(1.05); } }
@media (max-width: 700px) { .hero-orb { display: none; } }
.hero-sub {
font-family: var(--m); font-size: clamp(13px, 1.5vw, 18px);
color: var(--muted); max-width: 540px; line-height: 1.75;
margin: 28px 0 32px; padding-left: 16px; border-left: 5px solid var(--pink);
position: relative; z-index: 2;
}
.hero-sub b { color: #fff; }
.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; position: relative; z-index: 2; }
/* floating labels */
.fl {
position: absolute; z-index: 3;
font-family: var(--p); font-size: 8px; text-transform: uppercase;
border: 3px solid #000; box-shadow: 5px 5px 0 #000; padding: 9px 13px;
line-height: 1.5; text-align: center;
}
.fl-1 { top: 23%; left: 5%; background: var(--yellow); color: #000; transform: rotate(-8deg); }
.fl-2 { top: 35%; right: 5%; background: #fff; color: #000; transform: rotate(6deg); border-radius: 50%; width: 90px; height: 90px; display: flex; align-items: center; justify-content: center; }
.fl-3 { bottom: 22%; left: 46%; background: var(--pink); color: #000; transform: rotate(-4deg); }
@media (max-width: 900px) { .fl { display: none; } }
.hero-scroll {
position: absolute; bottom: 22px; left: 50%; transform: translateX(-50%);
font-family: var(--p); font-size: 7px; color: var(--muted);
display: flex; flex-direction: column; align-items: center; gap: 7px; z-index: 2;
}
.hero-scroll .arr { font-size: 16px; animation: bob 1.6s ease-in-out infinite; }
@keyframes bob { 50% { transform: translateY(5px); } }
/* ── STATS ── */
.stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; position: relative; z-index: 2; }
.stat-card {
border: 4px solid #000; padding: 32px 16px; text-align: center;
box-shadow: 8px 8px 0 #000; position: relative; overflow: hidden;
transition: transform .15s, box-shadow .15s;
}
.stat-card:hover { transform: translate(-3px,-3px); box-shadow: 12px 12px 0 #000; }
.stat-card .n { font-family: var(--d); font-size: clamp(38px, 6vw, 80px); line-height: 1; display: block; color: #000; }
.stat-card .l { font-family: var(--p); font-size: 7px; text-transform: uppercase; margin-top: 10px; display: block; color: #000; letter-spacing: .06em; }
.stat-card .tick { position: absolute; top: -10px; right: -10px; width: 32px; height: 32px; background: #fff; border: 3px solid #000; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 13px; box-shadow: 2px 2px 0 #000; }
.s1 { background: var(--pink); transform: rotate(-1.8deg); }
.s2 { background: var(--yellow); transform: rotate(1.4deg) translateY(8px); }
.s3 { background: var(--cyan); transform: rotate(-1deg) translateY(-5px); }
.s4 { background: var(--orange); transform: rotate(2deg) translateY(5px); }
@media (max-width: 860px) { .stats-grid { grid-template-columns: repeat(2,1fr); gap: 22px 12px; } .s2,.s3,.s4 { transform: none; } }
/* ── ABOUT ── */
.about-layout { display: grid; grid-template-columns: 260px 1fr; gap: 36px; position: relative; z-index: 2; }
.avatar-wrap { position: relative; align-self: start; }
.avatar-img {
width: 100%; display: block; border: 5px solid #000;
box-shadow: 10px 10px 0 var(--pink); transform: rotate(-3deg);
filter: grayscale(.15) contrast(1.1); transition: transform .22s;
}
.avatar-img:hover { transform: rotate(0) scale(1.02); }
.avatar-sticker {
position: absolute; bottom: -18px; left: -14px;
background: var(--yellow); border: 3px solid #000; padding: 9px 13px;
font-family: var(--p); font-size: 7px; transform: rotate(-5deg);
box-shadow: 4px 4px 0 #000; text-transform: uppercase; color: #000;
}
.bio-card {
background: var(--bg2); border: 4px solid #000; box-shadow: 10px 10px 0 #000;
padding: 32px; position: relative;
}
.bio-card::before {
content: ''; position: absolute; top: -12px; right: 28px;
width: 66px; height: 22px; background: #FFC93C; opacity: .85;
transform: rotate(2deg); box-shadow: 0 0 0 2px #000;
}
.bio-card h3 { font-family: var(--d); font-size: clamp(22px,2.8vw,36px); margin-bottom: 14px; }
.bio-card p { color: var(--muted); font-size: 13px; margin-bottom: 16px; line-height: 1.8; }
.bio-badges { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
.badge {
font-family: var(--p); font-size: 7px; padding: 9px 13px;
border: 2px solid #000; box-shadow: 3px 3px 0 #000; text-transform: uppercase; color: #000;
}
.b-pk { background: var(--pink); } .b-y { background: var(--yellow); }
.b-g { background: var(--green); } .b-o { background: var(--orange); }
.bio-actions { display: flex; gap: 10px; flex-wrap: wrap; border-top: 3px dashed rgba(255,255,255,.15); padding-top: 18px; }
@media (max-width: 840px) { .about-layout { grid-template-columns: 1fr; } .avatar-img { max-width: 220px; } }
/* ── SKILLS ── */
.skills-body { position: relative; z-index: 2; display: flex; flex-direction: column; gap: 36px; }
.skill-group-label {
font-family: var(--p); font-size: 9px; text-transform: uppercase; color: var(--yellow);
display: flex; align-items: center; gap: 10px; margin-bottom: 14px;
}
.skill-group-label::after { content: ''; flex: 1; height: 2px; background: rgba(255,255,255,.1); }
.pills { display: flex; flex-wrap: wrap; gap: 10px; }
.pill {
font-family: var(--m); font-weight: 700; font-size: 13px; text-transform: uppercase;
padding: 11px 16px; background: #fff; color: #000; border: 3px solid #000;
box-shadow: 4px 4px 0 #000; display: inline-flex; align-items: center; gap: 9px;
transition: transform .12s, box-shadow .12s, background .12s;
}
.pill:nth-child(5n) { transform: rotate(-2deg); }
.pill:nth-child(5n+2) { transform: rotate(1.5deg); }
.pill:nth-child(5n+4) { transform: rotate(-1deg); }
.pill:hover { transform: translate(-2px,-3px) rotate(0) scale(1.04); box-shadow: 8px 8px 0 var(--pink); }
.pill img { width: 18px; height: 18px; flex-shrink: 0; }
.pill.soon { background: var(--bg3); color: #fff; border-style: dashed; box-shadow: none; opacity: .7; }
.pill.soon:hover { background: var(--orange); color: #000; border-style: solid; box-shadow: 8px 8px 0 #000; opacity: 1; }
/* ── PROJECTS ── */
.proj-list { display: flex; flex-direction: column; gap: 22px; position: relative; z-index: 2; }
.proj {
background: var(--bg2); border: 4px solid #000; box-shadow: 10px 10px 0 #000;
padding: 28px 30px; position: relative; transition: transform .16s, box-shadow .16s;
display: block; overflow: hidden;
}
.proj:nth-child(odd) { transform: rotate(-1deg); }
.proj:nth-child(even) { transform: rotate(.8deg); }
.proj:hover { transform: rotate(0) translate(-3px,-3px) !important; box-shadow: 16px 16px 0 var(--pink); }
.proj-num {
position: absolute; top: 12px; right: 18px; font-family: var(--d);
font-size: clamp(50px, 8vw, 100px); line-height: 1;
color: transparent; -webkit-text-stroke: 1.5px rgba(255,255,255,.1);
user-select: none; pointer-events: none;
}
.proj-tags { display: flex; align-items: center; gap: 9px; margin-bottom: 14px; flex-wrap: wrap; }
.tag {
font-family: var(--p); font-size: 7px; padding: 7px 11px;
border: 2px solid #000; box-shadow: 3px 3px 0 #000; color: #000; text-transform: uppercase;
}
.proj-title {
font-family: var(--d); font-size: clamp(24px, 4vw, 50px);
line-height: 1; text-transform: uppercase; display: flex; align-items: baseline; gap: 12px;
}
.proj-arrow { font-family: var(--p); font-size: 14px; color: var(--yellow); transition: transform .15s; }
.proj:hover .proj-arrow { transform: translate(4px,-4px); }
.proj-desc { color: var(--muted); margin-top: 12px; font-size: 13px; max-width: 620px; transition: color .15s; }
.proj:hover .proj-desc { color: #fff; }
/* ── SCOREBOARD ── */
.score-blocks { display: flex; flex-direction: column; gap: 36px; position: relative; z-index: 2; }
.score-block {}
.score-block-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.score-block-head .lvl-badge { font-family: var(--p); font-size: 7px; background: var(--cyan); color: #000; border: 3px solid #000; padding: 6px 11px; box-shadow: 3px 3px 0 #000; }
.score-block-head h3 { font-family: var(--d); font-size: clamp(20px, 2.8vw, 32px); text-transform: uppercase; }
.score-cells { display: grid; grid-template-columns: repeat(4,1fr); gap: 14px; }
.scell { border: 4px solid #000; padding: 22px 16px; text-align: center; box-shadow: 6px 6px 0 #000; background: var(--bg2); }
.scell .v { font-family: var(--d); font-size: clamp(24px, 3.8vw, 44px); display: block; line-height: 1; }
.scell .k { font-family: var(--p); font-size: 6px; margin-top: 8px; display: block; color: var(--muted); text-transform: uppercase; }
.scell.hi { } .scell.hi.c1 { background: var(--pink); color: #000; } .scell.hi.c1 .k { color: #000; }
.scell.hi.c2 { background: var(--yellow); color: #000; } .scell.hi.c2 .k { color: #000; }
.scell.hi.c3 { background: var(--cyan); color: #000; } .scell.hi.c3 .k { color: #000; }
.scell.hi.c4 { background: var(--orange); color: #000; } .scell.hi.c4 .k { color: #000; }
@media (max-width: 840px) { .score-cells { grid-template-columns: repeat(2,1fr); } }
/* ── DEVLOG ── */
.blog-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 20px; position: relative; z-index: 2; }
.blog-card {
border: 4px solid #000; background: var(--bg2); box-shadow: 8px 8px 0 #000;
padding: 24px; display: block; position: relative; transition: transform .14s, box-shadow .14s;
}
.blog-card:nth-child(3n+1) { transform: rotate(-1deg); }
.blog-card:nth-child(3n+2) { transform: rotate(.7deg) translateY(5px); }
.blog-card:nth-child(3n) { transform: rotate(-.5deg); }
.blog-card:hover { transform: translate(-3px,-3px) rotate(0) !important; box-shadow: 14px 14px 0 var(--cyan); }
.blog-date { font-family: var(--p); font-size: 7px; color: var(--pink); display: block; margin-bottom: 10px; }
.blog-title { font-family: var(--d); font-size: 17px; line-height: 1.2; text-transform: uppercase; margin-bottom: 9px; }
.blog-excerpt { font-size: 12px; color: var(--muted); margin-bottom: 14px; line-height: 1.7; }
.blog-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.btag { font-family: var(--p); font-size: 6px; background: #fff; color: #000; border: 2px solid #000; padding: 5px 8px; box-shadow: 2px 2px 0 #000; }
/* ── CONTACT ── */
.contact-rows { position: relative; z-index: 2; display: flex; flex-direction: column; border-top: 4px solid #000; }
.crow {
display: flex; align-items: center; justify-content: space-between; gap: 18px;
padding: 24px 18px; border: 4px solid #000; border-top: none; position: relative;
background: var(--bg2); transition: background .12s, padding-left .15s;
box-shadow: 6px 6px 0 #000; margin-bottom: 6px;
}
.crow:last-child { margin-bottom: 0; }
.crow .k { font-family: var(--p); font-size: 9px; color: var(--yellow); text-transform: uppercase; }
.crow .v { font-family: var(--d); font-size: clamp(16px, 2.8vw, 28px); text-transform: lowercase; display: flex; align-items: center; gap: 9px; }
.crow .arr { font-size: 20px; color: var(--pink); transition: transform .15s; }
.crow:hover { background: var(--pink); color: #000; padding-left: 28px; }
.crow:hover .k, .crow:hover .arr { color: #000; }
.crow:hover .arr { transform: translateX(5px); }
/* ── FOOTER ── */
.footer { position: relative; padding: 80px 5vw 36px; text-align: center; overflow: hidden; }
.footer-word {
font-family: var(--d); font-size: clamp(64px, 18vw, 260px); line-height: .88;
color: transparent; -webkit-text-stroke: 2px rgba(255,255,255,.1); text-transform: uppercase;
user-select: none; pointer-events: none;
}
.footer-meta {
font-family: var(--p); font-size: 8px; color: var(--muted);
margin-top: 24px; display: flex; justify-content: center; gap: 16px; flex-wrap: wrap;
}
.footer-meta a { color: #fff; text-decoration: underline; text-underline-offset: 4px; }
.footer-meta a:hover { color: var(--pink); }
.to-top { margin-top: 28px; }
/* ── KONAMI ── */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
.splash { display: none; }
}
@media (max-width: 700px) {
.sec { padding: 70px 5vw 60px; }
.hero-title .row-2 { margin-left: .5em; }
.fl { display: none; }
}
</style>
</head>
<body>
<!-- splash -->
<div class="splash" aria-hidden="true">
<div class="splash-letters"><span>M</span><span>I</span><span>L</span><span>E</span><span>S</span></div>
<div class="splash-tag">MAXIMALISM ONLINE</div>
</div>
<!-- fixed bg -->
<div class="bg-grid" aria-hidden="true"></div>
<div class="noise" aria-hidden="true"></div>
<div class="vignette" aria-hidden="true"></div>
<!-- cursor -->
<div class="cursor cursor-halo" id="halo"></div>
<div class="cursor cursor-dot" id="dot"></div>
<!-- progress bar -->
<div id="progress"></div>
<!-- nav -->
<nav class="nav">
<a class="nav-logo" href="#top"><span class="live"></span>MILES</a>
<div class="nav-links">
<a href="#about">About</a>
<a href="#skills">Skills</a>
<a href="#projects">Builds</a>
<a href="#devlog">Devlog</a>
<a href="#contact">Contact</a>
</div>
<div class="nav-right"><span class="pulse"></span>USUALLY ONLINE</div>
</nav>
<!-- ═══ HERO ═══ -->
<header class="hero" id="top">
<div class="hero-orb" aria-hidden="true">
<div class="ring ring-1"></div>
<div class="ring ring-2"></div>
<div class="ring ring-3"></div>
<div class="ring-core"></div>
</div>
<div class="fl fl-1">★ EST.<br>2008</div>
<div class="fl fl-2"></div>
<div class="fl fl-3">THE WOW</div>
<div class="hero-chips">
<span class="chip chip-y">★ MILES WOLF ALLEN</span>
<span class="chip chip-p">DEVELOPER &amp; 3D ARTIST</span>
<span class="chip chip-c">DISKETTE LABS CO-FOUNDER</span>
</div>
<h1 class="hero-title" id="heroTitle">
<span class="row"><em>MI</em>L</span>
<span class="row row-2"><em>E</em>S<span class="star-dot">.</span></span>
</h1>
<p class="hero-sub">
I make <b>games</b>, <b>tools</b>, and <b>websites</b>.
Still in school, currently building a full <b>Electron replacement</b> — send help.
160 repos and counting.
</p>
<div class="hero-cta">
<a class="btn btn-pink" href="#projects">SEE THE BUILDS ↓</a>
<a class="btn btn-ghost" href="https://github.com/mileswolfallen2" target="_blank" rel="noopener">GITHUB ↗</a>
<a class="btn btn-yellow" href="https://diskettelabs.com/" target="_blank" rel="noopener">DISKETTE LABS ↗</a>
</div>
<div class="hero-scroll" aria-hidden="true">SCROLL<div class="arr"></div></div>
</header>
<!-- marquee 1 -->
<div class="mq mq-y" aria-hidden="true">
<div class="mq-track fwd" id="mq1"></div>
</div>
<!-- ═══ STATS ═══ -->
<section class="sec" id="stats">
<div class="sec-ghost" aria-hidden="true">000</div>
<div class="sec-header">
<div class="sec-eyebrow">LEVEL 00 — THE NUMBERS</div>
<h2 class="sec-title">THE <span class="out">NUMBERS</span><span class="dot">.</span></h2>
</div>
<div class="stats-grid">
<div class="stat-card s1" data-in="left"><span class="tick"></span><span class="n num" data-count="160">0</span><span class="l">REPOS ONLINE</span></div>
<div class="stat-card s2" data-in="pop"><span class="tick"></span><span class="n num" data-count="91">0</span><span class="l">STARS EARNED</span></div>
<div class="stat-card s3" data-in="right"><span class="tick"></span><span class="n num" data-count="13">0</span><span class="l">WATCHING ME</span></div>
<div class="stat-card s4" data-in="flip"><span class="tick"></span><span class="n num" data-count="37">0</span><span class="l">I WATCH</span></div>
</div>
</section>
<!-- ═══ ABOUT ═══ -->
<section class="sec" id="about">
<div class="sec-ghost" aria-hidden="true">01</div>
<div class="sec-header">
<div class="sec-eyebrow">LEVEL 01 — IDENTITY</div>
<h2 class="sec-title"><span class="out">WHO'S</span> MILES<span class="dot">?</span></h2>
<p class="sec-sub">the human behind the commits. pancakes &gt; waffles, cereal is soup.</p>
</div>
<div class="about-layout">
<div class="avatar-wrap" data-in="left">
<img class="avatar-img" src="https://avatars.githubusercontent.com/u/115095719?v=4" alt="Miles Wolf Allen" loading="lazy" width="260" height="260">
<span class="avatar-sticker">@mileswolfallen2</span>
</div>
<div class="bio-card" data-in="up">
<h3>// PLAYER BIO</h3>
<p>I build things on the internet. Some are games, some are tools, and some are just because I thought it'd be fun. I'm co-founder of <b style="color:#fff">Diskette Labs</b>, still in school, and chasing a world without bundled Chromium.</p>
<div class="bio-badges">
<span class="badge b-pk">PULL SHARK ×2</span>
<span class="badge b-y">YOLO</span>
<span class="badge b-g">QUICKDRAW</span>
<span class="badge b-o">GD ADDICT</span>
</div>
<div class="bio-actions">
<a class="btn btn-yellow" href="https://diskettelabs.com/" target="_blank" rel="noopener">DISKETTE LABS ↗</a>
<a class="btn btn-ghost" href="../about-me.html">MORE ABOUT ME →</a>
</div>
</div>
</div>
</section>
<!-- marquee 2 -->
<div class="mq mq-p" aria-hidden="true">
<div class="mq-track rev" id="mq2"></div>
</div>
<!-- ═══ SKILLS ═══ -->
<section class="sec" id="skills">
<div class="sec-ghost" aria-hidden="true">02</div>
<div class="sec-header">
<div class="sec-eyebrow">LEVEL 02 — LOADOUT</div>
<h2 class="sec-title">MY <span class="out">LOADOUT</span><span class="dot">.</span></h2>
<p class="sec-sub">what I actually know how to use (and what I'm currently failing at).</p>
</div>
<div class="skills-body">
<div data-in="up">
<div class="skill-group-label">READY TO USE</div>
<div class="pills" id="pillsReady">
<span class="pill" data-si="javascript">JS</span>
<span class="pill" data-si="nodedotjs">NODE</span>
<span class="pill" data-si="html5">HTML</span>
<span class="pill" data-si="css3">CSS</span>
<span class="pill" data-si="python">PYTHON</span>
<span class="pill" data-si="git">GIT</span>
<span class="pill" data-si="blender">BLENDER</span>
<span class="pill" data-si="unity">UNITY</span>
<span class="pill" data-si="unrealengine">UNREAL</span>
<span class="pill" data-si="cloudflare">CLOUDFLARE</span>
<span class="pill" data-si="linux">LINUX</span>
<span class="pill" data-si="netlify">NETLIFY</span>
<span class="pill" data-si="gnubash">BASH</span>
<span class="pill" data-si="github">GITHUB</span>
<span class="pill" data-si="electron">ELECTRON</span>
<span class="pill" data-si="typescript">GELECTRON</span>
</div>
</div>
<div data-in="up">
<div class="skill-group-label">CURRENTLY UNLOCKING</div>
<div class="pills">
<span class="pill soon" data-si="php">PHP</span>
<span class="pill soon" data-si="dotnet">.NET</span>
<span class="pill soon" data-si="nixos">NIX</span>
<span class="pill soon" data-si="rust">RUST</span>
</div>
</div>
</div>
</section>
<!-- ═══ PROJECTS ═══ -->
<section class="sec" id="projects">
<div class="sec-ghost" aria-hidden="true">03</div>
<div class="sec-header">
<div class="sec-eyebrow">LEVEL 03 — BUILDS</div>
<h2 class="sec-title">THE <span class="out">BUILDS</span><span class="dot">.</span></h2>
<p class="sec-sub">stuff I've made (and some I forked). every one of these was at least 80% 2am.</p>
</div>
<div class="proj-list">
<a class="proj" href="../projects/omniemu.html">
<span class="proj-num">01</span>
<div class="proj-tags"><span class="tag" style="background:var(--green);">ACTIVE</span><span class="chip chip-c" style="font-size:6px;">MIT · v0.3.2 · TS</span></div>
<div class="proj-title">OmniEmu 2.0 <span class="proj-arrow"></span></div>
<p class="proj-desc">All your emulators in one place. Install 20+ emulators, scan your ROMs, launch games without opening 15 apps.</p>
</a>
<a class="proj" href="../projects/gelectron.html">
<span class="proj-num">02</span>
<div class="proj-tags"><span class="tag" style="background:var(--yellow);">EARLY</span><span class="chip chip-y" style="font-size:6px;">RUST + NODE · MIT</span></div>
<div class="proj-title">Gelectron <span class="proj-arrow"></span></div>
<p class="proj-desc">Drop-in Electron replacement using native web views instead of bundling Chromium. The send-help project.</p>
</a>
<a class="proj" href="https://vanilla.milesallen.site/" target="_blank" rel="noopener">
<span class="proj-num">03</span>
<div class="proj-tags"><span class="tag" style="background:var(--cyan);">UNRELEASED</span><span class="chip chip-c" style="font-size:6px;">VANILLA JS</span></div>
<div class="proj-title">Vanilla <span class="proj-arrow"></span></div>
<p class="proj-desc">A clean, minimal web experiment. Pure vanilla JS, no frameworks, no cruft.</p>
</a>
<a class="proj" href="../projects/fedl.html">
<span class="proj-num">04</span>
<div class="proj-tags"><span class="tag" style="background:var(--red);">LIVE</span><span class="chip chip-p" style="font-size:6px;">2196 COMMITS</span></div>
<div class="proj-title">FEDL <span class="proj-arrow"></span></div>
<p class="proj-desc">The demon list for Geometry Dash. Ranked levels, run submissions, and a community way better at the game than me.</p>
</a>
<a class="proj" href="../projects/command-move.html">
<span class="proj-num">05</span>
<div class="proj-tags"><span class="tag" style="background:var(--purple);">SWIFT</span><span class="chip chip-g" style="font-size:6px;">MACOS · MIT</span></div>
<div class="proj-title">CommandMove <span class="proj-arrow"></span></div>
<p class="proj-desc">True cut-and-paste for Finder on macOS. Cmd+X, navigate, Cmd+V. What Apple forgot to build.</p>
</a>
<a class="proj" href="../projects/noto.html">
<span class="proj-num">06</span>
<div class="proj-tags"><span class="tag" style="background:var(--green);">ACTIVE</span><span class="chip chip-c" style="font-size:6px;">FLUTTER · AI</span></div>
<div class="proj-title">Noto <span class="proj-arrow"></span></div>
<p class="proj-desc">Note-taking with AI built in. Flutter, powered by Cortex AI, actually good at organizing my chaos.</p>
</a>
<a class="proj" href="../projects/nova.html">
<span class="proj-num">07</span>
<div class="proj-tags"><span class="tag" style="background:var(--yellow);">PYTHON</span><span class="chip chip-y" style="font-size:6px;">MIT · LOCAL AI</span></div>
<div class="proj-title">Nova AI <span class="proj-arrow"></span></div>
<p class="proj-desc">AI that runs on your machine. Desktop GUI, web interface, CLI. No cloud, no subscriptions, just vibes.</p>
</a>
<a class="proj" href="../projects/music-app.html">
<span class="proj-num">08</span>
<div class="proj-tags"><span class="tag" style="background:var(--cyan);">JS</span><span class="chip chip-c" style="font-size:6px;">APACHE-2.0</span></div>
<div class="proj-title">Music App <span class="proj-arrow"></span></div>
<p class="proj-desc">Music player that doesn't interrupt you with ads. YouTube Music minus the annoying parts.</p>
</a>
<a class="proj" href="../projects/rhythm-game.html">
<span class="proj-num">09</span>
<div class="proj-tags"><span class="tag" style="background:var(--pink);">HTML</span><span class="chip chip-p" style="font-size:6px;">MPL-2.0</span></div>
<div class="proj-title">Rhythm Game <span class="proj-arrow"></span></div>
<p class="proj-desc">Hit keys to the beat. Song selection, real-time notes, keyboard controls. My fingers hurt.</p>
</a>
<a class="proj" href="../projects/geode-mod.html">
<span class="proj-num">10</span>
<div class="proj-tags"><span class="tag" style="background:var(--orange);">WIP</span><span class="chip chip-o" style="font-size:6px;">MIT</span></div>
<div class="proj-title">FEDL Geode Mod <span class="proj-arrow"></span></div>
<p class="proj-desc">Geometry Dash mod that shows the demon list in-game. Roulette mode, banned mod detection, more.</p>
</a>
<a class="proj" href="../projects/moon-gaming.html">
<span class="proj-num">11</span>
<div class="proj-tags"><span class="tag" style="background:var(--yellow);">HTML</span><span class="chip chip-y" style="font-size:6px;">1542 COMMITS</span></div>
<div class="proj-title">Moon Gaming <span class="proj-arrow"></span></div>
<p class="proj-desc">Game hub with 1,500+ commits. A growing library of browser games I made at 2am.</p>
</a>
</div>
</section>
<!-- marquee 3 -->
<div class="mq mq-c" aria-hidden="true">
<div class="mq-track fwd" id="mq3"></div>
</div>
<!-- ═══ SCOREBOARD ═══ -->
<section class="sec" id="scoreboard">
<div class="sec-ghost" aria-hidden="true">04</div>
<div class="sec-header">
<div class="sec-eyebrow">LEVEL 04 — SCOREBOARD</div>
<h2 class="sec-title">SCORE<span class="out">BOARD</span><span class="dot">.</span></h2>
<p class="sec-sub">what my projects have achieved. all numbers real, some embarrassing.</p>
</div>
<div class="score-blocks">
<div class="score-block" data-in="up">
<div class="score-block-head"><span class="lvl-badge">HIGH SCORE</span><h3>FEDL</h3></div>
<div class="score-cells">
<div class="scell hi c1"><span class="v num" data-count="3839">0</span><span class="k">VERIFIED RUNS</span></div>
<div class="scell hi c2"><span class="v num" data-count="341">0</span><span class="k">RANKED LEVELS</span></div>
<div class="scell hi c3"><span class="v num" data-count="250" data-suffix="+">0</span><span class="k">ACTIVE PLAYERS</span></div>
<div class="scell hi c4"><span class="v num" data-count="3800" data-suffix="+">0</span><span class="k">YOUTUBE VIDEOS</span></div>
</div>
</div>
<div class="score-block" data-in="up">
<div class="score-block-head"><span class="lvl-badge">STAGE CLEAR</span><h3>OmniEmu 2.0</h3></div>
<div class="score-cells">
<div class="scell hi c1"><span class="v num" data-count="20" data-suffix="+">0</span><span class="k">EMULATORS</span></div>
<div class="scell hi c2"><span class="v num" data-count="3">0</span><span class="k">PLATFORMS</span></div>
<div class="scell"><span class="v">v0.3.2</span><span class="k">LATEST</span></div>
<div class="scell"><span class="v">TS</span><span class="k">BUILT WITH</span></div>
</div>
</div>
</div>
</section>
<!-- ═══ DEVLOG ═══ -->
<section class="sec" id="devlog">
<div class="sec-ghost" aria-hidden="true">05</div>
<div class="sec-header">
<div class="sec-eyebrow">LEVEL 05 — DEVLOG</div>
<h2 class="sec-title">THE <span class="out">DEVLOG</span><span class="dot">.</span></h2>
<p class="sec-sub">things I've learned, broken, and fixed.</p>
</div>
<div class="blog-grid">
<a class="blog-card" href="../blog/diskette-devlog.html" data-in="up">
<span class="blog-date">2026 // 001</span>
<h3 class="blog-title">Focusing on Diskette Labs</h3>
<p class="blog-excerpt">I'm co-founder of Diskette Labs, a product design collective. Where my focus is now — still open to collabs.</p>
<div class="blog-tags"><span class="btag">DESIGN</span><span class="btag">COLLECTIVE</span></div>
</a>
<a class="blog-card" href="../blog/gelectron-devlog.html" data-in="up">
<span class="blog-date">2026 // 002</span>
<h3 class="blog-title">Why I Built Gelectron</h3>
<p class="blog-excerpt">Electron bundles Chromium with every app. 150-300MB per app, hundreds of MB of RAM. Native web views fix that.</p>
<div class="blog-tags"><span class="btag">RUST</span><span class="btag">NATIVE</span></div>
</a>
<a class="blog-card" href="../blog/omniemu-devlog.html" data-in="up">
<span class="blog-date">2026 // 003</span>
<h3 class="blog-title">Why I Built OmniEmu</h3>
<p class="blog-excerpt">I got tired of opening 15 different emulator apps. So I built one that manages them all.</p>
<div class="blog-tags"><span class="btag">TYPESCRIPT</span><span class="btag">ELECTRON</span></div>
</a>
<a class="blog-card" href="../blog/command-move-devlog.html" data-in="up">
<span class="blog-date">2026 // 004</span>
<h3 class="blog-title">CommandMove: Cut &amp; Paste</h3>
<p class="blog-excerpt">macOS doesn't have Cmd+X for files. I fixed that with global event taps and AppleScript.</p>
<div class="blog-tags"><span class="btag">SWIFT</span><span class="btag">MACOS</span></div>
</a>
<a class="blog-card" href="../blog/fedl-devlog.html" data-in="up">
<span class="blog-date">2025 // 005</span>
<h3 class="blog-title">Running the FEDL</h3>
<p class="blog-excerpt">What it takes to maintain a Geometry Dash demon list. 3,800+ verified runs and a community that never sleeps.</p>
<div class="blog-tags"><span class="btag">NODE.JS</span><span class="btag">COMMUNITY</span></div>
</a>
<a class="blog-card" href="../blog/nova-devlog.html" data-in="up">
<span class="blog-date">2025 // 006</span>
<h3 class="blog-title">Building Nova AI</h3>
<p class="blog-excerpt">Local AI that doesn't phone home. Desktop GUI, web interface, CLI — no subscriptions, no cloud.</p>
<div class="blog-tags"><span class="btag">PYTHON</span><span class="btag">AI</span></div>
</a>
</div>
</section>
<!-- marquee 4 -->
<div class="mq mq-o" aria-hidden="true">
<div class="mq-track rev" id="mq4"></div>
</div>
<!-- ═══ CONTACT ═══ -->
<section class="sec" id="contact">
<div class="sec-ghost" aria-hidden="true">06</div>
<div class="sec-header">
<div class="sec-eyebrow">LEVEL 06 — REACH OUT</div>
<h2 class="sec-title">GET IN <span class="out">TOUCH</span><span class="dot">.</span></h2>
<p class="sec-sub">unless you're a bot, then please go away.</p>
</div>
<div class="contact-rows" data-in="up">
<a class="crow" href="mailto:[email protected]"><span class="k">EMAIL</span><span class="v">[email protected]<span class="arr"></span></span></a>
<a class="crow" href="https://github.com/mileswolfallen2" target="_blank" rel="noopener"><span class="k">GITHUB</span><span class="v">mileswolfallen2<span class="arr"></span></span></a>
<a class="crow" href="https://replit.com/@MilesAllen1" target="_blank" rel="noopener"><span class="k">REPLIT</span><span class="v">@MilesAllen1<span class="arr"></span></span></a>
<a class="crow" href="https://codepen.io/mileswolfallen2-the-typescripter" target="_blank" rel="noopener"><span class="k">CODEPEN</span><span class="v">mileswolfallen2<span class="arr"></span></span></a>
<a class="crow" href="https://me.fedl.site" target="_blank" rel="noopener"><span class="k">WEBSITE</span><span class="v">me.fedl.site<span class="arr"></span></span></a>
</div>
</section>
<!-- ═══ FOOTER ═══ -->
<footer class="footer">
<div class="footer-word" aria-hidden="true">MILES</div>
<div class="footer-meta">
<a href="#top">BACK TO TOP ↑</a>
<a href="../uses.html">USES</a>
<a href="../now.html">NOW</a>
<a href="../colophon.html">COLOPHON</a>
<span>BUILT BY MILES © 2026</span>
</div>
<div class="to-top">
<button class="btn btn-yellow" onclick="window.scrollTo({top:0,behavior:'smooth'})">↑ TOP</button>
</div>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>
<script>
(function () {
'use strict';
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var fine = window.matchMedia && window.matchMedia('(pointer: fine)').matches;
/* ── marquee content ── */
var mqSets = {
mq1: ['BUILDING EMULATORS','SEND HELP','160 REPOS','STILL DEBUGGING','GD ADDICT','USUALLY ONLINE','FULL MAXIMALISM','CEREAL IS SOUP'],
mq2: ['RATED ★★★★★','EST. 2008','PULL SHARK ×2','OVERCLOCKED','DISKETTE LABS','COFFEE COUNT: UNKNOWN','BUGS: INFINITE','YOLO'],
mq3: ['OMNIEMU 2.0','GELECTRON','FEDL','NOTO','NOVA AI','COMMANDMOVE','MOON GAMING','1500+ COMMITS','MIT LICENSE'],
mq4: ['EMAIL ME','PLEASE','GITHUB ↗','REPLIT ↗','CODEPEN ↗','I RESPOND','MAYBE','FAST'],
};
Object.keys(mqSets).forEach(function (id) {
var el = document.getElementById(id);
if (!el) return;
var half = '';
mqSets[id].forEach(function (t) { half += '<span>★ ' + t + '</span>'; });
el.innerHTML = half + half;
});
/* ── skill icons ── */
document.querySelectorAll('.pill[data-si]').forEach(function (pill) {
var img = document.createElement('img');
img.alt = ''; img.loading = 'lazy';
img.src = 'https://cdn.simpleicons.org/' + pill.getAttribute('data-si') + '/000000';
pill.insertBefore(img, pill.firstChild);
});
/* ── cursor ── */
var dotEl = document.getElementById('dot');
var haloEl = document.getElementById('halo');
if (dotEl && fine) {
var tx = -200, ty = -200, dx = -200, dy = -200, hx = -200, hy = -200;
document.addEventListener('mousemove', function (e) { tx = e.clientX; ty = e.clientY; }, { passive: true });
(function loop() {
dx += (tx - dx) * 0.38; dy += (ty - dy) * 0.38;
hx += (tx - hx) * 0.07; hy += (ty - hy) * 0.07;
dotEl.style.left = dx + 'px'; dotEl.style.top = dy + 'px';
haloEl.style.left = hx + 'px'; haloEl.style.top = hy + 'px';
requestAnimationFrame(loop);
})();
document.addEventListener('mouseover', function (e) {
if (e.target.closest && e.target.closest('a,button,.btn,.pill,.proj,.crow,.blog-card,.stat-card')) {
dotEl.classList.add('big');
}
}, { passive: true });
document.addEventListener('mouseout', function (e) {
if (e.target.closest && e.target.closest('a,button,.btn,.pill,.proj,.crow,.blog-card,.stat-card')) {
dotEl.classList.remove('big');
}
}, { passive: true });
}
/* ── scroll progress ── */
var prog = document.getElementById('progress');
function updateProg() {
var pct = window.scrollY / (document.body.scrollHeight - window.innerHeight) * 100;
prog.style.width = pct + '%';
}
window.addEventListener('scroll', updateProg, { passive: true });
updateProg();
/* ── count-up ── */
function countUp(el) {
var target = parseInt(el.getAttribute('data-count'), 10) || 0;
var suffix = el.getAttribute('data-suffix') || '';
if (reduce) { el.textContent = target.toLocaleString('en-US') + suffix; return; }
var t0 = null;
function step(ts) {
if (t0 === null) t0 = ts;
var p = Math.min(1, (ts - t0) / 1300);
var ease = 1 - Math.pow(1 - p, 3);
el.textContent = Math.round(target * ease).toLocaleString('en-US') + suffix;
if (p < 1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
if ('IntersectionObserver' in window) {
var cio = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
if (e.isIntersecting) { countUp(e.target); cio.unobserve(e.target); }
});
}, { threshold: 0.5 });
document.querySelectorAll('.num[data-count]').forEach(function (el) { cio.observe(el); });
}
/* ── reveal system ── */
function revealAll() {
document.querySelectorAll('[data-in]').forEach(function (el) { el.classList.add('in'); });
}
if ('IntersectionObserver' in window && !reduce) {
var rio = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
if (e.isIntersecting) { e.target.classList.add('in'); rio.unobserve(e.target); }
});
}, { threshold: 0.12, rootMargin: '0px 0px -36px 0px' });
document.querySelectorAll('[data-in]').forEach(function (el) { rio.observe(el); });
} else {
revealAll();
}
/* ── konami ── */
(function () {
var seq = [38,38,40,40,37,39,37,39,66,65], pos = 0;
document.addEventListener('keydown', function (e) {
pos = (e.keyCode === seq[pos]) ? pos + 1 : 0;
if (pos === seq.length) { pos = 0; party(); }
});
function party() {
var colors = ['#FF2EA6','#F7FF00','#00F4FF','#FF5C00','#00FF85','#FF1F1F'];
for (var i = 0; i < 40; i++) {
var s = document.createElement('div');
s.style.cssText = 'position:fixed;left:50%;top:50%;z-index:9999;pointer-events:none;width:' + (6 + Math.random() * 14) + 'px;height:' + (6 + Math.random() * 14) + 'px;border:2px solid #000;background:' + colors[i % colors.length] + ';box-shadow:3px 3px 0 #000;';
document.body.appendChild(s);
var ang = Math.random() * Math.PI * 2;
var dist = 60 + Math.random() * 380;
s.animate([
{ transform: 'translate(-50%,-50%) rotate(0deg)', opacity: 1 },
{ transform: 'translate(calc(-50% + ' + (Math.cos(ang)*dist) + 'px), calc(-50% + ' + (Math.sin(ang)*dist) + 'px)) rotate(' + (Math.random()*720-360) + 'deg)', opacity: 0 }
], { duration: 900 + Math.random() * 500, easing: 'cubic-bezier(.2,.8,.2,1)' }).onfinish = (function(el){ return function(){ el.remove(); }; })(s);
}
}
})();
/* ── GSAP choreography ── */
if (window.gsap && window.ScrollTrigger && !reduce) {
gsap.registerPlugin(ScrollTrigger);
/* hero title parallax */
gsap.to('#heroTitle', {
yPercent: -16, scale: .95, opacity: .2, ease: 'none',
scrollTrigger: { trigger: '#top', start: 'top top', end: 'bottom top', scrub: 1 }
});
gsap.to('.hero-sub', {
yPercent: -55, opacity: 0, ease: 'none',
scrollTrigger: { trigger: '#top', start: '8% top', end: 'bottom top', scrub: 1 }
});
gsap.to('.hero-orb', {
scale: 1.18, opacity: .25, ease: 'none',
scrollTrigger: { trigger: '#top', start: 'top top', end: 'bottom top', scrub: 1 }
});
/* section title band slide */
gsap.utils.toArray('.sec-title').forEach(function (t) {
var dir = gsap.utils.toArray('.sec').indexOf(t.closest('.sec')) % 2 === 0 ? 1 : -1;
gsap.fromTo(t, { xPercent: dir * 7 }, { xPercent: dir * -7, ease: 'none',
scrollTrigger: { trigger: t, start: 'top bottom', end: 'bottom top', scrub: 1 }
});
});
/* project cards stagger in */
gsap.utils.toArray('.proj').forEach(function (card) {
var dir = card.dataset.in ? 0 : (Math.random() > .5 ? 1 : -1);
gsap.set(card, { transition: 'none' });
gsap.fromTo(card,
{ y: 80, rotation: dir * 3.5, opacity: 0 },
{ y: 0, rotation: 0, opacity: 1, duration: .9, ease: 'power3.out',
scrollTrigger: { trigger: card, start: 'top 95%' },
onComplete: function () { gsap.set(card, { clearProps: 'transform,opacity,transition' }); }
});
});
ScrollTrigger.refresh();
} else if (!reduce) {
setTimeout(function () {
document.querySelectorAll('.proj').forEach(function (c) { c.style.opacity = '1'; });
}, 1400);
}
})();
</script>
</body>
</html>